KDEGames

kgamestandardaction.cpp
1/*
2 This file is part of the KDE games library
3 SPDX-FileCopyrightText: 2001 Andreas Beckermann <b_mann@gmx.de>
4 SPDX-FileCopyrightText: 2007 Simon Hürlimann <simon.huerlimann@huerlisi.ch>
5
6 SPDX-License-Identifier: LGPL-2.0-only
7*/
8
9#include "kgamestandardaction.h"
10
11// KF
12#include <KActionCollection>
13#include <KLazyLocalizedString>
14#include <KLocalizedString>
15#include <KStandardShortcut>
16// Qt
17#include <QIcon>
18// Std
19#include <string>
20
21// Helper class for storing raw data in static tables which can be used for QString instance
22// creation at runtime without copying/converting to new memalloc'ed memory, as well as avoiding
23// that way storing the strings directly as QStrings resulting in non-constexpr init code on
24// library loading
25struct RawStringData {
26 template<std::size_t StringSize>
27 constexpr inline RawStringData(const char16_t (&_data)[StringSize])
28 : data(_data)
29 , size(std::char_traits<char16_t>::length(_data))
30 {
31 }
32 constexpr inline RawStringData(std::nullptr_t)
33 {
34 }
35 constexpr inline RawStringData() = default;
36
37 inline QString toString() const
38 {
39 if (!data) {
40 return QString();
41 }
42
43 return Qt::Literals::StringLiterals::operator""_s(data, size);
44 }
45
46private:
47 const char16_t *const data = nullptr;
48 const std::size_t size = 0;
49};
50
51struct KGameStandardActionInfo {
53 KStandardShortcut::StandardShortcut globalAccel; // if we reuse a global accel
54 int shortcut; // specific shortcut (NH: should be configurable)
55 const RawStringData psName;
56 const KLazyLocalizedString psLabel;
57 const KLazyLocalizedString psWhatsThis;
58 const RawStringData psIconName;
59 const KLazyLocalizedString psToolTip;
60};
61
62#define CTRL(x) QKeyCombination(Qt::CTRL | Qt::Key_##x).toCombined()
63
64const KGameStandardActionInfo g_rgActionInfo[] = {
65 // clang-format off
66 // "game" menu
67 { KGameStandardAction::New, KStandardShortcut::New, 0, u"game_new",
68 kli18nc("new game", "&New"), kli18n("Start a new game."), u"document-new", kli18n("Start a new game") },
69 { KGameStandardAction::Load, KStandardShortcut::Open, 0, u"game_load",
70 kli18n("&Load..."), {}, u"document-open", kli18n("Open a saved game...") },
71 { KGameStandardAction::LoadRecent, KStandardShortcut::AccelNone, 0, u"game_load_recent",
72 kli18n("Load &Recent"), {}, nullptr, kli18n("Open a recently saved game...") },
73 { KGameStandardAction::Restart, KStandardShortcut::Reload, 0, u"game_restart",
74 kli18n("Restart &Game"), {}, u"view-refresh", kli18n("Restart the game") },
75 { KGameStandardAction::Save, KStandardShortcut::Save, 0, u"game_save",
76 kli18n("&Save"), {}, u"document-save", kli18n("Save the current game") },
77 { KGameStandardAction::SaveAs, KStandardShortcut::AccelNone, 0, u"game_save_as",
78 kli18n("Save &As..."), {}, u"document-save-as", kli18n("Save the current game to another file") },
79 { KGameStandardAction::End, KStandardShortcut::End, 0, u"game_end",
80 kli18n("&End Game"), {}, u"window-close", kli18n("End the current game") },
81 { KGameStandardAction::Pause, KStandardShortcut::AccelNone, Qt::Key_P, u"game_pause",
82 kli18n("Pa&use"), {}, u"media-playback-pause", kli18n("Pause the game") },
83 { KGameStandardAction::Highscores, KStandardShortcut::AccelNone, CTRL(H), u"game_highscores",
84 kli18n("Show &High Scores"), {}, u"games-highscores", kli18n("Show high scores") },
85 { KGameStandardAction::ClearHighscores, KStandardShortcut::AccelNone, 0, u"game_clear_highscores",
86 kli18n("&Clear High Scores"), {}, u"clear_highscore", kli18n("Clear high scores") },
87 { KGameStandardAction::Statistics, KStandardShortcut::AccelNone, 0, u"game_statistics",
88 kli18n("Show Statistics"), {}, u"highscore", kli18n("Show statistics") },
89 { KGameStandardAction::ClearStatistics, KStandardShortcut::AccelNone, 0, u"game_clear_statistics",
90 kli18n("&Clear Statistics"), {}, u"flag", kli18n("Delete all-time statistics.") },
91 { KGameStandardAction::Print, KStandardShortcut::Print, 0, u"game_print",
92 kli18n("&Print..."), {}, u"document-print", {} },
93 { KGameStandardAction::Quit, KStandardShortcut::Quit, 0, u"game_quit",
94 kli18n("&Quit"), {}, u"application-exit", kli18n("Quit the program") },
95
96 // "move" menu
97 { KGameStandardAction::Repeat, KStandardShortcut::AccelNone, 0, u"move_repeat",
98 kli18n("Repeat"), {}, nullptr, kli18n("Repeat the last move") },
99 { KGameStandardAction::Undo, KStandardShortcut::Undo, 0, u"move_undo",
100 kli18n("Und&o"), {}, u"edit-undo", kli18n("Undo the last move") },
101 { KGameStandardAction::Redo, KStandardShortcut::Redo, 0, u"move_redo",
102 kli18n("Re&do"), {}, u"edit-redo", kli18n("Redo the latest move") },
103 { KGameStandardAction::Roll, KStandardShortcut::AccelNone, CTRL(R), u"move_roll",
104 kli18n("&Roll Dice"), {}, u"roll", kli18n("Roll the dice") },
105 { KGameStandardAction::EndTurn, KStandardShortcut::AccelNone, 0, u"move_end_turn",
106 kli18n("End Turn"), {}, u"games-endturn", {} },
107 { KGameStandardAction::Hint, KStandardShortcut::AccelNone, Qt::Key_H, u"move_hint",
108 kli18n("&Hint"), {}, u"games-hint", kli18n("Give a hint") },
109 { KGameStandardAction::Demo, KStandardShortcut::AccelNone, Qt::Key_D, u"move_demo",
110 kli18n("&Demo"), {}, u"media-playback-start", kli18n("Play a demo") },
111 { KGameStandardAction::Solve, KStandardShortcut::AccelNone, 0, u"move_solve",
112 kli18n("&Solve"), {}, u"games-solve", kli18n("Solve the game") },
113
114 // "settings" menu
115 { KGameStandardAction::Carddecks, KStandardShortcut::AccelNone, 0, u"options_configure_carddecks",
116 kli18n("Configure &Carddecks..."), {}, nullptr, {} },
117 { KGameStandardAction::ConfigureHighscores, KStandardShortcut::AccelNone, 0, u"options_configure_highscores",
118 kli18n("Configure &High Scores..."), {}, nullptr, {} },
119
120 { KGameStandardAction::ActionNone, KStandardShortcut::AccelNone, 0, nullptr, {}, {}, nullptr, {} }
121 // clang-format on
122};
123
124static const KGameStandardActionInfo *infoPtr(KGameStandardAction::GameStandardAction id)
125{
126 for (uint i = 0; g_rgActionInfo[i].id != KGameStandardAction::ActionNone; i++) {
127 if (g_rgActionInfo[i].id == id)
128 return &g_rgActionInfo[i];
129 }
130 return nullptr;
131}
132
134{
135 QAction *pAction = nullptr;
136 const KGameStandardActionInfo *pInfo = infoPtr(id);
137 // qCDebug(GAMES_UI) << "KGameStandardAction::create( " << id << "=" << (pInfo ? pInfo->psName : (const char*)nullptr) << "," << parent << " )";
138 if (pInfo) {
139 const QString sLabel = pInfo->psLabel.toString();
140 switch (id) {
141 case LoadRecent:
142 pAction = new KRecentFilesAction(sLabel, parent);
143 break;
144 case Pause:
145 case Demo:
146 pAction = new KToggleAction(QIcon::fromTheme(pInfo->psIconName.toString()), sLabel, parent);
147 break;
148 default:
149 pAction = new QAction(QIcon::fromTheme(pInfo->psIconName.toString()), sLabel, parent);
150 break;
151 }
152
153 // clang-format off
154 const QList<QKeySequence> cut =
155 (pInfo->globalAccel != KStandardShortcut::AccelNone) ? KStandardShortcut::shortcut(pInfo->globalAccel) :
156 (pInfo->shortcut != 0) ? QList<QKeySequence>{QKeySequence(pInfo->shortcut)} :
157 /* else */ QList<QKeySequence>();
158 // clang-format on
159
160 if (!cut.isEmpty()) {
161 pAction->setShortcuts(cut);
162 pAction->setProperty("defaultShortcuts", QVariant::fromValue(cut));
163 }
164 if (!pInfo->psToolTip.isEmpty())
165 pAction->setToolTip(pInfo->psToolTip.toString());
166 if (!pInfo->psWhatsThis.isEmpty())
167 pAction->setWhatsThis(pInfo->psWhatsThis.toString());
168 else if (!pInfo->psToolTip.isEmpty())
169 pAction->setWhatsThis(pInfo->psToolTip.toString());
170
171 pAction->setObjectName(pInfo->psName.toString());
172 }
173
174 KActionCollection *collection = qobject_cast<KActionCollection *>(parent);
175 if (collection && pAction)
176 collection->addAction(pAction->objectName(), pAction);
177
178 return pAction;
179}
180
181QAction *KGameStandardAction::create(GameStandardAction id, const QObject *recvr, const char *slot, QObject *parent)
182{
183 QAction *pAction = _k_createInternal(id, parent);
184 if (recvr && slot) {
185 switch (id) {
186 case LoadRecent:
187 QObject::connect(pAction, SIGNAL(urlSelected(QUrl)), recvr, slot);
188 break;
189 default:
190 QObject::connect(pAction, SIGNAL(triggered(bool)), recvr, slot);
191 break;
192 }
193 }
194 return pAction;
195}
196
198{
199 const KGameStandardActionInfo *pInfo = infoPtr(id);
200 return (pInfo) ? pInfo->psName.toString() : QString();
201}
202
203QAction *KGameStandardAction::gameNew(const QObject *recvr, const char *slot, QObject *parent)
204{
205 return KGameStandardAction::create(New, recvr, slot, parent);
206}
207QAction *KGameStandardAction::load(const QObject *recvr, const char *slot, QObject *parent)
208{
209 return KGameStandardAction::create(Load, recvr, slot, parent);
210}
211KRecentFilesAction *KGameStandardAction::loadRecent(const QObject *recvr, const char *slot, QObject *parent)
212{
213 return static_cast<KRecentFilesAction *>(KGameStandardAction::create(LoadRecent, recvr, slot, parent));
214}
215QAction *KGameStandardAction::save(const QObject *recvr, const char *slot, QObject *parent)
216{
217 return KGameStandardAction::create(Save, recvr, slot, parent);
218}
219QAction *KGameStandardAction::saveAs(const QObject *recvr, const char *slot, QObject *parent)
220{
221 return KGameStandardAction::create(SaveAs, recvr, slot, parent);
222}
223QAction *KGameStandardAction::end(const QObject *recvr, const char *slot, QObject *parent)
224{
225 return KGameStandardAction::create(End, recvr, slot, parent);
226}
227KToggleAction *KGameStandardAction::pause(const QObject *recvr, const char *slot, QObject *parent)
228{
229 return static_cast<KToggleAction *>(KGameStandardAction::create(Pause, recvr, slot, parent));
230}
231QAction *KGameStandardAction::highscores(const QObject *recvr, const char *slot, QObject *parent)
232{
233 return KGameStandardAction::create(Highscores, recvr, slot, parent);
234}
235QAction *KGameStandardAction::statistics(const QObject *recvr, const char *slot, QObject *parent)
236{
237 return KGameStandardAction::create(Highscores, recvr, slot, parent);
238}
239QAction *KGameStandardAction::clearStatistics(const QObject *recvr, const char *slot, QObject *parent)
240{
241 return KGameStandardAction::create(ClearStatistics, recvr, slot, parent);
242}
243QAction *KGameStandardAction::print(const QObject *recvr, const char *slot, QObject *parent)
244{
245 return KGameStandardAction::create(Print, recvr, slot, parent);
246}
247QAction *KGameStandardAction::quit(const QObject *recvr, const char *slot, QObject *parent)
248{
249 return KGameStandardAction::create(Quit, recvr, slot, parent);
250}
251
252QAction *KGameStandardAction::repeat(const QObject *recvr, const char *slot, QObject *parent)
253{
254 return KGameStandardAction::create(Repeat, recvr, slot, parent);
255}
256QAction *KGameStandardAction::undo(const QObject *recvr, const char *slot, QObject *parent)
257{
258 return KGameStandardAction::create(Undo, recvr, slot, parent);
259}
260
261QAction *KGameStandardAction::redo(const QObject *recvr, const char *slot, QObject *parent)
262{
263 return KGameStandardAction::create(Redo, recvr, slot, parent);
264}
265
266QAction *KGameStandardAction::roll(const QObject *recvr, const char *slot, QObject *parent)
267{
268 return KGameStandardAction::create(Roll, recvr, slot, parent);
269}
270QAction *KGameStandardAction::endTurn(const QObject *recvr, const char *slot, QObject *parent)
271{
272 return KGameStandardAction::create(EndTurn, recvr, slot, parent);
273}
274
275QAction *KGameStandardAction::carddecks(const QObject *recvr, const char *slot, QObject *parent)
276{
277 return KGameStandardAction::create(Carddecks, recvr, slot, parent);
278}
279QAction *KGameStandardAction::configureHighscores(const QObject *recvr, const char *slot, QObject *parent)
280{
281 return KGameStandardAction::create(ConfigureHighscores, recvr, slot, parent);
282}
283QAction *KGameStandardAction::hint(const QObject *recvr, const char *slot, QObject *parent)
284{
285 return KGameStandardAction::create(Hint, recvr, slot, parent);
286}
287KToggleAction *KGameStandardAction::demo(const QObject *recvr, const char *slot, QObject *parent)
288{
289 return static_cast<KToggleAction *>(KGameStandardAction::create(Demo, recvr, slot, parent));
290}
291QAction *KGameStandardAction::solve(const QObject *recvr, const char *slot, QObject *parent)
292{
293 return KGameStandardAction::create(Solve, recvr, slot, parent);
294}
295QAction *KGameStandardAction::restart(const QObject *recvr, const char *slot, QObject *parent)
296{
297 return KGameStandardAction::create(Restart, recvr, slot, parent);
298}
QAction * addAction(const QString &name, const QObject *receiver=nullptr, const char *member=nullptr)
QString toString() const
constexpr bool isEmpty() const
QAction * configureHighscores(const QObject *recvr, const char *slot, QObject *parent)
Display configure highscores dialog.
QAction * restart(const QObject *recvr, const char *slot, QObject *parent)
Restart the game.
GameStandardAction
The standard menubar and toolbar actions.
QAction * quit(const QObject *recvr, const char *slot, QObject *parent)
Quit the game.
QAction * highscores(const QObject *recvr, const char *slot, QObject *parent)
Show the highscores.
QAction * carddecks(const QObject *recvr, const char *slot, QObject *parent)
Display configure carddecks dialog.
QAction * _k_createInternal(GameStandardAction id, QObject *parent)
QAction * redo(const QObject *recvr, const char *slot, QObject *parent)
Redo the last move (which has been undone).
QAction * create(GameStandardAction id, const QObject *recvr, const char *slot, QObject *parent)
Creates an action corresponding to the KStandardAction::StandardAction enum.
QAction * hint(const QObject *recvr, const char *slot, QObject *parent)
Give an advice/hint.
QAction * gameNew(const QObject *recvr, const char *slot, QObject *parent)
Start a new game.
KToggleAction * demo(const QObject *recvr, const char *slot, QObject *parent)
Show a demo.
QAction * endTurn(const QObject *recvr, const char *slot, QObject *parent)
End the current turn (not the game).
QAction * repeat(const QObject *recvr, const char *slot, QObject *parent)
Repeat the last move.
KRecentFilesAction * loadRecent(const QObject *recvr, const char *slot, QObject *parent)
Load a recently loaded game.
QAction * solve(const QObject *recvr, const char *slot, QObject *parent)
Solve the game.
QAction * undo(const QObject *recvr, const char *slot, QObject *parent)
Undo the last move.
QString name(GameStandardAction id)
This will return the internal name of a given standard action.
QAction * statistics(const QObject *recvr, const char *slot, QObject *parent)
Show the statistics.
QAction * roll(const QObject *recvr, const char *slot, QObject *parent)
Roll die or dice.
QAction * print(const QObject *recvr, const char *slot, QObject *parent)
Print current game.
QAction * end(const QObject *recvr, const char *slot, QObject *parent)
End the current game, but do not quit the program.
QAction * save(const QObject *recvr, const char *slot, QObject *parent)
Save the current game.
QAction * clearStatistics(const QObject *recvr, const char *slot, QObject *parent)
Clear statistics.
QAction * saveAs(const QObject *recvr, const char *slot, QObject *parent)
Save the current game under a different filename.
KToggleAction * pause(const QObject *recvr, const char *slot, QObject *parent)
Pause the game.
QAction * load(const QObject *recvr, const char *slot, QObject *parent)
Load a previously saved game.
const QList< QKeySequence > & shortcut(StandardShortcut id)
void setShortcuts(QKeySequence::StandardKey key)
void setToolTip(const QString &tip)
void setWhatsThis(const QString &what)
QIcon fromTheme(const QString &name)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setObjectName(QAnyStringView name)
bool setProperty(const char *name, QVariant &&value)
QVariant fromValue(T &&value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Apr 27 2024 22:10:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.