Merge remote-tracking branch 'origin/master' into dont-use-docdata-for-annots-and-forms
|
@ -68,6 +68,17 @@ set_package_properties(KF5Kirigami2 PROPERTIES
|
|||
TYPE RUNTIME
|
||||
)
|
||||
find_package(Phonon4Qt5 CONFIG REQUIRED)
|
||||
find_package(KDEExperimentalPurpose)
|
||||
set_package_properties(KDEExperimentalPurpose PROPERTIES
|
||||
DESCRIPTION "A framework for services and actions integration"
|
||||
PURPOSE "Required for enabling the share menu in Okular"
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
if (KDEExperimentalPurpose_FOUND)
|
||||
set(PURPOSE_FOUND 1)
|
||||
else()
|
||||
set(PURPOSE_FOUND 0)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules)
|
||||
|
||||
|
@ -197,7 +208,7 @@ ki18n_wrap_ui(okularcore_SRCS
|
|||
core/chooseenginewidget.ui
|
||||
)
|
||||
|
||||
kconfig_add_kcfg_files(okularcore_SRCS conf/settings_core.kcfgc )
|
||||
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")
|
||||
|
@ -323,7 +334,7 @@ ki18n_wrap_ui(okularpart_SRCS
|
|||
conf/dlgpresentationbase.ui
|
||||
)
|
||||
|
||||
kconfig_add_kcfg_files(okularpart_SRCS conf/settings.kcfgc )
|
||||
kconfig_add_kcfg_files(okularpart_SRCS conf/settings.kcfgc)
|
||||
|
||||
add_library(okularpart SHARED ${okularpart_SRCS})
|
||||
generate_export_header(okularpart BASE_NAME okularpart)
|
||||
|
@ -347,6 +358,10 @@ target_link_libraries(okularpart okularcore
|
|||
KF5::WindowSystem
|
||||
)
|
||||
|
||||
if (KDEExperimentalPurpose_FOUND)
|
||||
target_link_libraries(okularpart KDEExperimental::PurposeWidgets)
|
||||
endif()
|
||||
|
||||
set_target_properties(okularpart PROPERTIES PREFIX "")
|
||||
|
||||
if (Qt5TextToSpeech_FOUND)
|
||||
|
|
BIN
autotests/data/pdf_with_links.pdf
Normal file
|
@ -21,6 +21,9 @@
|
|||
#include <QScrollBar>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTreeView>
|
||||
#include <QUrl>
|
||||
#include <QDesktopServices>
|
||||
#include <QMenu>
|
||||
|
||||
namespace Okular
|
||||
{
|
||||
|
@ -31,6 +34,9 @@ class PartTest
|
|||
|
||||
static bool openDocument(Okular::Part *part, const QString &filePath);
|
||||
|
||||
signals:
|
||||
void urlHandler(const QUrl &url);
|
||||
|
||||
private slots:
|
||||
void testReload();
|
||||
void testCanceledReload();
|
||||
|
@ -42,6 +48,19 @@ class PartTest
|
|||
void testClickInternalLink();
|
||||
void testSaveAs();
|
||||
void testSaveAs_data();
|
||||
void testMouseMoveOverLinkWhileInSelectionMode();
|
||||
void testClickUrlLinkWhileInSelectionMode();
|
||||
void testeTextSelectionOverAndAcrossLinks_data();
|
||||
void testeTextSelectionOverAndAcrossLinks();
|
||||
void testClickUrlLinkWhileLinkTextIsSelected();
|
||||
void testRClickWhileLinkTextIsSelected();
|
||||
void testRClickOverLinkWhileLinkTextIsSelected();
|
||||
void testRClickOnSelectionModeShoulShowFollowTheLinkMenu();
|
||||
void testClickAnywhereAfterSelectionShouldUnselect();
|
||||
void testeRectSelectionStartingOnLinks();
|
||||
|
||||
private:
|
||||
void simulateMouseSelection(double startX, double startY, double endX, double endY, QWidget *target);
|
||||
};
|
||||
|
||||
class PartThatHijacksQueryClose : public Okular::Part
|
||||
|
@ -71,6 +90,7 @@ class PartThatHijacksQueryClose : public Okular::Part
|
|||
Behavior behavior;
|
||||
};
|
||||
|
||||
|
||||
bool PartTest::openDocument(Okular::Part *part, const QString &filePath)
|
||||
{
|
||||
part->openDocument( filePath );
|
||||
|
@ -214,13 +234,7 @@ void PartTest::testSelectText()
|
|||
const int mouseStartX = width * 0.12;
|
||||
const int mouseEndX = width * 0.7;
|
||||
|
||||
QTest::mouseMove(part.m_pageView->viewport(), QPoint(mouseStartX, mouseY));
|
||||
QTest::mousePress(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(mouseStartX, mouseY));
|
||||
QTest::mouseMove(part.m_pageView->viewport(), QPoint(mouseEndX, mouseY));
|
||||
// without this wait the test fails. 100ms were enough on my local system, but when running under valgrind
|
||||
// or on the CI server we need to wait longer.
|
||||
QTest::qWait(1000);
|
||||
QTest::mouseRelease(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(mouseEndX, mouseY));
|
||||
simulateMouseSelection(mouseStartX, mouseY, mouseEndX, mouseY, part.m_pageView->viewport());
|
||||
|
||||
QApplication::clipboard()->clear();
|
||||
QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "copyTextSelection"));
|
||||
|
@ -244,14 +258,474 @@ void PartTest::testClickInternalLink()
|
|||
part.m_document->setViewportPage(0);
|
||||
|
||||
// wait for pixmap
|
||||
while (!part.m_document->page(0)->hasPixmap(part.m_pageView))
|
||||
QTest::qWait(100);
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseNormal");
|
||||
|
||||
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));
|
||||
QCOMPARE(part.m_document->currentPage(), 1u);
|
||||
QTRY_COMPARE(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();
|
||||
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);
|
||||
|
||||
// wait for pixmap
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
// 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();
|
||||
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);
|
||||
|
||||
// wait for pixmap
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
// enter text-selection mode
|
||||
QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect"));
|
||||
|
||||
// overwrite urlHandler for 'mailto' urls
|
||||
QDesktopServices::setUrlHandler("mailto", this, "urlHandler");
|
||||
QSignalSpy openUrlSignalSpy(this, SIGNAL(urlHandler(QUrl)));
|
||||
|
||||
// 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<QVariant> arguments = openUrlSignalSpy.takeFirst();
|
||||
QCOMPARE(arguments.at(0).value<QUrl>(), QUrl("mailto:foo@foo.bar"));
|
||||
}
|
||||
|
||||
void PartTest::testeTextSelectionOverAndAcrossLinks_data()
|
||||
{
|
||||
QTest::addColumn<double>("mouseStartX");
|
||||
QTest::addColumn<double>("mouseEndX");
|
||||
QTest::addColumn<QString>("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();
|
||||
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);
|
||||
|
||||
// wait for pixmap
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
// 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();
|
||||
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);
|
||||
|
||||
// wait for pixmap
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
// 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("mailto", this, "urlHandler");
|
||||
QSignalSpy openUrlSignalSpy(this, SIGNAL(urlHandler(QUrl)));
|
||||
|
||||
// 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<QVariant> arguments = openUrlSignalSpy.takeFirst();
|
||||
QCOMPARE(arguments.at(0).value<QUrl>(), 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();
|
||||
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);
|
||||
|
||||
// wait for pixmap
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
// 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;
|
||||
QTimer::singleShot(2000, [view]() {
|
||||
// check if popup menu is active and visible
|
||||
QMenu *menu = qobject_cast<QMenu*>(view->findChild<QMenu*>("PopupMenu"));
|
||||
QVERIFY(menu);
|
||||
QVERIFY(menu->isVisible());
|
||||
|
||||
// check if the menu contains go-to link action
|
||||
QAction *goToAction = qobject_cast<QAction*>(menu->findChild<QAction*>("GoToAction"));
|
||||
QVERIFY(goToAction);
|
||||
|
||||
// check if the "follow this link" action is not visible
|
||||
QAction *processLinkAction = qobject_cast<QAction*>(menu->findChild<QAction*>("ProcessLinkAction"));
|
||||
QVERIFY(!processLinkAction);
|
||||
|
||||
// check if the "copy link address" action is not visible
|
||||
QAction *copyLinkLocation = qobject_cast<QAction*>(menu->findChild<QAction*>("CopyLinkLocationAction"));
|
||||
QVERIFY(!copyLinkLocation);
|
||||
|
||||
// close menu to continue test
|
||||
menu->close();
|
||||
});
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
// 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();
|
||||
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);
|
||||
|
||||
// wait for pixmap
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
// 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;
|
||||
QTimer::singleShot(2000, [view]() {
|
||||
// check if popup menu is active and visible
|
||||
QMenu *menu = qobject_cast<QMenu*>(view->findChild<QMenu*>("PopupMenu"));
|
||||
QVERIFY(menu);
|
||||
QVERIFY(menu->isVisible());
|
||||
|
||||
// check if the menu contains "follow this link" action
|
||||
QAction *processLinkAction = qobject_cast<QAction*>(menu->findChild<QAction*>("ProcessLinkAction"));
|
||||
QVERIFY(processLinkAction);
|
||||
|
||||
// check if the menu contains "copy link address" action
|
||||
QAction *copyLinkLocation = qobject_cast<QAction*>(menu->findChild<QAction*>("CopyLinkLocationAction"));
|
||||
QVERIFY(copyLinkLocation);
|
||||
|
||||
// close menu to continue test
|
||||
menu->close();
|
||||
});
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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();
|
||||
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);
|
||||
|
||||
// wait for pixmap
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
// 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;
|
||||
QTimer::singleShot(2000, [view]() {
|
||||
// check if popup menu is active and visible
|
||||
QMenu *menu = qobject_cast<QMenu*>(view->findChild<QMenu*>("PopupMenu"));
|
||||
QVERIFY(menu);
|
||||
QVERIFY(menu->isVisible());
|
||||
|
||||
// check if the menu contains "Follow this link" action
|
||||
QAction *processLink = qobject_cast<QAction*>(menu->findChild<QAction*>("ProcessLinkAction"));
|
||||
QVERIFY(processLink);
|
||||
|
||||
// chek if the menu contains "Copy Link Address" action
|
||||
QAction *actCopyLinkLocation = qobject_cast<QAction*>(menu->findChild<QAction*>("CopyLinkLocationAction"));
|
||||
QVERIFY(actCopyLinkLocation);
|
||||
|
||||
// close menu to continue test
|
||||
menu->close();
|
||||
});
|
||||
|
||||
// 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);
|
||||
QTest::qWait(3000);
|
||||
|
||||
// will continue after pop-menu get closed
|
||||
}
|
||||
|
||||
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();
|
||||
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);
|
||||
|
||||
// wait for pixmap
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
// 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")));
|
||||
// resize window to avoid problem with selection areas
|
||||
part.widget()->resize(800, 600);
|
||||
part.widget()->show();
|
||||
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);
|
||||
|
||||
// wait for pixmap
|
||||
QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView));
|
||||
|
||||
// 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;
|
||||
QTimer::singleShot(2000, [view]() {
|
||||
QApplication::clipboard()->clear();
|
||||
|
||||
// check if popup menu is active and visible
|
||||
QMenu *menu = qobject_cast<QMenu*>(view->findChild<QMenu*>("PopupMenu"));
|
||||
QVERIFY(menu);
|
||||
QVERIFY(menu->isVisible());
|
||||
|
||||
// check if the copy selected text to clipboard is present
|
||||
QAction *copyAct = qobject_cast<QAction*>(menu->findChild<QAction*>("CopyTextToClipboard"));
|
||||
QVERIFY(copyAct);
|
||||
|
||||
menu->close();
|
||||
});
|
||||
|
||||
simulateMouseSelection(mouseStartX, mouseStartY, mouseEndX, mouseEndY, part.m_pageView->viewport());
|
||||
|
||||
// wait menu get closed
|
||||
}
|
||||
|
||||
|
||||
void PartTest::simulateMouseSelection(double startX, double startY, double endX, double endY, QWidget *target)
|
||||
{
|
||||
QTestEventList events;
|
||||
events.addMouseMove(QPoint(startX, startY));
|
||||
events.addMousePress(Qt::LeftButton, Qt::NoModifier, QPoint(startX, startY));
|
||||
events.addMouseMove(QPoint(endX, endY));
|
||||
// without this wait the test fails. 100ms were enough on my local system, but when running under valgrind
|
||||
// or on the CI server we need to wait longer.
|
||||
events.addDelay(1000);
|
||||
events.addMouseRelease(Qt::LeftButton, Qt::NoModifier, QPoint(endX, endY));
|
||||
|
||||
events.simulate(target);
|
||||
}
|
||||
|
||||
void PartTest::testSaveAs()
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <config-okular.h>
|
||||
|
||||
#include "ui_dlggeneralbase.h"
|
||||
#include "settings.h"
|
||||
|
||||
DlgGeneral::DlgGeneral( QWidget * parent, Okular::EmbedMode embedMode )
|
||||
: QWidget( parent )
|
||||
|
@ -21,6 +22,8 @@ DlgGeneral::DlgGeneral( QWidget * parent, Okular::EmbedMode embedMode )
|
|||
m_dlg = new Ui_DlgGeneralBase();
|
||||
m_dlg->setupUi( this );
|
||||
|
||||
setCustomBackgroundColorButton( Okular::Settings::useCustomBackgroundColor() );
|
||||
|
||||
if( embedMode == Okular::ViewerWidgetMode )
|
||||
{
|
||||
m_dlg->kcfg_SyncThumbnailsViewport->setVisible( false );
|
||||
|
@ -48,3 +51,7 @@ void DlgGeneral::showEvent( QShowEvent * )
|
|||
#endif
|
||||
}
|
||||
|
||||
void DlgGeneral::setCustomBackgroundColorButton( bool value )
|
||||
{
|
||||
m_dlg->kcfg_BackgroundColor->setEnabled( value );
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ class DlgGeneral : public QWidget
|
|||
explicit DlgGeneral( QWidget * parent, Okular::EmbedMode embedMode );
|
||||
virtual ~DlgGeneral();
|
||||
|
||||
public slots:
|
||||
void setCustomBackgroundColorButton( bool value );
|
||||
|
||||
protected:
|
||||
void showEvent( QShowEvent * ) override;
|
||||
|
||||
|
|
|
@ -2,12 +2,15 @@
|
|||
<ui version="4.0">
|
||||
<class>DlgGeneralBase</class>
|
||||
<widget class="QWidget" name="DlgGeneralBase">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>558</width>
|
||||
<height>575</height>
|
||||
<height>632</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
|
@ -140,6 +143,30 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="horizontalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="1">
|
||||
<widget class="KColorButton" name="kcfg_BackgroundColor">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="kcfg_UseCustomBackgroundColor">
|
||||
<property name="text">
|
||||
<string>Use custom background color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
|
@ -439,9 +466,39 @@ For files which were opened before the previous zoom is applied.</string>
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>kcolorbutton.h</header>
|
||||
<slots>
|
||||
<slot>useDefaultBackgroundColor()</slot>
|
||||
</slots>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<includes>
|
||||
<include location="global">kiconloader.h</include>
|
||||
</includes>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>kcfg_UseCustomBackgroundColor</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>DlgGeneralBase</receiver>
|
||||
<slot>setCustomBackgroundColorButton(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>130</x>
|
||||
<y>229</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>203</x>
|
||||
<y>-9</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>setCustomBackgroundColorButton(bool)</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
|
|
|
@ -290,6 +290,11 @@
|
|||
<entry key="ShowSourceLocationsGraphically" type="Bool" >
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry key="UseCustomBackgroundColor" type="Bool" >
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry key="BackgroundColor" type="Color" >
|
||||
</entry>
|
||||
</group>
|
||||
<group name="Search" >
|
||||
<entry key="SearchCaseSensitive" type="Bool">
|
||||
|
|
|
@ -26,7 +26,7 @@ WidgetConfigurationToolsBase::WidgetConfigurationToolsBase( QWidget * parent )
|
|||
{
|
||||
QHBoxLayout *hBoxLayout = new QHBoxLayout( this );
|
||||
m_list = new QListWidget( this );
|
||||
m_list->setIconSize( QSize( 64, 64 ) );
|
||||
m_list->setIconSize( QSize( 32, 32 ) );
|
||||
hBoxLayout->addWidget( m_list );
|
||||
|
||||
QVBoxLayout *vBoxLayout = new QVBoxLayout();
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/* 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}
|
||||
|
||||
|
|
|
@ -1512,7 +1512,7 @@ void DocumentPrivate::refreshPixmaps( int pageNumber )
|
|||
for ( ; it != itEnd; ++it )
|
||||
{
|
||||
QSize size = (*it).m_pixmap->size();
|
||||
PixmapRequest * p = new PixmapRequest( it.key(), pageNumber, size.width(), size.height(), 1, PixmapRequest::Asynchronous );
|
||||
PixmapRequest * p = new PixmapRequest( it.key(), pageNumber, size.width() / qApp->devicePixelRatio(), size.height() / qApp->devicePixelRatio(), 1, PixmapRequest::Asynchronous );
|
||||
p->d->mForce = true;
|
||||
requestedPixmaps.push_back( p );
|
||||
}
|
||||
|
@ -1524,7 +1524,7 @@ void DocumentPrivate::refreshPixmaps( int pageNumber )
|
|||
{
|
||||
tilesManager->markDirty();
|
||||
|
||||
PixmapRequest * p = new PixmapRequest( observer, pageNumber, tilesManager->width(), tilesManager->height(), 1, PixmapRequest::Asynchronous );
|
||||
PixmapRequest * p = new PixmapRequest( observer, pageNumber, tilesManager->width() / qApp->devicePixelRatio(), tilesManager->height() / qApp->devicePixelRatio(), 1, PixmapRequest::Asynchronous );
|
||||
|
||||
NormalizedRect tilesRect;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "generator_p.h"
|
||||
#include "observer.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <qeventloop.h>
|
||||
#include <QtPrintSupport/QPrinter>
|
||||
|
||||
|
@ -495,8 +496,8 @@ PixmapRequest::PixmapRequest( DocumentObserver *observer, int pageNumber, int wi
|
|||
{
|
||||
d->mObserver = observer;
|
||||
d->mPageNumber = pageNumber;
|
||||
d->mWidth = width;
|
||||
d->mHeight = height;
|
||||
d->mWidth = ceil(width * qApp->devicePixelRatio());
|
||||
d->mHeight = ceil(height * qApp->devicePixelRatio());
|
||||
d->mPriority = priority;
|
||||
d->mFeatures = features;
|
||||
d->mForce = false;
|
||||
|
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 24 KiB |
|
@ -34,7 +34,7 @@ Context menu actions like Rename Bookmarks etc.)
|
|||
<!-- TRANS:ROLES_OF_TRANSLATORS -->
|
||||
</authorgroup>
|
||||
<legalnotice>&FDLNotice;</legalnotice>
|
||||
<date>2017-08-26</date>
|
||||
<date>2017-10-02</date>
|
||||
<releaseinfo>1.3 (Applications 17.12)</releaseinfo>
|
||||
<!-- Abstract about this handbook -->
|
||||
<abstract>
|
||||
|
@ -1111,6 +1111,19 @@ Context menu actions like Rename Bookmarks etc.)
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<menuchoice>
|
||||
<guimenu>File</guimenu>
|
||||
<guisubmenu>Share</guisubmenu>
|
||||
</menuchoice>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>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.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<menuchoice>
|
||||
|
@ -2003,6 +2016,22 @@ Context menu actions like Rename Bookmarks etc.)
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Use custom background color</guilabel></term>
|
||||
<listitem>
|
||||
<para>Enables <ulink url="help:/fundamentals/colors.html">choosing the document background color</ulink> (the color around the displayed page). By default, the &Qt; toolkit color is used when this option is unchecked.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Open new files in tabs</guilabel></term>
|
||||
<listitem>
|
||||
<para>Whether to open new documents in tabs. The tabs are disabled by default.</para>
|
||||
<para>
|
||||
The default shortcuts to switch between tabs are <keycombo>&Ctrl;<keycap>.</keycap></keycombo> (<guilabel>Next tab</guilabel>) and <keycombo>&Ctrl;<keycap>,</keycap></keycombo> (<guilabel>Previous tab</guilabel>).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Obey DRM limitations</guilabel></term>
|
||||
<listitem>
|
||||
|
@ -2013,15 +2042,6 @@ Context menu actions like Rename Bookmarks etc.)
|
|||
of &okular;, this option is not available.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Open new files in tabs</guilabel></term>
|
||||
<listitem>
|
||||
<para>Whether to open new documents in tabs. The tabs are disabled by default.</para>
|
||||
<para>
|
||||
The default shortcuts to switch between tabs are <keycombo>&Ctrl;<keycap>.</keycap></keycombo> (<guilabel>Next tab</guilabel>) and <keycombo>&Ctrl;<keycap>,</keycap></keycombo> (<guilabel>Previous tab</guilabel>).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Reload document on file change</guilabel></term>
|
||||
<listitem>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">CHM-tiedostot</name>
|
||||
<name xml:lang="fr">Documents CHM</name>
|
||||
<name xml:lang="gl">Documentos CHM</name>
|
||||
<name xml:lang="ia">Documentos CHM</name>
|
||||
<name xml:lang="it">Documenti CHM</name>
|
||||
<name xml:lang="ko">CHM 문서</name>
|
||||
<name xml:lang="nl">CHM-documenten</name>
|
||||
<name xml:lang="nn">CHM-dokument</name>
|
||||
<name xml:lang="pl">Dokumenty CHM</name>
|
||||
<name xml:lang="pt">Documentos CHM</name>
|
||||
<name xml:lang="ru">Документы CHM</name>
|
||||
<name xml:lang="sk">CHM dokumenty</name>
|
||||
<name xml:lang="sl">Dokumenti CHM</name>
|
||||
<name xml:lang="sr">ЦХМ документи</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää CHM-tiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents CHM</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos CHM.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos CHM</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti CHM</summary>
|
||||
<summary xml:lang="ko">CHM 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van CHM-documenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa CHM-dokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę dokumnetów CHM</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para a leitura de documentos CHM</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения документов CHM</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie CHM dokumentov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje dokumentov CHM</summary>
|
||||
<summary xml:lang="sr">Подршка за читање ЦХМ докумената</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">Sarjakuvakirjat</name>
|
||||
<name xml:lang="fr">Bandes dessinées</name>
|
||||
<name xml:lang="gl">Libros de banda deseñada</name>
|
||||
<name xml:lang="ia">Libros de Comic</name>
|
||||
<name xml:lang="it">Fumetti</name>
|
||||
<name xml:lang="ko">만화책</name>
|
||||
<name xml:lang="nl">Stripboeken</name>
|
||||
<name xml:lang="nn">Teikneseriar</name>
|
||||
<name xml:lang="pl">Komiksy</name>
|
||||
<name xml:lang="pt">Banda Desenhada</name>
|
||||
<name xml:lang="ru">Комиксы</name>
|
||||
<name xml:lang="sk">Knihy komiksov</name>
|
||||
<name xml:lang="sl">Stripi</name>
|
||||
<name xml:lang="sr">Стрипови</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää sarjakuvakirjojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des bandes dessinées</summary>
|
||||
<summary xml:lang="gl">Permite ler libros de banda deseñada.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger libros de comic</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di fumetti</summary>
|
||||
<summary xml:lang="ko">만화책 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van stripboeken toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa teikneseriefiler</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę komiksów</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler livros de banda desenhada</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения комиксов</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie komiksov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje stripov</summary>
|
||||
<summary xml:lang="sr">Подршка за читање стрипова</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">DjVu-tiedostot</name>
|
||||
<name xml:lang="fr">Documents DjVu</name>
|
||||
<name xml:lang="gl">Documentos DjVu</name>
|
||||
<name xml:lang="ia">Documentos DjVu</name>
|
||||
<name xml:lang="it">Documenti DjVu</name>
|
||||
<name xml:lang="ko">DjVu 문서</name>
|
||||
<name xml:lang="nl">DjVu-documenten</name>
|
||||
<name xml:lang="nn">DjVu-dokument</name>
|
||||
<name xml:lang="pl">Dokumenty DjVu</name>
|
||||
<name xml:lang="pt">Documentos DjVu</name>
|
||||
<name xml:lang="ru">Документы DjVu</name>
|
||||
<name xml:lang="sk">DjVu dokumenty</name>
|
||||
<name xml:lang="sl">Dokumenti DjVu</name>
|
||||
<name xml:lang="sr">ДјВу документи</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää DjVu-tiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents DjVu</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos de DjVu.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos DjVu</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti DjVu</summary>
|
||||
<summary xml:lang="ko">DjVu 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van DjVu-documenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa DjVu-dokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania dokumentów DjVu</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para a leitura de documentos DjVu</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения документов DjVu</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie DjVu dokumentov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje dokumentov DjVu</summary>
|
||||
<summary xml:lang="sr">Подршка за читање ДјВу докумената</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">DVI-tiedostot</name>
|
||||
<name xml:lang="fr">Documents DVI</name>
|
||||
<name xml:lang="gl">Documentos DVI</name>
|
||||
<name xml:lang="ia">Documentos DVI</name>
|
||||
<name xml:lang="it">Documenti DVI</name>
|
||||
<name xml:lang="ko">DVI 문서</name>
|
||||
<name xml:lang="nl">DVI-documenten</name>
|
||||
<name xml:lang="nn">DVI-dokument</name>
|
||||
<name xml:lang="pl">Dokumenty DVI</name>
|
||||
<name xml:lang="pt">Documentos DVI</name>
|
||||
<name xml:lang="ru">Документы DVI</name>
|
||||
<name xml:lang="sk">DVI dokumenty</name>
|
||||
<name xml:lang="sl">Dokumenti DVI</name>
|
||||
<name xml:lang="sr">ДВИ документи</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää DVI-tiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents DVI</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos DVI.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos DVI</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti DVI</summary>
|
||||
<summary xml:lang="ko">DVI 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van DVI-documenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa DVI-dokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę dokumnetów DVI</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para a leitura de documentos DVI</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения документов DVI</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie DVI dokumentov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje dokumentov DVI</summary>
|
||||
<summary xml:lang="sr">Подршка за читање ДВИ докумената</summary>
|
||||
|
|
|
@ -183,7 +183,7 @@ X-KDE-Keywords[et]=epub, e-book, e-raamat
|
|||
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[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
|
||||
|
|
|
@ -173,7 +173,7 @@ X-KDE-Keywords[et]=epub, e-book, e-raamat
|
|||
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[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
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">EPub</name>
|
||||
<name xml:lang="fr">EPub</name>
|
||||
<name xml:lang="gl">EPub</name>
|
||||
<name xml:lang="ia">EPub</name>
|
||||
<name xml:lang="it">EPub</name>
|
||||
<name xml:lang="ko">EPub</name>
|
||||
<name xml:lang="nl">EPub</name>
|
||||
<name xml:lang="nn">EPUB</name>
|
||||
<name xml:lang="pl">EPub</name>
|
||||
<name xml:lang="pt">EPub</name>
|
||||
<name xml:lang="ru">EPub</name>
|
||||
<name xml:lang="sk">EPub</name>
|
||||
<name xml:lang="sl">EPub</name>
|
||||
<name xml:lang="sr">ЕПУБ</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää e-kirjojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des E-Books</summary>
|
||||
<summary xml:lang="gl">Permite ler libros electrónicos.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger E-libros</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di libri digitali in formato EPub</summary>
|
||||
<summary xml:lang="ko">전자책 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van e-boeken toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa e-bøker i EPUB-formatet</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania ebooków</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para a leitura de E-Books</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения электронных книг EPub</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie e-kníh</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje e-knjig</summary>
|
||||
<summary xml:lang="sr">Подршка за читање е‑књига</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">Faksi</name>
|
||||
<name xml:lang="fr">Fax</name>
|
||||
<name xml:lang="gl">Fax</name>
|
||||
<name xml:lang="ia">Fax</name>
|
||||
<name xml:lang="it">Fax</name>
|
||||
<name xml:lang="ko">팩스</name>
|
||||
<name xml:lang="nl">Fax</name>
|
||||
<name xml:lang="nn">Faks</name>
|
||||
<name xml:lang="pl">Fax</name>
|
||||
<name xml:lang="pt">Fax</name>
|
||||
<name xml:lang="ru">Факсы</name>
|
||||
<name xml:lang="sk">Fax</name>
|
||||
<name xml:lang="sl">Faks</name>
|
||||
<name xml:lang="sr">Факс</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää faksitiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents Fax</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos de fax.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos Fax</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti Fax</summary>
|
||||
<summary xml:lang="ko">팩스 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van faxdocumenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa faksdokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania faksów</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para a leitura de documentos de Fax</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения документов факсов</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie faxových dokumentov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje faksiranih dokumentov</summary>
|
||||
<summary xml:lang="sr">Подршка за читање факс докумената</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">FictionBook</name>
|
||||
<name xml:lang="fr">FictionBook</name>
|
||||
<name xml:lang="gl">FictionBook</name>
|
||||
<name xml:lang="ia">Fiction Book</name>
|
||||
<name xml:lang="it">FictionBook</name>
|
||||
<name xml:lang="ko">FictionBook</name>
|
||||
<name xml:lang="nl">Fictie boek</name>
|
||||
<name xml:lang="nn">FictionBook</name>
|
||||
<name xml:lang="pl">Fikcja</name>
|
||||
<name xml:lang="pt">FictionBook</name>
|
||||
<name xml:lang="ru">FictionBook</name>
|
||||
<name xml:lang="sk">FictionBook</name>
|
||||
<name xml:lang="sl">FictionBook</name>
|
||||
<name xml:lang="sr">Фикшнбук</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää FictionBook-lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des fichiers FictionBooks</summary>
|
||||
<summary xml:lang="gl">Permite ler libros FictionBook.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger FictionBooks</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti in formato FictionBooks</summary>
|
||||
<summary xml:lang="ko">FictionBook 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van fictie boeken toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa e-bøker i FictionBook-formatet</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania fikcji</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para a leitura de livros no formato FictionBooks</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения электронных книг FictionBook</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie FictionBook</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje dokumentov FictionBook</summary>
|
||||
<summary xml:lang="sr">Подршка за читање фикшнбук е‑књига</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">Kuvat</name>
|
||||
<name xml:lang="fr">Images</name>
|
||||
<name xml:lang="gl">Imaxes</name>
|
||||
<name xml:lang="ia">Images</name>
|
||||
<name xml:lang="it">Immagini</name>
|
||||
<name xml:lang="ko">그림</name>
|
||||
<name xml:lang="nl">Afbeeldingen</name>
|
||||
<name xml:lang="nn">Bilete</name>
|
||||
<name xml:lang="pl">Obrazy</name>
|
||||
<name xml:lang="pt">Imagens</name>
|
||||
<name xml:lang="ru">Изображения</name>
|
||||
<name xml:lang="sk">Obrázky</name>
|
||||
<name xml:lang="sl">Slike</name>
|
||||
<name xml:lang="sr">Слике</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää monien kuvatiedostomuotojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture de nombreux formats d'images</summary>
|
||||
<summary xml:lang="gl">Permite ler moitos formatos de imaxe.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger formatos de image</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di vari formati di immagini</summary>
|
||||
<summary xml:lang="ko">다양한 그림 형식 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Ondersteuning toevoegen om vele afbeeldingsformaten te lezen</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa mange ulike biletformat</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania wielu formatów obrazów</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler muitos formatos de imagem</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения многих форматов изображений</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie mnohých obrazových formátov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje številnih slikovnih vrst</summary>
|
||||
<summary xml:lang="sr">Подршка за читање разних формата слика</summary>
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
"Name[el]": "Σύστημα υποστήριξης markdown",
|
||||
"Name[es]": "Motor para Markdown",
|
||||
"Name[fr]": "Moteur de markdown",
|
||||
"Name[ia]": "Retro-Administration Markdown",
|
||||
"Name[it]": "Backend Markdown",
|
||||
"Name[nl]": "Markdown-backend",
|
||||
"Name[nn]": "Markdown-motor",
|
||||
|
|
|
@ -174,6 +174,7 @@ X-KDE-Keywords[de]=Markdown
|
|||
X-KDE-Keywords[el]=Markdown
|
||||
X-KDE-Keywords[es]=Markdown
|
||||
X-KDE-Keywords[fr]=Markdown
|
||||
X-KDE-Keywords[ia]=Markdown
|
||||
X-KDE-Keywords[it]=Markdown
|
||||
X-KDE-Keywords[nl]=Markdown
|
||||
X-KDE-Keywords[nn]=Markdown
|
||||
|
|
|
@ -163,6 +163,7 @@ X-KDE-Keywords[de]=Markdown
|
|||
X-KDE-Keywords[el]=Markdown
|
||||
X-KDE-Keywords[es]=Markdown
|
||||
X-KDE-Keywords[fr]=Markdown
|
||||
X-KDE-Keywords[ia]=Markdown
|
||||
X-KDE-Keywords[it]=Markdown
|
||||
X-KDE-Keywords[nl]=Markdown
|
||||
X-KDE-Keywords[nn]=Markdown
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<name xml:lang="el">Markdown</name>
|
||||
<name xml:lang="es">Markdown</name>
|
||||
<name xml:lang="fr">Markdown</name>
|
||||
<name xml:lang="ia">Markdown</name>
|
||||
<name xml:lang="it">Markdown</name>
|
||||
<name xml:lang="nl">Markdown</name>
|
||||
<name xml:lang="nn">Markdown</name>
|
||||
|
@ -34,6 +35,7 @@
|
|||
<summary xml:lang="el">Προσθέτει υποστήριξη για ανάγνωση Markdown εγγράφων</summary>
|
||||
<summary xml:lang="es">Permite la lectura de documentos Markdown</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents Markdown</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos Markdown</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti Markdown</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van Markdown-documenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa Markdown-dokument</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">Mobipocket</name>
|
||||
<name xml:lang="fr">Mobipocket</name>
|
||||
<name xml:lang="gl">Mobipocket</name>
|
||||
<name xml:lang="ia">Mobipocket</name>
|
||||
<name xml:lang="it">Mobipocket</name>
|
||||
<name xml:lang="ko">Mobipocket</name>
|
||||
<name xml:lang="nl">Mobipocket</name>
|
||||
<name xml:lang="nn">Mobipocket</name>
|
||||
<name xml:lang="pl">Mobipocket</name>
|
||||
<name xml:lang="pt">Mobipocket</name>
|
||||
<name xml:lang="ru">Mobipocket</name>
|
||||
<name xml:lang="sk">Mobipocket</name>
|
||||
<name xml:lang="sl">Mobipocket</name>
|
||||
<name xml:lang="sr">Мобипокет</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää MobiPocket-e-kirjojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Ajouter la gestion en lecture des livres électroniques Mobipocket</summary>
|
||||
<summary xml:lang="gl">Permite ler libros electrónicos Mobipocket.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger E-libros in Mobipocket</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di libri digitali in formato Mobipocket</summary>
|
||||
<summary xml:lang="ko">Mobipocket 전자책 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van Mobipocket e-boeken toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa e-bøker i Mobipocket-formatet</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania ebooków Mobipocket</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler E-books da Mobipocket</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения электронных книг Mobipocket</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie e-kníh Mobipocket</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje e-knjig Mobipocket</summary>
|
||||
<summary xml:lang="sr">Подршка за читање мобипокет е‑књига</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">OpenDocument</name>
|
||||
<name xml:lang="fr">OpenDocument</name>
|
||||
<name xml:lang="gl">OpenDocument</name>
|
||||
<name xml:lang="ia">OpenDocument</name>
|
||||
<name xml:lang="it">OpenDocument</name>
|
||||
<name xml:lang="ko">OpenDocument</name>
|
||||
<name xml:lang="nl">OpenDocument</name>
|
||||
<name xml:lang="nn">OpenDocument</name>
|
||||
<name xml:lang="pl">OpenDocument</name>
|
||||
<name xml:lang="pt">OpenDocument</name>
|
||||
<name xml:lang="ru">OpenDocument</name>
|
||||
<name xml:lang="sk">OpenDocument</name>
|
||||
<name xml:lang="sl">OpenDocument</name>
|
||||
<name xml:lang="sr">Отворени документ</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää OpenDocument-tekstitiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des fichiers texte OpenDocument</summary>
|
||||
<summary xml:lang="gl">Permite ler ficheiros de texto OpenDocument.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger files de texto OpenDocument</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti di testo OpenDocument</summary>
|
||||
<summary xml:lang="ko">OpenDocument 텍스트 파일 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van OpenDocument tekstbestanden toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa tekstfiler i OpenDocument-formatet</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania plików tekstowych OpenDocument</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler documentos de texto em OpenDocument</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения текстовых документов OpenDocument</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie textových súborov OpenDocument</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje besedilnih datotek OpenDocument</summary>
|
||||
<summary xml:lang="sr">Подршка за читање отворенодокументских текстуалних фајлова</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">Plucker</name>
|
||||
<name xml:lang="fr">Plucker</name>
|
||||
<name xml:lang="gl">Plucker</name>
|
||||
<name xml:lang="ia">Plucker</name>
|
||||
<name xml:lang="it">Plucker</name>
|
||||
<name xml:lang="ko">plucker</name>
|
||||
<name xml:lang="nl">Plucker</name>
|
||||
<name xml:lang="nn">Plucker</name>
|
||||
<name xml:lang="pl">Plucker</name>
|
||||
<name xml:lang="pt">Plucker</name>
|
||||
<name xml:lang="ru">Plucker</name>
|
||||
<name xml:lang="sk">Plucker</name>
|
||||
<name xml:lang="sl">Plucker</name>
|
||||
<name xml:lang="sr">Плакер</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää Plucker-tiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents Plucker</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos de Plucker.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos Plucker</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti Plucker</summary>
|
||||
<summary xml:lang="ko">Plucker 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van Plucker-documenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa Plucker-dokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania dokumnetów Plucker</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler documentos do Plucker</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения документов Plucker</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie dokumentov Plucker</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje dokumentov Plucker</summary>
|
||||
<summary xml:lang="sr">Подршка за читање плакер докумената</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">PDF</name>
|
||||
<name xml:lang="fr">PDF</name>
|
||||
<name xml:lang="gl">PDF</name>
|
||||
<name xml:lang="ia">PDF</name>
|
||||
<name xml:lang="it">PDF</name>
|
||||
<name xml:lang="ko">PDF</name>
|
||||
<name xml:lang="nl">PDF</name>
|
||||
<name xml:lang="nn">PDF</name>
|
||||
<name xml:lang="pl">PDF</name>
|
||||
<name xml:lang="pt">PDF</name>
|
||||
<name xml:lang="ru">PDF</name>
|
||||
<name xml:lang="sk">PDF</name>
|
||||
<name xml:lang="sl">PDF</name>
|
||||
<name xml:lang="sr">ПДФ</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää PDF-tiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents PDF</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos PDF.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos PDF</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti PDF</summary>
|
||||
<summary xml:lang="ko">PDF 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van PDF-documenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa PDF-dokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania PDFów</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler documentos em PDF</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения документов PDF</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie PDF dokumentov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje dokumentov PDF</summary>
|
||||
<summary xml:lang="sr">Подршка за читање ПДФ докумената</summary>
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
"Description[fi]": "Spectre-kirjastoon pohjautuva PostScript-tiedostohahmonnin",
|
||||
"Description[fr]": "Système de rendu pour les fichiers « PostScript » utilisant la librairie 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[nl]": "Een renderer van PostScript bestanden gebaseerd op de bibliotheek Spectre",
|
||||
|
|
|
@ -17,12 +17,15 @@
|
|||
<name xml:lang="fi">PostScript</name>
|
||||
<name xml:lang="fr">PostScript</name>
|
||||
<name xml:lang="gl">PostScript</name>
|
||||
<name xml:lang="ia">PostScript</name>
|
||||
<name xml:lang="id">PostScript</name>
|
||||
<name xml:lang="it">PostScript</name>
|
||||
<name xml:lang="ko">포스트스크립트</name>
|
||||
<name xml:lang="nl">PostScript</name>
|
||||
<name xml:lang="nn">PostScript</name>
|
||||
<name xml:lang="pl">PostScript</name>
|
||||
<name xml:lang="pt">PostScript</name>
|
||||
<name xml:lang="ru">PostScript</name>
|
||||
<name xml:lang="sk">PostScript</name>
|
||||
<name xml:lang="sl">PostScript</name>
|
||||
<name xml:lang="sr">Постскрипт</name>
|
||||
|
@ -48,12 +51,15 @@
|
|||
<summary xml:lang="fi">Lisää PostScript-tiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents PostScript</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos PostScript.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos PostScript</summary>
|
||||
<summary xml:lang="id">Dukungan tambahan untuk pembacaan dokumen PostScript</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti PostScript</summary>
|
||||
<summary xml:lang="ko">포스트스크립트 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van PostScript-documenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa PostScript-dokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania dokumentów PostScript</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler documentos em PostScript</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения документов PostScript</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie dokumentov PostScript</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje dokumentov PostScript</summary>
|
||||
<summary xml:lang="sr">Подршка за читање постскрипт докумената</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">TIFF</name>
|
||||
<name xml:lang="fr">Tiff</name>
|
||||
<name xml:lang="gl">Tiff</name>
|
||||
<name xml:lang="ia">TIFF</name>
|
||||
<name xml:lang="it">Tiff</name>
|
||||
<name xml:lang="ko">TIFF</name>
|
||||
<name xml:lang="nl">Tiff</name>
|
||||
<name xml:lang="nn">TIFF</name>
|
||||
<name xml:lang="pl">Tiff</name>
|
||||
<name xml:lang="pt">TIFF</name>
|
||||
<name xml:lang="ru">TIFF</name>
|
||||
<name xml:lang="sk">Tiff</name>
|
||||
<name xml:lang="sl">Tiff</name>
|
||||
<name xml:lang="sr">ТИФФ</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää TIFF-kuvatiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents Tiff</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos Tiff.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos Tiff</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti Tiff</summary>
|
||||
<summary xml:lang="ko">TIFF 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van Tiff-documenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa TIFF-dokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania dokumentów Tiff</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler documentos em TIFF</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения документов TIFF</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie Tiff dokumentov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje dokumentov Tiff</summary>
|
||||
<summary xml:lang="sr">Подршка за читање ТИФФ докумената</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">Teksti</name>
|
||||
<name xml:lang="fr">Text</name>
|
||||
<name xml:lang="gl">Texto</name>
|
||||
<name xml:lang="ia">Texto</name>
|
||||
<name xml:lang="it">Testo</name>
|
||||
<name xml:lang="ko">텍스트</name>
|
||||
<name xml:lang="nl">Tekst</name>
|
||||
<name xml:lang="nn">Tekst</name>
|
||||
<name xml:lang="pl">Tekst</name>
|
||||
<name xml:lang="pt">Texto</name>
|
||||
<name xml:lang="ru">Текст</name>
|
||||
<name xml:lang="sk">Text</name>
|
||||
<name xml:lang="sl">Besedilo</name>
|
||||
<name xml:lang="sr">Текст</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää paljaiden tekstitiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des fichiers texte</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos de texto simple.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos plan</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti in testo semplice</summary>
|
||||
<summary xml:lang="ko">일반 텍스트 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van gewone tekstdocumenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa reintekstdokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę czytania zwykłych plików tekstowych</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler documentos em texto simples</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения простых текстовых документов</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie čistých textových dokumentov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje besedilnih dokumentov</summary>
|
||||
<summary xml:lang="sr">Подршка за читање докумената у обичном тексту</summary>
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
<name xml:lang="fi">XPS</name>
|
||||
<name xml:lang="fr">XPS</name>
|
||||
<name xml:lang="gl">XPS</name>
|
||||
<name xml:lang="ia">XPS</name>
|
||||
<name xml:lang="it">XPS</name>
|
||||
<name xml:lang="ko">XPS</name>
|
||||
<name xml:lang="nl">XPS</name>
|
||||
<name xml:lang="nn">XPS</name>
|
||||
<name xml:lang="pl">XPS</name>
|
||||
<name xml:lang="pt">XPS</name>
|
||||
<name xml:lang="ru">XPS</name>
|
||||
<name xml:lang="sk">XPS</name>
|
||||
<name xml:lang="sl">XPS</name>
|
||||
<name xml:lang="sr">ИксПС</name>
|
||||
|
@ -48,12 +50,14 @@
|
|||
<summary xml:lang="fi">Lisää XPS-tiedostojen lukutuen</summary>
|
||||
<summary xml:lang="fr">Permet la lecture des documents XPS</summary>
|
||||
<summary xml:lang="gl">Permite ler documentos XPS.</summary>
|
||||
<summary xml:lang="ia">Adde supporto per leger documentos XPS</summary>
|
||||
<summary xml:lang="it">Aggiunge il supporto per la lettura di documenti XPS</summary>
|
||||
<summary xml:lang="ko">XPS 문서 읽기 지원 추가</summary>
|
||||
<summary xml:lang="nl">Voegt ondersteuning voor lezen van XPS-documenten toe</summary>
|
||||
<summary xml:lang="nn">Legg til støtte for å lesa XPS-dokument</summary>
|
||||
<summary xml:lang="pl">Dodaje obsługę dokumnetów XPS</summary>
|
||||
<summary xml:lang="pt">Adiciona o suporte para ler documentos em XPS</summary>
|
||||
<summary xml:lang="ru">Поддержка чтения документов XPS</summary>
|
||||
<summary xml:lang="sk">Pridá podporu pre čítanie XPS dokumentov</summary>
|
||||
<summary xml:lang="sl">Doda podporo za branje dokumentov XPS</summary>
|
||||
<summary xml:lang="sr">Подршка за читање ИксПС докумената</summary>
|
||||
|
|
66
part.cpp
|
@ -69,6 +69,12 @@
|
|||
#include <KXMLGUIClient>
|
||||
#include <KXMLGUIFactory>
|
||||
|
||||
|
||||
#if PURPOSE_FOUND
|
||||
#include <Purpose/AlternativesModel>
|
||||
#include <PurposeWidgets/Menu>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <knewstuff2/engine.h>
|
||||
#endif
|
||||
|
@ -745,6 +751,13 @@ void Part::setupViewerActions()
|
|||
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"));
|
||||
|
@ -840,6 +853,16 @@ void Part::setupActions()
|
|||
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") ) );
|
||||
|
@ -914,6 +937,9 @@ Part::~Part()
|
|||
qDeleteAll( m_bookmarkActions );
|
||||
|
||||
delete m_exportAsMenu;
|
||||
#if PURPOSE_FOUND
|
||||
delete m_shareMenu;
|
||||
#endif
|
||||
|
||||
#ifdef OKULAR_KEEP_FILE_OPEN
|
||||
delete m_keeper;
|
||||
|
@ -1528,6 +1554,17 @@ bool Part::openFile()
|
|||
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();
|
||||
|
@ -1539,6 +1576,9 @@ bool Part::openFile()
|
|||
}
|
||||
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();
|
||||
|
@ -1716,6 +1756,13 @@ bool Part::closeUrl(bool promptToSave)
|
|||
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);
|
||||
|
@ -3323,6 +3370,25 @@ void Part::resetStartArguments()
|
|||
m_cliPrint = 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["url"].toString();
|
||||
if (url.isEmpty()) {
|
||||
m_pageView->displayMessage(i18n("Document shared successfully"));
|
||||
} else {
|
||||
KMessageBox::information(widget(), i18n("You can find the shared document at: <a href=\"%1\">%1</a>", url),
|
||||
i18n("Share"), QString(),
|
||||
KMessageBox::Notify | KMessageBox::AllowLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Part::setReadWrite(bool readwrite)
|
||||
{
|
||||
m_document->setAnnotationEditingEnabled( readwrite );
|
||||
|
|
17
part.h
|
@ -36,6 +36,8 @@
|
|||
|
||||
#include "okularpart_export.h"
|
||||
|
||||
#include <config-okular.h>
|
||||
|
||||
class QAction;
|
||||
class QWidget;
|
||||
class QPrinter;
|
||||
|
@ -50,6 +52,7 @@ class KSelectAction;
|
|||
class KAboutData;
|
||||
class QTemporaryFile;
|
||||
class QAction;
|
||||
class QJsonObject;
|
||||
namespace KParts { class GUIActivateEvent; }
|
||||
|
||||
class FindBar;
|
||||
|
@ -69,6 +72,10 @@ class BookmarkList;
|
|||
class DrawingToolActions;
|
||||
class Layers;
|
||||
|
||||
#if PURPOSE_FOUND
|
||||
namespace Purpose { class Menu; }
|
||||
#endif
|
||||
|
||||
namespace Okular
|
||||
{
|
||||
|
||||
|
@ -274,6 +281,10 @@ class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::Docu
|
|||
void setFileToWatch( const QString &filePath );
|
||||
void unsetFileToWatch();
|
||||
|
||||
#if PURPOSE_FOUND
|
||||
void slotShareActionFinished(const QJsonObject &output, int error, const QString &message);
|
||||
#endif
|
||||
|
||||
static int numberOfParts;
|
||||
|
||||
QTemporaryFile *m_tempfile;
|
||||
|
@ -349,6 +360,9 @@ class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::Docu
|
|||
QAction *m_exportAs;
|
||||
QAction *m_exportAsText;
|
||||
QAction *m_exportAsDocArchive;
|
||||
#if PURPOSE_FOUND
|
||||
QAction *m_share;
|
||||
#endif
|
||||
QAction *m_showPresentation;
|
||||
KToggleAction* m_showMenuBarAction;
|
||||
KToggleAction* m_showLeftPanel;
|
||||
|
@ -357,6 +371,9 @@ class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::Docu
|
|||
QAction *m_aboutBackend;
|
||||
QAction *m_reload;
|
||||
QMenu *m_exportAsMenu;
|
||||
#if PURPOSE_FOUND
|
||||
Purpose::Menu *m_shareMenu;
|
||||
#endif
|
||||
QAction *m_closeFindBar;
|
||||
DrawingToolActions *m_presentationDrawingActions;
|
||||
|
||||
|
|
1
part.rc
|
@ -12,6 +12,7 @@
|
|||
<Action name="properties" group="file_print"/>
|
||||
<Action name="embedded_files" group="file_print"/>
|
||||
<Action name="file_export_as" group="file_print"/>
|
||||
<Action name="file_share" group="file_print"/>
|
||||
</Menu>
|
||||
<Menu name="edit"><text>&Edit</text>
|
||||
<Action name="edit_undo"/>
|
||||
|
|
|
@ -29,8 +29,9 @@
|
|||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
|
||||
QApplication app(argc, argv);
|
||||
KLocalizedString::setApplicationDomain("okular");
|
||||
|
||||
KAboutData aboutData = okularAboutData();
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
<name xml:lang="nn">Okular</name>
|
||||
<name xml:lang="pl">Okular</name>
|
||||
<name xml:lang="pt">Okular</name>
|
||||
<name xml:lang="ru">Okular</name>
|
||||
<name xml:lang="sk">Okular</name>
|
||||
<name xml:lang="sl">Okular</name>
|
||||
<name xml:lang="sr">Окулар</name>
|
||||
|
@ -47,12 +48,14 @@
|
|||
<summary xml:lang="fi">Asiakirjakatselin</summary>
|
||||
<summary xml:lang="fr">Afficheur de documents</summary>
|
||||
<summary xml:lang="gl">Visor de documentos</summary>
|
||||
<summary xml:lang="ia">Visor de documento</summary>
|
||||
<summary xml:lang="it">Visore di documenti</summary>
|
||||
<summary xml:lang="ko">문서 뷰어</summary>
|
||||
<summary xml:lang="nl">Documentenviewer</summary>
|
||||
<summary xml:lang="nn">Dokumentvisar</summary>
|
||||
<summary xml:lang="pl">Przeglądarka dokumentów</summary>
|
||||
<summary xml:lang="pt">Visualizador do Documento</summary>
|
||||
<summary xml:lang="ru">Просмотр документов</summary>
|
||||
<summary xml:lang="sk">Prehliadač dokumentov</summary>
|
||||
<summary xml:lang="sl">Pregledovalnik dokumentov</summary>
|
||||
<summary xml:lang="sr">Приказивач докумената</summary>
|
||||
|
@ -111,12 +114,14 @@
|
|||
<p xml:lang="fi">Ominaisuuksia:</p>
|
||||
<p xml:lang="fr">Fonctionnalités :</p>
|
||||
<p xml:lang="gl">Funcionalidades:</p>
|
||||
<p xml:lang="ia">Characteristicas:</p>
|
||||
<p xml:lang="it">Funzionalità:</p>
|
||||
<p xml:lang="ko">기능:</p>
|
||||
<p xml:lang="nl">Kenmerken:</p>
|
||||
<p xml:lang="nn">Funksjonar:</p>
|
||||
<p xml:lang="pl">Możliwości:</p>
|
||||
<p xml:lang="pt">Funcionalidades:</p>
|
||||
<p xml:lang="ru">Возможности:</p>
|
||||
<p xml:lang="sk">Funkcie:</p>
|
||||
<p xml:lang="sl">Zmožnosti:</p>
|
||||
<p xml:lang="sr">Могућности:</p>
|
||||
|
|
|
@ -10,12 +10,17 @@ install(FILES
|
|||
# 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
|
||||
DESTINATION ${KDE_INSTALL_DATADIR}/okular/pics)
|
||||
# install annotation page images
|
||||
install(FILES
|
||||
|
|
BIN
ui/data/tool-base-okular@2x.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
ui/data/tool-highlighter-okular-colorizable@2x.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
ui/data/tool-ink-okular-colorizable@2x.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
ui/data/tool-note-inline-okular-colorizable@2x.png
Normal file
After Width: | Height: | Size: 945 B |
BIN
ui/data/tool-note-okular-colorizable@2x.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
|
@ -18,6 +18,7 @@
|
|||
#include <kiconloader.h>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QApplication>
|
||||
#include <QIcon>
|
||||
|
||||
// system includes
|
||||
#include <math.h>
|
||||
|
@ -35,7 +36,7 @@
|
|||
#include "settings_core.h"
|
||||
#include "ui/debug_ui.h"
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS( QPixmap, busyPixmap, ( KIconLoader::global()->loadIcon(QLatin1String("okular"), KIconLoader::NoGroup, 32, KIconLoader::DefaultState, QStringList(), 0, true) ) )
|
||||
Q_GLOBAL_STATIC_WITH_ARGS( QPixmap, busyPixmap, ( KIconLoader::global()->loadIcon(QLatin1String("okular"), KIconLoader::NoGroup, IconSize(KIconLoader::Desktop), KIconLoader::DefaultState, QStringList(), 0, true) ) )
|
||||
|
||||
#define TEXTANNOTATION_ICONSIZE 24
|
||||
|
||||
|
@ -62,11 +63,22 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
Okular::DocumentObserver *observer, int flags, int scaledWidth, int scaledHeight, const QRect &limits,
|
||||
const Okular::NormalizedRect &crop, Okular::NormalizedPoint *viewPortPoint )
|
||||
{
|
||||
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() )
|
||||
|
@ -89,22 +101,28 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
destPainter->fillRect( limits, backgroundColor );
|
||||
|
||||
const bool hasTilesManager = page->hasTilesManager( observer );
|
||||
const QPixmap *pixmap = nullptr;
|
||||
QPixmap pixmap;
|
||||
|
||||
if ( !hasTilesManager )
|
||||
{
|
||||
/** 1 - RETRIEVE THE 'PAGE+ID' PIXMAP OR A SIMILAR 'PAGE' ONE **/
|
||||
pixmap = page->_o_nearestPixmap( observer, scaledWidth, scaledHeight );
|
||||
const QPixmap *p = page->_o_nearestPixmap( observer, dScaledWidth, dScaledHeight );
|
||||
|
||||
if (p != NULL) {
|
||||
pixmap = *p;
|
||||
pixmap.setDevicePixelRatio( qApp->devicePixelRatio() );
|
||||
}
|
||||
|
||||
/** 1B - IF NO PIXMAP, DRAW EMPTY PAGE **/
|
||||
double pixmapRescaleRatio = pixmap ? scaledWidth / (double)pixmap->width() : -1;
|
||||
long pixmapPixels = pixmap ? (long)pixmap->width() * (long)pixmap->height() : 0;
|
||||
if ( !pixmap || pixmapRescaleRatio > 20.0 || pixmapRescaleRatio < 0.25 ||
|
||||
(scaledWidth > pixmap->width() && pixmapPixels > 60000000L) )
|
||||
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
|
||||
|
@ -135,10 +153,10 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
if ( canDrawHighlights || canDrawTextSelection || canDrawAnnotations )
|
||||
{
|
||||
// precalc normalized 'limits rect' for intersection
|
||||
double nXMin = ( (double)limits.left() / (double)scaledWidth ) + crop.left,
|
||||
nXMax = ( (double)limits.right() / (double)scaledWidth ) + crop.left,
|
||||
nYMin = ( (double)limits.top() / (double)scaledHeight ) + crop.top,
|
||||
nYMax = ( (double)limits.bottom() / (double)scaledHeight ) + crop.top;
|
||||
double nXMin = ( (double)limits.left() / dScaledWidth ) + crop.left,
|
||||
nXMax = ( (double)limits.right() / dScaledWidth ) + crop.left,
|
||||
nYMin = ( (double)limits.top() / dScaledHeight ) + crop.top,
|
||||
nYMax = ( (double)limits.bottom() / dScaledHeight ) + crop.top;
|
||||
// append all highlights inside limits to their list
|
||||
if ( canDrawHighlights )
|
||||
{
|
||||
|
@ -240,6 +258,8 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
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 **/
|
||||
|
@ -254,32 +274,30 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
{
|
||||
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() )
|
||||
{
|
||||
if ( tile.pixmap()->width() == tileRect.width() && tile.pixmap()->height() == tileRect.height() )
|
||||
destPainter->drawPixmap( limitsInTile.topLeft(), *(tile.pixmap()),
|
||||
limitsInTile.translated( -tileRect.topLeft() ) );
|
||||
else
|
||||
destPainter->drawPixmap( tileRect, *(tile.pixmap()) );
|
||||
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
|
||||
{
|
||||
// 4A.1. if size is ok, draw the page pixmap using painter
|
||||
if ( pixmap->width() == scaledWidth && pixmap->height() == scaledHeight )
|
||||
destPainter->drawPixmap( limits.topLeft(), *pixmap, limitsInPixmap );
|
||||
|
||||
// else draw a scaled portion of the magnified pixmap
|
||||
else
|
||||
{
|
||||
QImage destImage;
|
||||
scalePixmapOnImage( destImage, pixmap, scaledWidth, scaledHeight, limitsInPixmap );
|
||||
destPainter->drawImage( limits.left(), limits.top(), destImage, 0, 0,
|
||||
limits.width(),limits.height() );
|
||||
}
|
||||
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
|
||||
|
@ -289,13 +307,13 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
else
|
||||
{
|
||||
// the image over which we are going to draw
|
||||
QImage backImage;
|
||||
QImage backImage = QImage( dLimits.width(), dLimits.height(), QImage::Format_ARGB32_Premultiplied );
|
||||
backImage.setDevicePixelRatio(dpr);
|
||||
backImage.fill( paperColor );
|
||||
QPainter p( &backImage );
|
||||
|
||||
if ( hasTilesManager )
|
||||
{
|
||||
backImage = QImage( limits.width(), limits.height(), QImage::Format_ARGB32_Premultiplied );
|
||||
backImage.fill( paperColor.rgb() );
|
||||
QPainter p( &backImage );
|
||||
const Okular::NormalizedRect normalizedLimits( limitsInPixmap, scaledWidth, scaledHeight );
|
||||
const QList<Okular::Tile> tiles = page->tilesAt( observer, normalizedLimits );
|
||||
QList<Okular::Tile>::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd();
|
||||
|
@ -303,36 +321,42 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
{
|
||||
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() )
|
||||
{
|
||||
if ( tile.pixmap()->width() == tileRect.width() && tile.pixmap()->height() == tileRect.height() )
|
||||
QPixmap* tilePixmap = tile.pixmap();
|
||||
tilePixmap->setDevicePixelRatio( qApp->devicePixelRatio() );
|
||||
|
||||
if ( tilePixmap->width() == dTileRect.width() && tilePixmap->height() == dTileRect.height() )
|
||||
{
|
||||
p.drawPixmap( limitsInTile.translated( -limits.topLeft() ).topLeft(), *(tile.pixmap()),
|
||||
limitsInTile.translated( -tileRect.topLeft() ) );
|
||||
p.drawPixmap( limitsInTile.translated( -limits.topLeft() ).topLeft(), *tilePixmap,
|
||||
dLimitsInTile.translated( -dTileRect.topLeft() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
double xScale = tile.pixmap()->width() / (double)tileRect.width();
|
||||
double yScale = tile.pixmap()->height() / (double)tileRect.height();
|
||||
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() ), *(tile.pixmap()),
|
||||
transform.mapRect( limitsInTile ).translated( -transform.mapRect( tileRect ).topLeft() ) );
|
||||
p.drawPixmap( limitsInTile.translated( -limits.topLeft() ), *tilePixmap,
|
||||
transform.mapRect( dLimitsInTile ).translated( -transform.mapRect( dTileRect ).topLeft() ) );
|
||||
}
|
||||
}
|
||||
++tIt;
|
||||
}
|
||||
p.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4B.1. draw the page pixmap: normal or scaled
|
||||
if ( pixmap->width() == scaledWidth && pixmap->height() == scaledHeight )
|
||||
cropPixmapOnImage( backImage, pixmap, limitsInPixmap );
|
||||
else
|
||||
scalePixmapOnImage( backImage, pixmap, scaledWidth, scaledHeight, limitsInPixmap );
|
||||
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 )
|
||||
{
|
||||
|
@ -370,6 +394,7 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 4B.3. highlight rects in page
|
||||
if ( bufferedHighlights )
|
||||
{
|
||||
|
@ -387,6 +412,7 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
painter.fillRect(highlightRect, highlightColor);
|
||||
}
|
||||
}
|
||||
|
||||
// 4B.4. paint annotations [COMPOSITED ONES]
|
||||
if ( bufferedAnnotations )
|
||||
{
|
||||
|
@ -579,7 +605,6 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
}
|
||||
} // end current annotation drawing
|
||||
}
|
||||
|
||||
if(viewPortPoint)
|
||||
{
|
||||
QPainter painter(&backImage);
|
||||
|
@ -609,6 +634,7 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
|
||||
// 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 );
|
||||
|
@ -641,6 +667,7 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
QRect annotRect = annotBoundary.intersected( limits );
|
||||
QRect innerRect( annotRect.left() - annotBoundary.left(), annotRect.top() -
|
||||
annotBoundary.top(), annotRect.width(), annotRect.height() );
|
||||
QRectF dInnerRect(innerRect.x() * dpr, innerRect.y() * dpr, innerRect.width() * dpr, innerRect.height() * dpr);
|
||||
|
||||
Okular::Annotation::SubType type = a->subType();
|
||||
|
||||
|
@ -684,23 +711,24 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
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 );
|
||||
QImage scaledImage;
|
||||
QRect annotBoundary2 = QRect( annotBoundary.topLeft(), QSize( TEXTANNOTATION_ICONSIZE, TEXTANNOTATION_ICONSIZE ) );
|
||||
QRect annotBoundary2 = QRect( annotBoundary.topLeft(), QSize( TEXTANNOTATION_ICONSIZE * dpr, TEXTANNOTATION_ICONSIZE * dpr ) );
|
||||
QRect annotRect2 = annotBoundary2.intersected( limits );
|
||||
QRect innerRect2( annotRect2.left() - annotBoundary2.left(), annotRect2.top() -
|
||||
annotBoundary2.top(), annotRect2.width(), annotRect2.height() );
|
||||
scalePixmapOnImage( scaledImage, &pixmap,
|
||||
TEXTANNOTATION_ICONSIZE, TEXTANNOTATION_ICONSIZE,
|
||||
innerRect2, QImage::Format_ARGB32 );
|
||||
|
||||
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( scaledImage, a->style().color(), opacity );
|
||||
pixmap = QPixmap::fromImage( scaledImage );
|
||||
GuiUtils::colorizeImage( scaledCroppedImage, a->style().color(), opacity );
|
||||
pixmap = QPixmap::fromImage( scaledCroppedImage );
|
||||
|
||||
// draw the mangled image to painter
|
||||
mixedPainter->drawPixmap( annotRect.topLeft(), pixmap );
|
||||
// draw the mangled image to painter
|
||||
mixedPainter->drawPixmap( annotRect.topLeft(), pixmap);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -713,12 +741,16 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
QPixmap pixmap = GuiUtils::loadStamp( stamp->stampIconName(), annotBoundary.size() );
|
||||
if ( !pixmap.isNull() ) // should never happen but can happen on huge sizes
|
||||
{
|
||||
QImage scaledImage;
|
||||
scalePixmapOnImage( scaledImage, &pixmap, annotBoundary.width(),
|
||||
annotBoundary.height(), innerRect, QImage::Format_ARGB32 );
|
||||
const QRect dInnerRect(QRectF(innerRect.x() * dpr, innerRect.y() * dpr, innerRect.width() * dpr, innerRect.height() * dpr).toAlignedRect());
|
||||
|
||||
QPixmap scaledCroppedPixmap = pixmap.scaled(annotBoundary.width() * dpr, annotBoundary.height() * dpr).copy(dInnerRect);
|
||||
scaledCroppedPixmap.setDevicePixelRatio(dpr);
|
||||
|
||||
QImage scaledCroppedImage = scaledCroppedPixmap.toImage();
|
||||
|
||||
if ( opacity < 255 )
|
||||
changeImageAlpha( scaledImage, opacity );
|
||||
pixmap = QPixmap::fromImage( scaledImage );
|
||||
changeImageAlpha( scaledCroppedImage, opacity );
|
||||
pixmap = QPixmap::fromImage( scaledCroppedImage );
|
||||
|
||||
// draw the scaled and al
|
||||
mixedPainter->drawPixmap( annotRect.topLeft(), pixmap );
|
||||
|
@ -823,8 +855,10 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
|
|||
/** Private Helpers :: Pixmap conversion **/
|
||||
void PagePainter::cropPixmapOnImage( QImage & dest, const QPixmap * src, const QRect & r )
|
||||
{
|
||||
qreal dpr = src->devicePixelRatioF();
|
||||
|
||||
// handle quickly the case in which the whole pixmap has to be converted
|
||||
if ( r == QRect( 0, 0, src->width(), src->height() ) )
|
||||
if ( r == QRect( 0, 0, src->width() / dpr, src->height() / dpr ) )
|
||||
{
|
||||
dest = src->toImage();
|
||||
dest = dest.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
|
@ -832,7 +866,8 @@ void PagePainter::cropPixmapOnImage( QImage & dest, const QPixmap * src, const Q
|
|||
// else copy a portion of the src to an internal pixmap (smaller) and convert it
|
||||
else
|
||||
{
|
||||
QImage croppedImage( r.width(), r.height(), QImage::Format_ARGB32_Premultiplied );
|
||||
QImage croppedImage( r.width() * dpr, r.height() * dpr, QImage::Format_ARGB32_Premultiplied );
|
||||
croppedImage.setDevicePixelRatio(dpr);
|
||||
QPainter p( &croppedImage );
|
||||
p.drawPixmap( 0, 0, *src, r.left(), r.top(), r.width(), r.height() );
|
||||
p.end();
|
||||
|
@ -866,40 +901,6 @@ void PagePainter::recolor(QImage *image, const QColor &foreground, const QColor
|
|||
}
|
||||
}
|
||||
|
||||
void PagePainter::scalePixmapOnImage ( QImage & dest, const QPixmap * src,
|
||||
int scaledWidth, int scaledHeight, const QRect & cropRect, QImage::Format format )
|
||||
{
|
||||
// {source, destination, scaling} params
|
||||
int srcWidth = src->width(),
|
||||
srcHeight = src->height(),
|
||||
destLeft = cropRect.left(),
|
||||
destTop = cropRect.top(),
|
||||
destWidth = cropRect.width(),
|
||||
destHeight = cropRect.height();
|
||||
|
||||
// destination image (same geometry as the pageLimits rect)
|
||||
dest = QImage( destWidth, destHeight, format );
|
||||
unsigned int * destData = (unsigned int *)dest.bits();
|
||||
|
||||
// source image (1:1 conversion from pixmap)
|
||||
QImage srcImage = src->toImage().convertToFormat(format);
|
||||
unsigned int * srcData = (unsigned int *)srcImage.bits();
|
||||
|
||||
// precalc the x correspondancy conversion in a lookup table
|
||||
QVarLengthArray<unsigned int> xOffset( destWidth );
|
||||
for ( int x = 0; x < destWidth; x++ )
|
||||
xOffset[ x ] = ((x + destLeft) * srcWidth) / scaledWidth;
|
||||
|
||||
// for each pixel of the destination image apply the color of the
|
||||
// corresponsing pixel on the source image (note: keep parenthesis)
|
||||
for ( int y = 0; y < destHeight; y++ )
|
||||
{
|
||||
unsigned int srcOffset = srcWidth * (((destTop + y) * srcHeight) / scaledHeight);
|
||||
for ( int x = 0; x < destWidth; x++ )
|
||||
(*destData++) = srcData[ srcOffset + xOffset[x] ];
|
||||
}
|
||||
}
|
||||
|
||||
/** Private Helpers :: Image Drawing **/
|
||||
// from Arthur - qt4
|
||||
static inline int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
|
||||
|
|
|
@ -56,12 +56,6 @@ class Q_DECL_EXPORT PagePainter
|
|||
static void cropPixmapOnImage( QImage & dest, const QPixmap * src, const QRect & r );
|
||||
static void recolor(QImage *image, const QColor &foreground, const QColor &background);
|
||||
|
||||
// create an image taking the 'cropRect' portion of an image scaled
|
||||
// to 'scaledWidth' by 'scaledHeight' pixels. cropRect must be inside
|
||||
// the QRect(0,0, scaledWidth,scaledHeight)
|
||||
static void scalePixmapOnImage( QImage & dest, const QPixmap *src,
|
||||
int scaledWidth, int scaledHeight, const QRect & cropRect, QImage::Format format = QImage::Format_ARGB32_Premultiplied );
|
||||
|
||||
// set the alpha component of the image to a given value
|
||||
static void changeImageAlpha( QImage & image, unsigned int alpha );
|
||||
|
||||
|
|
328
ui/pageview.cpp
|
@ -236,6 +236,9 @@ public:
|
|||
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;
|
||||
};
|
||||
|
||||
PageViewPrivate::PageViewPrivate( PageView *qq )
|
||||
|
@ -1666,8 +1669,10 @@ void PageView::paintEvent(QPaintEvent *pe)
|
|||
if ( wantCompositing && Okular::Settings::enableCompositing() )
|
||||
{
|
||||
// create pixmap and open a painter over it (contents{left,top} becomes pixmap {0,0})
|
||||
QPixmap doubleBuffer( contentsRect.size() );
|
||||
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
|
||||
|
@ -1681,11 +1686,12 @@ void PageView::paintEvent(QPaintEvent *pe)
|
|||
if ( blendRect.isValid() )
|
||||
{
|
||||
// grab current pixmap into a new one to colorize contents
|
||||
QPixmap blendedPixmap( blendRect.width(), blendRect.height() );
|
||||
QPixmap blendedPixmap( blendRect.width() * devicePixelRatioF(), blendRect.height() * devicePixelRatioF() );
|
||||
blendedPixmap.setDevicePixelRatio(devicePixelRatioF());
|
||||
QPainter p( &blendedPixmap );
|
||||
p.drawPixmap( 0, 0, doubleBuffer,
|
||||
blendRect.left() - contentsRect.left(), blendRect.top() - contentsRect.top(),
|
||||
blendRect.width(), blendRect.height() );
|
||||
blendRect.width() * devicePixelRatioF(), blendRect.height() * devicePixelRatioF() );
|
||||
|
||||
QColor blCol = selBlendColor.dark( 140 );
|
||||
blCol.setAlphaF( 0.2 );
|
||||
|
@ -1712,11 +1718,12 @@ void PageView::paintEvent(QPaintEvent *pe)
|
|||
if ( blendRect.isValid() )
|
||||
{
|
||||
// grab current pixmap into a new one to colorize contents
|
||||
QPixmap blendedPixmap( blendRect.width(), blendRect.height() );
|
||||
QPixmap blendedPixmap( blendRect.width() * devicePixelRatioF(), blendRect.height() * devicePixelRatioF() );
|
||||
blendedPixmap.setDevicePixelRatio(devicePixelRatioF());
|
||||
QPainter p( &blendedPixmap );
|
||||
p.drawPixmap( 0, 0, doubleBuffer,
|
||||
blendRect.left() - contentsRect.left(), blendRect.top() - contentsRect.top(),
|
||||
blendRect.width(), blendRect.height() );
|
||||
blendRect.width() * devicePixelRatioF(), blendRect.height() * devicePixelRatioF() );
|
||||
|
||||
QColor blCol = d->mouseSelectionColor.dark( 140 );
|
||||
blCol.setAlphaF( 0.2 );
|
||||
|
@ -2166,8 +2173,11 @@ void PageView::mouseMoveEvent( QMouseEvent * e )
|
|||
case Okular::Settings::EnumMouseMode::TableSelect:
|
||||
case Okular::Settings::EnumMouseMode::TrimSelect:
|
||||
// set second corner of selection
|
||||
if ( d->mouseSelecting )
|
||||
if ( d->mouseSelecting ) {
|
||||
updateSelection( eventPos );
|
||||
d->mouseOverLinkObject = nullptr;
|
||||
}
|
||||
updateCursor();
|
||||
break;
|
||||
|
||||
case Okular::Settings::EnumMouseMode::Magnifier:
|
||||
|
@ -2477,18 +2487,11 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
|
|||
if ( leftButton && pageItem && pageItem == pageItemPressPos &&
|
||||
( (d->mousePressPos - e->globalPos()).manhattanLength() < QApplication::startDragDistance() ) )
|
||||
{
|
||||
double nX = pageItem->absToPageX(eventPos.x());
|
||||
double nY = pageItem->absToPageY(eventPos.y());
|
||||
const Okular::ObjectRect * rect;
|
||||
rect = pageItem->page()->objectRect( Okular::ObjectRect::Action, nX, nY, pageItem->uncroppedWidth(), pageItem->uncroppedHeight() );
|
||||
if ( rect )
|
||||
{
|
||||
// handle click over a link
|
||||
const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
|
||||
d->document->processAction( action );
|
||||
}
|
||||
else if ( e->modifiers() == Qt::ShiftModifier )
|
||||
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.
|
||||
|
@ -2543,53 +2546,19 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
|
|||
if ( pageItem && pageItem == pageItemPressPos &&
|
||||
( (d->mousePressPos - e->globalPos()).manhattanLength() < QApplication::startDragDistance() ) )
|
||||
{
|
||||
double nX = pageItem->absToPageX(eventPos.x());
|
||||
double nY = pageItem->absToPageY(eventPos.y());
|
||||
const Okular::ObjectRect * rect;
|
||||
rect = pageItem->page()->objectRect( Okular::ObjectRect::Action, nX, nY, pageItem->uncroppedWidth(), pageItem->uncroppedHeight() );
|
||||
if ( rect )
|
||||
QMenu * menu = createProcessLinkMenu(pageItem, eventPos );
|
||||
if ( menu )
|
||||
{
|
||||
// handle right click over a link
|
||||
const Okular::Action * link = static_cast< const Okular::Action * >( rect->object() );
|
||||
// creating the menu and its actions
|
||||
QMenu menu( this );
|
||||
QAction * actProcessLink = menu.addAction( i18n( "Follow This Link" ) );
|
||||
QAction * actStopSound = nullptr;
|
||||
if ( link->actionType() == Okular::Action::Sound ) {
|
||||
actProcessLink->setText( i18n( "Play this Sound" ) );
|
||||
if ( Okular::AudioPlayer::instance()->state() == Okular::AudioPlayer::PlayingState ) {
|
||||
actStopSound = menu.addAction( i18n( "Stop Sound" ) );
|
||||
}
|
||||
}
|
||||
QAction * actCopyLinkLocation = nullptr;
|
||||
if ( dynamic_cast< const Okular::BrowseAction * >( link ) )
|
||||
actCopyLinkLocation = menu.addAction( QIcon::fromTheme( QStringLiteral("edit-copy") ), i18n( "Copy Link Address" ) );
|
||||
QAction * res = menu.exec( e->globalPos() );
|
||||
if ( res )
|
||||
{
|
||||
if ( res == actProcessLink )
|
||||
{
|
||||
d->document->processAction( link );
|
||||
}
|
||||
else if ( res == actCopyLinkLocation )
|
||||
{
|
||||
const Okular::BrowseAction * browseLink = static_cast< const Okular::BrowseAction * >( link );
|
||||
QClipboard *cb = QApplication::clipboard();
|
||||
cb->setText( browseLink->url().toDisplayString(), QClipboard::Clipboard );
|
||||
if ( cb->supportsSelection() )
|
||||
cb->setText( browseLink->url().toDisplayString(), QClipboard::Selection );
|
||||
}
|
||||
else if ( res == actStopSound )
|
||||
{
|
||||
Okular::AudioPlayer::instance()->stopPlaybacks();
|
||||
}
|
||||
}
|
||||
menu->exec( e->globalPos() );
|
||||
menu->deleteLater();
|
||||
}
|
||||
else
|
||||
{
|
||||
const double nX = pageItem->absToPageX(eventPos.x());
|
||||
const double nY = pageItem->absToPageY(eventPos.y());
|
||||
// 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->uncroppedWidth(), pageItem->uncroppedHeight() );
|
||||
const Okular::ObjectRect * rect = pageItem->page()->objectRect( Okular::ObjectRect::Image, nX, nY, pageItem->uncroppedWidth(), pageItem->uncroppedHeight() );
|
||||
if ( rect )
|
||||
{
|
||||
// handle right click over a image
|
||||
|
@ -2651,6 +2620,12 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
|
|||
|
||||
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 )
|
||||
{
|
||||
|
@ -2699,6 +2674,12 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
|
|||
}
|
||||
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 )
|
||||
{
|
||||
|
@ -2757,6 +2738,7 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
|
|||
|
||||
// popup that ask to copy:text and copy/save:image
|
||||
QMenu menu( this );
|
||||
menu.setObjectName("PopupMenu");
|
||||
QAction *textToClipboard = nullptr;
|
||||
#ifdef HAVE_SPEECH
|
||||
QAction *speakText = nullptr;
|
||||
|
@ -2767,6 +2749,7 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
|
|||
{
|
||||
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("CopyTextToClipboard");
|
||||
bool copyAllowed = d->document->isAllowed( Okular::AllowCopy );
|
||||
if ( !copyAllowed )
|
||||
{
|
||||
|
@ -2861,6 +2844,12 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
|
|||
|
||||
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 )
|
||||
{
|
||||
|
@ -3002,6 +2991,12 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
|
|||
|
||||
}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;
|
||||
|
@ -3022,46 +3017,74 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
|
|||
PageViewItem* item = pickItemOnPoint(eventPos.x(),eventPos.y());
|
||||
const Okular::Page *page;
|
||||
//if there is text selected in the page
|
||||
if (item && (page = item->page())->textSelection())
|
||||
if (item)
|
||||
{
|
||||
QMenu menu( this );
|
||||
QAction *textToClipboard = menu.addAction( QIcon::fromTheme( QStringLiteral("edit-copy") ), i18n( "Copy Text" ) );
|
||||
QAction *httpLink = nullptr;
|
||||
QAction * httpLink = nullptr;
|
||||
QAction * textToClipboard = nullptr;
|
||||
QString url;
|
||||
|
||||
QMenu * menu = createProcessLinkMenu( item, eventPos );
|
||||
const bool mouseClickOverLink = (menu != nullptr);
|
||||
#ifdef HAVE_SPEECH
|
||||
QAction *speakText = nullptr;
|
||||
if ( Okular::Settings::useTTS() )
|
||||
speakText = menu.addAction( QIcon::fromTheme( QStringLiteral("text-speak") ), i18n( "Speak Text" ) );
|
||||
#endif
|
||||
if ( !d->document->isAllowed( Okular::AllowCopy ) )
|
||||
if ( (page = item->page())->textSelection() )
|
||||
{
|
||||
textToClipboard->setEnabled( false );
|
||||
textToClipboard->setText( i18n("Copy forbidden by DRM") );
|
||||
}
|
||||
else
|
||||
{
|
||||
addWebShortcutsMenu( &menu, d->selectedText() );
|
||||
}
|
||||
const QString url = UrlUtils::getUrl( d->selectedText() );
|
||||
if ( !url.isEmpty() )
|
||||
{
|
||||
const QString squeezedText = KStringHandler::rsqueeze( url, 30 );
|
||||
httpLink = menu.addAction( i18n( "Go to '%1'", squeezedText ) );
|
||||
}
|
||||
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 )
|
||||
if ( !menu )
|
||||
{
|
||||
const QString text = d->selectedText();
|
||||
d->tts()->say( text );
|
||||
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
|
||||
else if ( choice == httpLink )
|
||||
new KRun( QUrl( url ), this );
|
||||
if ( !d->document->isAllowed( Okular::AllowCopy ) )
|
||||
{
|
||||
textToClipboard->setEnabled( false );
|
||||
textToClipboard->setText( i18n("Copy forbidden by DRM") );
|
||||
}
|
||||
else
|
||||
{
|
||||
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, 30 );
|
||||
httpLink = menu->addAction( i18n( "Go to '%1'", squeezedText ) );
|
||||
httpLink->setObjectName("GoToAction");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( menu ) {
|
||||
menu->setObjectName("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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3434,7 +3457,12 @@ QList< Okular::RegularAreaRect * > PageView::textSelections( const QPoint& start
|
|||
|
||||
void PageView::drawDocumentOnPainter( const QRect & contentsRect, QPainter * p )
|
||||
{
|
||||
QColor backColor = viewport()->palette().color( QPalette::Dark );
|
||||
QColor backColor;
|
||||
|
||||
if ( Okular::Settings::useCustomBackgroundColor() )
|
||||
backColor = Okular::Settings::backgroundColor();
|
||||
else
|
||||
backColor = viewport()->palette().color( QPalette::Dark );
|
||||
|
||||
// when checking if an Item is contained in contentsRect, instead of
|
||||
// growing PageViewItems rects (for keeping outline into account), we
|
||||
|
@ -4017,6 +4045,9 @@ void PageView::updateCursor()
|
|||
|
||||
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() );
|
||||
|
||||
|
@ -4031,41 +4062,59 @@ void PageView::updateCursor( const QPoint &p )
|
|||
{
|
||||
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
|
||||
if ( d->mouseMode == Okular::Settings::EnumMouseMode::TextSelect )
|
||||
setCursor( Qt::IBeamCursor );
|
||||
else if ( d->mouseMode == Okular::Settings::EnumMouseMode::Magnifier )
|
||||
setCursor( Qt::CrossCursor );
|
||||
else if ( d->mouseMode == Okular::Settings::EnumMouseMode::RectSelect )
|
||||
setCursor( Qt::CrossCursor );
|
||||
else if ( d->mouseMode == Okular::Settings::EnumMouseMode::TrimSelect )
|
||||
setCursor( Qt::CrossCursor );
|
||||
else if ( d->mouseMode == Okular::Settings::EnumMouseMode::Browse )
|
||||
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
|
||||
{
|
||||
const Okular::ObjectRect * linkobj = pageItem->page()->objectRect( Okular::ObjectRect::Action, nX, nY, pageItem->uncroppedWidth(), pageItem->uncroppedHeight() );
|
||||
if ( linkobj )
|
||||
{
|
||||
d->mouseOnRect = true;
|
||||
setCursor( Qt::PointingHandCursor );
|
||||
}
|
||||
else
|
||||
{
|
||||
setCursor( Qt::OpenHandCursor );
|
||||
}
|
||||
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( Qt::ArrowCursor );
|
||||
setCursor(cursorShapeFallback);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4275,6 +4324,51 @@ void PageView::addWebShortcutsMenu( QMenu * menu, const QString & text )
|
|||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
QMenu *menu = new QMenu(this);
|
||||
const Okular::Action * link = static_cast< const Okular::Action * >( rect->object() );
|
||||
// creating the menu and its actions
|
||||
QAction * processLink = menu->addAction( i18n( "Follow This Link" ) );
|
||||
processLink->setObjectName("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< const Okular::BrowseAction * >( link ) )
|
||||
{
|
||||
QAction * actCopyLinkLocation = menu->addAction( QIcon::fromTheme( QStringLiteral("edit-copy") ), i18n( "Copy Link Address" ) );
|
||||
actCopyLinkLocation->setObjectName("CopyLinkLocationAction");
|
||||
connect( actCopyLinkLocation, &QAction::triggered, [ link ]() {
|
||||
const Okular::BrowseAction * browseLink = static_cast< const Okular::BrowseAction * >( 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, link]() {
|
||||
d->document->processAction( link );
|
||||
});
|
||||
return menu;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//BEGIN private SLOTS
|
||||
void PageView::slotRelayoutPages()
|
||||
// called by: notifySetup, viewportResizeEvent, slotViewMode, slotContinuousToggled, updateZoom
|
||||
|
@ -5106,6 +5200,18 @@ void PageView::updateTrimMode( int except_id ) {
|
|||
}
|
||||
}
|
||||
|
||||
bool PageView::mouseReleaseOverLink( const Okular::ObjectRect * rect ) const
|
||||
{
|
||||
if ( rect )
|
||||
{
|
||||
// handle click over a link
|
||||
const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
|
||||
d->document->processAction( action );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PageView::slotTrimMarginsToggled( bool on )
|
||||
{
|
||||
if (on) { // Turn off any other Trim modes
|
||||
|
|
|
@ -36,6 +36,7 @@ class DocumentViewport;
|
|||
class Annotation;
|
||||
class MovieAction;
|
||||
class RenditionAction;
|
||||
class PixmapRequest;
|
||||
}
|
||||
|
||||
class FormWidgetIface;
|
||||
|
@ -188,12 +189,16 @@ Q_OBJECT
|
|||
void updatePageStep();
|
||||
|
||||
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 );
|
||||
|
||||
// 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;
|
||||
|
||||
// don't want to expose classes in here
|
||||
class PageViewPrivate * d;
|
||||
|
||||
|
|
|
@ -1111,11 +1111,18 @@ QString PageViewAnnotator::defaultToolName( const QDomElement &toolElement )
|
|||
|
||||
QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
|
||||
{
|
||||
QPixmap pixmap( 32, 32 );
|
||||
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 = "@2x";
|
||||
}
|
||||
|
||||
// Load base pixmap. We'll draw on top of it
|
||||
pixmap.load( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("okular/pics/tool-base-okular.png") ) );
|
||||
pixmap.load( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-base-okular" + imageVariant + ".png") ) );
|
||||
|
||||
/* Parse color, innerColor and icon (if present) */
|
||||
QColor engineColor, innerColor;
|
||||
|
@ -1149,7 +1156,7 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
|
|||
}
|
||||
else if ( annotType == QLatin1String("highlight") )
|
||||
{
|
||||
QImage overlay( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("okular/pics/tool-highlighter-okular-colorizable.png") ) );
|
||||
QImage overlay( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-highlighter-okular-colorizable" + imageVariant + ".png") ) );
|
||||
QImage colorizedOverlay = overlay;
|
||||
GuiUtils::colorizeImage( colorizedOverlay, engineColor );
|
||||
|
||||
|
@ -1159,7 +1166,7 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
|
|||
}
|
||||
else if ( annotType == QLatin1String("ink") )
|
||||
{
|
||||
QImage overlay( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("okular/pics/tool-ink-okular-colorizable.png") ) );
|
||||
QImage overlay( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-ink-okular-colorizable" + imageVariant + ".png") ) );
|
||||
QImage colorizedOverlay = overlay;
|
||||
GuiUtils::colorizeImage( colorizedOverlay, engineColor );
|
||||
|
||||
|
@ -1169,13 +1176,13 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
|
|||
}
|
||||
else if ( annotType == QLatin1String("note-inline") )
|
||||
{
|
||||
QImage overlay( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("okular/pics/tool-note-inline-okular-colorizable.png") ) );
|
||||
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, QStringLiteral("okular/pics/tool-note-okular-colorizable.png") ) );
|
||||
QImage overlay( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-note-okular-colorizable.png" + imageVariant + ".png") ) );
|
||||
GuiUtils::colorizeImage( overlay, engineColor );
|
||||
p.drawImage( QPoint(0,0), overlay );
|
||||
}
|
||||
|
|
|
@ -232,26 +232,21 @@ void MouseAnnotation::routeKeyPressEvent( const QKeyEvent * e )
|
|||
void MouseAnnotation::routeTooltipEvent( const QHelpEvent * helpEvent )
|
||||
{
|
||||
/* qDebug() << "MouseAnnotation::routeTooltipEvent, event " << helpEvent; */
|
||||
const QPoint eventPos = m_pageView->contentAreaPoint( helpEvent->pos() );
|
||||
if ( m_mouseOverAnnotation.isValid() &&
|
||||
m_mouseOverAnnotation.annotation->subType() != Okular::Annotation::AWidget )
|
||||
{
|
||||
const ResizeHandle handle = getHandleAt( eventPos - m_mouseOverAnnotation.pageViewItem->uncroppedGeometry().topLeft(), m_mouseOverAnnotation );
|
||||
if ( handle != RH_None )
|
||||
{
|
||||
/* get boundingRect in uncropped page coordinates */
|
||||
QRect boundingRect = Okular::AnnotationUtils::annotationGeometry(
|
||||
m_mouseOverAnnotation.annotation, m_mouseOverAnnotation.pageViewItem->uncroppedWidth(),
|
||||
m_mouseOverAnnotation.pageViewItem->uncroppedHeight() );
|
||||
/* 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() );
|
||||
/* uncropped page to content area */
|
||||
boundingRect.translate( m_mouseOverAnnotation.pageViewItem->uncroppedGeometry().topLeft() );
|
||||
/* content area to viewport */
|
||||
boundingRect.translate( -m_pageView->contentAreaPosition() );
|
||||
|
||||
QString tip = GuiUtils::prettyToolTip( m_mouseOverAnnotation.annotation );
|
||||
QToolTip::showText( helpEvent->globalPos(), tip, m_pageView->viewport(), boundingRect );
|
||||
}
|
||||
const QString tip = GuiUtils::prettyToolTip( m_mouseOverAnnotation.annotation );
|
||||
QToolTip::showText( helpEvent->globalPos(), tip, m_pageView->viewport(), boundingRect );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ struct PresentationFrame
|
|||
geometry.setRect( ( width - pageWidth ) / 2,
|
||||
( height - pageHeight ) / 2,
|
||||
pageWidth, pageHeight );
|
||||
|
||||
Q_FOREACH ( VideoWidget *vw, videoWidgets )
|
||||
{
|
||||
const Okular::NormalizedRect r = vw->normGeometry();
|
||||
|
@ -451,7 +452,7 @@ void PresentationWidget::notifyCurrentPageChanged( int previousPage, int current
|
|||
|
||||
// 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, pixW, pixH ) )
|
||||
if ( !frame->page->hasPixmap( this, ceil(pixW * qApp->devicePixelRatio()), ceil(pixH * qApp->devicePixelRatio()) ) )
|
||||
{
|
||||
requestPixmaps();
|
||||
}
|
||||
|
@ -780,6 +781,8 @@ void PresentationWidget::mouseMoveEvent( QMouseEvent * e )
|
|||
|
||||
void PresentationWidget::paintEvent( QPaintEvent * pe )
|
||||
{
|
||||
qreal dpr = devicePixelRatioF();
|
||||
|
||||
if ( m_inBlackScreenMode )
|
||||
{
|
||||
QPainter painter( this );
|
||||
|
@ -824,28 +827,32 @@ void PresentationWidget::paintEvent( QPaintEvent * pe )
|
|||
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( r.size() );
|
||||
QPixmap backPixmap( dR.size() );
|
||||
backPixmap.setDevicePixelRatio( dpr );
|
||||
QPainter pixPainter( &backPixmap );
|
||||
|
||||
// first draw the background on the backbuffer
|
||||
pixPainter.drawPixmap( QPoint(0,0), m_lastRenderedPixmap, r );
|
||||
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(),
|
||||
ovr.top() - m_overlayGeometry.top(), ovr.width(), ovr.height() );
|
||||
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();
|
||||
painter.drawPixmap( r.topLeft(), backPixmap, backPixmap.rect() );
|
||||
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, r );
|
||||
painter.drawPixmap( r.topLeft(), m_lastRenderedPixmap, dR );
|
||||
}
|
||||
|
||||
// paint drawings
|
||||
|
@ -1001,7 +1008,10 @@ void PresentationWidget::generatePage( bool disableTransition )
|
|||
{
|
||||
if ( m_lastRenderedPixmap.isNull() )
|
||||
{
|
||||
m_lastRenderedPixmap = QPixmap( m_width, m_height );
|
||||
qreal dpr = qApp->devicePixelRatio();
|
||||
m_lastRenderedPixmap = QPixmap( m_width * dpr, m_height * dpr );
|
||||
m_lastRenderedPixmap.setDevicePixelRatio(dpr);
|
||||
|
||||
m_previousPagePixmap = QPixmap();
|
||||
}
|
||||
else
|
||||
|
@ -1054,6 +1064,8 @@ void PresentationWidget::generatePage( bool disableTransition )
|
|||
|
||||
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;
|
||||
|
@ -1069,7 +1081,8 @@ void PresentationWidget::generateIntroPage( QPainter & p )
|
|||
}
|
||||
|
||||
// draw okular logo in the four corners
|
||||
QPixmap logo = DesktopIcon( QStringLiteral("okular"), 64 );
|
||||
QPixmap logo = DesktopIcon( QStringLiteral("okular"), 64 * dpr );
|
||||
logo.setDevicePixelRatio( dpr );
|
||||
if ( !logo.isNull() )
|
||||
{
|
||||
p.drawPixmap( 5, 5, logo );
|
||||
|
@ -1116,6 +1129,7 @@ void PresentationWidget::generateContentsPage( int pageNum, QPainter & p )
|
|||
|
||||
// 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 );
|
||||
|
||||
|
@ -1137,6 +1151,8 @@ 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
|
||||
int side = m_width / 16;
|
||||
m_overlayGeometry.setRect( m_width - side - 4, 4, side, side );
|
||||
|
@ -1145,7 +1161,9 @@ void PresentationWidget::generateOverlay()
|
|||
// and the resulting image is smoothly scaled down. So here we open a
|
||||
// painter on the double sized pixmap.
|
||||
side *= 2;
|
||||
QPixmap doublePixmap( side, side );
|
||||
|
||||
QPixmap doublePixmap( side * dpr, side * dpr );
|
||||
doublePixmap.setDevicePixelRatio( dpr );
|
||||
doublePixmap.fill( Qt::black );
|
||||
QPainter pixmapPainter( &doublePixmap );
|
||||
pixmapPainter.setRenderHints( QPainter::Antialiasing );
|
||||
|
@ -1190,8 +1208,10 @@ void PresentationWidget::generateOverlay()
|
|||
|
||||
// end drawing pixmap and halve image
|
||||
pixmapPainter.end();
|
||||
QImage image( doublePixmap.toImage().scaled( side / 2, side / 2, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
|
||||
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 );
|
||||
|
@ -1200,7 +1220,8 @@ void PresentationWidget::generateOverlay()
|
|||
pixmapPainter.setBrush( QColor( 0x80 ) );
|
||||
pixmapPainter.drawEllipse( 0, 0, side, side );
|
||||
pixmapPainter.end();
|
||||
QImage shadow( doublePixmap.toImage().scaled( side / 2, side / 2, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
|
||||
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)
|
||||
|
@ -1238,6 +1259,7 @@ void PresentationWidget::generateOverlay()
|
|||
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
|
||||
|
@ -1519,6 +1541,7 @@ void PresentationWidget::slotTransitionStep()
|
|||
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 );
|
||||
|
|