diff --git a/CMakeLists.txt b/CMakeLists.txt
index 98031b3db..d05a74f80 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -275,7 +275,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 GENERATE_MOC 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")
@@ -381,6 +381,7 @@ if(BUILD_DESKTOP)
part/annotationwidgets.cpp
part/bookmarklist.cpp
part/certificateviewer.cpp
+ part/colormodemenu.cpp
part/cursorwraphelper.cpp
part/debug_ui.cpp
part/drawingtoolactions.cpp
diff --git a/conf/okular.kcfg b/conf/okular.kcfg
index f5d37333f..f10bf178e 100644
--- a/conf/okular.kcfg
+++ b/conf/okular.kcfg
@@ -8,6 +8,9 @@
+
+
+
true
@@ -376,19 +379,23 @@
0x600000
+
0xF0F0F0
+
127
2
253
+
2
2
6
+
diff --git a/conf/okular_core.kcfg b/conf/okular_core.kcfg
index 41b03bd0e..ad886b13f 100644
--- a/conf/okular_core.kcfg
+++ b/conf/okular_core.kcfg
@@ -5,6 +5,7 @@
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
kuser.h
+
Normal
@@ -43,9 +44,11 @@
Qt::white
+
false
+
Inverted
@@ -60,6 +63,7 @@
+
diff --git a/part/colormodemenu.cpp b/part/colormodemenu.cpp
new file mode 100644
index 000000000..7d8e28282
--- /dev/null
+++ b/part/colormodemenu.cpp
@@ -0,0 +1,145 @@
+/***************************************************************************
+ * Copyright (C) 2019-2021 by David Hurka *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "colormodemenu.h"
+
+#include
+#include
+#include // TODO KF6: Remove, this was needed for KActionMenu::setPopupMode().
+
+#include "guiutils.h"
+#include "settings.h"
+
+ColorModeMenu::ColorModeMenu(KActionCollection *ac, QObject *parent)
+ : ToggleActionMenu(QIcon::fromTheme(QStringLiteral("color-management")), i18nc("@title:menu", "&Color Mode"), parent)
+ , m_colorModeActionGroup(new QActionGroup(this))
+ , m_aChangeColors(new KToggleAction(QIcon::fromTheme(QStringLiteral("color-management")), i18nc("@action Change Colors feature toggle action", "Change Colors"), this))
+{
+#if KWIDGETSADDONS_VERSION < QT_VERSION_CHECK(5, 77, 0)
+ setDelayed(false);
+ setStickyMenu(true);
+#else
+ setPopupMode(QToolButton::MenuButtonPopup);
+#endif
+
+ Q_ASSERT_X(ac->action(QStringLiteral("color_mode_menu")) == nullptr, "ColorModeMenu", "ColorModeMenu constructed twice; color_mode_menu already in action collection.");
+ ac->addAction(QStringLiteral("color_mode_menu"), this);
+
+ // Normal Colors action.
+ m_aNormal = new KToggleAction(i18nc("@item:inmenu color mode", "&Normal Colors"), this);
+ ac->addAction(QStringLiteral("color_mode_normal"), m_aNormal);
+ addAction(m_aNormal);
+ m_colorModeActionGroup->addAction(m_aNormal);
+
+ // Other color mode actions.
+ auto addColorMode = [=](KToggleAction *a, const QString &name, Okular::SettingsCore::EnumRenderMode::type id) {
+ a->setData(int(id));
+ addAction(a);
+ ac->addAction(name, a);
+ m_colorModeActionGroup->addAction(a);
+ };
+ addColorMode(new KToggleAction(QIcon::fromTheme(QStringLiteral("invertimage")), i18nc("@item:inmenu color mode", "&Invert Colors"), this), QStringLiteral("color_mode_inverted"), Okular::SettingsCore::EnumRenderMode::Inverted);
+ m_aPaperColor = new KToggleAction(i18nc("@item:inmenu color mode", "Change &Paper Color"), this);
+ addColorMode(m_aPaperColor, QStringLiteral("color_mode_paper"), Okular::SettingsCore::EnumRenderMode::Paper);
+ m_aDarkLight = new KToggleAction(i18nc("@item:inmenu color mode", "Change &Dark && Light Colors"), this);
+ addColorMode(m_aDarkLight, QStringLiteral("color_mode_recolor"), Okular::SettingsCore::EnumRenderMode::Recolor);
+ addColorMode(new KToggleAction(QIcon::fromTheme(QStringLiteral("color-mode-black-white")), i18nc("@item:inmenu color mode", "Convert to &Black && White"), this),
+ QStringLiteral("color_mode_black_white"),
+ Okular::SettingsCore::EnumRenderMode::BlackWhite);
+ addColorMode(new KToggleAction(QIcon::fromTheme(QStringLiteral("color-mode-invert-text")), i18nc("@item:inmenu color mode", "Invert &Lightness"), this),
+ QStringLiteral("color_mode_invert_lightness"),
+ Okular::SettingsCore::EnumRenderMode::InvertLightness);
+ addColorMode(new KToggleAction(QIcon::fromTheme(QStringLiteral("color-mode-invert-image")), i18nc("@item:inmenu color mode", "Invert L&uma (sRGB Linear)"), this),
+ QStringLiteral("color_mode_invert_luma_srgb"),
+ Okular::SettingsCore::EnumRenderMode::InvertLuma);
+ addColorMode(new KToggleAction(QIcon::fromTheme(QStringLiteral("color-mode-invert-image")), i18nc("@item:inmenu color mode", "Invert Luma (&Symmetric)"), this),
+ QStringLiteral("color_mode_invert_luma_symmetric"),
+ Okular::SettingsCore::EnumRenderMode::InvertLumaSymmetric);
+ addColorMode(new KToggleAction(QIcon::fromTheme(QStringLiteral("color-mode-hue-shift-positive")), i18nc("@item:inmenu color mode", "Shift Hue P&ositive"), this),
+ QStringLiteral("color_mode_hue_shift_positive"),
+ Okular::SettingsCore::EnumRenderMode::HueShiftPositive);
+ addColorMode(new KToggleAction(QIcon::fromTheme(QStringLiteral("color-mode-hue-shift-negative")), i18nc("@item:inmenu color mode", "Shift Hue N&egative"), this),
+ QStringLiteral("color_mode_hue_shift_negative"),
+ Okular::SettingsCore::EnumRenderMode::HueShiftNegative);
+
+ // Add Configure Color Modes action.
+ addSeparator();
+ QAction *aConfigure = ac->action(QStringLiteral("options_configure_color_modes"));
+ Q_ASSERT_X(aConfigure, "ColorModeMenu", "ColorModeMenu constructed before Okular::Part?!? options_configure_color_modes not in action collection.");
+ addAction(aConfigure);
+
+ connect(m_colorModeActionGroup, &QActionGroup::triggered, this, &ColorModeMenu::slotColorModeActionTriggered);
+ connect(Okular::SettingsCore::self(), &Okular::SettingsCore::colorModesChanged, this, &ColorModeMenu::slotConfigChanged);
+ connect(Okular::Settings::self(), &Okular::Settings::colorModesChanged2, this, &ColorModeMenu::slotConfigChanged);
+ connect(this, &QAction::changed, this, &ColorModeMenu::slotChanged);
+
+ // Allow to configure a toggle shortcut.
+ connect(m_aChangeColors, &QAction::toggled, this, &ColorModeMenu::slotSetChangeColors);
+ ac->addAction(QStringLiteral("color_mode_change_colors"), m_aChangeColors);
+
+ slotConfigChanged();
+}
+
+void ColorModeMenu::slotColorModeActionTriggered(QAction *action)
+{
+ const int newRenderMode = action->data().toInt();
+ // Color mode toggles to normal when the currently checked mode is triggered.
+ // Normal mode is special, triggering it always enables normal mode.
+ // Otherwise, the triggered color mode is activated.
+ if (action == m_aNormal) {
+ Okular::SettingsCore::setChangeColors(false);
+ } else if (Okular::SettingsCore::renderMode() == newRenderMode) {
+ Okular::SettingsCore::setChangeColors(!Okular::SettingsCore::changeColors());
+ } else {
+ Okular::SettingsCore::setRenderMode(newRenderMode);
+ Okular::SettingsCore::setChangeColors(true);
+ }
+ Okular::SettingsCore::self()->save();
+}
+
+void ColorModeMenu::slotSetChangeColors(bool on)
+{
+ Okular::SettingsCore::setChangeColors(on);
+ Okular::SettingsCore::self()->save();
+}
+
+void ColorModeMenu::slotConfigChanged()
+{
+ // Check the current color mode action, and update the toolbar button default action
+ const int rm = Okular::SettingsCore::renderMode();
+ const QList colorModeActions = m_colorModeActionGroup->actions();
+ for (QAction *a : colorModeActions) {
+ if (a != m_aNormal && a->data().toInt() == rm) {
+ a->setChecked(true);
+ setDefaultAction(a);
+ break;
+ }
+ }
+
+ // If Change Colors is disabled, check Normal Colors instead
+ if (!Okular::SettingsCore::changeColors()) {
+ m_aNormal->setChecked(true);
+ }
+
+ // Update color icons
+ m_aPaperColor->setIcon(GuiUtils::createColorIcon(QList() << Okular::Settings::paperColor(), QIcon::fromTheme(QStringLiteral("paper-color"))));
+ m_aDarkLight->setIcon(GuiUtils::createColorIcon(QList() << Okular::Settings::recolorForeground() << Okular::Settings::recolorBackground(), QIcon::fromTheme(QStringLiteral("color-mode-black-white"))));
+
+ // Update toggle action
+ m_aChangeColors->setChecked(Okular::SettingsCore::changeColors());
+}
+
+void ColorModeMenu::slotChanged()
+{
+ const bool enabled = isEnabled();
+ const QList colorModeActions = m_colorModeActionGroup->actions();
+ for (QAction *a : colorModeActions) {
+ a->setEnabled(enabled);
+ }
+}
diff --git a/part/colormodemenu.h b/part/colormodemenu.h
new file mode 100644
index 000000000..aeaac0be0
--- /dev/null
+++ b/part/colormodemenu.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2019-2021 by David Hurka *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#ifndef COLORMODEMENU_H
+#define COLORMODEMENU_H
+
+#include "toggleactionmenu.h"
+
+class KActionCollection;
+class KToggleAction;
+
+/**
+ * Color Mode menu. Allows to change Okular::Settings::RenderMode from the toolbar.
+ *
+ * The toolbar button will always show the last selected color mode (except normal mode),
+ * so it can be quickly enabled and disabled by just clicking the button.
+ * Clicking on the menu arrow opens a menu with all color modes (including normal mode),
+ * and an action to configure the color modes.
+ *
+ * Every color mode actions is available in the action collection, in addition to this menu itself.
+ *
+ * Color mode actions are enabled/disabled automatically when this menu is enabled/disabled.
+ */
+class ColorModeMenu : public ToggleActionMenu
+{
+ Q_OBJECT
+
+public:
+ explicit ColorModeMenu(KActionCollection *ac, QObject *parent);
+
+protected:
+ /** Makes color mode actions exclusive */
+ QActionGroup *m_colorModeActionGroup;
+
+ KToggleAction *m_aNormal;
+ KToggleAction *m_aPaperColor;
+ KToggleAction *m_aDarkLight;
+
+ /** Allows to set a shortcut to toggle the Change Colors feature. */
+ KToggleAction *m_aChangeColors;
+
+protected Q_SLOTS:
+ /**
+ * Sets the color mode (render mode) to the one represented by @p action.
+ *
+ * If @p action represents the current mode, toggles the Change Colors feature.
+ */
+ void slotColorModeActionTriggered(QAction *action);
+
+ /**
+ * Sets the change colors feature on or off.
+ */
+ void slotSetChangeColors(bool on);
+
+ /**
+ * Updates the default action and the checked states of the color mode menu.
+ *
+ * Call this when the color mode was changed or Change Colors was toggled.
+ */
+ void slotConfigChanged();
+
+ /**
+ * Updates child actions as necessary
+ */
+ void slotChanged();
+};
+
+#endif // COLORMODEMENU_H
diff --git a/part/pageview.cpp b/part/pageview.cpp
index af61752ae..97333b9a1 100644
--- a/part/pageview.cpp
+++ b/part/pageview.cpp
@@ -72,6 +72,7 @@
// local includes
#include "annotationpopup.h"
#include "annotwindow.h"
+#include "colormodemenu.h"
#include "core/annotations.h"
#include "cursorwraphelper.h"
#include "debug_ui.h"
@@ -246,6 +247,7 @@ public:
KToggleAction *aZoomAutoFit;
KActionMenu *aViewModeMenu;
QActionGroup *viewModeActionGroup;
+ ColorModeMenu *aColorModeMenu;
KToggleAction *aViewContinuous;
QAction *aPrevAction;
KToggleAction *aToggleForms;
@@ -375,6 +377,7 @@ PageView::PageView(QWidget *parent, Okular::Document *document)
d->aViewModeMenu = nullptr;
d->aViewContinuous = nullptr;
d->viewModeActionGroup = nullptr;
+ d->aColorModeMenu = nullptr;
d->aPrevAction = nullptr;
d->aToggleForms = nullptr;
d->aSpeakDoc = nullptr;
@@ -670,9 +673,7 @@ void PageView::setupViewerActions(KActionCollection *ac)
mz->setActionGroup(d->mouseModeActionGroup);
mz->setChecked(Okular::Settings::mouseMode() == Okular::Settings::EnumMouseMode::Zoom);
- QAction *aToggleChangeColors = new QAction(i18n("&Toggle Change Colors"), this);
- ac->addAction(QStringLiteral("toggle_change_colors"), aToggleChangeColors);
- connect(aToggleChangeColors, &QAction::triggered, this, &PageView::slotToggleChangeColors);
+ d->aColorModeMenu = new ColorModeMenu(ac, this);
}
// WARNING: 'setupViewerActions' must have been called before this method
@@ -1300,6 +1301,9 @@ void PageView::updateActionState(bool haspages, bool hasformwidgets)
if (d->aZoomActual)
d->aZoomActual->setEnabled(haspages && d->zoomFactor != 1.0);
+ if (d->aColorModeMenu)
+ d->aColorModeMenu->setEnabled(haspages);
+
if (d->aReadingDirection) {
d->aReadingDirection->setEnabled(haspages);
}
@@ -5162,18 +5166,6 @@ void PageView::slotProcessRenditionAction(const Okular::RenditionAction *action)
};
}
-void PageView::slotSetChangeColors(bool active)
-{
- Okular::SettingsCore::setChangeColors(active);
- Okular::Settings::self()->save();
- viewport()->update();
-}
-
-void PageView::slotToggleChangeColors()
-{
- slotSetChangeColors(!Okular::SettingsCore::changeColors());
-}
-
void PageView::slotFitWindowToPage()
{
const PageViewItem *currentPageItem = nullptr;
diff --git a/part/pageview.h b/part/pageview.h
index 0872fbd8f..44dad6d52 100644
--- a/part/pageview.h
+++ b/part/pageview.h
@@ -126,9 +126,6 @@ public Q_SLOTS:
void openAnnotationWindow(Okular::Annotation *annotation, int pageNumber);
void reloadForms();
- void slotToggleChangeColors();
- void slotSetChangeColors(bool active);
-
void slotSelectPage();
void slotAction(Okular::Action *action);
diff --git a/part/part.cpp b/part/part.cpp
index 0dfd2ca74..0ac2a7f5e 100644
--- a/part/part.cpp
+++ b/part/part.cpp
@@ -945,6 +945,11 @@ void Part::setupActions()
eraseDrawingAction->setIcon(QIcon::fromTheme(QStringLiteral("draw-eraser-delete-objects")));
eraseDrawingAction->setEnabled(false);
+ QAction *configureColorModes = new QAction(i18nc("@action", "Configure Color Modes..."), ac);
+ ac->addAction(QStringLiteral("options_configure_color_modes"), configureColorModes);
+ configureColorModes->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
+ connect(configureColorModes, &QAction::triggered, this, &Part::slotAccessibilityPreferences);
+
QAction *configureAnnotations = new QAction(i18n("Configure Annotations..."), ac);
ac->addAction(QStringLiteral("options_configure_annotations"), configureAnnotations);
configureAnnotations->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
@@ -2809,12 +2814,24 @@ void Part::slotPreferences()
void Part::slotToggleChangeColors()
{
- m_pageView->slotToggleChangeColors();
+ slotSetChangeColors(!Okular::SettingsCore::changeColors());
}
void Part::slotSetChangeColors(bool active)
{
- m_pageView->slotSetChangeColors(active);
+ Okular::SettingsCore::setChangeColors(active);
+ Okular::Settings::self()->save();
+}
+
+void Part::slotAccessibilityPreferences()
+{
+ // Create dialog
+ PreferencesDialog *dialog = new PreferencesDialog(m_pageView, Okular::Settings::self(), m_embedMode);
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
+
+ // Show it
+ dialog->switchToAccessibilityPage();
+ dialog->show();
}
void Part::slotAnnotationPreferences()
diff --git a/part/part.h b/part/part.h
index 743d04402..9adbf1eb6 100644
--- a/part/part.h
+++ b/part/part.h
@@ -436,6 +436,7 @@ private:
QUrl m_urlWithFragment;
private Q_SLOTS:
+ void slotAccessibilityPreferences();
void slotAnnotationPreferences();
void slotHandleActivatedSourceReference(const QString &absFileName, int line, int col, bool *handled);
};
diff --git a/part/preferencesdialog.cpp b/part/preferencesdialog.cpp
index a34ece3de..6e3d7279d 100644
--- a/part/preferencesdialog.cpp
+++ b/part/preferencesdialog.cpp
@@ -29,6 +29,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, KConfigSkeleton *skeleton,
m_general = new DlgGeneral(this, embedMode);
m_performance = new DlgPerformance(this);
m_accessibility = new DlgAccessibility(this);
+ m_accessibilityPage = nullptr;
m_presentation = nullptr;
m_annotations = nullptr;
m_annotationsPage = nullptr;
@@ -39,7 +40,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, KConfigSkeleton *skeleton,
#endif
addPage(m_general, i18n("General"), QStringLiteral("okular"), i18n("General Options"));
- addPage(m_accessibility, i18n("Accessibility"), QStringLiteral("preferences-desktop-accessibility"), i18n("Accessibility Reading Aids"));
+ m_accessibilityPage = addPage(m_accessibility, i18n("Accessibility"), QStringLiteral("preferences-desktop-accessibility"), i18n("Accessibility Reading Aids"));
addPage(m_performance, i18n("Performance"), QStringLiteral("preferences-system-performance"), i18n("Performance Tuning"));
if (embedMode == Okular::ViewerWidgetMode) {
setWindowTitle(i18n("Configure Viewer"));
@@ -57,6 +58,12 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, KConfigSkeleton *skeleton,
setHelp(QStringLiteral("configure"), QStringLiteral("okular"));
}
+void PreferencesDialog::switchToAccessibilityPage()
+{
+ if (m_accessibilityPage)
+ setCurrentPage(m_accessibilityPage);
+}
+
void PreferencesDialog::switchToAnnotationsPage()
{
if (m_annotationsPage)
diff --git a/part/preferencesdialog.h b/part/preferencesdialog.h
index d43b073a4..79a768716 100644
--- a/part/preferencesdialog.h
+++ b/part/preferencesdialog.h
@@ -33,6 +33,7 @@ class PreferencesDialog : public KConfigDialog
public:
PreferencesDialog(QWidget *parent, KConfigSkeleton *skeleton, Okular::EmbedMode embedMode);
+ void switchToAccessibilityPage();
void switchToAnnotationsPage();
protected:
@@ -54,6 +55,7 @@ private:
DlgDebug *m_debug;
#endif
+ KPageWidgetItem *m_accessibilityPage;
KPageWidgetItem *m_annotationsPage;
};