File indexing completed on 2024-05-05 04:50:48

0001 /*
0002  * SPDX-FileCopyrightText: 2022 George Florea Bănuș <georgefb899@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "actionsmodel.h"
0008 
0009 #include <KConfigGroup>
0010 
0011 #include <QMessageBox>
0012 #include <QPushButton>
0013 
0014 #include "global.h"
0015 
0016 ActionsModel::ActionsModel(QObject *parent)
0017     : QAbstractListModel(parent)
0018     , m_config(KSharedConfig::openConfig(Global::instance()->appConfigFilePath(Global::ConfigFile::Shortcuts)))
0019 {
0020     Action action;
0021     action.name = QStringLiteral("openActionsDialogAction");
0022     action.text = i18nc("@action", "Open Actions Dialog");
0023     action.defaultShortcut = Qt::CTRL | Qt::Key_QuoteLeft; // Key_QuoteLeft =  backtick
0024     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0025     m_actions << action;
0026 
0027     action.name = QStringLiteral("aboutHarunaAction");
0028     action.text = i18nc("@action", "About Haruna");
0029     action.iconName = QStringLiteral("haruna");
0030     action.defaultShortcut = Qt::Key_F1;
0031     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0032     m_actions << action;
0033 
0034     action.name = QStringLiteral("audioCycleUpAction");
0035     action.text = i18nc("@action", "Audio Cycle Up");
0036     action.iconName = QString();
0037     action.defaultShortcut = Qt::SHIFT | Qt::Key_3;
0038     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0039     m_actions << action;
0040 
0041     action.name = QStringLiteral("audioCycleDownAction");
0042     action.text = i18nc("@action", "Audio Cycle Down");
0043     action.iconName = QString();
0044     action.defaultShortcut = Qt::SHIFT | Qt::Key_2;
0045     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0046     m_actions << action;
0047 
0048     action.name = QStringLiteral("configureAction");
0049     action.text = i18nc("@action", "Configure");
0050     action.iconName = QStringLiteral("configure");
0051     action.defaultShortcut = Qt::CTRL | Qt::SHIFT | Qt::Key_Comma;
0052     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0053     m_actions << action;
0054 
0055     action.name = QStringLiteral("configureShortcutsAction");
0056     action.text = i18nc("@action", "Configure Keyboard Shortcuts");
0057     action.iconName = QStringLiteral("configure-shortcuts");
0058     action.defaultShortcut = Qt::CTRL | Qt::ALT | Qt::Key_Comma;
0059     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0060     m_actions << action;
0061 
0062     action.name = QStringLiteral("exitFullscreenAction");
0063     action.text = i18nc("@action", "Exit Fullscreen");
0064     action.iconName = QString();
0065     action.defaultShortcut = Qt::Key_Escape;
0066     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0067     m_actions << action;
0068 
0069     action.name = QStringLiteral("frameStepForwardAction");
0070     action.text = i18nc("@action", "Frame Step Forward");
0071     action.iconName = QString();
0072     action.defaultShortcut = Qt::Key_Period;
0073     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0074     action.description = QStringLiteral("Move one frame forward, then pause");
0075     m_actions << action;
0076 
0077     action.name = QStringLiteral("frameStepBackwardAction");
0078     action.text = i18nc("@action", "Frame Step Backward");
0079     action.iconName = QString();
0080     action.defaultShortcut = Qt::Key_Comma;
0081     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0082     action.description = QStringLiteral("Move one frame backward, then pause");
0083     m_actions << action;
0084 
0085     action.name = QStringLiteral("loadLastPlayedFileAction");
0086     action.text = i18nc("@action", "Load Last Played File");
0087     action.iconName = QStringLiteral("document-open-recent");
0088     action.defaultShortcut = Qt::CTRL | Qt::SHIFT | Qt::Key_L;
0089     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0090     m_actions << action;
0091 
0092     action.name = QStringLiteral("muteAction");
0093     action.text = i18nc("@action", "Mute");
0094     action.iconName = QStringLiteral("player-volume-muted");
0095     action.defaultShortcut = Qt::Key_M;
0096     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0097     m_actions << action;
0098 
0099     action.name = QStringLiteral("openContextMenuAction");
0100     action.text = i18nc("@action", "Open Context Menu");
0101     action.iconName = QStringLiteral("application-menu");
0102     action.defaultShortcut = Qt::Key_Menu;
0103     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0104     action.description = i18nc("@action", "Opens and closes the context menu at the position of the mouse pointer");
0105     m_actions << action;
0106 
0107     action.name = QStringLiteral("openFileAction");
0108     action.text = i18nc("@action", "Open File");
0109     action.iconName = QStringLiteral("folder-videos");
0110     action.defaultShortcut = Qt::CTRL | Qt::Key_O;
0111     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0112     m_actions << action;
0113 
0114     action.name = QStringLiteral("openSubtitlesFileAction");
0115     action.text = i18nc("@action", "Add External Subtitle…");
0116     action.iconName = QStringLiteral("add-subtitle");
0117     action.defaultShortcut = Qt::ALT | Qt::Key_S;
0118     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0119     m_actions << action;
0120 
0121     action.name = QStringLiteral("openUrlAction");
0122     action.text = i18nc("@action", "Open Url");
0123     action.iconName = QStringLiteral("internet-services");
0124     action.defaultShortcut = Qt::CTRL | Qt::SHIFT | Qt::Key_O;
0125     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0126     m_actions << action;
0127 
0128     action.name = QStringLiteral("playbackSpeedIncreaseAction");
0129     action.text = i18nc("@action", "Playback Speed Increase");
0130     action.iconName = QString();
0131     action.defaultShortcut = Qt::Key_BracketRight;
0132     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0133     m_actions << action;
0134 
0135     action.name = QStringLiteral("playbackSpeedDecreaseAction");
0136     action.text = i18nc("@action", "Playback Speed Decrease");
0137     action.iconName = QString();
0138     action.defaultShortcut = Qt::Key_BracketLeft;
0139     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0140     m_actions << action;
0141 
0142     action.name = QStringLiteral("playbackSpeedResetAction");
0143     action.text = i18nc("@action", "Playback Speed Reset");
0144     action.iconName = QString();
0145     action.defaultShortcut = Qt::Key_Backspace;
0146     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0147     m_actions << action;
0148 
0149     action.name = QStringLiteral("playPauseAction");
0150     action.text = i18nc("@action", "Play/Pause");
0151     action.iconName = QStringLiteral("media-playback-pause");
0152     action.defaultShortcut = Qt::Key_Space;
0153     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0154     m_actions << action;
0155 
0156     action.name = QStringLiteral("playNextAction");
0157     action.text = i18nc("@action", "Play Next");
0158     action.iconName = QStringLiteral("media-skip-forward");
0159     action.defaultShortcut = Qt::SHIFT | Qt::Key_Period;
0160     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0161     m_actions << action;
0162 
0163     action.name = QStringLiteral("playPreviousAction");
0164     action.text = i18nc("@action", "Play Previous");
0165     action.iconName = QStringLiteral("media-skip-backward");
0166     action.defaultShortcut = Qt::SHIFT | Qt::Key_Comma;
0167     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0168     m_actions << action;
0169 
0170     action.name = QStringLiteral("quitApplicationAction");
0171     action.text = i18nc("@action", "Quit");
0172     action.iconName = QStringLiteral("application-exit");
0173     action.defaultShortcut = Qt::CTRL | Qt::Key_Q;
0174     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0175     m_actions << action;
0176 
0177     action.name = QStringLiteral("restartPlaybackAction");
0178     action.text = i18nc("@action", "Restart Playback");
0179     action.iconName = QStringLiteral("edit-reset");
0180     action.defaultShortcut = Qt::Key_F5;
0181     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0182     m_actions << action;
0183 
0184     action.name = QStringLiteral("seekForwardSmallAction");
0185     action.text = i18nc("@action", "Seek Small Step Forward");
0186     action.iconName = QStringLiteral("media-seek-forward");
0187     action.defaultShortcut = Qt::Key_Right;
0188     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0189     m_actions << action;
0190 
0191     action.name = QStringLiteral("seekBackwardSmallAction");
0192     action.text = i18nc("@action", "Seek Small Step Backward");
0193     action.iconName = QStringLiteral("media-seek-backward");
0194     action.defaultShortcut = Qt::Key_Left;
0195     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0196     m_actions << action;
0197 
0198     action.name = QStringLiteral("seekForwardMediumAction");
0199     action.text = i18nc("@action", "Seek Medium Step Forward");
0200     action.iconName = QStringLiteral("media-seek-forward");
0201     action.defaultShortcut = Qt::SHIFT | Qt::Key_Right;
0202     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0203     m_actions << action;
0204 
0205     action.name = QStringLiteral("seekBackwardMediumAction");
0206     action.text = i18nc("@action", "Seek Medium Step Backward");
0207     action.iconName = QStringLiteral("media-seek-backward");
0208     action.defaultShortcut = Qt::SHIFT | Qt::Key_Left;
0209     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0210     m_actions << action;
0211 
0212     action.name = QStringLiteral("seekForwardBigAction");
0213     action.text = i18nc("@action", "Seek Big Step Forward");
0214     action.iconName = QStringLiteral("media-seek-forward");
0215     action.defaultShortcut = Qt::Key_Up;
0216     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0217     m_actions << action;
0218 
0219     action.name = QStringLiteral("seekBackwardBigAction");
0220     action.text = i18nc("@action", "Seek Big Step Backward");
0221     action.iconName = QStringLiteral("media-seek-backward");
0222     action.defaultShortcut = Qt::Key_Down;
0223     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0224     m_actions << action;
0225 
0226     action.name = QStringLiteral("seekNextChapterAction");
0227     action.text = i18nc("@action", "Seek Next Chapter");
0228     action.iconName = QStringLiteral("media-seek-forward");
0229     action.defaultShortcut = Qt::Key_PageUp;
0230     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0231     m_actions << action;
0232 
0233     action.name = QStringLiteral("seekPreviousChapterAction");
0234     action.text = i18nc("@action", "Seek Previous Chapter");
0235     action.iconName = QStringLiteral("media-seek-backward");
0236     action.defaultShortcut = Qt::Key_PageDown;
0237     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0238     m_actions << action;
0239 
0240     action.name = QStringLiteral("seekNextSubtitleAction");
0241     action.text = i18nc("@action", "Seek To Next Subtitle");
0242     action.iconName = QStringLiteral("media-seek-forward");
0243     action.defaultShortcut = Qt::CTRL | Qt::Key_Right;
0244     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0245     m_actions << action;
0246 
0247     action.name = QStringLiteral("seekPreviousSubtitleAction");
0248     action.text = i18nc("@action", "Seek To Previous Subtitle");
0249     action.iconName = QStringLiteral("media-seek-backward");
0250     action.defaultShortcut = Qt::CTRL | Qt::Key_Left;
0251     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0252     m_actions << action;
0253 
0254     action.name = QStringLiteral("seekToWatchLaterPositionAction");
0255     action.text = i18nc("@action", "Seek To Watch Later Position");
0256     action.iconName = QStringLiteral("pin");
0257     action.defaultShortcut = Qt::CTRL | Qt::SHIFT | Qt::Key_P;
0258     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0259     m_actions << action;
0260 
0261     action.name = QStringLiteral("setLoopAction");
0262     action.text = i18nc("@action", "Set Loop");
0263     action.iconName = QString();
0264     action.defaultShortcut = Qt::Key_L;
0265     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0266     m_actions << action;
0267 
0268     action.name = QStringLiteral("screenshotAction");
0269     action.text = i18nc("@action", "Screenshot");
0270     action.iconName = QStringLiteral("image-x-generic");
0271     action.defaultShortcut = Qt::Key_S;
0272     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0273     m_actions << action;
0274 
0275     action.name = QStringLiteral("subtitleToggleAction");
0276     action.text = i18nc("@action", "Subtitle Toggle");
0277     action.iconName = QString();
0278     action.defaultShortcut = Qt::CTRL | Qt::Key_S;
0279     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0280     m_actions << action;
0281 
0282     action.name = QStringLiteral("subtitleIncreaseFontSizeAction");
0283     action.text = i18nc("@action", "Subtitle Increase Font Size");
0284     action.iconName = QString();
0285     action.defaultShortcut = Qt::CTRL | Qt::Key_Z;
0286     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0287     m_actions << action;
0288 
0289     action.name = QStringLiteral("subtitleDecreaseFontSizeAction");
0290     action.text = i18nc("@action", "Subtitle Decrease Font Size");
0291     action.iconName = QString();
0292     action.defaultShortcut = Qt::CTRL | Qt::Key_X;
0293     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0294     m_actions << action;
0295 
0296     action.name = QStringLiteral("subtitleMoveUpAction");
0297     action.text = i18nc("@action", "Subtitle Move Up");
0298     action.iconName = QString();
0299     action.defaultShortcut = Qt::Key_R;
0300     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0301     m_actions << action;
0302 
0303     action.name = QStringLiteral("subtitleMoveDownAction");
0304     action.text = i18nc("@action", "Subtitle Move Down");
0305     action.iconName = QString();
0306     action.defaultShortcut = Qt::SHIFT | Qt::Key_R;
0307     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0308     m_actions << action;
0309 
0310     action.name = QStringLiteral("subtitleQuickenAction");
0311     action.text = i18nc("@action", "Subtitle Quicken");
0312     action.iconName = QString();
0313     action.defaultShortcut = Qt::Key_Z;
0314     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0315     m_actions << action;
0316 
0317     action.name = QStringLiteral("subtitleDelayAction");
0318     action.text = i18nc("@action", "Subtitle Delay");
0319     action.iconName = QString();
0320     action.defaultShortcut = Qt::SHIFT | Qt::Key_Z;
0321     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0322     m_actions << action;
0323 
0324     action.name = QStringLiteral("subtitleCycleUpAction");
0325     action.text = i18nc("@action", "Subtitle Cycle Up");
0326     action.iconName = QString();
0327     action.defaultShortcut = Qt::Key_J;
0328     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0329     m_actions << action;
0330 
0331     action.name = QStringLiteral("subtitleCycleDownAction");
0332     action.text = i18nc("@action", "Subtitle Cycle Down");
0333     action.iconName = QString();
0334     action.defaultShortcut = Qt::SHIFT | Qt::Key_J;
0335     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0336     m_actions << action;
0337 
0338     action.name = QStringLiteral("toggleDeinterlacingAction");
0339     action.text = i18nc("@action", "Toggle Deinterlacing");
0340     action.iconName = QString();
0341     action.defaultShortcut = Qt::Key_D;
0342     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0343     m_actions << action;
0344 
0345     action.name = QStringLiteral("toggleFullscreenAction");
0346     action.text = i18nc("@action", "Toggle Fullscreen");
0347     action.iconName = QStringLiteral("view-fullscreen");
0348     action.defaultShortcut = Qt::Key_F;
0349     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0350     m_actions << action;
0351 
0352     action.name = QStringLiteral("toggleMenuBarAction");
0353     action.text = i18nc("@action", "Toggle Menu Bar");
0354     action.iconName = QString();
0355     action.defaultShortcut = Qt::CTRL | Qt::Key_M;
0356     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0357     m_actions << action;
0358 
0359     action.name = QStringLiteral("toggleHeaderAction");
0360     action.text = i18nc("@action", "Toggle Header");
0361     action.iconName = QString();
0362     action.defaultShortcut = Qt::CTRL | Qt::Key_H;
0363     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0364     m_actions << action;
0365 
0366     action.name = QStringLiteral("togglePlaylistAction");
0367     action.text = i18nc("@action", "Playlist");
0368     action.iconName = QStringLiteral("view-media-playlist");
0369     action.defaultShortcut = Qt::Key_P;
0370     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0371     m_actions << action;
0372 
0373     action.name = QStringLiteral("videoPanXLeftAction");
0374     action.text = i18nc("@action", "Video Move Left");
0375     action.iconName = QString();
0376     action.defaultShortcut = Qt::CTRL | Qt::ALT | Qt::Key_Left;
0377     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0378     m_actions << action;
0379 
0380     action.name = QStringLiteral("videoPanXRightAction");
0381     action.text = i18nc("@action", "Video Move Right");
0382     action.iconName = QString();
0383     action.defaultShortcut = Qt::CTRL | Qt::ALT | Qt::Key_Right;
0384     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0385     m_actions << action;
0386 
0387     action.name = QStringLiteral("videoPanYUpAction");
0388     action.text = i18nc("@action", "Video Move Up");
0389     action.iconName = QString();
0390     action.defaultShortcut = Qt::CTRL | Qt::ALT | Qt::Key_Up;
0391     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0392     m_actions << action;
0393 
0394     action.name = QStringLiteral("videoPanYDownAction");
0395     action.text = i18nc("@action", "Video Move Down");
0396     action.iconName = QString();
0397     action.defaultShortcut = Qt::CTRL | Qt::ALT | Qt::Key_Down;
0398     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0399     m_actions << action;
0400 
0401     action.name = QStringLiteral("volumeUpAction");
0402     action.text = i18nc("@action", "Volume Up");
0403     action.iconName = QStringLiteral("audio-volume-high");
0404     action.defaultShortcut = Qt::Key_9;
0405     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0406     m_actions << action;
0407 
0408     action.name = QStringLiteral("volumeDownAction");
0409     action.text = i18nc("@action", "Volume Down");
0410     action.iconName = QStringLiteral("audio-volume-low");
0411     action.defaultShortcut = Qt::Key_0;
0412     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0413     m_actions << action;
0414 
0415     action.name = QStringLiteral("zoomInAction");
0416     action.text = i18nc("@action", "Zoom In");
0417     action.iconName = QStringLiteral("zoom-in");
0418     action.defaultShortcut = Qt::CTRL | Qt::Key_Plus;
0419     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0420     m_actions << action;
0421 
0422     action.name = QStringLiteral("zoomOutAction");
0423     action.text = i18nc("@action", "Zoom Out");
0424     action.iconName = QStringLiteral("zoom-out");
0425     action.defaultShortcut = Qt::CTRL | Qt::Key_Minus;
0426     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0427     m_actions << action;
0428 
0429     action.name = QStringLiteral("zoomResetAction");
0430     action.text = i18nc("@action", "Zoom Reset");
0431     action.iconName = QStringLiteral("zoom-original");
0432     action.defaultShortcut = Qt::CTRL | Qt::Key_0;
0433     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0434     m_actions << action;
0435 
0436     action.name = QStringLiteral("contrastUpAction");
0437     action.text = i18nc("@action", "Contrast Up");
0438     action.iconName = QStringLiteral("contrast");
0439     action.defaultShortcut = Qt::Key_1;
0440     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0441     m_actions << action;
0442 
0443     action.name = QStringLiteral("contrastDownAction");
0444     action.text = i18nc("@action", "Contrast Down");
0445     action.iconName = QStringLiteral("contrast");
0446     action.defaultShortcut = Qt::Key_2;
0447     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0448     m_actions << action;
0449 
0450     action.name = QStringLiteral("contrastResetAction");
0451     action.text = i18nc("@action", "Contrast Reset");
0452     action.iconName = QStringLiteral("contrast");
0453     action.defaultShortcut = Qt::CTRL | Qt::Key_1;
0454     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0455     m_actions << action;
0456 
0457     action.name = QStringLiteral("brightnessUpAction");
0458     action.text = i18nc("@action", "Brightness Up");
0459     action.iconName = QStringLiteral("contrast");
0460     action.defaultShortcut = Qt::Key_3;
0461     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0462     m_actions << action;
0463 
0464     action.name = QStringLiteral("brightnessDownAction");
0465     action.text = i18nc("@action", "Brightness Down");
0466     action.iconName = QStringLiteral("contrast");
0467     action.defaultShortcut = Qt::Key_4;
0468     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0469     m_actions << action;
0470 
0471     action.name = QStringLiteral("brightnessResetAction");
0472     action.text = i18nc("@action", "Brightness Reset");
0473     action.iconName = QStringLiteral("contrast");
0474     action.defaultShortcut = Qt::CTRL | Qt::Key_3;
0475     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0476     m_actions << action;
0477 
0478     action.name = QStringLiteral("gammaUpAction");
0479     action.text = i18nc("@action", "Gamma Up");
0480     action.iconName = QStringLiteral("contrast");
0481     action.defaultShortcut = Qt::Key_5;
0482     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0483     m_actions << action;
0484 
0485     action.name = QStringLiteral("gammaDownAction");
0486     action.text = i18nc("@action", "Gamma Down");
0487     action.iconName = QStringLiteral("contrast");
0488     action.defaultShortcut = Qt::Key_6;
0489     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0490     m_actions << action;
0491 
0492     action.name = QStringLiteral("gammaResetAction");
0493     action.text = i18nc("@action", "Gamma Reset");
0494     action.iconName = QStringLiteral("contrast");
0495     action.defaultShortcut = Qt::CTRL | Qt::Key_5;
0496     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0497     m_actions << action;
0498 
0499     action.name = QStringLiteral("saturationUpAction");
0500     action.text = i18nc("@action", "Saturation Up");
0501     action.iconName = QStringLiteral("contrast");
0502     action.defaultShortcut = Qt::Key_7;
0503     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0504     m_actions << action;
0505 
0506     action.name = QStringLiteral("saturationDownAction");
0507     action.text = i18nc("@action", "Saturation Down");
0508     action.iconName = QStringLiteral("contrast");
0509     action.defaultShortcut = Qt::Key_8;
0510     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0511     m_actions << action;
0512 
0513     action.name = QStringLiteral("saturationResetAction");
0514     action.text = i18nc("@action", "Saturation Reset");
0515     action.iconName = QStringLiteral("contrast");
0516     action.defaultShortcut = Qt::CTRL | Qt::Key_7;
0517     action.shortcut = getShortcut(action.name, action.defaultShortcut);
0518     m_actions << action;
0519 }
0520 
0521 int ActionsModel::rowCount(const QModelIndex &parent) const
0522 {
0523     // For list models only the root node (an invalid parent) should return the list's size. For all
0524     // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
0525     if (parent.isValid()) {
0526         return 0;
0527     }
0528 
0529     return m_actions.count();
0530 }
0531 
0532 QVariant ActionsModel::data(const QModelIndex &index, int role) const
0533 {
0534     if (!index.isValid()) {
0535         return QVariant();
0536     }
0537 
0538     auto action = m_actions.at(index.row());
0539 
0540     switch (role) {
0541     case NameRole:
0542         return QVariant(action.name);
0543     case TextRole:
0544         return QVariant(action.text);
0545     case IconRole:
0546         return QVariant(action.iconName);
0547     case ShortcutRole:
0548         return QVariant(action.shortcut);
0549     case DefaultShortcutRole:
0550         return QVariant(action.defaultShortcut);
0551     case DescriptionRole:
0552         return QVariant(action.description);
0553     case TypeRole:
0554         return QVariant(action.type);
0555     }
0556 
0557     return QVariant();
0558 }
0559 
0560 QHash<int, QByteArray> ActionsModel::roleNames() const
0561 {
0562     QHash<int, QByteArray> roles;
0563     roles[NameRole] = "name";
0564     roles[TextRole] = "text";
0565     roles[IconRole] = "icon";
0566     roles[ShortcutRole] = "shortcut";
0567     roles[DefaultShortcutRole] = "defaultShortcut";
0568     roles[DescriptionRole] = "description";
0569     roles[TypeRole] = "type";
0570     return roles;
0571 }
0572 
0573 void ActionsModel::appendCustomAction(const Action &action)
0574 {
0575     beginInsertRows(QModelIndex(), rowCount(), rowCount());
0576     m_actions.append(action);
0577     endInsertRows();
0578 }
0579 
0580 void ActionsModel::editCustomAction(const QString &name, const QString &text, const QString &description)
0581 {
0582     for (int i{0}; i < m_actions.count(); ++i) {
0583         if (m_actions[i].name == name) {
0584             m_actions[i].text = text;
0585             m_actions[i].description = description;
0586             Q_EMIT dataChanged(index(i, 0), index(i, 0));
0587             return;
0588         }
0589     }
0590 }
0591 
0592 bool ActionsModel::saveShortcut(const QString &name, const QVariant &shortcut)
0593 {
0594     for (int i{0}; i < m_actions.count(); ++i) {
0595         if (m_actions[i].name == name) {
0596             return saveShortcut(i, shortcut);
0597         }
0598     }
0599     return false;
0600 }
0601 
0602 bool ActionsModel::saveShortcut(int row, const QVariant &shortcut)
0603 {
0604     auto group = m_config->group(QStringLiteral("Shortcuts"));
0605     auto shortcutString = shortcut.value<QKeySequence>().toString(QKeySequence::PortableText);
0606     // action whose shortcut is changed
0607     auto action = &m_actions[row];
0608 
0609     // if shortcut is being cleared, no need to search for a conflict
0610     if (!shortcut.toString().isEmpty()) {
0611         // if shortcut is used, this is the action holding the shortcut
0612         Action *result = nullptr;
0613         int i{0};
0614         for (; i < m_actions.count(); ++i) {
0615             if (m_actions[i].shortcut == shortcutString) {
0616                 result = &m_actions[i];
0617                 break;
0618             }
0619         }
0620 
0621         if (result != nullptr && action->name == result->name) {
0622             return false;
0623         }
0624 
0625         if (result != nullptr) {
0626             // shortcut is used by an action
0627             // ask user what whether to reassign or to cancel
0628             if (keyConflictMessageBox(result->text)) {
0629                 // user chose reassign, remove shortcut from action holding it
0630                 result->shortcut = QString();
0631                 group.writeEntry(result->name, result->shortcut);
0632                 Q_EMIT shortcutChanged(result->name, result->shortcut);
0633                 Q_EMIT dataChanged(index(i, 0), index(i, 0));
0634             } else {
0635                 // user chose cancel
0636                 return false;
0637             }
0638         }
0639     }
0640     // set shortcut on the action being changed
0641     action->shortcut = shortcutString;
0642     group.writeEntry(action->name, action->shortcut);
0643     Q_EMIT shortcutChanged(action->name, action->shortcut);
0644     Q_EMIT dataChanged(index(row, 0), index(row, 0));
0645 
0646     return group.sync();
0647 }
0648 
0649 QString ActionsModel::getShortcut(const QString &key, const QKeySequence &defaultValue) const
0650 {
0651     auto v = defaultValue.toString(QKeySequence::PortableText);
0652     auto group = m_config->group(QStringLiteral("Shortcuts"));
0653     return group.readEntry(key, v);
0654 }
0655 
0656 bool ActionsModel::keyConflictMessageBox(const QString &actionText)
0657 {
0658     auto message = i18nc("@info",
0659                          "The chosen shortcut conflicts with "
0660                          "the shortcut of the <b>%1</b> action.<br><br>"
0661                          "Do you want to reassign the shortcut?",
0662                          actionText);
0663     QMessageBox msgBox;
0664     msgBox.setText(message);
0665     QPushButton *reassignBtn = msgBox.addButton(i18nc("@action:button", "Reassign"), QMessageBox::AcceptRole);
0666     msgBox.addButton(QMessageBox::Cancel);
0667     msgBox.exec();
0668 
0669     if (msgBox.clickedButton() == reassignBtn) {
0670         return true;
0671     }
0672     return false;
0673 }
0674 
0675 QList<Action> &ActionsModel::actions()
0676 {
0677     return m_actions;
0678 }
0679 
0680 void ActionsModel::signalEmitter(const QString &actionName)
0681 {
0682     QMetaObject::invokeMethod(this, actionName.toUtf8().data());
0683 }
0684 
0685 ProxyActionsModel::ProxyActionsModel(QObject *parent)
0686     : QSortFilterProxyModel(parent)
0687 {
0688     setDynamicSortFilter(true);
0689     setFilterCaseSensitivity(Qt::CaseInsensitive);
0690 
0691     nameRegExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
0692     typeRegExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
0693 }
0694 
0695 bool ProxyActionsModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
0696 {
0697     QModelIndex nameIndex = sourceModel()->index(sourceRow, 0, sourceParent);
0698     QModelIndex typeIndex = sourceModel()->index(sourceRow, 0, sourceParent);
0699 
0700     QString name = sourceModel()->data(nameIndex, ActionsModel::NameRole).toString();
0701     QString type = sourceModel()->data(typeIndex, ActionsModel::TypeRole).toString();
0702 
0703     return (name.contains(nameRegExp) && type.contains(typeRegExp));
0704 }
0705 
0706 void ProxyActionsModel::setNameFilter(const QString &regExp)
0707 {
0708     nameRegExp.setPattern(regExp);
0709     invalidateFilter();
0710 }
0711 
0712 void ProxyActionsModel::setTypeFilter(const QString &regExp)
0713 {
0714     typeRegExp.setPattern(regExp);
0715     invalidateFilter();
0716 }
0717 
0718 bool ProxyActionsModel::saveShortcut(int row, const QVariant &shortcut)
0719 {
0720     auto actionsModel = qobject_cast<ActionsModel *>(sourceModel());
0721     return actionsModel->saveShortcut(mapToSource(index(row, 0)).row(), shortcut);
0722 }
0723 
0724 #include "moc_actionsmodel.cpp"