File indexing completed on 2024-05-12 03:54:28

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 1997 Stefan Taferner <taferner@alpin.or.at>
0004     SPDX-FileCopyrightText: 2000 Nicolas Hadacek <haadcek@kde.org>
0005     SPDX-FileCopyrightText: 2001, 2002 Ellis Whitehead <ellis@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #include "kstandardshortcut.h"
0011 #include "kstandardshortcutwatcher.h"
0012 
0013 #include "kconfig.h"
0014 #include "kconfigwatcher.h"
0015 #include "ksharedconfig.h"
0016 #include <kconfiggroup.h>
0017 
0018 #include <QCoreApplication>
0019 #include <QDebug>
0020 #include <QKeySequence>
0021 
0022 namespace KStandardShortcut
0023 {
0024 struct KStandardShortcutInfo {
0025     //! The standard shortcut id. @see StandardShortcut
0026     StandardShortcut id;
0027 
0028     /**
0029      * Unique name for the given accel. The name is used to save the user
0030      * settings. It's not representable. Use description for that.
0031      * @warning NEVER EVER CHANGE IT OR TRANSLATE IT!
0032      */
0033     const char *name;
0034 
0035     //! Localized label for user-visible display, including translation context.
0036     struct {
0037         const char *text;
0038         const char *context;
0039     } description;
0040 
0041     //! The keys for this shortcut
0042     int cutDefault, cutDefault2;
0043 
0044     //! A shortcut that is created with @a cutDefault and @cutDefault2
0045     QList<QKeySequence> cut;
0046 
0047     //! If this struct is initialized. If not initialized @cut is not valid
0048     bool isInitialized;
0049 
0050     // Category of this Shortcut
0051     Category category;
0052 };
0053 
0054 #define CTRL(x) QKeyCombination(Qt::CTRL | Qt::Key_##x).toCombined()
0055 #define SHIFT(x) QKeyCombination(Qt::SHIFT | Qt::Key_##x).toCombined()
0056 #define CTRLALT(x) QKeyCombination(Qt::CTRL | Qt::ALT | Qt::Key_##x).toCombined()
0057 #define CTRLSHIFT(x) QKeyCombination(Qt::CTRL | Qt::SHIFT | Qt::Key_##x).toCombined()
0058 #define ALT(x) QKeyCombination(Qt::ALT | Qt::Key_##x).toCombined()
0059 #define ALTSHIFT(x) QKeyCombination(Qt::ALT | Qt::SHIFT | Qt::Key_##x).toCombined()
0060 
0061 /** Array of predefined KStandardShortcutInfo objects, which cover all
0062     the "standard" accelerators. Each enum value from StandardShortcut
0063     should appear in this table.
0064 */
0065 // STUFF WILL BREAK IF YOU DON'T READ THIS!!!
0066 // Read the comments of the big enum in kstandardshortcut.h before you change anything!
0067 static KStandardShortcutInfo g_infoStandardShortcut[] = {
0068     // Group File,
0069     {AccelNone, nullptr, {nullptr, nullptr}, 0, 0, QList<QKeySequence>(), false, Category::InvalidCategory},
0070     {Open, "Open", QT_TRANSLATE_NOOP3("KStandardShortcut", "Open", "@action"), CTRL(O), 0, QList<QKeySequence>(), false, Category::File},
0071     {New, "New", QT_TRANSLATE_NOOP3("KStandardShortcut", "New", "@action"), CTRL(N), 0, QList<QKeySequence>(), false, Category::File},
0072     {Close, "Close", QT_TRANSLATE_NOOP3("KStandardShortcut", "Close", "@action"), CTRL(W), CTRL(Escape), QList<QKeySequence>(), false, Category::File},
0073     {Save, "Save", QT_TRANSLATE_NOOP3("KStandardShortcut", "Save", "@action"), CTRL(S), 0, QList<QKeySequence>(), false, Category::File},
0074     {Print, "Print", QT_TRANSLATE_NOOP3("KStandardShortcut", "Print", "@action"), CTRL(P), 0, QList<QKeySequence>(), false, Category::File},
0075     {Quit, "Quit", QT_TRANSLATE_NOOP3("KStandardShortcut", "Quit", "@action"), CTRL(Q), 0, QList<QKeySequence>(), false, Category::Navigation},
0076 
0077     // Group Edit
0078     {Undo, "Undo", QT_TRANSLATE_NOOP3("KStandardShortcut", "Undo", "@action"), CTRL(Z), 0, QList<QKeySequence>(), false, Category::Edit},
0079     {Redo, "Redo", QT_TRANSLATE_NOOP3("KStandardShortcut", "Redo", "@action"), CTRLSHIFT(Z), 0, QList<QKeySequence>(), false, Category::Edit},
0080     // Both "Cut" and "Delete" use Shift+Delete, but this is okay; see
0081     // https://commits.kde.org/kxmlgui/8eabbf6725386e716b7536c71a9181dfe5d959f0
0082     {Cut, "Cut", QT_TRANSLATE_NOOP3("KStandardShortcut", "Cut", "@action"), CTRL(X), SHIFT(Delete), QList<QKeySequence>(), false, Category::Edit},
0083     {Copy, "Copy", QT_TRANSLATE_NOOP3("KStandardShortcut", "Copy", "@action"), CTRL(C), CTRL(Insert), QList<QKeySequence>(), false, Category::Edit},
0084     {Paste, "Paste", QT_TRANSLATE_NOOP3("KStandardShortcut", "Paste", "@action"), CTRL(V), SHIFT(Insert), QList<QKeySequence>(), false, Category::Edit},
0085     {PasteSelection,
0086      "Paste Selection",
0087      QT_TRANSLATE_NOOP3("KStandardShortcut", "Paste Selection", "@action"),
0088      CTRLSHIFT(Insert),
0089      0,
0090      QList<QKeySequence>(),
0091      false,
0092      Category::Edit},
0093 
0094     {SelectAll, "SelectAll", QT_TRANSLATE_NOOP3("KStandardShortcut", "Select All", "@action"), CTRL(A), 0, QList<QKeySequence>(), false, Category::Edit},
0095     {Deselect, "Deselect", QT_TRANSLATE_NOOP3("KStandardShortcut", "Deselect", "@action"), CTRLSHIFT(A), 0, QList<QKeySequence>(), false, Category::Edit},
0096     {DeleteWordBack,
0097      "DeleteWordBack",
0098      QT_TRANSLATE_NOOP3("KStandardShortcut", "Delete Word Backwards", "@action"),
0099      CTRL(Backspace),
0100      0,
0101      QList<QKeySequence>(),
0102      false,
0103      Category::Edit},
0104     {DeleteWordForward,
0105      "DeleteWordForward",
0106      QT_TRANSLATE_NOOP3("KStandardShortcut", "Delete Word Forward", "@action"),
0107      CTRL(Delete),
0108      0,
0109      QList<QKeySequence>(),
0110      false,
0111      Category::Edit},
0112 
0113     {Find, "Find", QT_TRANSLATE_NOOP3("KStandardShortcut", "Find", "@action"), CTRL(F), 0, QList<QKeySequence>(), false, Category::Edit},
0114     {FindNext, "FindNext", QT_TRANSLATE_NOOP3("KStandardShortcut", "Find Next", "@action"), Qt::Key_F3, 0, QList<QKeySequence>(), false, Category::Edit},
0115     {FindPrev, "FindPrev", QT_TRANSLATE_NOOP3("KStandardShortcut", "Find Prev", "@action"), SHIFT(F3), 0, QList<QKeySequence>(), false, Category::Edit},
0116     {Replace, "Replace", QT_TRANSLATE_NOOP3("KStandardShortcut", "Replace", "@action"), CTRL(R), 0, QList<QKeySequence>(), false, Category::Edit},
0117 
0118     // Group Navigation
0119     {Home,
0120      "Home",
0121      QT_TRANSLATE_NOOP3("KStandardShortcut", "Home", "@action Go to main page"),
0122      ALT(Home),
0123      Qt::Key_HomePage,
0124      QList<QKeySequence>(),
0125      false,
0126      Category::Navigation},
0127     {Begin,
0128      "Begin",
0129      QT_TRANSLATE_NOOP3("KStandardShortcut", "Begin", "@action Beginning of document"),
0130      CTRL(Home),
0131      0,
0132      QList<QKeySequence>(),
0133      false,
0134      Category::Navigation},
0135     {End, "End", QT_TRANSLATE_NOOP3("KStandardShortcut", "End", "@action End of document"), CTRL(End), 0, QList<QKeySequence>(), false, Category::Navigation},
0136     {Prior, "Prior", QT_TRANSLATE_NOOP3("KStandardShortcut", "Prior", "@action"), Qt::Key_PageUp, 0, QList<QKeySequence>(), false, Category::Navigation},
0137     {Next,
0138      "Next",
0139      QT_TRANSLATE_NOOP3("KStandardShortcut", "Next", "@action Opposite to Prior"),
0140      Qt::Key_PageDown,
0141      0,
0142      QList<QKeySequence>(),
0143      false,
0144      Category::Navigation},
0145 
0146     {Up, "Up", QT_TRANSLATE_NOOP3("KStandardShortcut", "Up", "@action"), ALT(Up), 0, QList<QKeySequence>(), false, Category::Navigation},
0147     {Back, "Back", QT_TRANSLATE_NOOP3("KStandardShortcut", "Back", "@action"), ALT(Left), Qt::Key_Back, QList<QKeySequence>(), false, Category::Navigation},
0148     {Forward,
0149      "Forward",
0150      QT_TRANSLATE_NOOP3("KStandardShortcut", "Forward", "@action"),
0151      ALT(Right),
0152      Qt::Key_Forward,
0153      QList<QKeySequence>(),
0154      false,
0155      Category::Navigation},
0156     {Reload,
0157      "Reload",
0158      QT_TRANSLATE_NOOP3("KStandardShortcut", "Reload", "@action"),
0159      Qt::Key_F5,
0160      Qt::Key_Refresh,
0161      QList<QKeySequence>(),
0162      false,
0163      Category::Navigation},
0164 
0165     {BeginningOfLine,
0166      "BeginningOfLine",
0167      QT_TRANSLATE_NOOP3("KStandardShortcut", "Beginning of Line", "@action"),
0168      Qt::Key_Home,
0169      0,
0170      QList<QKeySequence>(),
0171      false,
0172      Category::Navigation},
0173     {EndOfLine,
0174      "EndOfLine",
0175      QT_TRANSLATE_NOOP3("KStandardShortcut", "End of Line", "@action"),
0176      Qt::Key_End,
0177      0,
0178      QList<QKeySequence>(),
0179      false,
0180      Category::Navigation},
0181     {GotoLine, "GotoLine", QT_TRANSLATE_NOOP3("KStandardShortcut", "Go to Line", "@action"), CTRL(G), 0, QList<QKeySequence>(), false, Category::Navigation},
0182     {BackwardWord,
0183      "BackwardWord",
0184      QT_TRANSLATE_NOOP3("KStandardShortcut", "Backward Word", "@action"),
0185      CTRL(Left),
0186      0,
0187      QList<QKeySequence>(),
0188      false,
0189      Category::Navigation},
0190     {ForwardWord,
0191      "ForwardWord",
0192      QT_TRANSLATE_NOOP3("KStandardShortcut", "Forward Word", "@action"),
0193      CTRL(Right),
0194      0,
0195      QList<QKeySequence>(),
0196      false,
0197      Category::Navigation},
0198 
0199     {AddBookmark,
0200      "AddBookmark",
0201      QT_TRANSLATE_NOOP3("KStandardShortcut", "Add Bookmark", "@action"),
0202      CTRL(B),
0203      0,
0204      QList<QKeySequence>(),
0205      false,
0206      Category::Navigation},
0207     {ZoomIn, "ZoomIn", QT_TRANSLATE_NOOP3("KStandardShortcut", "Zoom In", "@action"), CTRL(Plus), CTRL(Equal), QList<QKeySequence>(), false, Category::View},
0208     {ZoomOut, "ZoomOut", QT_TRANSLATE_NOOP3("KStandardShortcut", "Zoom Out", "@action"), CTRL(Minus), 0, QList<QKeySequence>(), false, Category::View},
0209     {FullScreen,
0210      "FullScreen",
0211      QT_TRANSLATE_NOOP3("KStandardShortcut", "Full Screen Mode", "@action"),
0212      CTRLSHIFT(F),
0213      0,
0214      QList<QKeySequence>(),
0215      false,
0216      Category::View},
0217 
0218     {ShowMenubar, "ShowMenubar", QT_TRANSLATE_NOOP3("KStandardShortcut", "Show Menu Bar", "@action"), CTRL(M), 0, QList<QKeySequence>(), false, Category::View},
0219     {TabNext,
0220      "Activate Next Tab",
0221      QT_TRANSLATE_NOOP3("KStandardShortcut", "Activate Next Tab", "@action"),
0222      CTRL(PageDown),
0223      CTRL(BracketRight),
0224      QList<QKeySequence>(),
0225      false,
0226      Category::Navigation},
0227     {TabPrev,
0228      "Activate Previous Tab",
0229      QT_TRANSLATE_NOOP3("KStandardShortcut", "Activate Previous Tab", "@action"),
0230      CTRL(PageUp),
0231      CTRL(BracketLeft),
0232      QList<QKeySequence>(),
0233      false,
0234      Category::Navigation},
0235 
0236     // Group Help
0237     {Help, "Help", QT_TRANSLATE_NOOP3("KStandardShortcut", "Help", "@action"), Qt::Key_F1, 0, QList<QKeySequence>(), false, Category::Help},
0238     {WhatsThis, "WhatsThis", QT_TRANSLATE_NOOP3("KStandardShortcut", "What's This", "@action"), SHIFT(F1), 0, QList<QKeySequence>(), false, Category::Help},
0239 
0240     // Group TextCompletion
0241     {TextCompletion,
0242      "TextCompletion",
0243      QT_TRANSLATE_NOOP3("KStandardShortcut", "Text Completion", "@action"),
0244      CTRL(E),
0245      0,
0246      QList<QKeySequence>(),
0247      false,
0248      Category::Edit},
0249     {PrevCompletion,
0250      "PrevCompletion",
0251      QT_TRANSLATE_NOOP3("KStandardShortcut", "Previous Completion Match", "@action"),
0252      CTRL(Up),
0253      0,
0254      QList<QKeySequence>(),
0255      false,
0256      Category::Edit},
0257     {NextCompletion,
0258      "NextCompletion",
0259      QT_TRANSLATE_NOOP3("KStandardShortcut", "Next Completion Match", "@action"),
0260      CTRL(Down),
0261      0,
0262      QList<QKeySequence>(),
0263      false,
0264      Category::Edit},
0265     {SubstringCompletion,
0266      "SubstringCompletion",
0267      QT_TRANSLATE_NOOP3("KStandardShortcut", "Substring Completion", "@action"),
0268      CTRL(T),
0269      0,
0270      QList<QKeySequence>(),
0271      false,
0272      Category::Edit},
0273 
0274     {RotateUp,
0275      "RotateUp",
0276      QT_TRANSLATE_NOOP3("KStandardShortcut", "Previous Item in List", "@action"),
0277      Qt::Key_Up,
0278      0,
0279      QList<QKeySequence>(),
0280      false,
0281      Category::Navigation},
0282     {RotateDown,
0283      "RotateDown",
0284      QT_TRANSLATE_NOOP3("KStandardShortcut", "Next Item in List", "@action"),
0285      Qt::Key_Down,
0286      0,
0287      QList<QKeySequence>(),
0288      false,
0289      Category::Navigation},
0290 
0291     {OpenRecent, "OpenRecent", QT_TRANSLATE_NOOP3("KStandardShortcut", "Open Recent", "@action"), 0, 0, QList<QKeySequence>(), false, Category::File},
0292     {SaveAs, "SaveAs", QT_TRANSLATE_NOOP3("KStandardShortcut", "Save As", "@action"), CTRLSHIFT(S), 0, QList<QKeySequence>(), false, Category::File},
0293     {Revert, "Revert", QT_TRANSLATE_NOOP3("KStandardShortcut", "Revert", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Edit},
0294     {PrintPreview, "PrintPreview", QT_TRANSLATE_NOOP3("KStandardShortcut", "Print Preview", "@action"), 0, 0, QList<QKeySequence>(), false, Category::File},
0295     {Mail, "Mail", QT_TRANSLATE_NOOP3("KStandardShortcut", "Mail", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0296     {Clear, "Clear", QT_TRANSLATE_NOOP3("KStandardShortcut", "Clear", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Edit},
0297     {ActualSize,
0298      "ActualSize",
0299      QT_TRANSLATE_NOOP3("KStandardShortcut", "Zoom to Actual Size", "@action"),
0300      CTRL(0),
0301      0,
0302      QList<QKeySequence>(),
0303      false,
0304      Category::View},
0305     {FitToPage, "FitToPage", QT_TRANSLATE_NOOP3("KStandardShortcut", "Fit To Page", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0306     {FitToWidth, "FitToWidth", QT_TRANSLATE_NOOP3("KStandardShortcut", "Fit To Width", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0307     {FitToHeight, "FitToHeight", QT_TRANSLATE_NOOP3("KStandardShortcut", "Fit To Height", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0308     {Zoom, "Zoom", QT_TRANSLATE_NOOP3("KStandardShortcut", "Zoom", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0309     {Goto, "Goto", QT_TRANSLATE_NOOP3("KStandardShortcut", "Goto", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Navigation},
0310     {GotoPage, "GotoPage", QT_TRANSLATE_NOOP3("KStandardShortcut", "Goto Page", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Navigation},
0311     {DocumentBack,
0312      "DocumentBack",
0313      QT_TRANSLATE_NOOP3("KStandardShortcut", "Document Back", "@action"),
0314      ALTSHIFT(Left),
0315      0,
0316      QList<QKeySequence>(),
0317      false,
0318      Category::Navigation},
0319     {DocumentForward,
0320      "DocumentForward",
0321      QT_TRANSLATE_NOOP3("KStandardShortcut", "Document Forward", "@action"),
0322      ALTSHIFT(Right),
0323      0,
0324      QList<QKeySequence>(),
0325      false,
0326      Category::Navigation},
0327     {EditBookmarks,
0328      "EditBookmarks",
0329      QT_TRANSLATE_NOOP3("KStandardShortcut", "Edit Bookmarks", "@action"),
0330      0,
0331      0,
0332      QList<QKeySequence>(),
0333      false,
0334      Category::Navigation},
0335     {Spelling, "Spelling", QT_TRANSLATE_NOOP3("KStandardShortcut", "Spelling", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Edit},
0336     {ShowToolbar, "ShowToolbar", QT_TRANSLATE_NOOP3("KStandardShortcut", "Show Toolbar", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0337     {ShowStatusbar, "ShowStatusbar", QT_TRANSLATE_NOOP3("KStandardShortcut", "Show Statusbar", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0338     {KeyBindings,
0339      "KeyBindings",
0340      QT_TRANSLATE_NOOP3("KStandardShortcut", "Key Bindings", "@action"),
0341      CTRLALT(Comma),
0342      0,
0343      QList<QKeySequence>(),
0344      false,
0345      Category::Settings},
0346     {Preferences,
0347      "Preferences",
0348      QT_TRANSLATE_NOOP3("KStandardShortcut", "Configure Application", "@action"),
0349      CTRLSHIFT(Comma),
0350      0,
0351      QList<QKeySequence>(),
0352      false,
0353      Category::Settings},
0354     {ConfigureToolbars,
0355      "ConfigureToolbars",
0356      QT_TRANSLATE_NOOP3("KStandardShortcut", "Configure Toolbars", "@action"),
0357      0,
0358      0,
0359      QList<QKeySequence>(),
0360      false,
0361      Category::Settings},
0362     {ConfigureNotifications,
0363      "ConfigureNotifications",
0364      QT_TRANSLATE_NOOP3("KStandardShortcut", "Configure Notifications", "@action"),
0365      0,
0366      0,
0367      QList<QKeySequence>(),
0368      false,
0369      Category::Settings},
0370     {ReportBug, "ReportBug", QT_TRANSLATE_NOOP3("KStandardShortcut", "Report Bug", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0371     {SwitchApplicationLanguage,
0372      "SwitchApplicationLanguage",
0373      QT_TRANSLATE_NOOP3("KStandardShortcut", "Configure Language...", "@action"),
0374      0,
0375      0,
0376      QList<QKeySequence>(),
0377      false,
0378      Category::Settings},
0379     {AboutApp, "AboutApp", QT_TRANSLATE_NOOP3("KStandardShortcut", "About Application", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0380     {AboutKDE, "AboutKDE", QT_TRANSLATE_NOOP3("KStandardShortcut", "About KDE", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0381     // Both "Cut" and "Delete" use Shift+Delete, but this is okay; see
0382     // https://commits.kde.org/kxmlgui/8eabbf6725386e716b7536c71a9181dfe5d959f0
0383     {DeleteFile, "DeleteFile", QT_TRANSLATE_NOOP3("KStandardShortcut", "Delete", "@action"), SHIFT(Delete), 0, QList<QKeySequence>(), false, Category::File},
0384     {RenameFile, "RenameFile", QT_TRANSLATE_NOOP3("KStandardShortcut", "Rename", "@action"), Qt::Key_F2, 0, QList<QKeySequence>(), false, Category::File},
0385     {MoveToTrash,
0386      "MoveToTrash",
0387      QT_TRANSLATE_NOOP3("KStandardShortcut", "Move to Trash", "@action"),
0388      Qt::Key_Delete,
0389      0,
0390      QList<QKeySequence>(),
0391      false,
0392      Category::File},
0393     {Donate, "Donate", QT_TRANSLATE_NOOP3("KStandardShortcut", "Donate", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0394     {ShowHideHiddenFiles,
0395      "ShowHideHiddenFiles",
0396      QT_TRANSLATE_NOOP3("KStandardShortcut", "Show/Hide Hidden Files", "@action"),
0397      CTRL(H),
0398      ALT(Period),
0399      QList<QKeySequence>(),
0400      false,
0401      Category::View},
0402     {CreateFolder,
0403      "CreateFolder",
0404      QT_TRANSLATE_NOOP3("KStandardShortcut", "Create Folder", "@action"),
0405      CTRLSHIFT(N),
0406      0,
0407      QList<QKeySequence>(),
0408      false,
0409      Category::File},
0410     {OpenMainMenu,
0411      "OpenMainMenu",
0412      QT_TRANSLATE_NOOP3("KStandardShortcut", "Open Main Menu", "@action referring to the menu bar or a hamburger menu"),
0413      Qt::Key_F10,
0414      0,
0415      QList<QKeySequence>(),
0416      false,
0417      Category::View},
0418     {OpenContextMenu,
0419      "OpenContextMenu",
0420      QT_TRANSLATE_NOOP3("KStandardShortcut", "Open Context Menu", "@action"),
0421      Qt::Key_Menu,
0422      SHIFT(F10),
0423      QList<QKeySequence>(),
0424      false,
0425      Category::View},
0426 
0427     // dummy entry to catch simple off-by-one errors. Insert new entries before this line.
0428     {AccelNone, nullptr, {nullptr, nullptr}, 0, 0, QList<QKeySequence>(), false, Category::InvalidCategory}};
0429 
0430 /** Search for the KStandardShortcutInfo object associated with the given @p id.
0431     Return a dummy entry with no name and an empty shortcut if @p id is invalid.
0432 */
0433 static KStandardShortcutInfo *guardedStandardShortcutInfo(StandardShortcut id)
0434 {
0435     if (id >= static_cast<int>(sizeof(g_infoStandardShortcut) / sizeof(KStandardShortcutInfo)) || id < 0) {
0436         qWarning() << "KStandardShortcut: id not found!";
0437         return &g_infoStandardShortcut[AccelNone];
0438     } else {
0439         return &g_infoStandardShortcut[id];
0440     }
0441 }
0442 
0443 // Sanitize the list for duplicates. For some reason some
0444 // people have kdeglobals entries like
0445 //   Close=Ctrl+W; Ctrl+Esc; Ctrl+W; Ctrl+Esc;
0446 // having the same shortcut more than once in the shortcut
0447 // declaration is clearly bogus so fix it
0448 static void sanitizeShortcutList(QList<QKeySequence> *list)
0449 {
0450     for (int i = 0; i < list->size(); ++i) {
0451         const QKeySequence &ks = list->at(i);
0452         int other = list->indexOf(ks, i + 1);
0453         while (other != -1) {
0454             list->removeAt(other);
0455             other = list->indexOf(ks, other);
0456         }
0457     }
0458 }
0459 
0460 /** Initialize the accelerator @p id by checking if it is overridden
0461     in the configuration file (and if it isn't, use the default).
0462     On X11, if QApplication was initialized with GUI disabled,
0463     the default will always be used.
0464 */
0465 void initialize(StandardShortcut id)
0466 {
0467     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0468 
0469     // All three are needed.
0470     if (info->id != AccelNone) {
0471         Q_ASSERT(info->description.text);
0472         Q_ASSERT(info->description.context);
0473         Q_ASSERT(info->name);
0474     }
0475 
0476     KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Shortcuts"));
0477 
0478     if (cg.hasKey(info->name)) {
0479         QString s = cg.readEntry(info->name);
0480         if (s != QLatin1String("none")) {
0481             info->cut = QKeySequence::listFromString(s);
0482             sanitizeShortcutList(&info->cut);
0483         } else {
0484             info->cut = QList<QKeySequence>();
0485         }
0486     } else {
0487         info->cut = hardcodedDefaultShortcut(id);
0488     }
0489 
0490     info->isInitialized = true;
0491 }
0492 
0493 void saveShortcut(StandardShortcut id, const QList<QKeySequence> &newShortcut)
0494 {
0495     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0496     // If the action has no standard shortcut associated there is nothing to
0497     // save
0498     if (info->id == AccelNone) {
0499         return;
0500     }
0501 
0502     KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Shortcuts"));
0503 
0504     info->cut = newShortcut;
0505     bool sameAsDefault = (newShortcut == hardcodedDefaultShortcut(id));
0506 
0507     if (sameAsDefault) {
0508         // If the shortcut is the equal to the hardcoded one we remove it from
0509         // kdeglobal if necessary and return.
0510         if (cg.hasKey(info->name)) {
0511             cg.deleteEntry(info->name, KConfig::Global | KConfig::Persistent | KConfig::Notify);
0512             cg.sync();
0513         }
0514 
0515         return;
0516     }
0517 
0518     // Write the changed shortcut to kdeglobals
0519     sanitizeShortcutList(&info->cut);
0520     cg.writeEntry(info->name, QKeySequence::listToString(info->cut), KConfig::Global | KConfig::Persistent | KConfig::Notify);
0521     cg.sync();
0522 }
0523 
0524 QString name(StandardShortcut id)
0525 {
0526     return QString::fromLatin1(guardedStandardShortcutInfo(id)->name);
0527 }
0528 
0529 QString label(StandardShortcut id)
0530 {
0531     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0532     return QCoreApplication::translate("KStandardShortcut", info->description.text, info->description.context);
0533 }
0534 
0535 // TODO: Add psWhatsThis entry to KStandardShortcutInfo
0536 QString whatsThis(StandardShortcut /*id*/)
0537 {
0538     //  KStandardShortcutInfo* info = guardedStandardShortcutInfo( id );
0539     //  if( info && info->whatsThis )
0540     //      return i18n(info->whatsThis);
0541     //  else
0542     return QString();
0543 }
0544 
0545 const QList<QKeySequence> &shortcut(StandardShortcut id)
0546 {
0547     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0548 
0549     if (!info->isInitialized) {
0550         initialize(id);
0551     }
0552 
0553     return info->cut;
0554 }
0555 
0556 StandardShortcut find(const QKeySequence &seq)
0557 {
0558     if (!seq.isEmpty()) {
0559         for (const KStandardShortcutInfo &shortcutInfo : g_infoStandardShortcut) {
0560             const StandardShortcut id = shortcutInfo.id;
0561             if (id != AccelNone) {
0562                 if (!shortcutInfo.isInitialized) {
0563                     initialize(id);
0564                 }
0565                 if (shortcutInfo.cut.contains(seq)) {
0566                     return id;
0567                 }
0568             }
0569         }
0570     }
0571     return AccelNone;
0572 }
0573 
0574 StandardShortcut findByName(const QString &name)
0575 {
0576     for (const KStandardShortcutInfo &shortcutInfo : g_infoStandardShortcut) {
0577         if (QLatin1StringView(shortcutInfo.name) == name) {
0578             return shortcutInfo.id;
0579         }
0580     }
0581     return AccelNone;
0582 }
0583 
0584 QList<QKeySequence> hardcodedDefaultShortcut(StandardShortcut id)
0585 {
0586     QList<QKeySequence> cut;
0587     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0588 
0589     if (info->cutDefault != 0) {
0590         cut << info->cutDefault;
0591     }
0592 
0593     if (info->cutDefault2 != 0) {
0594         if (cut.isEmpty()) {
0595             cut << QKeySequence();
0596         }
0597 
0598         cut << info->cutDefault2;
0599     }
0600 
0601     return cut;
0602 }
0603 
0604 Category category(StandardShortcut id)
0605 {
0606     return guardedStandardShortcutInfo(id)->category;
0607 }
0608 
0609 const QList<QKeySequence> &open()
0610 {
0611     return shortcut(Open);
0612 }
0613 const QList<QKeySequence> &openNew()
0614 {
0615     return shortcut(New);
0616 }
0617 const QList<QKeySequence> &close()
0618 {
0619     return shortcut(Close);
0620 }
0621 const QList<QKeySequence> &save()
0622 {
0623     return shortcut(Save);
0624 }
0625 const QList<QKeySequence> &print()
0626 {
0627     return shortcut(Print);
0628 }
0629 const QList<QKeySequence> &quit()
0630 {
0631     return shortcut(Quit);
0632 }
0633 const QList<QKeySequence> &cut()
0634 {
0635     return shortcut(Cut);
0636 }
0637 const QList<QKeySequence> &copy()
0638 {
0639     return shortcut(Copy);
0640 }
0641 const QList<QKeySequence> &paste()
0642 {
0643     return shortcut(Paste);
0644 }
0645 const QList<QKeySequence> &pasteSelection()
0646 {
0647     return shortcut(PasteSelection);
0648 }
0649 const QList<QKeySequence> &deleteWordBack()
0650 {
0651     return shortcut(DeleteWordBack);
0652 }
0653 const QList<QKeySequence> &deleteWordForward()
0654 {
0655     return shortcut(DeleteWordForward);
0656 }
0657 const QList<QKeySequence> &undo()
0658 {
0659     return shortcut(Undo);
0660 }
0661 const QList<QKeySequence> &redo()
0662 {
0663     return shortcut(Redo);
0664 }
0665 const QList<QKeySequence> &find()
0666 {
0667     return shortcut(Find);
0668 }
0669 const QList<QKeySequence> &findNext()
0670 {
0671     return shortcut(FindNext);
0672 }
0673 const QList<QKeySequence> &findPrev()
0674 {
0675     return shortcut(FindPrev);
0676 }
0677 const QList<QKeySequence> &replace()
0678 {
0679     return shortcut(Replace);
0680 }
0681 const QList<QKeySequence> &home()
0682 {
0683     return shortcut(Home);
0684 }
0685 const QList<QKeySequence> &begin()
0686 {
0687     return shortcut(Begin);
0688 }
0689 const QList<QKeySequence> &end()
0690 {
0691     return shortcut(End);
0692 }
0693 const QList<QKeySequence> &beginningOfLine()
0694 {
0695     return shortcut(BeginningOfLine);
0696 }
0697 const QList<QKeySequence> &endOfLine()
0698 {
0699     return shortcut(EndOfLine);
0700 }
0701 const QList<QKeySequence> &prior()
0702 {
0703     return shortcut(Prior);
0704 }
0705 const QList<QKeySequence> &next()
0706 {
0707     return shortcut(Next);
0708 }
0709 const QList<QKeySequence> &backwardWord()
0710 {
0711     return shortcut(BackwardWord);
0712 }
0713 const QList<QKeySequence> &forwardWord()
0714 {
0715     return shortcut(ForwardWord);
0716 }
0717 const QList<QKeySequence> &gotoLine()
0718 {
0719     return shortcut(GotoLine);
0720 }
0721 const QList<QKeySequence> &addBookmark()
0722 {
0723     return shortcut(AddBookmark);
0724 }
0725 const QList<QKeySequence> &tabNext()
0726 {
0727     return shortcut(TabNext);
0728 }
0729 const QList<QKeySequence> &tabPrev()
0730 {
0731     return shortcut(TabPrev);
0732 }
0733 const QList<QKeySequence> &fullScreen()
0734 {
0735     return shortcut(FullScreen);
0736 }
0737 const QList<QKeySequence> &zoomIn()
0738 {
0739     return shortcut(ZoomIn);
0740 }
0741 const QList<QKeySequence> &zoomOut()
0742 {
0743     return shortcut(ZoomOut);
0744 }
0745 const QList<QKeySequence> &help()
0746 {
0747     return shortcut(Help);
0748 }
0749 const QList<QKeySequence> &completion()
0750 {
0751     return shortcut(TextCompletion);
0752 }
0753 const QList<QKeySequence> &prevCompletion()
0754 {
0755     return shortcut(PrevCompletion);
0756 }
0757 const QList<QKeySequence> &nextCompletion()
0758 {
0759     return shortcut(NextCompletion);
0760 }
0761 const QList<QKeySequence> &rotateUp()
0762 {
0763     return shortcut(RotateUp);
0764 }
0765 const QList<QKeySequence> &rotateDown()
0766 {
0767     return shortcut(RotateDown);
0768 }
0769 const QList<QKeySequence> &substringCompletion()
0770 {
0771     return shortcut(SubstringCompletion);
0772 }
0773 const QList<QKeySequence> &whatsThis()
0774 {
0775     return shortcut(WhatsThis);
0776 }
0777 const QList<QKeySequence> &reload()
0778 {
0779     return shortcut(Reload);
0780 }
0781 const QList<QKeySequence> &selectAll()
0782 {
0783     return shortcut(SelectAll);
0784 }
0785 const QList<QKeySequence> &up()
0786 {
0787     return shortcut(Up);
0788 }
0789 const QList<QKeySequence> &back()
0790 {
0791     return shortcut(Back);
0792 }
0793 const QList<QKeySequence> &forward()
0794 {
0795     return shortcut(Forward);
0796 }
0797 const QList<QKeySequence> &showMenubar()
0798 {
0799     return shortcut(ShowMenubar);
0800 }
0801 const QList<QKeySequence> &deleteFile()
0802 {
0803     return shortcut(DeleteFile);
0804 }
0805 const QList<QKeySequence> &renameFile()
0806 {
0807     return shortcut(RenameFile);
0808 }
0809 const QList<QKeySequence> &createFolder()
0810 {
0811     return shortcut(CreateFolder);
0812 }
0813 const QList<QKeySequence> &moveToTrash()
0814 {
0815     return shortcut(MoveToTrash);
0816 }
0817 const QList<QKeySequence> &preferences()
0818 {
0819     return shortcut(Preferences);
0820 }
0821 const QList<QKeySequence> &showHideHiddenFiles()
0822 {
0823     return shortcut(ShowHideHiddenFiles);
0824 }
0825 const QList<QKeySequence> &openMainMenu()
0826 {
0827     return shortcut(OpenMainMenu);
0828 }
0829 const QList<QKeySequence> &openContextMenu()
0830 {
0831     return shortcut(OpenContextMenu);
0832 }
0833 }