Merge remote-tracking branch 'origin/master' into dont-use-docdata-for-annots-and-forms

This commit is contained in:
Albert Astals Cid 2017-10-23 16:02:52 +02:00 committed by Albert Astals Cid
commit 54bcb44559
54 changed files with 1161 additions and 278 deletions

View file

@ -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)

Binary file not shown.

View 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()

View file

@ -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 );
}

View file

@ -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;

View file

@ -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>

View file

@ -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">

View file

@ -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();

View file

@ -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}

View file

@ -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;

View file

@ -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;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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",

View file

@ -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

View file

@ -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

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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",

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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
View file

@ -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;

View file

@ -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>&amp;Edit</text>
<Action name="edit_undo"/>

View file

@ -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();

View file

@ -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>

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 945 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -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; }

View file

@ -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 );

View file

@ -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

View file

@ -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;

View file

@ -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 );
}

View file

@ -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 );
}
}

View file

@ -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 );