| 1 | /* |
| 2 | This file is part of the KDE libraries |
| 3 | SPDX-FileCopyrightText: 1999, 2000 Kurt Granroth <granroth@kde.org> |
| 4 | |
| 5 | SPDX-License-Identifier: LGPL-2.0-only |
| 6 | */ |
| 7 | |
| 8 | #pragma once |
| 9 | |
| 10 | #include <QAction> |
| 11 | #include <QGuiApplication> |
| 12 | |
| 13 | #include <KStandardActions> |
| 14 | #include <KStandardShortcut> |
| 15 | |
| 16 | #include <string> |
| 17 | |
| 18 | namespace KStandardActions |
| 19 | { |
| 20 | |
| 21 | /* |
| 22 | * Helper class for storing raw data in static tables which can be used for QString instance |
| 23 | * creation at runtime without copying/converting to new memalloc'ed memory, as well as avoiding |
| 24 | * that way storing the strings directly as QStrings resulting in non-constexpr init code on |
| 25 | * library loading |
| 26 | * |
| 27 | */ |
| 28 | struct RawStringData { |
| 29 | template<std::size_t StringSize> |
| 30 | constexpr inline RawStringData(const char16_t (&_data)[StringSize]) |
| 31 | : data(_data) |
| 32 | , size(std::char_traits<char16_t>::length(s: _data)) |
| 33 | { |
| 34 | } |
| 35 | constexpr inline RawStringData(std::nullptr_t) |
| 36 | { |
| 37 | } |
| 38 | constexpr inline RawStringData() = default; |
| 39 | |
| 40 | inline QString toString() const |
| 41 | { |
| 42 | if (!data) { |
| 43 | return QString(); |
| 44 | } |
| 45 | |
| 46 | return Qt::Literals::StringLiterals::operator""_s (str: data, size); |
| 47 | } |
| 48 | |
| 49 | private: |
| 50 | const char16_t *const data = nullptr; |
| 51 | const std::size_t size = 0; |
| 52 | }; |
| 53 | |
| 54 | struct KStandardActionsInfo { |
| 55 | KStandardActions::StandardAction id; |
| 56 | KStandardShortcut::StandardShortcut idAccel; |
| 57 | const RawStringData psName; |
| 58 | const char *psLabel; |
| 59 | const char *psToolTip; |
| 60 | const RawStringData psIconName; |
| 61 | }; |
| 62 | // clang-format off |
| 63 | static constexpr KStandardActionsInfo g_rgActionInfo[] = { |
| 64 | { .id: New, .idAccel: KStandardShortcut::New, .psName: u"file_new" , QT_TRANSLATE_NOOP("KStandardActions" , "&New" ), QT_TRANSLATE_NOOP("KStandardActions" , "Create new document" ), .psIconName: u"document-new" }, |
| 65 | { .id: Open, .idAccel: KStandardShortcut::Open, .psName: u"file_open" , QT_TRANSLATE_NOOP("KStandardActions" , "&Open…" ), QT_TRANSLATE_NOOP("KStandardActions" , "Open an existing document" ), .psIconName: u"document-open" }, |
| 66 | { .id: OpenRecent, .idAccel: KStandardShortcut::AccelNone, .psName: u"file_open_recent" , QT_TRANSLATE_NOOP("KStandardActions" , "Open &Recent" ), QT_TRANSLATE_NOOP("KStandardActions" , "Open a document which was recently opened" ), .psIconName: u"document-open-recent" }, |
| 67 | { .id: Save, .idAccel: KStandardShortcut::Save, .psName: u"file_save" , QT_TRANSLATE_NOOP("KStandardActions" , "&Save" ), QT_TRANSLATE_NOOP("KStandardActions" , "Save document" ), .psIconName: u"document-save" }, |
| 68 | { .id: SaveAs, .idAccel: KStandardShortcut::SaveAs, .psName: u"file_save_as" , QT_TRANSLATE_NOOP("KStandardActions" , "Save &As…" ), QT_TRANSLATE_NOOP("KStandardActions" , "Save document under a new name" ), .psIconName: u"document-save-as" }, |
| 69 | { .id: Revert, .idAccel: KStandardShortcut::Revert, .psName: u"file_revert" , QT_TRANSLATE_NOOP("KStandardActions" , "Re&vert" ), QT_TRANSLATE_NOOP("KStandardActions" , "Revert unsaved changes made to document" ), .psIconName: u"document-revert" }, |
| 70 | { .id: Close, .idAccel: KStandardShortcut::Close, .psName: u"file_close" , QT_TRANSLATE_NOOP("KStandardActions" , "&Close" ), QT_TRANSLATE_NOOP("KStandardActions" , "Close document" ), .psIconName: u"document-close" }, |
| 71 | { .id: Print, .idAccel: KStandardShortcut::Print, .psName: u"file_print" , QT_TRANSLATE_NOOP("KStandardActions" , "&Print…" ), QT_TRANSLATE_NOOP("KStandardActions" , "Print document" ), .psIconName: u"document-print" }, |
| 72 | { .id: PrintPreview, .idAccel: KStandardShortcut::PrintPreview, .psName: u"file_print_preview" , QT_TRANSLATE_NOOP("KStandardActions" , "Print Previe&w" ), QT_TRANSLATE_NOOP("KStandardActions" , "Show a print preview of document" ), .psIconName: u"document-print-preview" }, |
| 73 | { .id: Mail, .idAccel: KStandardShortcut::Mail, .psName: u"file_mail" , QT_TRANSLATE_NOOP("KStandardActions" , "&Mail…" ), QT_TRANSLATE_NOOP("KStandardActions" , "Send document by mail" ), .psIconName: u"mail-send" }, |
| 74 | { .id: Quit, .idAccel: KStandardShortcut::Quit, .psName: u"file_quit" , QT_TRANSLATE_NOOP("KStandardActions" , "&Quit" ), QT_TRANSLATE_NOOP("KStandardActions" , "Quit application" ), .psIconName: u"application-exit" }, |
| 75 | |
| 76 | { .id: Undo, .idAccel: KStandardShortcut::Undo, .psName: u"edit_undo" , QT_TRANSLATE_NOOP("KStandardActions" , "&Undo" ), QT_TRANSLATE_NOOP("KStandardActions" , "Undo last action" ), .psIconName: u"edit-undo" }, |
| 77 | { .id: Redo, .idAccel: KStandardShortcut::Redo, .psName: u"edit_redo" , QT_TRANSLATE_NOOP("KStandardActions" , "Re&do" ), QT_TRANSLATE_NOOP("KStandardActions" , "Redo last undone action" ), .psIconName: u"edit-redo" }, |
| 78 | { .id: Cut, .idAccel: KStandardShortcut::Cut, .psName: u"edit_cut" , QT_TRANSLATE_NOOP("KStandardActions" , "Cu&t" ), QT_TRANSLATE_NOOP("KStandardActions" , "Cut selection to clipboard" ), .psIconName: u"edit-cut" }, |
| 79 | { .id: Copy, .idAccel: KStandardShortcut::Copy, .psName: u"edit_copy" , QT_TRANSLATE_NOOP("KStandardActions" , "&Copy" ), QT_TRANSLATE_NOOP("KStandardActions" , "Copy selection to clipboard" ), .psIconName: u"edit-copy" }, |
| 80 | { .id: Paste, .idAccel: KStandardShortcut::Paste, .psName: u"edit_paste" , QT_TRANSLATE_NOOP("KStandardActions" , "&Paste" ), QT_TRANSLATE_NOOP("KStandardActions" , "Paste clipboard content" ), .psIconName: u"edit-paste" }, |
| 81 | { .id: Clear, .idAccel: KStandardShortcut::Clear, .psName: u"edit_clear" , QT_TRANSLATE_NOOP("KStandardActions" , "C&lear" ), .psToolTip: {}, .psIconName: u"edit-clear" }, |
| 82 | { .id: SelectAll, .idAccel: KStandardShortcut::SelectAll, .psName: u"edit_select_all" , QT_TRANSLATE_NOOP("KStandardActions" , "Select &All" ), .psToolTip: {}, .psIconName: u"edit-select-all" }, |
| 83 | { .id: Deselect, .idAccel: KStandardShortcut::Deselect, .psName: u"edit_deselect" , QT_TRANSLATE_NOOP("KStandardActions" , "Dese&lect" ), .psToolTip: {}, .psIconName: u"edit-select-none" }, |
| 84 | { .id: Find, .idAccel: KStandardShortcut::Find, .psName: u"edit_find" , QT_TRANSLATE_NOOP("KStandardActions" , "&Find…" ), .psToolTip: {}, .psIconName: u"edit-find" }, |
| 85 | { .id: FindNext, .idAccel: KStandardShortcut::FindNext, .psName: u"edit_find_next" , QT_TRANSLATE_NOOP("KStandardActions" , "Find &Next" ), .psToolTip: {}, .psIconName: u"go-down-search" }, |
| 86 | { .id: FindPrev, .idAccel: KStandardShortcut::FindPrev, .psName: u"edit_find_prev" , QT_TRANSLATE_NOOP("KStandardActions" , "Find Pre&vious" ), .psToolTip: {}, .psIconName: u"go-up-search" }, |
| 87 | { .id: Replace, .idAccel: KStandardShortcut::Replace, .psName: u"edit_replace" , QT_TRANSLATE_NOOP("KStandardActions" , "&Replace…" ), .psToolTip: {}, .psIconName: u"edit-find-replace" }, |
| 88 | |
| 89 | { .id: ActualSize, .idAccel: KStandardShortcut::ActualSize, .psName: u"view_actual_size" , QT_TRANSLATE_NOOP("KStandardActions" , "Zoom to &Actual Size" ), QT_TRANSLATE_NOOP("KStandardActions" , "View document at its actual size" ), .psIconName: u"zoom-original" }, |
| 90 | { .id: FitToPage, .idAccel: KStandardShortcut::FitToPage, .psName: u"view_fit_to_page" , QT_TRANSLATE_NOOP("KStandardActions" , "&Fit to Page" ), QT_TRANSLATE_NOOP("KStandardActions" , "Zoom to fit page in window" ), .psIconName: u"zoom-fit-page" }, |
| 91 | { .id: FitToWidth, .idAccel: KStandardShortcut::FitToWidth, .psName: u"view_fit_to_width" , QT_TRANSLATE_NOOP("KStandardActions" , "Fit to Page &Width" ), QT_TRANSLATE_NOOP("KStandardActions" , "Zoom to fit page width in window" ), .psIconName: u"zoom-fit-width" }, |
| 92 | { .id: FitToHeight, .idAccel: KStandardShortcut::FitToHeight, .psName: u"view_fit_to_height" , QT_TRANSLATE_NOOP("KStandardActions" , "Fit to Page &Height" ), QT_TRANSLATE_NOOP("KStandardActions" , "Zoom to fit page height in window" ), .psIconName: u"zoom-fit-height" }, |
| 93 | { .id: ZoomIn, .idAccel: KStandardShortcut::ZoomIn, .psName: u"view_zoom_in" , QT_TRANSLATE_NOOP("KStandardActions" , "Zoom &In" ), .psToolTip: {}, .psIconName: u"zoom-in" }, |
| 94 | { .id: ZoomOut, .idAccel: KStandardShortcut::ZoomOut, .psName: u"view_zoom_out" , QT_TRANSLATE_NOOP("KStandardActions" , "Zoom &Out" ), .psToolTip: {}, .psIconName: u"zoom-out" }, |
| 95 | { .id: Zoom, .idAccel: KStandardShortcut::Zoom, .psName: u"view_zoom" , QT_TRANSLATE_NOOP("KStandardActions" , "&Zoom…" ), QT_TRANSLATE_NOOP("KStandardActions" , "Select zoom level" ), .psIconName: u"zoom" }, |
| 96 | { .id: Redisplay, .idAccel: KStandardShortcut::Reload, .psName: u"view_redisplay" , QT_TRANSLATE_NOOP("KStandardActions" , "&Refresh" ), QT_TRANSLATE_NOOP("KStandardActions" , "Refresh document" ), .psIconName: u"view-refresh" }, |
| 97 | |
| 98 | { .id: Up, .idAccel: KStandardShortcut::Up, .psName: u"go_up" , QT_TRANSLATE_NOOP("KStandardActions" , "&Up" ), QT_TRANSLATE_NOOP("KStandardActions" , "Go up" ), .psIconName: u"go-up" }, |
| 99 | // The following three have special i18n() needs for sLabel |
| 100 | { .id: Back, .idAccel: KStandardShortcut::Back, .psName: u"go_back" , .psLabel: {}, .psToolTip: {}, .psIconName: u"go-previous" }, |
| 101 | { .id: Forward, .idAccel: KStandardShortcut::Forward, .psName: u"go_forward" , .psLabel: {}, .psToolTip: {}, .psIconName: u"go-next" }, |
| 102 | { .id: Home, .idAccel: KStandardShortcut::Home, .psName: u"go_home" , .psLabel: {}, .psToolTip: {}, .psIconName: u"go-home" }, |
| 103 | { .id: Prior, .idAccel: KStandardShortcut::Prior, .psName: u"go_previous" , QT_TRANSLATE_NOOP("KStandardActions" , "&Previous Page" ), QT_TRANSLATE_NOOP("KStandardActions" , "Go to previous page" ), .psIconName: u"go-previous-view-page" }, |
| 104 | { .id: Next, .idAccel: KStandardShortcut::Next, .psName: u"go_next" , QT_TRANSLATE_NOOP("KStandardActions" , "&Next Page" ), QT_TRANSLATE_NOOP("KStandardActions" , "Go to next page" ), .psIconName: u"go-next-view-page" }, |
| 105 | { .id: Goto, .idAccel: KStandardShortcut::Goto, .psName: u"go_goto" , QT_TRANSLATE_NOOP("KStandardActions" , "&Go To…" ), .psToolTip: {}, .psIconName: {} }, |
| 106 | { .id: GotoPage, .idAccel: KStandardShortcut::GotoPage, .psName: u"go_goto_page" , QT_TRANSLATE_NOOP("KStandardActions" , "&Go to Page…" ), .psToolTip: {}, .psIconName: u"go-jump" }, |
| 107 | { .id: GotoLine, .idAccel: KStandardShortcut::GotoLine, .psName: u"go_goto_line" , QT_TRANSLATE_NOOP("KStandardActions" , "&Go to Line…" ), .psToolTip: {}, .psIconName: {} }, |
| 108 | { .id: FirstPage, .idAccel: KStandardShortcut::Begin, .psName: u"go_first" , QT_TRANSLATE_NOOP("KStandardActions" , "&First Page" ), QT_TRANSLATE_NOOP("KStandardActions" , "Go to first page" ), .psIconName: u"go-first-view-page" }, |
| 109 | { .id: LastPage, .idAccel: KStandardShortcut::End, .psName: u"go_last" , QT_TRANSLATE_NOOP("KStandardActions" , "&Last Page" ), QT_TRANSLATE_NOOP("KStandardActions" , "Go to last page" ), .psIconName: u"go-last-view-page" }, |
| 110 | { .id: DocumentBack, .idAccel: KStandardShortcut::DocumentBack, .psName: u"go_document_back" , QT_TRANSLATE_NOOP("KStandardActions" , "&Back" ), QT_TRANSLATE_NOOP("KStandardActions" , "Go back in document" ), .psIconName: u"go-previous" }, |
| 111 | { .id: DocumentForward, .idAccel: KStandardShortcut::DocumentForward, .psName: u"go_document_forward" , QT_TRANSLATE_NOOP("KStandardActions" , "&Forward" ), QT_TRANSLATE_NOOP("KStandardActions" , "Go forward in document" ), .psIconName: u"go-next" }, |
| 112 | |
| 113 | { .id: AddBookmark, .idAccel: KStandardShortcut::AddBookmark, .psName: u"bookmark_add" , QT_TRANSLATE_NOOP("KStandardActions" , "&Add Bookmark" ), .psToolTip: {}, .psIconName: u"bookmark-new" }, |
| 114 | { .id: EditBookmarks, .idAccel: KStandardShortcut::EditBookmarks, .psName: u"bookmark_edit" , QT_TRANSLATE_NOOP("KStandardActions" , "&Edit Bookmarks…" ), .psToolTip: {}, .psIconName: u"bookmarks-organize" }, |
| 115 | |
| 116 | { .id: Spelling, .idAccel: KStandardShortcut::Spelling, .psName: u"tools_spelling" , QT_TRANSLATE_NOOP("KStandardActions" , "&Spelling…" ), QT_TRANSLATE_NOOP("KStandardActions" , "Check spelling in document" ), .psIconName: u"tools-check-spelling" }, |
| 117 | |
| 118 | { .id: ShowMenubar, .idAccel: KStandardShortcut::ShowMenubar, .psName: u"options_show_menubar" , QT_TRANSLATE_NOOP("KStandardActions" , "Show &Menubar" ), QT_TRANSLATE_NOOP("KStandardActions" , "Show or hide menubar" ), .psIconName: u"show-menu" }, |
| 119 | { .id: ShowToolbar, .idAccel: KStandardShortcut::ShowToolbar, .psName: u"options_show_toolbar" , QT_TRANSLATE_NOOP("KStandardActions" , "Show &Toolbar" ), QT_TRANSLATE_NOOP("KStandardActions" , "Show or hide toolbar" ), .psIconName: {} }, |
| 120 | { .id: ShowStatusbar, .idAccel: KStandardShortcut::ShowStatusbar, .psName: u"options_show_statusbar" , QT_TRANSLATE_NOOP("KStandardActions" , "Show St&atusbar" ), QT_TRANSLATE_NOOP("KStandardActions" , "Show or hide statusbar" ), .psIconName: {} }, |
| 121 | { .id: FullScreen, .idAccel: KStandardShortcut::FullScreen, .psName: u"fullscreen" , QT_TRANSLATE_NOOP("KStandardActions" , "F&ull Screen Mode" ), .psToolTip: {}, .psIconName: u"view-fullscreen" }, |
| 122 | { .id: KeyBindings, .idAccel: KStandardShortcut::KeyBindings, .psName: u"options_configure_keybinding" , QT_TRANSLATE_NOOP("KStandardActions" , "Configure Keyboard S&hortcuts…" ), .psToolTip: {}, .psIconName: u"configure-shortcuts" }, |
| 123 | { .id: Preferences, .idAccel: KStandardShortcut::Preferences, .psName: u"options_configure" , QT_TRANSLATE_NOOP("KStandardActions" , "&Configure %1…" ), .psToolTip: {}, .psIconName: u"configure" }, |
| 124 | { .id: ConfigureToolbars, .idAccel: KStandardShortcut::ConfigureToolbars, .psName: u"options_configure_toolbars" , QT_TRANSLATE_NOOP("KStandardActions" , "Configure Tool&bars…" ), .psToolTip: {}, .psIconName: u"configure-toolbars" }, |
| 125 | { .id: ConfigureNotifications, .idAccel: KStandardShortcut::ConfigureNotifications, .psName: u"options_configure_notifications" , QT_TRANSLATE_NOOP("KStandardActions" , "Configure &Notifications…" ), .psToolTip: {}, .psIconName: u"preferences-desktop-notification" }, |
| 126 | |
| 127 | // the idea here is that Contents is used in menus, and Help in dialogs, so both share the same |
| 128 | // shortcut |
| 129 | { .id: HelpContents, .idAccel: KStandardShortcut::Help, .psName: u"help_contents" , QT_TRANSLATE_NOOP("KStandardActions" , "%1 &Handbook" ), .psToolTip: {}, .psIconName: u"help-contents" }, |
| 130 | { .id: WhatsThis, .idAccel: KStandardShortcut::WhatsThis, .psName: u"help_whats_this" , QT_TRANSLATE_NOOP("KStandardActions" , "What's &This?" ), .psToolTip: {}, .psIconName: u"help-contextual" }, |
| 131 | { .id: ReportBug, .idAccel: KStandardShortcut::ReportBug, .psName: u"help_report_bug" , QT_TRANSLATE_NOOP("KStandardActions" , "&Report Bug…" ), .psToolTip: {}, .psIconName: u"tools-report-bug" }, |
| 132 | { .id: SwitchApplicationLanguage, .idAccel: KStandardShortcut::SwitchApplicationLanguage, .psName: u"switch_application_language" , QT_TRANSLATE_NOOP("KStandardActions" , "Configure &Language…" ), .psToolTip: {}, .psIconName: u"preferences-desktop-locale" }, |
| 133 | { .id: AboutApp, .idAccel: KStandardShortcut::AccelNone, .psName: u"help_about_app" , QT_TRANSLATE_NOOP("KStandardActions" , "&About %1" ), .psToolTip: {}, .psIconName: nullptr }, |
| 134 | { .id: AboutKDE, .idAccel: KStandardShortcut::AccelNone, .psName: u"help_about_kde" , QT_TRANSLATE_NOOP("KStandardActions" , "About &KDE" ), .psToolTip: {}, .psIconName: u"kde" }, |
| 135 | { .id: DeleteFile, .idAccel: KStandardShortcut::DeleteFile, .psName: u"deletefile" , QT_TRANSLATE_NOOP("KStandardActions" , "&Delete" ), .psToolTip: {}, .psIconName: u"edit-delete" }, |
| 136 | { .id: RenameFile, .idAccel: KStandardShortcut::RenameFile, .psName: u"renamefile" , QT_TRANSLATE_NOOP("KStandardActions" , "&Rename…" ), .psToolTip: {}, .psIconName: u"edit-rename" }, |
| 137 | { .id: MoveToTrash, .idAccel: KStandardShortcut::MoveToTrash, .psName: u"movetotrash" , QT_TRANSLATE_NOOP("KStandardActions" , "&Move to Trash" ), .psToolTip: {}, .psIconName: u"trash-empty" }, |
| 138 | { .id: Donate, .idAccel: KStandardShortcut::Donate, .psName: u"help_donate" , QT_TRANSLATE_NOOP("KStandardActions" , "&Donate" ), .psToolTip: {}, .psIconName: u"help-donate" }, |
| 139 | { .id: HamburgerMenu, .idAccel: KStandardShortcut::OpenMainMenu, .psName: u"hamburger_menu" , QT_TRANSLATE_NOOP("KStandardActions" , "Open &Menu" ), .psToolTip: {}, .psIconName: u"application-menu" }, |
| 140 | }; |
| 141 | // clang-format on |
| 142 | |
| 143 | inline const KStandardActionsInfo *infoPtr(StandardAction id) |
| 144 | { |
| 145 | for (const auto &action : g_rgActionInfo) { |
| 146 | if (action.id == id) { |
| 147 | return &action; |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | return nullptr; |
| 152 | } |
| 153 | |
| 154 | static inline QStringList internal_stdNames() |
| 155 | { |
| 156 | QStringList result; |
| 157 | |
| 158 | for (const auto &action : g_rgActionInfo) { |
| 159 | if (!QCoreApplication::translate(context: "KStandardActions" , key: action.psLabel).isEmpty()) { |
| 160 | if (QByteArrayView(action.psLabel).contains(a: "%1" )) |
| 161 | // Prevents KLocalizedString::toString() from complaining about unsubstituted placeholder. |
| 162 | { |
| 163 | result.append(t: QCoreApplication::translate(context: "KStandardActions" , key: action.psLabel).arg(a: QString())); |
| 164 | } else { |
| 165 | result.append(t: QCoreApplication::translate(context: "KStandardActions" , key: action.psLabel)); |
| 166 | } |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | return result; |
| 171 | } |
| 172 | } |
| 173 | |