Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanek Bevendorff <janek@jbev.net>2019-12-30 02:15:11 +0300
committerJanek Bevendorff <janek@jbev.net>2019-12-30 02:15:11 +0300
commit8637054c319759f4d5aa11c9108f08ed4797a326 (patch)
tree4c9e00e014f1e2e3a924239fcb5d6daa6b9e74e3
parent2fab4d576a35c28cdee38ed88f2fb3b6d8901fdf (diff)
Implement initial prototype UIfeature/qtquick-ui
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/CMakeLists.txt5
-rw-r--r--src/main.cpp61
-rw-r--r--src/qml.qrc47
-rw-r--r--src/qml/classic/main.qml423
5 files changed, 510 insertions, 28 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 643e2f093..b697ce746 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -368,7 +368,7 @@ endif()
include(CLangFormat)
-set(QT_COMPONENTS Core Network Concurrent Gui Svg Widgets Test LinguistTools)
+set(QT_COMPONENTS Core Network Concurrent Gui Qml Quick QuickControls2 Svg Widgets Test LinguistTools)
if(UNIX AND NOT APPLE)
find_package(Qt5 COMPONENTS ${QT_COMPONENTS} DBus REQUIRED)
elseif(APPLE)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index af9b9bb58..ab67688b0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -197,7 +197,7 @@ if(MINGW OR (UNIX AND NOT APPLE))
core/OSEventFilter.cpp)
endif()
-set(keepassx_SOURCES_MAINEXE main.cpp)
+set(keepassx_SOURCES_MAINEXE main.cpp qml.qrc)
add_feature_info(Auto-Type WITH_XC_AUTOTYPE "Automatic password typing")
add_feature_info(Networking WITH_XC_NETWORKING "Compile KeePassXC with network access code (e.g. for downloading website icons)")
@@ -300,6 +300,9 @@ target_link_libraries(keepassx_core
Qt5::Core
Qt5::Concurrent
Qt5::Network
+ Qt5::Qml
+ Qt5::Quick
+ Qt5::QuickControls2
Qt5::Widgets
${sodium_LIBRARY_RELEASE}
${YUBIKEY_LIBRARIES}
diff --git a/src/main.cpp b/src/main.cpp
index dd503d957..f9ef0f39b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <QQmlApplicationEngine>
+#include <QQuickStyle>
#include <QCommandLineParser>
#include <QFile>
#include <QTextStream>
@@ -49,10 +51,8 @@ int main(int argc, char** argv)
QT_REQUIRE_VERSION(argc, argv, QT_VERSION_STR)
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
- QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
-#ifdef Q_OS_LINUX
- QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
-#endif
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
@@ -129,29 +129,38 @@ int main(int argc, char** argv)
Config::createConfigFromFile(parser.value(configOption));
}
- MainWindow mainWindow;
- QObject::connect(&app, SIGNAL(anotherInstanceStarted()), &mainWindow, SLOT(bringToFront()));
- QObject::connect(&app, SIGNAL(applicationActivated()), &mainWindow, SLOT(bringToFront()));
- QObject::connect(&app, SIGNAL(openFile(QString)), &mainWindow, SLOT(openDatabase(QString)));
- QObject::connect(&app, SIGNAL(quitSignalReceived()), &mainWindow, SLOT(appExit()), Qt::DirectConnection);
-
- Bootstrap::restoreMainWindowState(mainWindow);
-
- const bool pwstdin = parser.isSet(pwstdinOption);
- for (const QString& filename : fileNames) {
- QString password;
- if (pwstdin) {
- // we always need consume a line of STDIN if --pw-stdin is set to clear out the
- // buffer for native messaging, even if the specified file does not exist
- QTextStream out(stdout, QIODevice::WriteOnly);
- out << QObject::tr("Database password: ") << flush;
- password = Utils::getPassword();
- }
-
- if (!filename.isEmpty() && QFile::exists(filename) && !filename.endsWith(".json", Qt::CaseInsensitive)) {
- mainWindow.openDatabase(filename, password, parser.value(keyfileOption));
+ QQmlApplicationEngine engine;
+ const QUrl url("qrc:/qml/classic/main.qml");
+ QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) {
+ if (!obj && url == objUrl) {
+ QCoreApplication::exit(-1);
}
- }
+ }, Qt::QueuedConnection);
+ engine.load(url);
+
+// MainWindow mainWindow;
+// QObject::connect(&app, SIGNAL(anotherInstanceStarted()), &mainWindow, SLOT(bringToFront()));
+// QObject::connect(&app, SIGNAL(applicationActivated()), &mainWindow, SLOT(bringToFront()));
+// QObject::connect(&app, SIGNAL(openFile(QString)), &mainWindow, SLOT(openDatabase(QString)));
+// QObject::connect(&app, SIGNAL(quitSignalReceived()), &mainWindow, SLOT(appExit()), Qt::DirectConnection);
+//
+// Bootstrap::restoreMainWindowState(mainWindow);
+//
+// const bool pwstdin = parser.isSet(pwstdinOption);
+// for (const QString& filename : fileNames) {
+// QString password;
+// if (pwstdin) {
+// // we always need consume a line of STDIN if --pw-stdin is set to clear out the
+// // buffer for native messaging, even if the specified file does not exist
+// QTextStream out(stdout, QIODevice::WriteOnly);
+// out << QObject::tr("Database password: ") << flush;
+// password = Utils::getPassword();
+// }
+//
+// if (!filename.isEmpty() && QFile::exists(filename) && !filename.endsWith(".json", Qt::CaseInsensitive)) {
+// mainWindow.openDatabase(filename, password, parser.value(keyfileOption));
+// }
+// }
int exitCode = Application::exec();
diff --git a/src/qml.qrc b/src/qml.qrc
new file mode 100644
index 000000000..f16b8ea5e
--- /dev/null
+++ b/src/qml.qrc
@@ -0,0 +1,47 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qml/classic/main.qml</file>
+ </qresource>
+
+ <qresource prefix="/icons">
+ <file alias="application-exit">../share/icons/application/32x32/actions/application-exit.png</file>
+ <file alias="auto-type">../share/icons/application/32x32/actions/auto-type.png</file>
+ <file alias="chronometer">../share/icons/application/32x32/actions/chronometer.png</file>
+ <file alias="configure">../share/icons/application/32x32/actions/configure.png</file>
+ <file alias="database-change-key">../share/icons/application/32x32/actions/database-change-key.png</file>
+ <file alias="database-lock">../share/icons/application/32x32/actions/database-lock.png</file>
+ <file alias="dialog-close">../share/icons/application/32x32/actions/dialog-close.png</file>
+ <file alias="dialog-ok">../share/icons/application/32x32/actions/dialog-ok.png</file>
+ <file alias="document-close">../share/icons/application/32x32/actions/document-close.png</file>
+ <file alias="document-edit">../share/icons/application/32x32/actions/document-edit.png</file>
+ <file alias="document-new">../share/icons/application/32x32/actions/document-new.png</file>
+ <file alias="document-open">../share/icons/application/32x32/actions/document-open.png</file>
+ <file alias="document-properties">../share/icons/application/32x32/actions/document-properties.png</file>
+ <file alias="document-save">../share/icons/application/32x32/actions/document-save.png</file>
+ <file alias="edit-clear-locationbar-ltr">../share/icons/application/32x32/actions/edit-clear-locationbar-ltr.png</file>
+ <file alias="edit-clear-locationbar-rtl">../share/icons/application/32x32/actions/edit-clear-locationbar-rtl.png</file>
+ <file alias="entry-clone">../share/icons/application/32x32/actions/entry-clone.png</file>
+ <file alias="entry-delete">../share/icons/application/32x32/actions/entry-delete.png</file>
+ <file alias="entry-edit">../share/icons/application/32x32/actions/entry-edit.png</file>
+ <file alias="entry-new">../share/icons/application/32x32/actions/entry-new.png</file>
+ <file alias="favicon-download">../share/icons/application/32x32/actions/favicon-download.png</file>
+ <file alias="group-empty-trash">../share/icons/application/32x32/actions/group-empty-trash.png</file>
+ <file alias="group-delete">../share/icons/application/16x16/actions/group-delete.png</file>
+ <file alias="group-new">../share/icons/application/16x16/actions/group-new.png</file>
+ <file alias="group-edit">../share/icons/application/16x16/actions/group-edit.png</file>
+ <file alias="help-about">../share/icons/application/32x32/actions/help-about.png</file>
+ <file alias="key-enter">../share/icons/application/32x32/actions/key-enter.png</file>
+ <file alias="paperclip">../share/icons/application/32x32/actions/paperclip.png</file>
+ <file alias="password-copy">../share/icons/application/32x32/actions/password-copy.png</file>
+ <file alias="password-generate">../share/icons/application/32x32/actions/password-generate.png</file>
+ <file alias="password-generator">../share/icons/application/32x32/actions/password-generator.png</file>
+ <file alias="password-show-off">../share/icons/application/32x32/actions/password-show-off.png</file>
+ <file alias="password-show-on">../share/icons/application/32x32/actions/password-show-on.png</file>
+ <file alias="statistics">../share/icons/application/32x32/actions/statistics.png</file>
+ <file alias="system-help">../share/icons/application/32x32/actions/system-help.png</file>
+ <file alias="system-search">../share/icons/application/32x32/actions/system-search.png</file>
+ <file alias="url-copy">../share/icons/application/32x32/actions/url-copy.png</file>
+ <file alias="username-copy">../share/icons/application/32x32/actions/username-copy.png</file>
+ <file alias="view-history">../share/icons/application/32x32/actions/view-history.png</file>
+ </qresource>
+</RCC>
diff --git a/src/qml/classic/main.qml b/src/qml/classic/main.qml
new file mode 100644
index 000000000..d548fa823
--- /dev/null
+++ b/src/qml/classic/main.qml
@@ -0,0 +1,423 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.7
+import QtQuick.Layouts 1.7
+
+ApplicationWindow {
+ title: "KeePassXC"
+ width: 900
+ height: 600
+ visible: true
+
+ menuBar: MenuBar {
+ Menu {
+ title: qsTr("&Database")
+ MenuItem { action: actionDatabaseNew; hoverEnabled: true }
+ MenuItem { action: actionDatabaseOpen; hoverEnabled: true }
+ Menu {
+ title: qsTr("&Recent databases")
+ }
+ MenuItem { action: actionDatabaseSave; hoverEnabled: true }
+ MenuItem { action: actionDatabaseSaveAs; hoverEnabled: true }
+ MenuItem { action: actionDatabaseClose; hoverEnabled: true }
+ MenuSeparator { }
+ MenuItem { action: actionChangeMasterKey; hoverEnabled: true }
+ MenuItem { action: actionChangeDatabaseSettings; hoverEnabled: true }
+ MenuSeparator { }
+ MenuItem { action: actionDatabaseMerge; hoverEnabled: true }
+ Menu {
+ title: qsTr("&Import")
+ MenuItem { action: actionImportKeePass1; hoverEnabled: true }
+ MenuItem { action: actionImportOpVault; hoverEnabled: true }
+ MenuItem { action: actionImportCsv; hoverEnabled: true }
+ }
+ Menu {
+ title: qsTr("&Export")
+ enabled: false
+ MenuItem { action: actionExportCsv; hoverEnabled: true }
+ MenuItem { action: actionExportHtml; hoverEnabled: true }
+ }
+ MenuItem { action: actionQuit }
+ }
+
+ Menu {
+ title: qsTr("E&ntries")
+ MenuItem { action: actionEntryNew; hoverEnabled: true }
+ MenuItem { action: actionEntryEdit; hoverEnabled: true }
+ MenuItem { action: actionEntryClone; hoverEnabled: true }
+ MenuItem { action: actionEntryDelete; hoverEnabled: true }
+ MenuSeparator { }
+ MenuItem { action: actionEntryCopyUsername; hoverEnabled: true }
+ MenuItem { action: actionEntryCopyPassword; hoverEnabled: true }
+ Menu {
+ title: qsTr("Copy att&ribute")
+ MenuItem { action: actionEntryCopyTitle; hoverEnabled: true }
+ MenuItem { action: actionEntryCopyUrl; hoverEnabled: true }
+ MenuItem { action: actionEntryCopyNotes; hoverEnabled: true }
+ }
+ Menu {
+ title: qsTr("TOTP")
+ MenuItem { action: actionEntryCopyTotp; hoverEnabled: true }
+ MenuItem { action: actionEntryTotp; hoverEnabled: true }
+ MenuItem { action: actionEntryTotpQRCode; hoverEnabled: true }
+ MenuItem { action: actionEntrySetupTotp; hoverEnabled: true }
+ }
+ MenuSeparator { }
+ MenuItem { action: actionEntryAutoType; hoverEnabled: true }
+ MenuSeparator { }
+ MenuItem { action: actionEntryOpenUrl; hoverEnabled: true }
+ MenuItem { action: actionEntryDownloadIcon; hoverEnabled: true }
+
+ }
+
+ Menu {
+ title: qsTr("&Groups")
+ MenuItem { action: actionGroupNew; hoverEnabled: true }
+ MenuItem { action: actionGroupEdit; hoverEnabled: true }
+ MenuItem { action: actionGroupDelete; hoverEnabled: true }
+ MenuSeparator { }
+ MenuItem { action: actionGroupDownloadFavicons; hoverEnabled: true }
+ MenuSeparator { }
+ MenuItem { action: actionGroupSortAsc; hoverEnabled: true }
+ MenuItem { action: actionGroupSortDesc; hoverEnabled: true }
+ }
+
+ Menu {
+ title: qsTr("&Tools")
+ MenuItem { action: actionLockDatabases; hoverEnabled: true }
+ MenuItem { action: actionPasswordGenerator; hoverEnabled: true }
+ MenuItem { action: actionSettings; hoverEnabled: true }
+ }
+
+ Menu {
+ title: qsTr("&Help")
+ MenuItem { action: actionGettingStarted; hoverEnabled: true }
+ MenuItem { action: actionUserGuide; hoverEnabled: true }
+ MenuItem { action: actionKeyboardShortcuts; hoverEnabled: true }
+ MenuItem { action: actionOnlineHelp; hoverEnabled: true }
+ MenuSeparator { }
+ MenuItem { action: actionCheckForUpdates; hoverEnabled: true }
+ MenuItem { action: actionDonate; hoverEnabled: true }
+ MenuItem { action: actionBugReport; hoverEnabled: true }
+ MenuSeparator { }
+ MenuItem { action: actionAbout; hoverEnabled: true }
+ }
+ }
+
+ header: ToolBar {
+ RowLayout {
+ anchors.fill: parent
+ ToolButton { action: actionDatabaseNew; display: AbstractButton.IconOnly }
+ ToolButton { action: actionDatabaseOpen; display: AbstractButton.IconOnly }
+ ToolButton { action: actionDatabaseSave; display: AbstractButton.IconOnly }
+ ToolSeparator { }
+ ToolButton { action: actionEntryNew; display: AbstractButton.IconOnly }
+ ToolButton { action: actionEntryEdit; display: AbstractButton.IconOnly }
+ ToolButton { action: actionEntryDelete; display: AbstractButton.IconOnly }
+ ToolSeparator { }
+ ToolButton { action: actionEntryCopyUsername; display: AbstractButton.IconOnly }
+ ToolButton { action: actionEntryCopyPassword; display: AbstractButton.IconOnly }
+ ToolButton { action: actionEntryCopyUrl; display: AbstractButton.IconOnly }
+ ToolButton { action: actionEntryAutoType; display: AbstractButton.IconOnly }
+ ToolSeparator { }
+ ToolButton { action: actionPasswordGenerator; display: AbstractButton.IconOnly }
+ ToolButton { action: actionLockDatabases; display: AbstractButton.IconOnly }
+ ToolButton { action: actionSettings; display: AbstractButton.IconOnly }
+ ToolSeparator { }
+ Item { Layout.fillWidth: true }
+ TextField {
+ placeholderText: qsTr("Search (Ctrl+F)")
+ Layout.preferredWidth: 300
+ leftPadding: 36
+ ToolButton { action: actionSearch; display: AbstractButton.IconOnly }
+ }
+ }
+ }
+
+ TabBar {
+ width: parent.width
+ TabButton {
+ text: "Database.kdbx"
+ }
+ }
+
+ // Database menu actions
+ Action {
+ id: actionDatabaseNew
+ text: qsTr("&New Database...")
+ shortcut: "Ctrl+Shift+N"
+ icon.name: "document-new"
+ icon.source: "qrc:/icons/document-new"
+ }
+ Action {
+ id: actionDatabaseOpen
+ text: qsTr("&Open Database...")
+ shortcut: StandardKey.Open
+ icon.name: "document-open"
+ icon.source: "qrc:/icons/document-open"
+ }
+ Action {
+ id: actionDatabaseSave
+ text: qsTr("&Save Database")
+ shortcut: StandardKey.Save
+ icon.name: "document-save"
+ icon.source: "qrc:/icons/document-save"
+ }
+ Action {
+ id: actionDatabaseSaveAs
+ text: qsTr("Sa&ve Database As...")
+ shortcut: StandardKey.SaveAs
+ icon.name: "document-save-as"
+ icon.source: "qrc:/icons/document-new"
+ }
+ Action {
+ id: actionDatabaseClose
+ text: qsTr("&Close Database")
+ shortcut: StandardKey.Close
+ icon.name: "document-close"
+ icon.source: "qrc:/icons/document-close"
+ }
+ Action {
+ id: actionChangeMasterKey
+ text: qsTr("Change Master &Key...")
+ icon.name: "database-change-key"
+ icon.source: "qrc:/icons/database-change-key"
+ }
+ Action {
+ id: actionChangeDatabaseSettings
+ text: qsTr("&Database Settings...")
+ icon.name: "document-edit"
+ icon.source: "qrc:/icons/document-edit"
+ }
+ Action {
+ id: actionDatabaseMerge
+ text: qsTr("&Merge From Database...")
+ icon.name: "document-edit"
+ icon.source: "qrc:/icons/document-edit"
+ }
+ Action {
+ id: actionImportKeePass1
+ text: qsTr("KeePass 1 Database...")
+ }
+ Action {
+ id: actionImportOpVault
+ text: qsTr("1Password OpVault...")
+ }
+ Action {
+ id: actionImportCsv
+ text: qsTr("CSV...")
+ }
+ Action {
+ id: actionExportCsv
+ text: qsTr("Export to CSV File...")
+ }
+ Action {
+ id: actionExportHtml
+ text: qsTr("Export to HTML File...")
+ }
+ Action {
+ id: actionQuit
+ text: qsTr("&Quit")
+ shortcut: StandardKey.Quit
+ icon.name: "application-exit"
+ icon.source: "qrc:/icons/application-exit"
+ }
+
+ // Edit menu actions
+ Action {
+ id: actionEntryNew
+ text: qsTr("&New Entry...")
+ shortcut: StandardKey.New
+ icon.name: "entry-new"
+ icon.source: "qrc:/icons/entry-new"
+ }
+ Action {
+ id: actionEntryEdit
+ text: qsTr("&Edit Entry...")
+ shortcut: "Ctrl+E"
+ icon.name: "entry-edit"
+ icon.source: "qrc:/icons/entry-edit"
+ }
+ Action {
+ id: actionEntryClone
+ text: qsTr("&Clone Entry...")
+ shortcut: "Ctrl+K"
+ icon.name: "entry-clone"
+ icon.source: "qrc:/icons/entry-clone"
+ }
+ Action {
+ id: actionEntryDelete
+ text: qsTr("&Delete Entry...")
+ shortcut: StandardKey.Delete
+ icon.name: "entry-delete"
+ icon.source: "qrc:/icons/entry-delete"
+ }
+ Action {
+ id: actionEntryCopyUsername
+ text: qsTr("Copy &Username")
+ shortcut: "Ctrl+B"
+ icon.name: "username-copy"
+ icon.source: "qrc:/icons/username-copy"
+ }
+ Action {
+ id: actionEntryCopyPassword
+ text: qsTr("Copy &Password")
+ shortcut: StandardKey.Copy
+ icon.name: "password-copy"
+ icon.source: "qrc:/icons/password-copy"
+ }
+ Action {
+ id: actionEntryCopyTitle
+ text: qsTr("&Title")
+ }
+ Action {
+ id: actionEntryCopyUrl
+ text: qsTr("&URL")
+ shortcut: "Ctr+U"
+ icon.name: "url-copy"
+ icon.source: "qrc:/icons/url-copy"
+ }
+ Action {
+ id: actionEntryCopyNotes
+ text: qsTr("&Notes")
+ }
+ Action {
+ id: actionEntryCopyTotp
+ text: qsTr("Copy &TOTP")
+ shortcut: "Ctrl+T"
+ }
+ Action {
+ id: actionEntryTotp
+ text: qsTr("Show TOTP...")
+ shortcut: "Ctrl+Shift+T"
+ }
+ Action {
+ id: actionEntryTotpQRCode
+ text: qsTr("Show TOTP QR Code...")
+ }
+ Action {
+ id: actionEntrySetupTotp
+ text: qsTr("Set up TOTP...")
+ }
+ Action {
+ id: actionEntryAutoType
+ text: qsTr("Perform &Auto-Type")
+ shortcut: "Ctrl+Shift+V"
+ icon.name: "auto-type"
+ icon.source: "qrc:/icons/auto-type"
+ }
+ Action {
+ id: actionEntryOpenUrl
+ text: qsTr("Open &URL")
+ shortcut: "Ctrl+Shift+U"
+ }
+ Action {
+ id: actionEntryDownloadIcon
+ text: qsTr("Download Favicon")
+ shortcut: "Ctrl+Shift+D"
+ icon.name: "favicon-download"
+ icon.source: "qrc:/icons/favicon-download"
+ }
+
+ // Groups menu actions
+ Action {
+ id: actionGroupNew
+ text: qsTr("&New Group...")
+ icon.name: "group-new"
+ icon.source: "qrc:/icons/group-new"
+ }
+ Action {
+ id: actionGroupEdit
+ text: qsTr("&Edit Group...")
+ icon.name: "group-edit"
+ icon.source: "qrc:/icons/group-edit"
+ }
+ Action {
+ id: actionGroupDelete
+ text: qsTr("&Delete Group...")
+ icon.name: "group-delete"
+ icon.source: "qrc:/icons/group-delete"
+ }
+ Action {
+ id: actionGroupDownloadFavicons
+ text: qsTr("Downlo&ad All Favicons...")
+ icon.name: "favicon-download"
+ icon.source: "qrc:/icons/favicon-download"
+ }
+ Action {
+ id: actionGroupSortAsc
+ text: qsTr("Sort &A-Z")
+ }
+ Action {
+ id: actionGroupSortDesc
+ text: qsTr("Sort &Z-A")
+ }
+
+ // Tools menu actions
+ Action {
+ id: actionLockDatabases
+ text: qsTr("&Lock Databases")
+ shortcut: "Ctrl+L"
+ icon.name: "database-lock"
+ icon.source: "qrc:/icons/database-lock"
+ }
+ Action {
+ id: actionPasswordGenerator
+ text: qsTr("&Password Generator...")
+ icon.name: "password-generator"
+ icon.source: "qrc:/icons/password-generator"
+ checkable: true
+ }
+ Action {
+ id: actionSettings
+ text: qsTr("&Settings...")
+ icon.name: "configure"
+ icon.source: "qrc:/icons/configure"
+ checkable: true
+ }
+
+ // Help menu actions
+ Action {
+ id: actionGettingStarted
+ text: qsTr("&Getting Started...")
+ }
+ Action {
+ id: actionUserGuide
+ text: qsTr("&User Guide...")
+ }
+ Action {
+ id: actionKeyboardShortcuts
+ text: qsTr("&Keyboard Shortcuts...")
+ shortcut: "Ctrl+/"
+ }
+ Action {
+ id: actionOnlineHelp
+ text: qsTr("&Online Help...")
+ }
+ Action {
+ id: actionCheckForUpdates
+ text: qsTr("&Check for Updates...")
+ icon.name: "system-software-update"
+ icon.source: "qrc:/icons/system-software-update"
+ }
+ Action {
+ id: actionDonate
+ text: qsTr("&Donate...")
+ }
+ Action {
+ id: actionBugReport
+ text: qsTr("&Report a Bug...")
+ }
+ Action {
+ id: actionAbout
+ text: qsTr("&About KeePassXC...")
+ icon.name: "help-about"
+ icon.source: "qrc:/icons/help-about"
+ }
+
+ // Search action
+ Action {
+ id: actionSearch
+ icon.name: "system-search"
+ icon.source: "qrc:/icons/system-search"
+ }
+}