File indexing completed on 2024-10-13 03:36:45

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 1999, 2000 Kurt Granroth <granroth@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 #ifndef KSTANDARDACTION_PRIVATE_H
0009 #define KSTANDARDACTION_PRIVATE_H
0010 
0011 #include <QAction>
0012 #include <QApplication>
0013 
0014 #include <KLazyLocalizedString>
0015 #include <KLocalizedString>
0016 #include <KStandardShortcut>
0017 
0018 #include <string>
0019 
0020 namespace KStandardAction
0021 {
0022 
0023 // Helper class for storing raw data in static tables which can be used for QString instance
0024 // creation at runtime without copying/converting to new memalloc'ed memory, as well as avoiding
0025 // that way storing the strings directly as QStrings resulting in non-constexpr init code on
0026 // library loading
0027 struct RawStringData {
0028     template<std::size_t StringSize>
0029     constexpr inline RawStringData(const char16_t (&_data)[StringSize])
0030         : data(_data)
0031         , size(std::char_traits<char16_t>::length(_data))
0032     {
0033     }
0034     constexpr inline RawStringData(std::nullptr_t)
0035     {
0036     }
0037     constexpr inline RawStringData() = default;
0038 
0039     inline QString toString() const
0040     {
0041         if (!data) {
0042             return QString();
0043         }
0044 
0045         return Qt::Literals::StringLiterals::operator""_s(data, size);
0046     }
0047 
0048 private:
0049     const char16_t *const data = nullptr;
0050     const std::size_t size = 0;
0051 };
0052 
0053 struct KStandardActionInfo {
0054     StandardAction id;
0055     KStandardShortcut::StandardShortcut idAccel;
0056     const RawStringData psName;
0057     const KLazyLocalizedString psLabel;
0058     const KLazyLocalizedString psToolTip;
0059     const RawStringData psIconName;
0060 };
0061 // clang-format off
0062 static const KStandardActionInfo g_rgActionInfo[] = {
0063     { New,           KStandardShortcut::New, u"file_new", kli18n("&New"), kli18n("Create new document"), u"document-new" },
0064     { Open,          KStandardShortcut::Open, u"file_open", kli18n("&Open…"), kli18n("Open an existing document"), u"document-open" },
0065     { OpenRecent,    KStandardShortcut::AccelNone, u"file_open_recent", kli18n("Open &Recent"), kli18n("Open a document which was recently opened"), u"document-open-recent" },
0066     { Save,          KStandardShortcut::Save, u"file_save", kli18n("&Save"), kli18n("Save document"), u"document-save" },
0067     { SaveAs,        KStandardShortcut::SaveAs, u"file_save_as", kli18n("Save &As…"), kli18n("Save document under a new name"), u"document-save-as" },
0068     { Revert,        KStandardShortcut::Revert, u"file_revert", kli18n("Re&vert"), kli18n("Revert unsaved changes made to document"), u"document-revert" },
0069     { Close,         KStandardShortcut::Close, u"file_close", kli18n("&Close"), kli18n("Close document"), u"document-close" },
0070     { Print,         KStandardShortcut::Print, u"file_print", kli18n("&Print…"), kli18n("Print document"), u"document-print" },
0071     { PrintPreview,  KStandardShortcut::PrintPreview, u"file_print_preview", kli18n("Print Previe&w"), kli18n("Show a print preview of document"), u"document-print-preview" },
0072     { Mail,          KStandardShortcut::Mail, u"file_mail", kli18n("&Mail…"), kli18n("Send document by mail"), u"mail-send" },
0073     { Quit,          KStandardShortcut::Quit, u"file_quit", kli18n("&Quit"), kli18n("Quit application"), u"application-exit" },
0074 
0075     { Undo,          KStandardShortcut::Undo, u"edit_undo", kli18n("&Undo"), kli18n("Undo last action"), u"edit-undo" },
0076     { Redo,          KStandardShortcut::Redo, u"edit_redo", kli18n("Re&do"), kli18n("Redo last undone action"), u"edit-redo" },
0077     { Cut,           KStandardShortcut::Cut, u"edit_cut", kli18n("Cu&t"), kli18n("Cut selection to clipboard"), u"edit-cut" },
0078     { Copy,          KStandardShortcut::Copy, u"edit_copy", kli18n("&Copy"), kli18n("Copy selection to clipboard"), u"edit-copy" },
0079     { Paste,         KStandardShortcut::Paste, u"edit_paste", kli18n("&Paste"), kli18n("Paste clipboard content"), u"edit-paste" },
0080     { Clear,         KStandardShortcut::Clear, u"edit_clear", kli18n("C&lear"), {}, u"edit-clear" },
0081     { SelectAll,     KStandardShortcut::SelectAll, u"edit_select_all", kli18n("Select &All"), {}, u"edit-select-all" },
0082     { Deselect,      KStandardShortcut::Deselect, u"edit_deselect", kli18n("Dese&lect"), {}, u"edit-select-none" },
0083     { Find,          KStandardShortcut::Find, u"edit_find", kli18n("&Find…"), {}, u"edit-find" },
0084     { FindNext,      KStandardShortcut::FindNext, u"edit_find_next", kli18n("Find &Next"), {}, u"go-down-search" },
0085     { FindPrev,      KStandardShortcut::FindPrev, u"edit_find_prev", kli18n("Find Pre&vious"), {}, u"go-up-search" },
0086     { Replace,       KStandardShortcut::Replace, u"edit_replace", kli18n("&Replace…"), {}, u"edit-find-replace" },
0087 
0088     { ActualSize,    KStandardShortcut::ActualSize, u"view_actual_size", kli18n("Zoom to &Actual Size"), kli18n("View document at its actual size"), u"zoom-original" },
0089     { FitToPage,     KStandardShortcut::FitToPage, u"view_fit_to_page", kli18n("&Fit to Page"), kli18n("Zoom to fit page in window"), u"zoom-fit-page" },
0090     { FitToWidth,    KStandardShortcut::FitToWidth, u"view_fit_to_width", kli18n("Fit to Page &Width"), kli18n("Zoom to fit page width in window"), u"zoom-fit-width" },
0091     { FitToHeight,   KStandardShortcut::FitToHeight, u"view_fit_to_height", kli18n("Fit to Page &Height"), kli18n("Zoom to fit page height in window"), u"zoom-fit-height" },
0092     { ZoomIn,        KStandardShortcut::ZoomIn, u"view_zoom_in", kli18n("Zoom &In"), {}, u"zoom-in" },
0093     { ZoomOut,       KStandardShortcut::ZoomOut, u"view_zoom_out", kli18n("Zoom &Out"), {}, u"zoom-out" },
0094     { Zoom,          KStandardShortcut::Zoom, u"view_zoom", kli18n("&Zoom…"), kli18n("Select zoom level"), u"zoom" },
0095     { Redisplay,     KStandardShortcut::Reload, u"view_redisplay", kli18n("&Refresh"), kli18n("Refresh document"), u"view-refresh" },
0096 
0097     { Up,            KStandardShortcut::Up, u"go_up", kli18n("&Up"), kli18n("Go up"), u"go-up" },
0098     // The following three have special i18n() needs for sLabel
0099     { Back,          KStandardShortcut::Back, u"go_back", {}, {}, u"go-previous" },
0100     { Forward,       KStandardShortcut::Forward, u"go_forward", {}, {}, u"go-next" },
0101     { Home,          KStandardShortcut::Home, u"go_home", {}, {}, u"go-home" },
0102     { Prior,         KStandardShortcut::Prior, u"go_previous", kli18n("&Previous Page"), kli18n("Go to previous page"), u"go-previous-view-page" },
0103     { Next,          KStandardShortcut::Next, u"go_next", kli18n("&Next Page"), kli18n("Go to next page"), u"go-next-view-page" },
0104     { Goto,          KStandardShortcut::Goto, u"go_goto", kli18n("&Go To…"), {}, {} },
0105     { GotoPage,      KStandardShortcut::GotoPage, u"go_goto_page", kli18n("&Go to Page…"), {}, u"go-jump" },
0106     { GotoLine,      KStandardShortcut::GotoLine, u"go_goto_line", kli18n("&Go to Line…"), {}, {} },
0107     { FirstPage,     KStandardShortcut::Begin, u"go_first", kli18n("&First Page"), kli18n("Go to first page"), u"go-first-view-page" },
0108     { LastPage,      KStandardShortcut::End, u"go_last", kli18n("&Last Page"), kli18n("Go to last page"), u"go-last-view-page" },
0109     { DocumentBack,  KStandardShortcut::DocumentBack, u"go_document_back", kli18n("&Back"), kli18n("Go back in document"), u"go-previous" },
0110     { DocumentForward, KStandardShortcut::DocumentForward, u"go_document_forward", kli18n("&Forward"), kli18n("Go forward in document"), u"go-next" },
0111 
0112     { AddBookmark,   KStandardShortcut::AddBookmark, u"bookmark_add", kli18n("&Add Bookmark"), {}, u"bookmark-new" },
0113     { EditBookmarks, KStandardShortcut::EditBookmarks, u"bookmark_edit", kli18n("&Edit Bookmarks…"), {}, u"bookmarks-organize" },
0114 
0115     { Spelling,      KStandardShortcut::Spelling, u"tools_spelling", kli18n("&Spelling…"), kli18n("Check spelling in document"), u"tools-check-spelling" },
0116 
0117     { ShowMenubar,   KStandardShortcut::ShowMenubar, u"options_show_menubar", kli18n("Show &Menubar"), kli18n("Show or hide menubar"), u"show-menu" },
0118     { ShowToolbar,   KStandardShortcut::ShowToolbar, u"options_show_toolbar", kli18n("Show &Toolbar"), kli18n("Show or hide toolbar"), {} },
0119     { ShowStatusbar, KStandardShortcut::ShowStatusbar, u"options_show_statusbar", kli18n("Show St&atusbar"), kli18n("Show or hide statusbar"), {} },
0120     { FullScreen,    KStandardShortcut::FullScreen, u"fullscreen", kli18n("F&ull Screen Mode"), {}, u"view-fullscreen" },
0121     { KeyBindings,   KStandardShortcut::KeyBindings, u"options_configure_keybinding", kli18n("Configure Keyboard S&hortcuts…"), {}, u"configure-shortcuts" },
0122     { Preferences,   KStandardShortcut::Preferences, u"options_configure", kli18n("&Configure %1…"), {}, u"configure" },
0123     { ConfigureToolbars, KStandardShortcut::ConfigureToolbars, u"options_configure_toolbars", kli18n("Configure Tool&bars…"), {}, u"configure-toolbars" },
0124     { ConfigureNotifications, KStandardShortcut::ConfigureNotifications, u"options_configure_notifications", kli18n("Configure &Notifications…"), {}, u"preferences-desktop-notification" },
0125 
0126     // the idea here is that Contents is used in menus, and Help in dialogs, so both share the same
0127     // shortcut
0128     { HelpContents,  KStandardShortcut::Help, u"help_contents", kli18n("%1 &Handbook"), {}, u"help-contents" },
0129     { WhatsThis,     KStandardShortcut::WhatsThis, u"help_whats_this", kli18n("What's &This?"), {}, u"help-contextual" },
0130     { ReportBug,     KStandardShortcut::ReportBug, u"help_report_bug", kli18n("&Report Bug…"), {}, u"tools-report-bug" },
0131     { SwitchApplicationLanguage, KStandardShortcut::SwitchApplicationLanguage, u"switch_application_language", kli18n("Configure &Language…"), {}, u"preferences-desktop-locale" },
0132     { AboutApp,      KStandardShortcut::AccelNone, u"help_about_app", kli18n("&About %1"), {}, nullptr },
0133     { AboutKDE,      KStandardShortcut::AccelNone, u"help_about_kde", kli18n("About &KDE"), {}, u"kde" },
0134     { DeleteFile,    KStandardShortcut::DeleteFile, u"deletefile", kli18n("&Delete"), {}, u"edit-delete" },
0135     { RenameFile,    KStandardShortcut::RenameFile, u"renamefile", kli18n("&Rename…"), {}, u"edit-rename" },
0136     { MoveToTrash,   KStandardShortcut::MoveToTrash, u"movetotrash", kli18n("&Move to Trash"), {}, u"trash-empty" },
0137     { Donate,        KStandardShortcut::Donate, u"help_donate", kli18n("&Donate"), {}, u"help-donate"},
0138     { HamburgerMenu, KStandardShortcut::OpenMainMenu, u"hamburger_menu", kli18n("Open &Menu"), {}, u"application-menu" },
0139     { ActionNone,    KStandardShortcut::AccelNone, nullptr, {}, {}, nullptr }
0140 };
0141 // clang-format on
0142 
0143 inline const KStandardActionInfo *infoPtr(StandardAction id)
0144 {
0145     for (uint i = 0; g_rgActionInfo[i].id != ActionNone; i++) {
0146         if (g_rgActionInfo[i].id == id) {
0147             return &g_rgActionInfo[i];
0148         }
0149     }
0150 
0151     return nullptr;
0152 }
0153 
0154 static inline QStringList internal_stdNames()
0155 {
0156     QStringList result;
0157 
0158     for (uint i = 0; g_rgActionInfo[i].id != ActionNone; i++)
0159         if (!g_rgActionInfo[i].psLabel.isEmpty()) {
0160             if (QByteArray(g_rgActionInfo[i].psLabel.untranslatedText()).contains("%1"))
0161             // Prevents KLocalizedString::toString() from complaining about unsubstituted placeholder.
0162             {
0163                 result.append(g_rgActionInfo[i].psLabel.subs(QString()).toString());
0164             } else {
0165                 result.append(g_rgActionInfo[i].psLabel.toString());
0166             }
0167         }
0168 
0169     return result;
0170 }
0171 
0172 class AutomaticAction : public QAction
0173 {
0174     Q_OBJECT
0175 
0176 public:
0177     AutomaticAction(const QIcon &icon, const QString &text, KStandardShortcut::StandardShortcut standardShortcut, const char *slot, QObject *parent);
0178 public Q_SLOTS:
0179     inline void cut()
0180     {
0181         invokeEditSlot("cut");
0182     }
0183     inline void copy()
0184     {
0185         invokeEditSlot("copy");
0186     }
0187     inline void paste()
0188     {
0189         invokeEditSlot("paste");
0190     }
0191     inline void clear()
0192     {
0193         invokeEditSlot("clear");
0194     }
0195     inline void selectAll()
0196     {
0197         invokeEditSlot("selectAll");
0198     }
0199 
0200     void invokeEditSlot(const char *slot)
0201     {
0202         if (qApp->focusWidget()) {
0203             QMetaObject::invokeMethod(qApp->focusWidget(), slot);
0204         }
0205     }
0206 };
0207 
0208 }
0209 
0210 #endif