Create color mode menu.

Implemented using a ColorModeMenu class,
derived from ToggleActionMenu (derived from KActionMenu),
as a child object of PageView.

* KToggleAction for every color mode, allows to set shortcuts for every mode.
  Color mode actions have icons.
* KToggleAction for normal colors mode.
* ToggleActionMenu containing all color mode actions.
  If triggered, toggles color mode between normal colors and last change colors mode.

"Toggle Change Colors" is replaced by "Change Colors", which is actually a toggle action.

BUG: 407217
BUG: 437755
This commit is contained in:
David Hurka 2021-05-29 23:08:56 +00:00
parent 8b13d989c6
commit 195bbe3636
11 changed files with 269 additions and 22 deletions

View File

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

View File

@ -8,6 +8,9 @@
<signal name="builtinAnnotationToolsChanged" />
<signal name="quickAnnotationToolsChanged" />
<signal name="viewContinuousChanged" />
<signal name="colorModesChanged2" >
<label>Same as colorModesChanged(), but kconfig_compiler does not allow to inherit signals, so appending a '2'.</label>
</signal>
<group name="Dlg Performance" >
<entry key="EnableCompositing" type="Bool" >
<default>true</default>
@ -376,19 +379,23 @@
</entry>
<entry key="RecolorForeground" type="Color" >
<default code="true" >0x600000</default>
<emit signal="colorModesChanged2" />
</entry>
<entry key="RecolorBackground" type="Color" >
<default code="true" >0xF0F0F0</default>
<emit signal="colorModesChanged2" />
</entry>
<entry key="BWThreshold" type="UInt" >
<default>127</default>
<min>2</min>
<max>253</max>
<emit signal="colorModesChanged2" />
</entry>
<entry key="BWContrast" type="UInt" >
<default>2</default>
<min>2</min>
<max>6</max>
<emit signal="colorModesChanged2" />
</entry>
</group>
<group name="Identity" >

View File

@ -5,6 +5,7 @@
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<include>kuser.h</include>
<kcfgfile arg="true" />
<signal name="colorModesChanged" />
<group name="Core Performance" >
<entry key="MemoryLevel" type="Enum" >
<default>Normal</default>
@ -43,9 +44,11 @@
<group name="Document">
<entry key="PaperColor" type="Color" >
<default code="true" >Qt::white</default>
<emit signal="colorModesChanged" />
</entry>
<entry key="ChangeColors" type="Bool" >
<default>false</default>
<emit signal="colorModesChanged" />
</entry>
<entry key="RenderMode" type="Enum" >
<default>Inverted</default>
@ -60,6 +63,7 @@
<choice name="HueShiftPositive" />
<choice name="HueShiftNegative" />
</choices>
<emit signal="colorModesChanged" />
</entry>
</group>
<group name="Core General" >

145
part/colormodemenu.cpp Normal file
View File

@ -0,0 +1,145 @@
/***************************************************************************
* Copyright (C) 2019-2021 by David Hurka <david.hurka@mailbox.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include "colormodemenu.h"
#include <KActionCollection>
#include <KLocalizedString>
#include <kwidgetsaddons_version.h> // 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<QAction *> 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<QColor>() << Okular::Settings::paperColor(), QIcon::fromTheme(QStringLiteral("paper-color"))));
m_aDarkLight->setIcon(GuiUtils::createColorIcon(QList<QColor>() << 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<QAction *> colorModeActions = m_colorModeActionGroup->actions();
for (QAction *a : colorModeActions) {
a->setEnabled(enabled);
}
}

74
part/colormodemenu.h Normal file
View File

@ -0,0 +1,74 @@
/***************************************************************************
* Copyright (C) 2019-2021 by David Hurka <david.hurka@mailbox.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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