File indexing completed on 2024-05-12 15:34:14

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) Qt::CTRL | Qt::Key_##x
0055 #define SHIFT(x) Qt::SHIFT | Qt::Key_##x
0056 #define CTRLALT(x) Qt::CTRL | Qt::ALT | Qt::Key_##x
0057 #define CTRLSHIFT(x) Qt::CTRL | Qt::SHIFT | Qt::Key_##x
0058 #define ALT(x) Qt::ALT | Qt::Key_##x
0059 #define ALTSHIFT(x) Qt::ALT | Qt::SHIFT | Qt::Key_##x
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, "ActualSize", QT_TRANSLATE_NOOP3("KStandardShortcut", "Zoom to Actual Size", "@action"), CTRL(0), 0, QList<QKeySequence>(), false, Category::View},
0298     {FitToPage, "FitToPage", QT_TRANSLATE_NOOP3("KStandardShortcut", "Fit To Page", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0299     {FitToWidth, "FitToWidth", QT_TRANSLATE_NOOP3("KStandardShortcut", "Fit To Width", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0300     {FitToHeight, "FitToHeight", QT_TRANSLATE_NOOP3("KStandardShortcut", "Fit To Height", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0301     {Zoom, "Zoom", QT_TRANSLATE_NOOP3("KStandardShortcut", "Zoom", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0302     {Goto, "Goto", QT_TRANSLATE_NOOP3("KStandardShortcut", "Goto", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Navigation},
0303     {GotoPage, "GotoPage", QT_TRANSLATE_NOOP3("KStandardShortcut", "Goto Page", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Navigation},
0304     {DocumentBack,
0305      "DocumentBack",
0306      QT_TRANSLATE_NOOP3("KStandardShortcut", "Document Back", "@action"),
0307      ALTSHIFT(Left),
0308      0,
0309      QList<QKeySequence>(),
0310      false,
0311      Category::Navigation},
0312     {DocumentForward,
0313      "DocumentForward",
0314      QT_TRANSLATE_NOOP3("KStandardShortcut", "Document Forward", "@action"),
0315      ALTSHIFT(Right),
0316      0,
0317      QList<QKeySequence>(),
0318      false,
0319      Category::Navigation},
0320     {EditBookmarks,
0321      "EditBookmarks",
0322      QT_TRANSLATE_NOOP3("KStandardShortcut", "Edit Bookmarks", "@action"),
0323      0,
0324      0,
0325      QList<QKeySequence>(),
0326      false,
0327      Category::Navigation},
0328     {Spelling, "Spelling", QT_TRANSLATE_NOOP3("KStandardShortcut", "Spelling", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Edit},
0329     {ShowToolbar, "ShowToolbar", QT_TRANSLATE_NOOP3("KStandardShortcut", "Show Toolbar", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0330     {ShowStatusbar, "ShowStatusbar", QT_TRANSLATE_NOOP3("KStandardShortcut", "Show Statusbar", "@action"), 0, 0, QList<QKeySequence>(), false, Category::View},
0331 #if KCONFIGGUI_BUILD_DEPRECATED_SINCE(5, 39)
0332     {SaveOptions, "SaveOptions", QT_TRANSLATE_NOOP3("KStandardShortcut", "Save Options", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Settings},
0333 #else
0334     // dummy entry
0335     {SaveOptions_DEPRECATED_DO_NOT_USE, nullptr, {nullptr, nullptr}, 0, 0, QList<QKeySequence>(), false, Category::InvalidCategory},
0336 #endif
0337     {KeyBindings, "KeyBindings", QT_TRANSLATE_NOOP3("KStandardShortcut", "Key Bindings", "@action"), CTRLALT(Comma), 0, QList<QKeySequence>(), false, Category::Settings},
0338     {Preferences,
0339      "Preferences",
0340      QT_TRANSLATE_NOOP3("KStandardShortcut", "Configure Application", "@action"),
0341      CTRLSHIFT(Comma),
0342      0,
0343      QList<QKeySequence>(),
0344      false,
0345      Category::Settings},
0346     {ConfigureToolbars,
0347      "ConfigureToolbars",
0348      QT_TRANSLATE_NOOP3("KStandardShortcut", "Configure Toolbars", "@action"),
0349      0,
0350      0,
0351      QList<QKeySequence>(),
0352      false,
0353      Category::Settings},
0354     {ConfigureNotifications,
0355      "ConfigureNotifications",
0356      QT_TRANSLATE_NOOP3("KStandardShortcut", "Configure Notifications", "@action"),
0357      0,
0358      0,
0359      QList<QKeySequence>(),
0360      false,
0361      Category::Settings},
0362     {TipofDay, "TipofDay", QT_TRANSLATE_NOOP3("KStandardShortcut", "Tip Of Day", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0363     {ReportBug, "ReportBug", QT_TRANSLATE_NOOP3("KStandardShortcut", "Report Bug", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0364     {SwitchApplicationLanguage,
0365      "SwitchApplicationLanguage",
0366      QT_TRANSLATE_NOOP3("KStandardShortcut", "Configure Language...", "@action"),
0367      0,
0368      0,
0369      QList<QKeySequence>(),
0370      false,
0371      Category::Settings},
0372     {AboutApp, "AboutApp", QT_TRANSLATE_NOOP3("KStandardShortcut", "About Application", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0373     {AboutKDE, "AboutKDE", QT_TRANSLATE_NOOP3("KStandardShortcut", "About KDE", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0374     // Both "Cut" and "Delete" use Shift+Delete, but this is okay; see
0375     // https://commits.kde.org/kxmlgui/8eabbf6725386e716b7536c71a9181dfe5d959f0
0376     {DeleteFile, "DeleteFile", QT_TRANSLATE_NOOP3("KStandardShortcut", "Delete", "@action"), SHIFT(Delete), 0, QList<QKeySequence>(), false, Category::File},
0377     {RenameFile, "RenameFile", QT_TRANSLATE_NOOP3("KStandardShortcut", "Rename", "@action"), Qt::Key_F2, 0, QList<QKeySequence>(), false, Category::File},
0378     {MoveToTrash,
0379      "MoveToTrash",
0380      QT_TRANSLATE_NOOP3("KStandardShortcut", "Move to Trash", "@action"),
0381      Qt::Key_Delete,
0382      0,
0383      QList<QKeySequence>(),
0384      false,
0385      Category::File},
0386     {Donate, "Donate", QT_TRANSLATE_NOOP3("KStandardShortcut", "Donate", "@action"), 0, 0, QList<QKeySequence>(), false, Category::Help},
0387     {ShowHideHiddenFiles,
0388      "ShowHideHiddenFiles",
0389      QT_TRANSLATE_NOOP3("KStandardShortcut", "Show/Hide Hidden Files", "@action"),
0390      CTRL(H),
0391      ALT(Period),
0392      QList<QKeySequence>(),
0393      false,
0394      Category::View},
0395     {CreateFolder,
0396      "CreateFolder",
0397      QT_TRANSLATE_NOOP3("KStandardShortcut", "Create Folder", "@action"),
0398      Qt::Key_F10,
0399      0,
0400      QList<QKeySequence>(),
0401      false,
0402      Category::File},
0403 
0404     // dummy entry to catch simple off-by-one errors. Insert new entries before this line.
0405     {AccelNone, nullptr, {nullptr, nullptr}, 0, 0, QList<QKeySequence>(), false, Category::InvalidCategory}};
0406 
0407 /** Search for the KStandardShortcutInfo object associated with the given @p id.
0408     Return a dummy entry with no name and an empty shortcut if @p id is invalid.
0409 */
0410 static KStandardShortcutInfo *guardedStandardShortcutInfo(StandardShortcut id)
0411 {
0412     if (id >= static_cast<int>(sizeof(g_infoStandardShortcut) / sizeof(KStandardShortcutInfo)) || id < 0) {
0413         qWarning() << "KStandardShortcut: id not found!";
0414         return &g_infoStandardShortcut[AccelNone];
0415     } else {
0416         return &g_infoStandardShortcut[id];
0417     }
0418 }
0419 
0420 // Sanitize the list for duplicates. For some reason some
0421 // people have kdeglobals entries like
0422 //   Close=Ctrl+W; Ctrl+Esc; Ctrl+W; Ctrl+Esc;
0423 // having the same shortcut more than once in the shortcut
0424 // declaration is clearly bogus so fix it
0425 static void sanitizeShortcutList(QList<QKeySequence> *list)
0426 {
0427     for (int i = 0; i < list->size(); ++i) {
0428         const QKeySequence &ks = list->at(i);
0429         int other = list->indexOf(ks, i + 1);
0430         while (other != -1) {
0431             list->removeAt(other);
0432             other = list->indexOf(ks, other);
0433         }
0434     }
0435 }
0436 
0437 /** Initialize the accelerator @p id by checking if it is overridden
0438     in the configuration file (and if it isn't, use the default).
0439     On X11, if QApplication was initialized with GUI disabled,
0440     the default will always be used.
0441 */
0442 void initialize(StandardShortcut id)
0443 {
0444     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0445 
0446     // All three are needed.
0447     if (info->id != AccelNone) {
0448         Q_ASSERT(info->description.text);
0449         Q_ASSERT(info->description.context);
0450         Q_ASSERT(info->name);
0451     }
0452 
0453     KConfigGroup cg(KSharedConfig::openConfig(), "Shortcuts");
0454 
0455     if (cg.hasKey(info->name)) {
0456         QString s = cg.readEntry(info->name);
0457         if (s != QLatin1String("none")) {
0458             info->cut = QKeySequence::listFromString(s);
0459             sanitizeShortcutList(&info->cut);
0460         } else {
0461             info->cut = QList<QKeySequence>();
0462         }
0463     } else {
0464         info->cut = hardcodedDefaultShortcut(id);
0465     }
0466 
0467     info->isInitialized = true;
0468 }
0469 
0470 void saveShortcut(StandardShortcut id, const QList<QKeySequence> &newShortcut)
0471 {
0472     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0473     // If the action has no standard shortcut associated there is nothing to
0474     // save
0475     if (info->id == AccelNone) {
0476         return;
0477     }
0478 
0479     KConfigGroup cg(KSharedConfig::openConfig(), "Shortcuts");
0480 
0481     info->cut = newShortcut;
0482     bool sameAsDefault = (newShortcut == hardcodedDefaultShortcut(id));
0483 
0484     if (sameAsDefault) {
0485         // If the shortcut is the equal to the hardcoded one we remove it from
0486         // kdeglobal if necessary and return.
0487         if (cg.hasKey(info->name)) {
0488             cg.deleteEntry(info->name, KConfig::Global | KConfig::Persistent | KConfig::Notify);
0489             cg.sync();
0490         }
0491 
0492         return;
0493     }
0494 
0495     // Write the changed shortcut to kdeglobals
0496     sanitizeShortcutList(&info->cut);
0497     cg.writeEntry(info->name, QKeySequence::listToString(info->cut), KConfig::Global | KConfig::Persistent | KConfig::Notify);
0498     cg.sync();
0499 }
0500 
0501 QString name(StandardShortcut id)
0502 {
0503     return QString::fromLatin1(guardedStandardShortcutInfo(id)->name);
0504 }
0505 
0506 QString label(StandardShortcut id)
0507 {
0508     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0509     return QCoreApplication::translate("KStandardShortcut", info->description.text, info->description.context);
0510 }
0511 
0512 // TODO: Add psWhatsThis entry to KStandardShortcutInfo
0513 QString whatsThis(StandardShortcut /*id*/)
0514 {
0515     //  KStandardShortcutInfo* info = guardedStandardShortcutInfo( id );
0516     //  if( info && info->whatsThis )
0517     //      return i18n(info->whatsThis);
0518     //  else
0519     return QString();
0520 }
0521 
0522 const QList<QKeySequence> &shortcut(StandardShortcut id)
0523 {
0524     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0525 
0526     if (!info->isInitialized) {
0527         initialize(id);
0528     }
0529 
0530     return info->cut;
0531 }
0532 
0533 StandardShortcut find(const QKeySequence &seq)
0534 {
0535     if (!seq.isEmpty()) {
0536         for (const KStandardShortcutInfo &shortcutInfo : g_infoStandardShortcut) {
0537             const StandardShortcut id = shortcutInfo.id;
0538 #if KCONFIGGUI_BUILD_DEPRECATED_SINCE(5, 39)
0539             if (id != AccelNone) {
0540 #else
0541             if (id != AccelNone && id != SaveOptions_DEPRECATED_DO_NOT_USE) {
0542 #endif
0543                 if (!shortcutInfo.isInitialized) {
0544                     initialize(id);
0545                 }
0546                 if (shortcutInfo.cut.contains(seq)) {
0547                     return id;
0548                 }
0549             }
0550         }
0551     }
0552     return AccelNone;
0553 }
0554 
0555 #if KCONFIGGUI_BUILD_DEPRECATED_SINCE(5, 71)
0556 StandardShortcut find(const char *keyName)
0557 {
0558     for (const KStandardShortcutInfo &shortcutInfo : g_infoStandardShortcut) {
0559         if (qstrcmp(shortcutInfo.name, keyName) == 0) {
0560             return shortcutInfo.id;
0561         }
0562     }
0563 
0564     return AccelNone;
0565 }
0566 #endif
0567 
0568 StandardShortcut findByName(const QString &name)
0569 {
0570     for (const KStandardShortcutInfo &shortcutInfo : g_infoStandardShortcut) {
0571         if (QString::fromLatin1(shortcutInfo.name) == name) {
0572             return shortcutInfo.id;
0573         }
0574     }
0575     return AccelNone;
0576 }
0577 
0578 QList<QKeySequence> hardcodedDefaultShortcut(StandardShortcut id)
0579 {
0580     QList<QKeySequence> cut;
0581     KStandardShortcutInfo *info = guardedStandardShortcutInfo(id);
0582 
0583     if (info->cutDefault != 0) {
0584         cut << info->cutDefault;
0585     }
0586 
0587     if (info->cutDefault2 != 0) {
0588         if (cut.isEmpty()) {
0589             cut << QKeySequence();
0590         }
0591 
0592         cut << info->cutDefault2;
0593     }
0594 
0595     return cut;
0596 }
0597 
0598 Category category(StandardShortcut id)
0599 {
0600     return guardedStandardShortcutInfo(id)->category;
0601 }
0602 
0603 const QList<QKeySequence> &open()
0604 {
0605     return shortcut(Open);
0606 }
0607 const QList<QKeySequence> &openNew()
0608 {
0609     return shortcut(New);
0610 }
0611 const QList<QKeySequence> &close()
0612 {
0613     return shortcut(Close);
0614 }
0615 const QList<QKeySequence> &save()
0616 {
0617     return shortcut(Save);
0618 }
0619 const QList<QKeySequence> &print()
0620 {
0621     return shortcut(Print);
0622 }
0623 const QList<QKeySequence> &quit()
0624 {
0625     return shortcut(Quit);
0626 }
0627 const QList<QKeySequence> &cut()
0628 {
0629     return shortcut(Cut);
0630 }
0631 const QList<QKeySequence> &copy()
0632 {
0633     return shortcut(Copy);
0634 }
0635 const QList<QKeySequence> &paste()
0636 {
0637     return shortcut(Paste);
0638 }
0639 const QList<QKeySequence> &pasteSelection()
0640 {
0641     return shortcut(PasteSelection);
0642 }
0643 const QList<QKeySequence> &deleteWordBack()
0644 {
0645     return shortcut(DeleteWordBack);
0646 }
0647 const QList<QKeySequence> &deleteWordForward()
0648 {
0649     return shortcut(DeleteWordForward);
0650 }
0651 const QList<QKeySequence> &undo()
0652 {
0653     return shortcut(Undo);
0654 }
0655 const QList<QKeySequence> &redo()
0656 {
0657     return shortcut(Redo);
0658 }
0659 const QList<QKeySequence> &find()
0660 {
0661     return shortcut(Find);
0662 }
0663 const QList<QKeySequence> &findNext()
0664 {
0665     return shortcut(FindNext);
0666 }
0667 const QList<QKeySequence> &findPrev()
0668 {
0669     return shortcut(FindPrev);
0670 }
0671 const QList<QKeySequence> &replace()
0672 {
0673     return shortcut(Replace);
0674 }
0675 const QList<QKeySequence> &home()
0676 {
0677     return shortcut(Home);
0678 }
0679 const QList<QKeySequence> &begin()
0680 {
0681     return shortcut(Begin);
0682 }
0683 const QList<QKeySequence> &end()
0684 {
0685     return shortcut(End);
0686 }
0687 const QList<QKeySequence> &beginningOfLine()
0688 {
0689     return shortcut(BeginningOfLine);
0690 }
0691 const QList<QKeySequence> &endOfLine()
0692 {
0693     return shortcut(EndOfLine);
0694 }
0695 const QList<QKeySequence> &prior()
0696 {
0697     return shortcut(Prior);
0698 }
0699 const QList<QKeySequence> &next()
0700 {
0701     return shortcut(Next);
0702 }
0703 const QList<QKeySequence> &backwardWord()
0704 {
0705     return shortcut(BackwardWord);
0706 }
0707 const QList<QKeySequence> &forwardWord()
0708 {
0709     return shortcut(ForwardWord);
0710 }
0711 const QList<QKeySequence> &gotoLine()
0712 {
0713     return shortcut(GotoLine);
0714 }
0715 const QList<QKeySequence> &addBookmark()
0716 {
0717     return shortcut(AddBookmark);
0718 }
0719 const QList<QKeySequence> &tabNext()
0720 {
0721     return shortcut(TabNext);
0722 }
0723 const QList<QKeySequence> &tabPrev()
0724 {
0725     return shortcut(TabPrev);
0726 }
0727 const QList<QKeySequence> &fullScreen()
0728 {
0729     return shortcut(FullScreen);
0730 }
0731 const QList<QKeySequence> &zoomIn()
0732 {
0733     return shortcut(ZoomIn);
0734 }
0735 const QList<QKeySequence> &zoomOut()
0736 {
0737     return shortcut(ZoomOut);
0738 }
0739 const QList<QKeySequence> &help()
0740 {
0741     return shortcut(Help);
0742 }
0743 const QList<QKeySequence> &completion()
0744 {
0745     return shortcut(TextCompletion);
0746 }
0747 const QList<QKeySequence> &prevCompletion()
0748 {
0749     return shortcut(PrevCompletion);
0750 }
0751 const QList<QKeySequence> &nextCompletion()
0752 {
0753     return shortcut(NextCompletion);
0754 }
0755 const QList<QKeySequence> &rotateUp()
0756 {
0757     return shortcut(RotateUp);
0758 }
0759 const QList<QKeySequence> &rotateDown()
0760 {
0761     return shortcut(RotateDown);
0762 }
0763 const QList<QKeySequence> &substringCompletion()
0764 {
0765     return shortcut(SubstringCompletion);
0766 }
0767 const QList<QKeySequence> &whatsThis()
0768 {
0769     return shortcut(WhatsThis);
0770 }
0771 const QList<QKeySequence> &reload()
0772 {
0773     return shortcut(Reload);
0774 }
0775 const QList<QKeySequence> &selectAll()
0776 {
0777     return shortcut(SelectAll);
0778 }
0779 const QList<QKeySequence> &up()
0780 {
0781     return shortcut(Up);
0782 }
0783 const QList<QKeySequence> &back()
0784 {
0785     return shortcut(Back);
0786 }
0787 const QList<QKeySequence> &forward()
0788 {
0789     return shortcut(Forward);
0790 }
0791 const QList<QKeySequence> &showMenubar()
0792 {
0793     return shortcut(ShowMenubar);
0794 }
0795 const QList<QKeySequence> &deleteFile()
0796 {
0797     return shortcut(DeleteFile);
0798 }
0799 const QList<QKeySequence> &renameFile()
0800 {
0801     return shortcut(RenameFile);
0802 }
0803 const QList<QKeySequence> &createFolder()
0804 {
0805     return shortcut(CreateFolder);
0806 }
0807 const QList<QKeySequence> &moveToTrash()
0808 {
0809     return shortcut(MoveToTrash);
0810 }
0811 const QList<QKeySequence> &preferences()
0812 {
0813     return shortcut(Preferences);
0814 }
0815 
0816 const QList<QKeySequence> &showHideHiddenFiles()
0817 {
0818     return shortcut(ShowHideHiddenFiles);
0819 }
0820 
0821 }