Shortcuts manager.

This commit is contained in:
Roman Telezhynskyi 2023-10-23 16:57:22 +03:00
parent 6696c613c4
commit f620b24b56
50 changed files with 2075 additions and 161 deletions

View File

@ -50,6 +50,7 @@
- Puzzle app. Fix updating layout when file already opened. - Puzzle app. Fix updating layout when file already opened.
- Tape app. Custom measurement name. - Tape app. Custom measurement name.
- Tape app. Show variables in order they were added. - Tape app. Show variables in order they were added.
- Shortcuts manager.
# Valentina 0.7.52 September 12, 2022 # Valentina 0.7.52 September 12, 2022
- Fix crash when default locale is ru. - Fix crash when default locale is ru.

View File

@ -29,7 +29,9 @@
#include "puzzlepreferencesconfigurationpage.h" #include "puzzlepreferencesconfigurationpage.h"
#include "../../vpapplication.h" #include "../../vpapplication.h"
#include "../vganalytics/vganalytics.h" #include "../vganalytics/vganalytics.h"
#include "../vmisc/dialogs/vshortcutdialog.h"
#include "../vmisc/theme/vtheme.h" #include "../vmisc/theme/vtheme.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "ui_puzzlepreferencesconfigurationpage.h" #include "ui_puzzlepreferencesconfigurationpage.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
@ -79,6 +81,12 @@ PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *
//----------------------- Update //----------------------- Update
ui->checkBoxAutomaticallyCheckUpdates->setChecked(settings->IsAutomaticallyCheckUpdates()); ui->checkBoxAutomaticallyCheckUpdates->setChecked(settings->IsAutomaticallyCheckUpdates());
// Tab Shortcuts
InitShortcuts();
connect(ui->pushButtonRestoreDefaults, &QPushButton::clicked, this, [this]() { InitShortcuts(true); });
connect(ui->shortcutsTable, &QTableWidget::cellDoubleClicked, this,
&PuzzlePreferencesConfigurationPage::ShortcutCellDoubleClicked);
// Tab Scrolling // Tab Scrolling
ui->spinBoxDuration->setMinimum(VCommonSettings::scrollingDurationMin); ui->spinBoxDuration->setMinimum(VCommonSettings::scrollingDurationMin);
ui->spinBoxDuration->setMaximum(VCommonSettings::scrollingDurationMax); ui->spinBoxDuration->setMaximum(VCommonSettings::scrollingDurationMax);
@ -193,6 +201,19 @@ auto PuzzlePreferencesConfigurationPage::Apply() -> QStringList
} }
settings->SetSingleLineFonts(ui->checkBoxSingleLineFonts->isChecked()); settings->SetSingleLineFonts(ui->checkBoxSingleLineFonts->isChecked());
// Tab Shortcuts
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
const auto &shortcutsList = manager->GetShortcutsList();
for (int i = 0; i < m_transientShortcuts.length(); i++)
{
settings->SetActionShortcuts(VAbstractShortcutManager::ShortcutActionToString(shortcutsList.value(i).type),
m_transientShortcuts.value(i));
}
manager->UpdateShortcuts();
}
// Tab Scrolling // Tab Scrolling
settings->SetScrollingDuration(ui->spinBoxDuration->value()); settings->SetScrollingDuration(ui->spinBoxDuration->value());
settings->SetScrollingUpdateInterval(ui->spinBoxUpdateInterval->value()); settings->SetScrollingUpdateInterval(ui->spinBoxUpdateInterval->value());
@ -213,12 +234,27 @@ void PuzzlePreferencesConfigurationPage::changeEvent(QEvent *event)
if (event->type() == QEvent::LanguageChange) if (event->type() == QEvent::LanguageChange)
{ {
// retranslate designer form (single inheritance approach) // retranslate designer form (single inheritance approach)
RetranslateShortcutsTable();
ui->retranslateUi(this); ui->retranslateUi(this);
} }
// remember to call base class implementation // remember to call base class implementation
QWidget::changeEvent(event); QWidget::changeEvent(event);
} }
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesConfigurationPage::ShortcutCellDoubleClicked(int row, int column)
{
Q_UNUSED(column)
auto *shortcutDialog = new VShortcutDialog(row, this);
connect(shortcutDialog, &VShortcutDialog::ShortcutsListChanged, this,
[this](int index, const QStringList &stringListShortcuts)
{
m_transientShortcuts.replace(index, stringListShortcuts);
UpdateShortcutsTable();
});
shortcutDialog->open();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesConfigurationPage::SetThemeModeComboBox() void PuzzlePreferencesConfigurationPage::SetThemeModeComboBox()
{ {
@ -227,3 +263,75 @@ void PuzzlePreferencesConfigurationPage::SetThemeModeComboBox()
ui->comboBoxThemeMode->addItem(tr("Dark", "theme"), static_cast<int>(VThemeMode::Dark)); ui->comboBoxThemeMode->addItem(tr("Dark", "theme"), static_cast<int>(VThemeMode::Dark));
ui->comboBoxThemeMode->addItem(tr("Light", "theme"), static_cast<int>(VThemeMode::Light)); ui->comboBoxThemeMode->addItem(tr("Light", "theme"), static_cast<int>(VThemeMode::Light));
} }
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesConfigurationPage::InitShortcuts(bool defaults)
{
VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager();
if (manager == nullptr)
{
return;
}
manager->UpdateShortcuts();
m_transientShortcuts.clear();
ui->shortcutsTable->clearContents();
const auto &shortcutsList = manager->GetShortcutsList();
ui->shortcutsTable->setRowCount(static_cast<int>(shortcutsList.length()));
for (int i = 0; i < shortcutsList.length(); i++)
{
const VAbstractShortcutManager::VSShortcut &shortcut = shortcutsList.value(i);
// Add shortcut to transient shortcut list
if (defaults)
{
m_transientShortcuts.append(shortcut.defaultShortcuts);
}
else
{
m_transientShortcuts.append(shortcut.shortcuts);
}
// Add shortcut to table widget
auto *nameItem = new QTableWidgetItem();
nameItem->setText(VAbstractShortcutManager::ReadableName(shortcut.type));
ui->shortcutsTable->setItem(i, 0, nameItem);
auto *shortcutsItem = new QTableWidgetItem();
shortcutsItem->setText(VAbstractShortcutManager::StringListToReadableString(m_transientShortcuts.value(i)));
ui->shortcutsTable->setItem(i, 1, shortcutsItem);
}
UpdateShortcutsTable();
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesConfigurationPage::UpdateShortcutsTable()
{
for (int i = 0; i < m_transientShortcuts.length(); i++)
{
const QStringList &shortcuts = m_transientShortcuts.value(i);
ui->shortcutsTable->item(i, 1)->setText(VAbstractShortcutManager::StringListToReadableString(shortcuts));
}
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesConfigurationPage::RetranslateShortcutsTable()
{
VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager();
if (manager == nullptr)
{
return;
}
const auto &shortcutsList = manager->GetShortcutsList();
for (int i = 0; i < shortcutsList.length(); i++)
{
const VAbstractShortcutManager::VSShortcut &shortcut = shortcutsList.value(i);
if (QTableWidgetItem *it = ui->shortcutsTable->item(i, 0))
{
it->setText(VAbstractShortcutManager::ReadableName(shortcut.type));
}
}
}

View File

@ -52,13 +52,20 @@ public:
protected: protected:
void changeEvent(QEvent *event) override; void changeEvent(QEvent *event) override;
private slots:
void ShortcutCellDoubleClicked(int row, int column);
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(PuzzlePreferencesConfigurationPage) // NOLINT Q_DISABLE_COPY_MOVE(PuzzlePreferencesConfigurationPage) // NOLINT
Ui::PuzzlePreferencesConfigurationPage *ui; Ui::PuzzlePreferencesConfigurationPage *ui;
bool m_langChanged{false}; bool m_langChanged{false};
QList<QStringList> m_transientShortcuts{};
void SetThemeModeComboBox(); void SetThemeModeComboBox();
void InitShortcuts(bool defaults = false);
void UpdateShortcutsTable();
void RetranslateShortcutsTable();
}; };
#endif // PUZZLEPREFERENCESCONFIGURATIONPAGE_H #endif // PUZZLEPREFERENCESCONFIGURATIONPAGE_H

View File

@ -235,6 +235,87 @@ This option will take an affect after restart.</string>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabShortcuts">
<attribute name="title">
<string>Shortcuts</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<widget class="QTableWidget" name="shortcutsTable">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="rowCount">
<number>0</number>
</property>
<property name="columnCount">
<number>2</number>
</property>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>150</number>
</attribute>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Action</string>
</property>
</column>
<column>
<property name="text">
<string>Shortcuts</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonRestoreDefaults">
<property name="text">
<string>Restore defaults</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabScrolling"> <widget class="QWidget" name="tabScrolling">
<attribute name="title"> <attribute name="title">
<string>Scrolling</string> <string>Scrolling</string>

View File

@ -39,7 +39,8 @@ SOURCES += \
$$PWD/xml/vplayoutfilereader.cpp \ $$PWD/xml/vplayoutfilereader.cpp \
$$PWD/xml/vplayoutfilewriter.cpp \ $$PWD/xml/vplayoutfilewriter.cpp \
$$PWD/xml/vplayoutliterals.cpp \ $$PWD/xml/vplayoutliterals.cpp \
$$PWD/dialogs/dialogsavemanuallayout.cpp $$PWD/dialogs/dialogsavemanuallayout.cpp \
$$PWD/vpuzzleshortcutmanager.cpp
*msvc*:SOURCES += $$PWD/stable.cpp *msvc*:SOURCES += $$PWD/stable.cpp
@ -82,7 +83,8 @@ HEADERS += \
$$PWD/xml/vplayoutfilereader.h \ $$PWD/xml/vplayoutfilereader.h \
$$PWD/xml/vplayoutfilewriter.h \ $$PWD/xml/vplayoutfilewriter.h \
$$PWD/xml/vplayoutliterals.h \ $$PWD/xml/vplayoutliterals.h \
$$PWD/dialogs/dialogsavemanuallayout.h $$PWD/dialogs/dialogsavemanuallayout.h \
$$PWD/vpuzzleshortcutmanager.h
FORMS += \ FORMS += \
$$PWD/dialogs/configpages/puzzlepreferencesconfigurationpage.ui \ $$PWD/dialogs/configpages/puzzlepreferencesconfigurationpage.ui \

View File

@ -56,6 +56,8 @@ VToolApp {
"vpsettings.h", "vpsettings.h",
"vptilefactory.h", "vptilefactory.h",
"vpmainwindow.ui", "vpmainwindow.ui",
"vpuzzleshortcutmanager.cpp",
"vpuzzleshortcutmanager.h",
] ]
Group { Group {

View File

@ -40,6 +40,7 @@
#include "../vmisc/vsysexits.h" #include "../vmisc/vsysexits.h"
#include "version.h" #include "version.h"
#include "vpmainwindow.h" #include "vpmainwindow.h"
#include "vpuzzleshortcutmanager.h"
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QFileOpenEvent> #include <QFileOpenEvent>
@ -459,6 +460,8 @@ void VPApplication::InitOptions()
statistic->SetApiSecret(GA_API_SECRET); statistic->SetApiSecret(GA_API_SECRET);
statistic->SetRepoRevision(QLatin1String(BUILD_REVISION)); statistic->SetRepoRevision(QLatin1String(BUILD_REVISION));
statistic->Enable(settings->IsCollectStatistic()); statistic->Enable(settings->IsCollectStatistic());
m_shortcutManager = new VPuzzleShortcutManager(this);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -432,6 +432,12 @@ VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent)
{ {
QTimer::singleShot(V_SECONDS(1), this, &VPMainWindow::AskDefaultSettings); QTimer::singleShot(V_SECONDS(1), this, &VPMainWindow::AskDefaultSettings);
} }
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
connect(manager, &VAbstractShortcutManager::shortcutsUpdated, this, &VPMainWindow::UpdateShortcuts);
UpdateShortcuts();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -655,9 +661,10 @@ void VPMainWindow::SetupMenu()
// most of the actions are connected through name convention (auto-connection) // most of the actions are connected through name convention (auto-connection)
// File // File
// -------------------- connects the actions for the file menu // -------------------- connects the actions for the file menu
ui->actionNew->setShortcuts(QKeySequence::New); m_actionShortcuts.insert(VShortcutAction::New, ui->actionNew);
ui->actionSave->setShortcuts(QKeySequence::Save); m_actionShortcuts.insert(VShortcutAction::Open, ui->actionOpen);
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs); m_actionShortcuts.insert(VShortcutAction::Save, ui->actionSave);
m_actionShortcuts.insert(VShortcutAction::SaveAs, ui->actionSaveAs);
m_recentFileActs.fill(nullptr); m_recentFileActs.fill(nullptr);
for (auto &recentFileAct : m_recentFileActs) for (auto &recentFileAct : m_recentFileActs)
@ -689,7 +696,7 @@ void VPMainWindow::SetupMenu()
UpdateRecentFileActions(); UpdateRecentFileActions();
connect(ui->actionExit, &QAction::triggered, this, &VPMainWindow::close); connect(ui->actionExit, &QAction::triggered, this, &VPMainWindow::close);
ui->actionExit->setShortcuts(QKeySequence::Quit); m_actionShortcuts.insert(VShortcutAction::Quit, ui->actionExit);
// Layout // Layout
connect(ui->actionExportLayout, &QAction::triggered, this, &VPMainWindow::on_ExportLayout); connect(ui->actionExportLayout, &QAction::triggered, this, &VPMainWindow::on_ExportLayout);
@ -705,13 +712,13 @@ void VPMainWindow::SetupMenu()
// Add Undo/Redo actions. // Add Undo/Redo actions.
undoAction = m_layout->UndoStack()->createUndoAction(this, tr("&Undo")); undoAction = m_layout->UndoStack()->createUndoAction(this, tr("&Undo"));
undoAction->setShortcuts(QKeySequence::Undo); m_actionShortcuts.insert(VShortcutAction::Undo, undoAction);
undoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo"))); undoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo")));
ui->menuSheet->addAction(undoAction); ui->menuSheet->addAction(undoAction);
ui->toolBarUndoCommands->addAction(undoAction); ui->toolBarUndoCommands->addAction(undoAction);
redoAction = m_layout->UndoStack()->createRedoAction(this, tr("&Redo")); redoAction = m_layout->UndoStack()->createRedoAction(this, tr("&Redo"));
redoAction->setShortcuts(QKeySequence::Redo); m_actionShortcuts.insert(VShortcutAction::Redo, redoAction);
redoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-redo"))); redoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-redo")));
ui->menuSheet->addAction(redoAction); ui->menuSheet->addAction(redoAction);
ui->toolBarUndoCommands->addAction(redoAction); ui->toolBarUndoCommands->addAction(redoAction);
@ -1586,61 +1593,18 @@ void VPMainWindow::InitZoomToolBar()
delete m_mouseCoordinate; delete m_mouseCoordinate;
QT_WARNING_PUSH
#if !defined(Q_OS_MACOS) && defined(Q_CC_CLANG)
QT_WARNING_DISABLE_CLANG("-Wenum-enum-conversion")
#endif
// connect the zoom buttons and shortcuts to the slots // connect the zoom buttons and shortcuts to the slots
QList<QKeySequence> zoomInShortcuts; m_actionShortcuts.insert(VShortcutAction::ZoomIn, ui->actionZoomIn);
zoomInShortcuts.append(QKeySequence(QKeySequence::ZoomIn));
zoomInShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(QKeyCombination(Qt::ControlModifier), Qt::Key_Plus | Qt::KeypadModifier));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_Plus + Qt::KeypadModifier));
#endif
ui->actionZoomIn->setShortcuts(zoomInShortcuts);
connect(ui->actionZoomIn, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomIn); connect(ui->actionZoomIn, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomIn);
QList<QKeySequence> zoomOutShortcuts; m_actionShortcuts.insert(VShortcutAction::ZoomOut, ui->actionZoomOut);
zoomOutShortcuts.append(QKeySequence(QKeySequence::ZoomOut));
zoomOutShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(QKeyCombination(Qt::ControlModifier), Qt::Key_Minus | Qt::KeypadModifier));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_Minus + Qt::KeypadModifier));
#endif
ui->actionZoomOut->setShortcuts(zoomOutShortcuts);
connect(ui->actionZoomOut, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOut); connect(ui->actionZoomOut, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOut);
QList<QKeySequence> zoomOriginalShortcuts; m_actionShortcuts.insert(VShortcutAction::ZoomOriginal, ui->actionZoomOriginal);
zoomOriginalShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ControlModifier | Qt::Key_0));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_0));
#endif
zoomOriginalShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(QKeyCombination(Qt::ControlModifier), Qt::Key_0 | Qt::KeypadModifier));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_0 + Qt::KeypadModifier));
#endif
ui->actionZoomOriginal->setShortcuts(zoomOriginalShortcuts);
connect(ui->actionZoomOriginal, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOriginal); connect(ui->actionZoomOriginal, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOriginal);
QList<QKeySequence> zoomFitBestShortcuts; m_actionShortcuts.insert(VShortcutAction::ZoomFitBest, ui->actionZoomFitBest);
zoomFitBestShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ControlModifier | Qt::Key_Equal));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_Equal));
#endif
ui->actionZoomFitBest->setShortcuts(zoomFitBestShortcuts);
connect(ui->actionZoomFitBest, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomFitBest); connect(ui->actionZoomFitBest, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomFitBest);
QT_WARNING_POP
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -4762,6 +4726,15 @@ void VPMainWindow::LayoutWarningPiecesOutOfBound_toggled(bool checked)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::UpdateShortcuts()
{
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
manager->UpdateActionShortcuts(m_actionShortcuts);
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
void VPMainWindow::AboutToShowDockMenu() void VPMainWindow::AboutToShowDockMenu()

View File

@ -36,6 +36,7 @@
#include "../vlayout/dialogs/vabstractlayoutdialog.h" #include "../vlayout/dialogs/vabstractlayoutdialog.h"
#include "../vlayout/vlayoutpiece.h" #include "../vlayout/vlayoutpiece.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vlockguard.h" #include "../vmisc/vlockguard.h"
#include "../vwidgets/vabstractmainwindow.h" #include "../vwidgets/vabstractmainwindow.h"
#include "carousel/vpcarrousel.h" #include "carousel/vpcarrousel.h"
@ -294,6 +295,8 @@ private slots:
void LayoutWarningPiecesSuperposition_toggled(bool checked); void LayoutWarningPiecesSuperposition_toggled(bool checked);
void LayoutWarningPiecesOutOfBound_toggled(bool checked); void LayoutWarningPiecesOutOfBound_toggled(bool checked);
void UpdateShortcuts();
private: private:
Q_DISABLE_COPY_MOVE(VPMainWindow) // NOLINT Q_DISABLE_COPY_MOVE(VPMainWindow) // NOLINT
Ui::VPMainWindow *ui; Ui::VPMainWindow *ui;
@ -339,6 +342,8 @@ private:
QFileSystemWatcher *m_watermarkWatcher{nullptr}; QFileSystemWatcher *m_watermarkWatcher{nullptr};
QMultiHash<VShortcutAction, QAction *> m_actionShortcuts{};
struct VPLayoutPrinterPage struct VPLayoutPrinterPage
{ {
VPSheetPtr sheet{}; VPSheetPtr sheet{};

View File

@ -0,0 +1,59 @@
/************************************************************************
**
** @file vpuzzleshortcutmanager.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 23 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vpuzzleshortcutmanager.h"
VPuzzleShortcutManager::VPuzzleShortcutManager(QObject *parent)
: VAbstractShortcutManager{parent}
{
QT_WARNING_PUSH
#if !defined(Q_OS_MACOS) && defined(Q_CC_CLANG)
QT_WARNING_DISABLE_CLANG("-Wenum-enum-conversion")
#endif
AddShortcut({VShortcutAction::New, KeyBindingsToStringList(QKeySequence::New), {}});
AddShortcut({VShortcutAction::Open, KeyBindingsToStringList(QKeySequence::Open), {}});
AddShortcut({VShortcutAction::Save, KeyBindingsToStringList(QKeySequence::Save), {}});
AddShortcut({VShortcutAction::SaveAs, KeyBindingsToStringList(QKeySequence::SaveAs), {}});
AddShortcut({VShortcutAction::Undo, KeyBindingsToStringList(QKeySequence::Undo), {}});
AddShortcut({VShortcutAction::Redo, KeyBindingsToStringList(QKeySequence::Redo), {}});
AddShortcut({VShortcutAction::ZoomIn, KeyBindingsToStringList(QKeySequence::ZoomIn), {}});
AddShortcut({VShortcutAction::ZoomOut, KeyBindingsToStringList(QKeySequence::ZoomOut), {}});
AddShortcut({VShortcutAction::ZoomOriginal,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_0).toString(),
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ControlModifier + Qt::Key_0 + Qt::KeypadModifier).toString()
#endif
},
{}});
AddShortcut({VShortcutAction::ZoomFitBest,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_Equal).toString()},
{}});
AddShortcut({VShortcutAction::Quit, KeyBindingsToStringList(QKeySequence::Quit), {}});
QT_WARNING_POP
}

View File

@ -0,0 +1,49 @@
/************************************************************************
**
** @file vpuzzleshortcutmanager.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 23 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPUZZLESHORTCUTMANAGER_H
#define VPUZZLESHORTCUTMANAGER_H
#include "../vmisc/vabstractshortcutmanager.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
#include "../vmisc/defglobal.h"
#endif
class VPuzzleShortcutManager : public VAbstractShortcutManager
{
Q_OBJECT // NOLINT
public:
explicit VPuzzleShortcutManager(QObject *parent = nullptr);
~VPuzzleShortcutManager() override = default;
private:
Q_DISABLE_COPY_MOVE(VPuzzleShortcutManager) // NOLINT
};
#endif // VPUZZLESHORTCUTMANAGER_H

View File

@ -31,7 +31,9 @@
#include "../../vtapesettings.h" #include "../../vtapesettings.h"
#include "../qmuparser/qmudef.h" #include "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h" #include "../vganalytics/vganalytics.h"
#include "../vmisc/dialogs/vshortcutdialog.h"
#include "../vmisc/theme/vtheme.h" #include "../vmisc/theme/vtheme.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vpatterndb/pmsystems.h" #include "../vpatterndb/pmsystems.h"
#include "ui_tapepreferencesconfigurationpage.h" #include "ui_tapepreferencesconfigurationpage.h"
@ -105,6 +107,12 @@ TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *pare
//----------------------- Update //----------------------- Update
ui->checkBoxAutomaticallyCheckUpdates->setChecked(settings->IsAutomaticallyCheckUpdates()); ui->checkBoxAutomaticallyCheckUpdates->setChecked(settings->IsAutomaticallyCheckUpdates());
// Tab Shortcuts
InitShortcuts();
connect(ui->pushButtonRestoreDefaults, &QPushButton::clicked, this, [this]() { InitShortcuts(true); });
connect(ui->shortcutsTable, &QTableWidget::cellDoubleClicked, this,
&TapePreferencesConfigurationPage::ShortcutCellDoubleClicked);
// Tab Privacy // Tab Privacy
ui->checkBoxSendUsageStatistics->setChecked(settings->IsCollectStatistic()); ui->checkBoxSendUsageStatistics->setChecked(settings->IsCollectStatistic());
} }
@ -181,6 +189,19 @@ auto TapePreferencesConfigurationPage::Apply() -> QStringList
settings->SetAutomaticallyCheckUpdates(ui->checkBoxAutomaticallyCheckUpdates->isChecked()); settings->SetAutomaticallyCheckUpdates(ui->checkBoxAutomaticallyCheckUpdates->isChecked());
} }
// Tab Shortcuts
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
const auto &shortcutsList = manager->GetShortcutsList();
for (int i = 0; i < m_transientShortcuts.length(); i++)
{
settings->SetActionShortcuts(VAbstractShortcutManager::ShortcutActionToString(shortcutsList.value(i).type),
m_transientShortcuts.value(i));
}
manager->UpdateShortcuts();
}
// Tab Privacy // Tab Privacy
settings->SetCollectStatistic(ui->checkBoxSendUsageStatistics->isChecked()); settings->SetCollectStatistic(ui->checkBoxSendUsageStatistics->isChecked());
VGAnalytics::Instance()->Enable(ui->checkBoxSendUsageStatistics->isChecked()); VGAnalytics::Instance()->Enable(ui->checkBoxSendUsageStatistics->isChecked());
@ -201,6 +222,20 @@ void TapePreferencesConfigurationPage::changeEvent(QEvent *event)
QWidget::changeEvent(event); QWidget::changeEvent(event);
} }
//---------------------------------------------------------------------------------------------------------------------
void TapePreferencesConfigurationPage::ShortcutCellDoubleClicked(int row, int column)
{
Q_UNUSED(column)
auto *shortcutDialog = new VShortcutDialog(row, this);
connect(shortcutDialog, &VShortcutDialog::ShortcutsListChanged, this,
[this](int index, const QStringList &stringListShortcuts)
{
m_transientShortcuts.replace(index, stringListShortcuts);
UpdateShortcutsTable();
});
shortcutDialog->open();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void TapePreferencesConfigurationPage::RetranslateUi() void TapePreferencesConfigurationPage::RetranslateUi()
{ {
@ -215,6 +250,8 @@ void TapePreferencesConfigurationPage::RetranslateUi()
ui->systemCombo->blockSignals(false); ui->systemCombo->blockSignals(false);
ui->systemCombo->setCurrentIndex(ui->systemCombo->findData(code)); ui->systemCombo->setCurrentIndex(ui->systemCombo->findData(code));
} }
RetranslateShortcutsTable();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -225,3 +262,75 @@ void TapePreferencesConfigurationPage::SetThemeModeComboBox()
ui->comboBoxThemeMode->addItem(tr("Dark", "theme"), static_cast<int>(VThemeMode::Dark)); ui->comboBoxThemeMode->addItem(tr("Dark", "theme"), static_cast<int>(VThemeMode::Dark));
ui->comboBoxThemeMode->addItem(tr("Light", "theme"), static_cast<int>(VThemeMode::Light)); ui->comboBoxThemeMode->addItem(tr("Light", "theme"), static_cast<int>(VThemeMode::Light));
} }
//---------------------------------------------------------------------------------------------------------------------
void TapePreferencesConfigurationPage::InitShortcuts(bool defaults)
{
VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager();
if (manager == nullptr)
{
return;
}
manager->UpdateShortcuts();
m_transientShortcuts.clear();
ui->shortcutsTable->clearContents();
const auto &shortcutsList = manager->GetShortcutsList();
ui->shortcutsTable->setRowCount(static_cast<int>(shortcutsList.length()));
for (int i = 0; i < shortcutsList.length(); i++)
{
const VAbstractShortcutManager::VSShortcut &shortcut = shortcutsList.value(i);
// Add shortcut to transient shortcut list
if (defaults)
{
m_transientShortcuts.append(shortcut.defaultShortcuts);
}
else
{
m_transientShortcuts.append(shortcut.shortcuts);
}
// Add shortcut to table widget
auto *nameItem = new QTableWidgetItem();
nameItem->setText(VAbstractShortcutManager::ReadableName(shortcut.type));
ui->shortcutsTable->setItem(i, 0, nameItem);
auto *shortcutsItem = new QTableWidgetItem();
shortcutsItem->setText(VAbstractShortcutManager::StringListToReadableString(m_transientShortcuts.value(i)));
ui->shortcutsTable->setItem(i, 1, shortcutsItem);
}
UpdateShortcutsTable();
}
//---------------------------------------------------------------------------------------------------------------------
void TapePreferencesConfigurationPage::UpdateShortcutsTable()
{
for (int i = 0; i < m_transientShortcuts.length(); i++)
{
const QStringList &shortcuts = m_transientShortcuts.value(i);
ui->shortcutsTable->item(i, 1)->setText(VAbstractShortcutManager::StringListToReadableString(shortcuts));
}
}
//---------------------------------------------------------------------------------------------------------------------
void TapePreferencesConfigurationPage::RetranslateShortcutsTable()
{
VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager();
if (manager == nullptr)
{
return;
}
const auto &shortcutsList = manager->GetShortcutsList();
for (int i = 0; i < shortcutsList.length(); i++)
{
const VAbstractShortcutManager::VSShortcut &shortcut = shortcutsList.value(i);
if (QTableWidgetItem *it = ui->shortcutsTable->item(i, 0))
{
it->setText(VAbstractShortcutManager::ReadableName(shortcut.type));
}
}
}

View File

@ -53,15 +53,22 @@ public:
protected: protected:
void changeEvent(QEvent *event) override; void changeEvent(QEvent *event) override;
private slots:
void ShortcutCellDoubleClicked(int row, int column);
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(TapePreferencesConfigurationPage) // NOLINT Q_DISABLE_COPY_MOVE(TapePreferencesConfigurationPage) // NOLINT
Ui::TapePreferencesConfigurationPage *ui; Ui::TapePreferencesConfigurationPage *ui;
bool m_langChanged; bool m_langChanged;
bool m_systemChanged; bool m_systemChanged;
QList<QStringList> m_transientShortcuts{};
void RetranslateUi(); void RetranslateUi();
void SetThemeModeComboBox(); void SetThemeModeComboBox();
void InitShortcuts(bool defaults = false);
void UpdateShortcutsTable();
void RetranslateShortcutsTable();
}; };
#endif // TAPEPREFERENCESCONFIGURATIONPAGE_H #endif // TAPEPREFERENCESCONFIGURATIONPAGE_H

View File

@ -249,6 +249,87 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabShortcuts">
<attribute name="title">
<string>Shortcuts</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QTableWidget" name="shortcutsTable">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="rowCount">
<number>0</number>
</property>
<property name="columnCount">
<number>2</number>
</property>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>150</number>
</attribute>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Action</string>
</property>
</column>
<column>
<property name="text">
<string>Shortcuts</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonRestoreDefaults">
<property name="text">
<string>Restore defaults</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabPrivacy"> <widget class="QWidget" name="tabPrivacy">
<attribute name="title"> <attribute name="title">
<string>Privacy</string> <string>Privacy</string>

View File

@ -42,6 +42,7 @@
#include "../vmisc/vsysexits.h" #include "../vmisc/vsysexits.h"
#include "tmainwindow.h" #include "tmainwindow.h"
#include "version.h" #include "version.h"
#include "vtapeshortcutmanager.h"
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QDir> #include <QDir>
@ -504,6 +505,8 @@ void MApplication::InitOptions()
statistic->SetApiSecret(GA_API_SECRET); statistic->SetApiSecret(GA_API_SECRET);
statistic->SetRepoRevision(QLatin1String(BUILD_REVISION)); statistic->SetRepoRevision(QLatin1String(BUILD_REVISION));
statistic->Enable(settings->IsCollectStatistic()); statistic->Enable(settings->IsCollectStatistic());
m_shortcutManager = new VTapeShortcutManager(this);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -16,7 +16,8 @@ SOURCES += \
$$PWD/dialogs/dialogtapepreferences.cpp \ $$PWD/dialogs/dialogtapepreferences.cpp \
$$PWD/dialogs/configpages/tapepreferencesconfigurationpage.cpp \ $$PWD/dialogs/configpages/tapepreferencesconfigurationpage.cpp \
$$PWD/vtapesettings.cpp \ $$PWD/vtapesettings.cpp \
$$PWD/dialogs/dialogsetupmultisize.cpp $$PWD/dialogs/dialogsetupmultisize.cpp \
$$PWD/vtapeshortcutmanager.cpp
*msvc*:SOURCES += $$PWD/stable.cpp *msvc*:SOURCES += $$PWD/stable.cpp
@ -36,7 +37,8 @@ HEADERS += \
$$PWD/dialogs/dialogtapepreferences.h \ $$PWD/dialogs/dialogtapepreferences.h \
$$PWD/dialogs/configpages/tapepreferencesconfigurationpage.h \ $$PWD/dialogs/configpages/tapepreferencesconfigurationpage.h \
$$PWD/vtapesettings.h \ $$PWD/vtapesettings.h \
$$PWD/dialogs/dialogsetupmultisize.h $$PWD/dialogs/dialogsetupmultisize.h \
$$PWD/vtapeshortcutmanager.h
FORMS += \ FORMS += \
$$PWD/dialogs/dialogdimensioncustomnames.ui \ $$PWD/dialogs/dialogdimensioncustomnames.ui \

View File

@ -62,6 +62,8 @@ VToolApp {
"vlitepattern.h", "vlitepattern.h",
"vtapesettings.h", "vtapesettings.h",
"tmainwindow.ui", "tmainwindow.ui",
"vtapeshortcutmanager.cpp",
"vtapeshortcutmanager.h",
] ]
Group { Group {

View File

@ -316,6 +316,20 @@ TMainWindow::TMainWindow(QWidget *parent)
{ {
QTimer::singleShot(V_SECONDS(1), this, &TMainWindow::AskDefaultSettings); QTimer::singleShot(V_SECONDS(1), this, &TMainWindow::AskDefaultSettings);
} }
m_buttonShortcuts.insert(VShortcutAction::CaseSensitiveMatch, ui->toolButtonCaseSensitive);
m_buttonShortcuts.insert(VShortcutAction::WholeWordMatch, ui->toolButtonWholeWord);
m_buttonShortcuts.insert(VShortcutAction::RegexMatch, ui->toolButtonRegexp);
m_buttonShortcuts.insert(VShortcutAction::SearchHistory, ui->pushButtonSearch);
m_buttonShortcuts.insert(VShortcutAction::RegexMatchUnicodeProperties, ui->toolButtonUseUnicodeProperties);
m_buttonShortcuts.insert(VShortcutAction::FindNext, ui->toolButtonFindNext);
m_buttonShortcuts.insert(VShortcutAction::FindPrevious, ui->toolButtonFindNext);
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
connect(manager, &VAbstractShortcutManager::shortcutsUpdated, this, &TMainWindow::UpdateShortcuts);
UpdateShortcuts();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -2864,12 +2878,23 @@ void TMainWindow::AskDefaultSettings()
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::UpdateShortcuts()
{
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
manager->UpdateButtonShortcut(m_buttonShortcuts);
manager->UpdateActionShortcuts(m_actionShortcuts);
UpdateSearchControlsTooltips();
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void TMainWindow::SetupMenu() void TMainWindow::SetupMenu()
{ {
// File // File
connect(ui->actionNew, &QAction::triggered, this, &TMainWindow::FileNew); connect(ui->actionNew, &QAction::triggered, this, &TMainWindow::FileNew);
ui->actionNew->setShortcuts(QKeySequence::New); m_actionShortcuts.insert(VShortcutAction::New, ui->actionNew);
connect(ui->actionOpenIndividual, &QAction::triggered, this, &TMainWindow::OpenIndividual); connect(ui->actionOpenIndividual, &QAction::triggered, this, &TMainWindow::OpenIndividual);
connect(ui->actionOpenMultisize, &QAction::triggered, this, &TMainWindow::OpenMultisize); connect(ui->actionOpenMultisize, &QAction::triggered, this, &TMainWindow::OpenMultisize);
@ -2877,10 +2902,10 @@ void TMainWindow::SetupMenu()
connect(ui->actionCreateFromExisting, &QAction::triggered, this, &TMainWindow::CreateFromExisting); connect(ui->actionCreateFromExisting, &QAction::triggered, this, &TMainWindow::CreateFromExisting);
connect(ui->actionSave, &QAction::triggered, this, &TMainWindow::FileSave); connect(ui->actionSave, &QAction::triggered, this, &TMainWindow::FileSave);
ui->actionSave->setShortcuts(QKeySequence::Save); m_actionShortcuts.insert(VShortcutAction::Save, ui->actionSave);
connect(ui->actionSaveAs, &QAction::triggered, this, &TMainWindow::FileSaveAs); connect(ui->actionSaveAs, &QAction::triggered, this, &TMainWindow::FileSaveAs);
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs); m_actionShortcuts.insert(VShortcutAction::SaveAs, ui->actionSaveAs);
connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportDataToCSV); connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportDataToCSV);
connect(ui->actionImportFromCSV, &QAction::triggered, this, &TMainWindow::ImportDataFromCSV); connect(ui->actionImportFromCSV, &QAction::triggered, this, &TMainWindow::ImportDataFromCSV);
@ -2930,7 +2955,7 @@ void TMainWindow::SetupMenu()
ui->menuFile->insertAction(ui->actionPreferences, m_separatorAct); ui->menuFile->insertAction(ui->actionPreferences, m_separatorAct);
connect(ui->actionQuit, &QAction::triggered, this, &TMainWindow::close); connect(ui->actionQuit, &QAction::triggered, this, &TMainWindow::close);
ui->actionQuit->setShortcuts(QKeySequence::Quit); m_actionShortcuts.insert(VShortcutAction::Quit, ui->actionQuit);
// Measurements // Measurements
connect(ui->actionAddCustom, &QAction::triggered, this, &TMainWindow::AddCustom); connect(ui->actionAddCustom, &QAction::triggered, this, &TMainWindow::AddCustom);
@ -5043,12 +5068,18 @@ void TMainWindow::SaveSearchRequest()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void TMainWindow::UpdateSearchControlsTooltips() void TMainWindow::UpdateSearchControlsTooltips()
{ {
auto UpdateToolTip = [](QAbstractButton *button) auto UpdateToolTip = [this](QAbstractButton *button)
{ {
if (button->toolTip().contains("%1"_L1)) if (button->toolTip().contains("%1"_L1))
{ {
m_serachButtonTooltips.insert(button, button->toolTip());
button->setToolTip(button->toolTip().arg(button->shortcut().toString(QKeySequence::NativeText))); button->setToolTip(button->toolTip().arg(button->shortcut().toString(QKeySequence::NativeText)));
} }
else if (m_serachButtonTooltips.contains(button))
{
QString tooltip = m_serachButtonTooltips.value(button);
button->setToolTip(tooltip.arg(button->shortcut().toString(QKeySequence::NativeText)));
}
}; };
UpdateToolTip(ui->toolButtonCaseSensitive); UpdateToolTip(ui->toolButtonCaseSensitive);

View File

@ -35,6 +35,7 @@
#include "../vformat/vmeasurements.h" #include "../vformat/vmeasurements.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vlockguard.h" #include "../vmisc/vlockguard.h"
#include "../vmisc/vtablesearch.h" #include "../vmisc/vtablesearch.h"
#include "../vwidgets/vabstractmainwindow.h" #include "../vwidgets/vabstractmainwindow.h"
@ -47,6 +48,7 @@ class TMainWindow;
class QLabel; class QLabel;
class QxtCsvModel; class QxtCsvModel;
class VMeasurement; class VMeasurement;
class QAbstractButton;
class TMainWindow : public VAbstractMainWindow class TMainWindow : public VAbstractMainWindow
{ {
@ -155,6 +157,8 @@ private slots:
void AskDefaultSettings(); void AskDefaultSettings();
void UpdateShortcuts();
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(TMainWindow) // NOLINT Q_DISABLE_COPY_MOVE(TMainWindow) // NOLINT
@ -201,6 +205,10 @@ private:
QString description{}; // NOLINT(misc-non-private-member-variables-in-classes) QString description{}; // NOLINT(misc-non-private-member-variables-in-classes)
}; };
QMultiHash<VShortcutAction, QAction *> m_actionShortcuts{};
QMultiHash<VShortcutAction, QAbstractButton *> m_buttonShortcuts{};
QHash<QAbstractButton *, QString> m_serachButtonTooltips{};
void SetupMenu(); void SetupMenu();
void InitWindow(); void InitWindow();
void InitMenu(); void InitMenu();

View File

@ -0,0 +1,59 @@
/************************************************************************
**
** @file vtapeshortcutmanager.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 23 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vtapeshortcutmanager.h"
VTapeShortcutManager::VTapeShortcutManager(QObject *parent)
: VAbstractShortcutManager{parent}
{
QT_WARNING_PUSH
#if !defined(Q_OS_MACOS) && defined(Q_CC_CLANG)
QT_WARNING_DISABLE_CLANG("-Wenum-enum-conversion")
#endif
AddShortcut({VShortcutAction::New, KeyBindingsToStringList(QKeySequence::New), {}});
AddShortcut({VShortcutAction::Save, KeyBindingsToStringList(QKeySequence::Save), {}});
AddShortcut({VShortcutAction::SaveAs, KeyBindingsToStringList(QKeySequence::SaveAs), {}});
AddShortcut({VShortcutAction::Quit, KeyBindingsToStringList(QKeySequence::Quit), {}});
AddShortcut({VShortcutAction::CaseSensitiveMatch,
{QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_C).toString()},
{}});
AddShortcut(
{VShortcutAction::WholeWordMatch, {QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_W).toString()}, {}});
AddShortcut(
{VShortcutAction::RegexMatch, {QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_X).toString()}, {}});
AddShortcut(
{VShortcutAction::SearchHistory, {QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_Down).toString()}, {}});
AddShortcut({VShortcutAction::RegexMatchUnicodeProperties,
{QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_U).toString()},
{}});
AddShortcut({VShortcutAction::FindNext, {QKeySequence(Qt::Key_F3).toString()}, {}});
AddShortcut(
{VShortcutAction::FindPrevious, {QKeySequence(Qt::ShiftModifier QKEY_SEQUENCE_OP Qt::Key_F3).toString()}, {}});
QT_WARNING_POP
}

View File

@ -0,0 +1,49 @@
/************************************************************************
**
** @file vtapeshortcutmanager.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 23 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VTAPESHORTCUTMANAGER_H
#define VTAPESHORTCUTMANAGER_H
#include "../vmisc/vabstractshortcutmanager.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
#include "../vmisc/defglobal.h"
#endif
class VTapeShortcutManager : public VAbstractShortcutManager
{
Q_OBJECT // NOLINT
public:
explicit VTapeShortcutManager(QObject *parent = nullptr);
~VTapeShortcutManager() override = default;
private:
Q_DISABLE_COPY_MOVE(VTapeShortcutManager) // NOLINT
};
#endif // VTAPESHORTCUTMANAGER_H

View File

@ -42,6 +42,7 @@
#include "../vmisc/theme/vtheme.h" #include "../vmisc/theme/vtheme.h"
#include "../vmisc/vsysexits.h" #include "../vmisc/vsysexits.h"
#include "../vmisc/vvalentinasettings.h" #include "../vmisc/vvalentinasettings.h"
#include "vvalentinashortcutmanager.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
#include "../vmisc/backport/text.h" #include "../vmisc/backport/text.h"
@ -53,6 +54,7 @@
#include <QIcon> #include <QIcon>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QMessageBox> #include <QMessageBox>
#include <QObject>
#include <QProcess> #include <QProcess>
#include <QStandardPaths> #include <QStandardPaths>
#include <QStyleFactory> #include <QStyleFactory>
@ -704,6 +706,8 @@ void VApplication::InitOptions()
VTheme::InitApplicationStyle(); VTheme::InitApplicationStyle();
VTheme::SetIconTheme(); VTheme::SetIconTheme();
VTheme::InitThemeMode(); VTheme::InitThemeMode();
m_shortcutManager = new VValentinaShortcutManager(this);
} }
auto *statistic = VGAnalytics::Instance(); auto *statistic = VGAnalytics::Instance();

View File

@ -0,0 +1,124 @@
/************************************************************************
**
** @file vvalentinashortcutmanager.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 20 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vvalentinashortcutmanager.h"
#include "qnamespace.h"
#include "vabstractshortcutmanager.h"
#include <QKeySequence>
//---------------------------------------------------------------------------------------------------------------------
VValentinaShortcutManager::VValentinaShortcutManager(QObject *parent)
: VAbstractShortcutManager{parent}
{
QT_WARNING_PUSH
#if !defined(Q_OS_MACOS) && defined(Q_CC_CLANG)
QT_WARNING_DISABLE_CLANG("-Wenum-enum-conversion")
#endif
AddShortcut({VShortcutAction::ZoomIn, KeyBindingsToStringList(QKeySequence::ZoomIn), {}});
AddShortcut({VShortcutAction::ZoomOut, KeyBindingsToStringList(QKeySequence::ZoomOut), {}});
AddShortcut({VShortcutAction::ZoomOriginal,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_0).toString(),
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ControlModifier + Qt::Key_0 + Qt::KeypadModifier).toString()
#endif
},
{}});
AddShortcut({VShortcutAction::ZoomFitBest,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_Equal).toString()},
{}});
AddShortcut({VShortcutAction::ZoomFitBestCurrent,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_M).toString()},
{}});
AddShortcut({VShortcutAction::IncreaseLabelFont,
{QKeySequence(Qt::ShiftModifier QKEY_SEQUENCE_OP Qt::Key_Plus).toString()},
{}});
AddShortcut({VShortcutAction::DecreaseLabelFont,
{QKeySequence(Qt::ShiftModifier QKEY_SEQUENCE_OP Qt::Key_Minus).toString()},
{}});
AddShortcut({VShortcutAction::OriginalLabelFont,
{QKeySequence(Qt::ShiftModifier QKEY_SEQUENCE_OP Qt::Key_0).toString()},
{}});
AddShortcut(
{VShortcutAction::HideLabels, {QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_L).toString()}, {}});
AddShortcut({VShortcutAction::Undo, KeyBindingsToStringList(QKeySequence::Undo), {}});
AddShortcut({VShortcutAction::Redo, KeyBindingsToStringList(QKeySequence::Redo), {}});
AddShortcut({VShortcutAction::New, KeyBindingsToStringList(QKeySequence::New), {}});
AddShortcut({VShortcutAction::Open, KeyBindingsToStringList(QKeySequence::Open), {}});
AddShortcut({VShortcutAction::Save, KeyBindingsToStringList(QKeySequence::Save), {}});
AddShortcut({VShortcutAction::SaveAs, KeyBindingsToStringList(QKeySequence::SaveAs), {}});
AddShortcut(
{VShortcutAction::DrawMode, {QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_W).toString()}, {}});
AddShortcut(
{VShortcutAction::DetailsMode, {QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_E).toString()}, {}});
AddShortcut(
{VShortcutAction::LayoutMode, {QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_L).toString()}, {}});
AddShortcut(
{VShortcutAction::NewPatternPiece,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::ShiftModifier QKEY_SEQUENCE_OP Qt::Key_N).toString()},
{}});
AddShortcut({VShortcutAction::NextPatternPiece,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_PageDown).toString()},
{}});
AddShortcut({VShortcutAction::PreviusPatternPiece,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_PageUp).toString()},
{}});
AddShortcut({VShortcutAction::InteractiveTools,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_D).toString()},
{}});
AddShortcut({VShortcutAction::TableOfVariables,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_T).toString()},
{}});
AddShortcut({VShortcutAction::PatternHistory,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_H).toString()},
{}});
AddShortcut({VShortcutAction::Quit, KeyBindingsToStringList(QKeySequence::Quit), {}});
AddShortcut({VShortcutAction::LastTool, {QKeySequence(Qt::Key_L).toString()}, {}});
AddShortcut({VShortcutAction::CurveDetails, {QKeySequence(Qt::Key_F2).toString()}, {}});
AddShortcut({VShortcutAction::FinalMeasurements,
{QKeySequence(Qt::ControlModifier QKEY_SEQUENCE_OP Qt::Key_I).toString()},
{}});
AddShortcut({VShortcutAction::CaseSensitiveMatch,
{QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_C).toString()},
{}});
AddShortcut(
{VShortcutAction::WholeWordMatch, {QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_W).toString()}, {}});
AddShortcut(
{VShortcutAction::RegexMatch, {QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_X).toString()}, {}});
AddShortcut(
{VShortcutAction::SearchHistory, {QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_Down).toString()}, {}});
AddShortcut({VShortcutAction::RegexMatchUnicodeProperties,
{QKeySequence(Qt::AltModifier QKEY_SEQUENCE_OP Qt::Key_U).toString()},
{}});
AddShortcut({VShortcutAction::FindNext, {QKeySequence(Qt::Key_F3).toString()}, {}});
AddShortcut(
{VShortcutAction::FindPrevious, {QKeySequence(Qt::ShiftModifier QKEY_SEQUENCE_OP Qt::Key_F3).toString()}, {}});
QT_WARNING_POP
}

View File

@ -0,0 +1,49 @@
/************************************************************************
**
** @file vvalentinashortcutmanager.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 20 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VVALENTINASHORTCUTMANAGER_H
#define VVALENTINASHORTCUTMANAGER_H
#include "../vmisc/vabstractshortcutmanager.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
#include "../vmisc/defglobal.h"
#endif
class VValentinaShortcutManager : public VAbstractShortcutManager
{
Q_OBJECT // NOLINT
public:
explicit VValentinaShortcutManager(QObject *parent = nullptr);
~VValentinaShortcutManager() override = default;
private:
Q_DISABLE_COPY_MOVE(VValentinaShortcutManager) // NOLINT
};
#endif // VVALENTINASHORTCUTMANAGER_H

View File

@ -30,10 +30,13 @@
#include "../../core/vapplication.h" #include "../../core/vapplication.h"
#include "../qmuparser/qmudef.h" #include "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h" #include "../vganalytics/vganalytics.h"
#include "../vmisc/dialogs/vshortcutdialog.h"
#include "../vmisc/literals.h" #include "../vmisc/literals.h"
#include "../vmisc/theme/vtheme.h" #include "../vmisc/theme/vtheme.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vvalentinasettings.h" #include "../vmisc/vvalentinasettings.h"
#include "../vpatterndb/pmsystems.h" #include "../vpatterndb/pmsystems.h"
#include "qpushbutton.h"
#include "ui_preferencesconfigurationpage.h" #include "ui_preferencesconfigurationpage.h"
#include "vcommonsettings.h" #include "vcommonsettings.h"
@ -161,6 +164,12 @@ PreferencesConfigurationPage::PreferencesConfigurationPage(QWidget *parent)
//----------------------- Update //----------------------- Update
ui->checkBoxAutomaticallyCheckUpdates->setChecked(settings->IsAutomaticallyCheckUpdates()); ui->checkBoxAutomaticallyCheckUpdates->setChecked(settings->IsAutomaticallyCheckUpdates());
// Tab Shortcuts
InitShortcuts();
connect(ui->pushButtonRestoreDefaults, &QPushButton::clicked, this, [this]() { InitShortcuts(true); });
connect(ui->shortcutsTable, &QTableWidget::cellDoubleClicked, this,
&PreferencesConfigurationPage::ShortcutCellDoubleClicked);
// Tab Scrolling // Tab Scrolling
ui->spinBoxDuration->setMinimum(VCommonSettings::scrollingDurationMin); ui->spinBoxDuration->setMinimum(VCommonSettings::scrollingDurationMin);
ui->spinBoxDuration->setMaximum(VCommonSettings::scrollingDurationMax); ui->spinBoxDuration->setMaximum(VCommonSettings::scrollingDurationMax);
@ -294,6 +303,19 @@ auto PreferencesConfigurationPage::Apply() -> QStringList
settings->SetAutomaticallyCheckUpdates(ui->checkBoxAutomaticallyCheckUpdates->isChecked()); settings->SetAutomaticallyCheckUpdates(ui->checkBoxAutomaticallyCheckUpdates->isChecked());
} }
// Tab Shortcuts
if (VAbstractShortcutManager *manager = VAbstractValApplication::VApp()->GetShortcutManager())
{
const auto &shortcutsList = manager->GetShortcutsList();
for (int i = 0; i < m_transientShortcuts.length(); i++)
{
settings->SetActionShortcuts(VAbstractShortcutManager::ShortcutActionToString(shortcutsList.value(i).type),
m_transientShortcuts.value(i));
}
manager->UpdateShortcuts();
}
// Tab Scrolling // Tab Scrolling
settings->SetScrollingDuration(ui->spinBoxDuration->value()); settings->SetScrollingDuration(ui->spinBoxDuration->value());
settings->SetScrollingUpdateInterval(ui->spinBoxUpdateInterval->value()); settings->SetScrollingUpdateInterval(ui->spinBoxUpdateInterval->value());
@ -321,6 +343,20 @@ void PreferencesConfigurationPage::changeEvent(QEvent *event)
QWidget::changeEvent(event); QWidget::changeEvent(event);
} }
//---------------------------------------------------------------------------------------------------------------------
void PreferencesConfigurationPage::ShortcutCellDoubleClicked(int row, int column)
{
Q_UNUSED(column)
auto *shortcutDialog = new VShortcutDialog(row, this);
connect(shortcutDialog, &VShortcutDialog::ShortcutsListChanged, this,
[this](int index, const QStringList &stringListShortcuts)
{
m_transientShortcuts.replace(index, stringListShortcuts);
UpdateShortcutsTable();
});
shortcutDialog->open();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PreferencesConfigurationPage::SetLabelComboBox(const QStringList &list) void PreferencesConfigurationPage::SetLabelComboBox(const QStringList &list)
{ {
@ -387,4 +423,78 @@ void PreferencesConfigurationPage::RetranslateUi()
ui->comboBoxPieceLbelLanguage->blockSignals(false); ui->comboBoxPieceLbelLanguage->blockSignals(false);
ui->comboBoxPieceLbelLanguage->setCurrentIndex(ui->comboBoxPieceLbelLanguage->findData(code)); ui->comboBoxPieceLbelLanguage->setCurrentIndex(ui->comboBoxPieceLbelLanguage->findData(code));
} }
RetranslateShortcutsTable();
}
//---------------------------------------------------------------------------------------------------------------------
void PreferencesConfigurationPage::InitShortcuts(bool defaults)
{
VAbstractShortcutManager *manager = VAbstractValApplication::VApp()->GetShortcutManager();
if (manager == nullptr)
{
return;
}
manager->UpdateShortcuts();
m_transientShortcuts.clear();
ui->shortcutsTable->clearContents();
const auto &shortcutsList = manager->GetShortcutsList();
ui->shortcutsTable->setRowCount(static_cast<int>(shortcutsList.length()));
for (int i = 0; i < shortcutsList.length(); i++)
{
const VAbstractShortcutManager::VSShortcut &shortcut = shortcutsList.value(i);
// Add shortcut to transient shortcut list
if (defaults)
{
m_transientShortcuts.append(shortcut.defaultShortcuts);
}
else
{
m_transientShortcuts.append(shortcut.shortcuts);
}
// Add shortcut to table widget
auto *nameItem = new QTableWidgetItem();
nameItem->setText(VAbstractShortcutManager::ReadableName(shortcut.type));
ui->shortcutsTable->setItem(i, 0, nameItem);
auto *shortcutsItem = new QTableWidgetItem();
shortcutsItem->setText(VAbstractShortcutManager::StringListToReadableString(m_transientShortcuts.value(i)));
ui->shortcutsTable->setItem(i, 1, shortcutsItem);
}
UpdateShortcutsTable();
}
//---------------------------------------------------------------------------------------------------------------------
void PreferencesConfigurationPage::UpdateShortcutsTable()
{
for (int i = 0; i < m_transientShortcuts.length(); i++)
{
const QStringList &shortcuts = m_transientShortcuts.value(i);
ui->shortcutsTable->item(i, 1)->setText(VAbstractShortcutManager::StringListToReadableString(shortcuts));
}
}
//---------------------------------------------------------------------------------------------------------------------
void PreferencesConfigurationPage::RetranslateShortcutsTable()
{
VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager();
if (manager == nullptr)
{
return;
}
const auto &shortcutsList = manager->GetShortcutsList();
for (int i = 0; i < shortcutsList.length(); i++)
{
const VAbstractShortcutManager::VSShortcut &shortcut = shortcutsList.value(i);
if (QTableWidgetItem *it = ui->shortcutsTable->item(i, 0))
{
it->setText(VAbstractShortcutManager::ReadableName(shortcut.type));
}
}
} }

View File

@ -53,6 +53,9 @@ public:
protected: protected:
void changeEvent(QEvent *event) override; void changeEvent(QEvent *event) override;
private slots:
void ShortcutCellDoubleClicked(int row, int column);
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(PreferencesConfigurationPage) // NOLINT Q_DISABLE_COPY_MOVE(PreferencesConfigurationPage) // NOLINT
@ -62,12 +65,16 @@ private:
bool m_systemChanged{false}; bool m_systemChanged{false};
bool m_unitChanged{false}; bool m_unitChanged{false};
bool m_labelLangChanged{false}; bool m_labelLangChanged{false};
QList<QStringList> m_transientShortcuts{};
void SetLabelComboBox(const QStringList &list); void SetLabelComboBox(const QStringList &list);
void SetThemeModeComboBox(); void SetThemeModeComboBox();
void SetPointerModeComboBox(); void SetPointerModeComboBox();
void InitUnits(); void InitUnits();
void RetranslateUi(); void RetranslateUi();
void InitShortcuts(bool defaults = false);
void UpdateShortcutsTable();
void RetranslateShortcutsTable();
}; };
#endif // PREFERENCESCONFIGURATIONPAGE_H #endif // PREFERENCESCONFIGURATIONPAGE_H

View File

@ -17,7 +17,7 @@
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="tabGeneral"> <widget class="QWidget" name="tabGeneral">
<attribute name="title"> <attribute name="title">
@ -33,7 +33,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>-163</y> <y>0</y>
<width>624</width> <width>624</width>
<height>995</height> <height>995</height>
</rect> </rect>
@ -443,6 +443,87 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabShortcuts">
<attribute name="title">
<string>Shortcuts</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="QTableWidget" name="shortcutsTable">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="rowCount">
<number>0</number>
</property>
<property name="columnCount">
<number>2</number>
</property>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>150</number>
</attribute>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Action</string>
</property>
</column>
<column>
<property name="text">
<string>Shortcuts</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonRestoreDefaults">
<property name="text">
<string>Restore defaults</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabScrolling"> <widget class="QWidget" name="tabScrolling">
<attribute name="title"> <attribute name="title">
<string>Scrolling</string> <string>Scrolling</string>

View File

@ -104,6 +104,21 @@ DialogFinalMeasurements::DialogFinalMeasurements(VPattern *doc, QWidget *parent)
{ {
ui->tableWidget->selectRow(0); ui->tableWidget->selectRow(0);
} }
m_shortcuts.insert(VShortcutAction::CaseSensitiveMatch, ui->toolButtonCaseSensitive);
m_shortcuts.insert(VShortcutAction::WholeWordMatch, ui->toolButtonWholeWord);
m_shortcuts.insert(VShortcutAction::RegexMatch, ui->toolButtonRegexp);
m_shortcuts.insert(VShortcutAction::SearchHistory, ui->pushButtonSearch);
m_shortcuts.insert(VShortcutAction::RegexMatchUnicodeProperties, ui->toolButtonUseUnicodeProperties);
m_shortcuts.insert(VShortcutAction::FindNext, ui->toolButtonFindNext);
m_shortcuts.insert(VShortcutAction::FindPrevious, ui->toolButtonFindNext);
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
connect(VAbstractValApplication::VApp()->GetShortcutManager(), &VAbstractShortcutManager::shortcutsUpdated,
this, &DialogFinalMeasurements::UpdateShortcuts);
UpdateShortcuts();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -491,6 +506,16 @@ void DialogFinalMeasurements::FullUpdateFromFile()
m_search->RefreshList(ui->lineEditFind->text()); m_search->RefreshList(ui->lineEditFind->text());
} }
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::UpdateShortcuts()
{
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
manager->UpdateButtonShortcut(m_shortcuts);
UpdateSearchControlsTooltips();
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::FillFinalMeasurements(bool freshCall) void DialogFinalMeasurements::FillFinalMeasurements(bool freshCall)
{ {
@ -906,12 +931,18 @@ void DialogFinalMeasurements::SaveSearchRequest()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::UpdateSearchControlsTooltips() void DialogFinalMeasurements::UpdateSearchControlsTooltips()
{ {
auto UpdateToolTip = [](QAbstractButton *button) auto UpdateToolTip = [this](QAbstractButton *button)
{ {
if (button->toolTip().contains("%1"_L1)) if (button->toolTip().contains("%1"_L1))
{ {
m_serachButtonTooltips.insert(button, button->toolTip());
button->setToolTip(button->toolTip().arg(button->shortcut().toString(QKeySequence::NativeText))); button->setToolTip(button->toolTip().arg(button->shortcut().toString(QKeySequence::NativeText)));
} }
else if (m_serachButtonTooltips.contains(button))
{
QString tooltip = m_serachButtonTooltips.value(button);
button->setToolTip(tooltip.arg(button->shortcut().toString(QKeySequence::NativeText)));
}
}; };
UpdateToolTip(ui->toolButtonCaseSensitive); UpdateToolTip(ui->toolButtonCaseSensitive);

View File

@ -31,6 +31,7 @@
#include <QDialog> #include <QDialog>
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vtablesearch.h" #include "../vmisc/vtablesearch.h"
#include "../vpatterndb/vcontainer.h" #include "../vpatterndb/vcontainer.h"
#include "../xml/vpattern.h" #include "../xml/vpattern.h"
@ -40,6 +41,8 @@ namespace Ui
class DialogFinalMeasurements; class DialogFinalMeasurements;
} }
class QAbstractButton;
class DialogFinalMeasurements : public QDialog class DialogFinalMeasurements : public QDialog
{ {
Q_OBJECT // NOLINT Q_OBJECT // NOLINT
@ -68,6 +71,7 @@ private slots:
void DeployFormula(); void DeployFormula();
void Fx(); void Fx();
void FullUpdateFromFile(); void FullUpdateFromFile();
void UpdateShortcuts();
private: private:
Q_DISABLE_COPY_MOVE(DialogFinalMeasurements) // NOLINT Q_DISABLE_COPY_MOVE(DialogFinalMeasurements) // NOLINT
@ -82,6 +86,9 @@ private:
QMenu *m_searchHistory; QMenu *m_searchHistory;
QMultiHash<VShortcutAction, QAbstractButton *> m_shortcuts{};
QHash<QAbstractButton *, QString> m_serachButtonTooltips{};
void FillFinalMeasurements(bool freshCall = false); void FillFinalMeasurements(bool freshCall = false);
void ShowUnits(); void ShowUnits();

View File

@ -88,6 +88,21 @@ DialogHistory::DialogHistory(VContainer *data, VPattern *doc, QWidget *parent)
ShowPoint(); ShowPoint();
InitSearch(); InitSearch();
m_shortcuts.insert(VShortcutAction::CaseSensitiveMatch, ui->toolButtonCaseSensitive);
m_shortcuts.insert(VShortcutAction::WholeWordMatch, ui->toolButtonWholeWord);
m_shortcuts.insert(VShortcutAction::RegexMatch, ui->toolButtonRegexp);
m_shortcuts.insert(VShortcutAction::SearchHistory, ui->pushButtonSearch);
m_shortcuts.insert(VShortcutAction::RegexMatchUnicodeProperties, ui->toolButtonUseUnicodeProperties);
m_shortcuts.insert(VShortcutAction::FindNext, ui->toolButtonFindNext);
m_shortcuts.insert(VShortcutAction::FindPrevious, ui->toolButtonFindNext);
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
connect(VAbstractValApplication::VApp()->GetShortcutManager(), &VAbstractShortcutManager::shortcutsUpdated,
this, &DialogHistory::UpdateShortcuts);
UpdateShortcuts();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -571,6 +586,16 @@ void DialogHistory::showEvent(QShowEvent *event)
QDialog::showEvent(event); // return default behavior NOLINT(bugprone-parent-virtual-call) QDialog::showEvent(event); // return default behavior NOLINT(bugprone-parent-virtual-call)
} }
//---------------------------------------------------------------------------------------------------------------------
void DialogHistory::UpdateShortcuts()
{
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
manager->UpdateButtonShortcut(m_shortcuts);
UpdateSearchControlsTooltips();
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void DialogHistory::RetranslateUi() void DialogHistory::RetranslateUi()
{ {
@ -784,12 +809,18 @@ void DialogHistory::SaveSearchRequest()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void DialogHistory::UpdateSearchControlsTooltips() void DialogHistory::UpdateSearchControlsTooltips()
{ {
auto UpdateToolTip = [](QAbstractButton *button) auto UpdateToolTip = [this](QAbstractButton *button)
{ {
if (button->toolTip().contains("%1"_L1)) if (button->toolTip().contains("%1"_L1))
{ {
m_serachButtonTooltips.insert(button, button->toolTip());
button->setToolTip(button->toolTip().arg(button->shortcut().toString(QKeySequence::NativeText))); button->setToolTip(button->toolTip().arg(button->shortcut().toString(QKeySequence::NativeText)));
} }
else if (m_serachButtonTooltips.contains(button))
{
QString tooltip = m_serachButtonTooltips.value(button);
button->setToolTip(tooltip.arg(button->shortcut().toString(QKeySequence::NativeText)));
}
}; };
UpdateToolTip(ui->toolButtonCaseSensitive); UpdateToolTip(ui->toolButtonCaseSensitive);

View File

@ -29,6 +29,7 @@
#ifndef DIALOGHISTORY_H #ifndef DIALOGHISTORY_H
#define DIALOGHISTORY_H #define DIALOGHISTORY_H
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vtools/dialogs/tools/dialogtool.h" #include "../vtools/dialogs/tools/dialogtool.h"
#include <QDomElement> #include <QDomElement>
@ -80,6 +81,9 @@ protected:
auto IsValid() const -> bool final { return true; } auto IsValid() const -> bool final { return true; }
void showEvent(QShowEvent *event) override; void showEvent(QShowEvent *event) override;
private slots:
void UpdateShortcuts();
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(DialogHistory) // NOLINT Q_DISABLE_COPY_MOVE(DialogHistory) // NOLINT
@ -96,6 +100,9 @@ private:
QMenu *m_searchHistory; QMenu *m_searchHistory;
QMultiHash<VShortcutAction, QAbstractButton *> m_shortcuts{};
QHash<QAbstractButton *, QString> m_serachButtonTooltips{};
void FillTable(); void FillTable();
auto Record(const VToolRecord &tool) const -> HistoryRecord; auto Record(const VToolRecord &tool) const -> HistoryRecord;
auto RecordDescription(const VToolRecord &tool, HistoryRecord record, const QDomElement &domElem) const auto RecordDescription(const VToolRecord &tool, HistoryRecord record, const QDomElement &domElem) const

View File

@ -185,6 +185,29 @@ DialogIncrements::DialogIncrements(VContainer *data, VPattern *doc, QWidget *par
{ {
ui->tableWidgetPC->selectRow(0); ui->tableWidgetPC->selectRow(0);
} }
m_shortcuts.insert(VShortcutAction::CaseSensitiveMatch, ui->toolButtonCaseSensitive);
m_shortcuts.insert(VShortcutAction::WholeWordMatch, ui->toolButtonWholeWord);
m_shortcuts.insert(VShortcutAction::RegexMatch, ui->toolButtonRegexp);
m_shortcuts.insert(VShortcutAction::SearchHistory, ui->pushButtonSearch);
m_shortcuts.insert(VShortcutAction::RegexMatchUnicodeProperties, ui->toolButtonUseUnicodeProperties);
m_shortcuts.insert(VShortcutAction::FindNext, ui->toolButtonFindNext);
m_shortcuts.insert(VShortcutAction::FindPrevious, ui->toolButtonFindNext);
m_shortcuts.insert(VShortcutAction::CaseSensitiveMatch, ui->toolButtonCaseSensitivePC);
m_shortcuts.insert(VShortcutAction::WholeWordMatch, ui->toolButtonWholeWordPC);
m_shortcuts.insert(VShortcutAction::RegexMatch, ui->toolButtonRegexpPC);
m_shortcuts.insert(VShortcutAction::SearchHistory, ui->pushButtonSearchPC);
m_shortcuts.insert(VShortcutAction::RegexMatchUnicodeProperties, ui->toolButtonUseUnicodePropertiesPC);
m_shortcuts.insert(VShortcutAction::FindNext, ui->toolButtonFindNextPC);
m_shortcuts.insert(VShortcutAction::FindPrevious, ui->toolButtonFindNextPC);
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
connect(VAbstractValApplication::VApp()->GetShortcutManager(), &VAbstractShortcutManager::shortcutsUpdated,
this, &DialogIncrements::UpdateShortcuts);
UpdateShortcuts();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1195,12 +1218,18 @@ void DialogIncrements::SavePreviewCalculationsSearchRequest()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void DialogIncrements::UpdateSearchControlsTooltips() void DialogIncrements::UpdateSearchControlsTooltips()
{ {
auto UpdateToolTip = [](QAbstractButton *button) auto UpdateToolTip = [this](QAbstractButton *button)
{ {
if (button->toolTip().contains("%1"_L1)) if (button->toolTip().contains("%1"_L1))
{ {
m_serachButtonTooltips.insert(button, button->toolTip());
button->setToolTip(button->toolTip().arg(button->shortcut().toString(QKeySequence::NativeText))); button->setToolTip(button->toolTip().arg(button->shortcut().toString(QKeySequence::NativeText)));
} }
else if (m_serachButtonTooltips.contains(button))
{
QString tooltip = m_serachButtonTooltips.value(button);
button->setToolTip(tooltip.arg(button->shortcut().toString(QKeySequence::NativeText)));
}
}; };
UpdateToolTip(ui->toolButtonCaseSensitive); UpdateToolTip(ui->toolButtonCaseSensitive);
@ -1337,6 +1366,16 @@ void DialogIncrements::RefreshPattern()
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void DialogIncrements::UpdateShortcuts()
{
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
manager->UpdateButtonShortcut(m_shortcuts);
UpdateSearchControlsTooltips();
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void DialogIncrements::FillIncrementsTable(QTableWidget *table, void DialogIncrements::FillIncrementsTable(QTableWidget *table,
const QMap<QString, QSharedPointer<VIncrement>> &increments, const QMap<QString, QSharedPointer<VIncrement>> &increments,

View File

@ -29,6 +29,7 @@
#ifndef DIALOGINCREMENTS_H #ifndef DIALOGINCREMENTS_H
#define DIALOGINCREMENTS_H #define DIALOGINCREMENTS_H
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vtablesearch.h" #include "../vmisc/vtablesearch.h"
#include "../vtools/dialogs/tools/dialogtool.h" #include "../vtools/dialogs/tools/dialogtool.h"
#include "../xml/vpattern.h" #include "../xml/vpattern.h"
@ -82,6 +83,7 @@ private slots:
void DeployFormula(); void DeployFormula();
void Fx(); void Fx();
void RefreshPattern(); void RefreshPattern();
void UpdateShortcuts();
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
@ -112,6 +114,9 @@ private:
QMenu *m_searchHistory; QMenu *m_searchHistory;
QMenu *m_searchHistoryPC; QMenu *m_searchHistoryPC;
QMultiHash<VShortcutAction, QAbstractButton *> m_shortcuts{};
QHash<QAbstractButton *, QString> m_serachButtonTooltips{};
template <typename T> void FillTable(const QMap<QString, T> &varTable, QTableWidget *table); template <typename T> void FillTable(const QMap<QString, T> &varTable, QTableWidget *table);
static void FillIncrementsTable(QTableWidget *table, const QMap<QString, QSharedPointer<VIncrement>> &increments, static void FillIncrementsTable(QTableWidget *table, const QMap<QString, QSharedPointer<VIncrement>> &increments,

View File

@ -193,6 +193,7 @@
#include "dialogs/vwidgetgroups.h" #include "dialogs/vwidgetgroups.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include "vabstractapplication.h" #include "vabstractapplication.h"
#include "vabstractshortcutmanager.h"
#include "vsinglelineoutlinechar.h" #include "vsinglelineoutlinechar.h"
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@ -396,6 +397,7 @@ MainWindow::MainWindow(QWidget *parent)
ToolBarStages(); ToolBarStages();
ToolBarDrawTools(); ToolBarDrawTools();
InitToolButtons(); InitToolButtons();
InitActionShortcuts();
connect(ui->actionAddBackgroundImage, &QAction::triggered, this, &MainWindow::ActionAddBackgroundImage); connect(ui->actionAddBackgroundImage, &QAction::triggered, this, &MainWindow::ActionAddBackgroundImage);
connect(ui->actionExportFontCorrections, &QAction::triggered, this, &MainWindow::ActionExportFontCorrections); connect(ui->actionExportFontCorrections, &QAction::triggered, this, &MainWindow::ActionExportFontCorrections);
@ -533,6 +535,12 @@ MainWindow::MainWindow(QWidget *parent)
} }
ui->actionExportFontCorrections->setEnabled(settings->GetSingleStrokeOutlineFont()); ui->actionExportFontCorrections->setEnabled(settings->GetSingleStrokeOutlineFont());
if (VAbstractShortcutManager *manager = VAbstractValApplication::VApp()->GetShortcutManager())
{
connect(manager, &VAbstractShortcutManager::shortcutsUpdated, this, &MainWindow::UpdateShortcuts);
UpdateShortcuts();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -2943,83 +2951,25 @@ void MainWindow::ToolBarDraws()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void MainWindow::ToolBarTools() void MainWindow::ToolBarTools()
{ {
/*First we will try use Standard Shortcuts from Qt, but because keypad "-" and "+" not the same keys like in main m_shortcutActions.insert(VShortcutAction::ZoomIn, ui->actionZoomIn);
keypad, shortcut Ctrl+"-" or "+" from keypad will not working with standard shortcut (QKeySequence::ZoomIn or
QKeySequence::ZoomOut). For examle "+" is Qt::Key_Plus + Qt::KeypadModifier for keypad.
Also for me don't work Qt:CTRL and work Qt::ControlModifier.*/
QT_WARNING_PUSH
#if !defined(Q_OS_MACOS) && defined(Q_CC_CLANG)
QT_WARNING_DISABLE_CLANG("-Wenum-enum-conversion")
#endif
QList<QKeySequence> zoomInShortcuts;
zoomInShortcuts.append(QKeySequence(QKeySequence::ZoomIn));
zoomInShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(QKeyCombination(Qt::ControlModifier), Qt::Key_Plus | Qt::KeypadModifier));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_Plus + Qt::KeypadModifier));
#endif
ui->actionZoomIn->setShortcuts(zoomInShortcuts);
connect(ui->actionZoomIn, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomIn); connect(ui->actionZoomIn, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomIn);
QList<QKeySequence> zoomOutShortcuts; m_shortcutActions.insert(VShortcutAction::ZoomOut, ui->actionZoomOut);
zoomOutShortcuts.append(QKeySequence(QKeySequence::ZoomOut));
zoomOutShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(QKeyCombination(Qt::ControlModifier), Qt::Key_Minus | Qt::KeypadModifier));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_Minus + Qt::KeypadModifier));
#endif
ui->actionZoomOut->setShortcuts(zoomOutShortcuts);
connect(ui->actionZoomOut, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomOut); connect(ui->actionZoomOut, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomOut);
QList<QKeySequence> zoomOriginalShortcuts; m_shortcutActions.insert(VShortcutAction::ZoomOriginal, ui->actionZoomOriginal);
zoomOriginalShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ControlModifier | Qt::Key_0));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_0));
#endif
zoomOriginalShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(QKeyCombination(Qt::ControlModifier), Qt::Key_0 | Qt::KeypadModifier));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_0 + Qt::KeypadModifier));
#endif
ui->actionZoomOriginal->setShortcuts(zoomOriginalShortcuts);
connect(ui->actionZoomOriginal, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomOriginal); connect(ui->actionZoomOriginal, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomOriginal);
QList<QKeySequence> zoomFitBestShortcuts; m_shortcutActions.insert(VShortcutAction::ZoomFitBest, ui->actionZoomFitBest);
zoomFitBestShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ControlModifier | Qt::Key_Equal));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_Equal));
#endif
ui->actionZoomFitBest->setShortcuts(zoomFitBestShortcuts);
connect(ui->actionZoomFitBest, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomFitBest); connect(ui->actionZoomFitBest, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomFitBest);
QList<QKeySequence> zoomFitBestCurrentShortcuts; m_shortcutActions.insert(VShortcutAction::ZoomFitBestCurrent, ui->actionZoomFitBestCurrent);
zoomFitBestCurrentShortcuts.append(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ControlModifier | Qt::Key_M));
#else
QKeySequence(Qt::ControlModifier + Qt::Key_M));
#endif
ui->actionZoomFitBestCurrent->setShortcuts(zoomFitBestCurrentShortcuts);
connect(ui->actionZoomFitBestCurrent, &QAction::triggered, this, &MainWindow::ZoomFitBestCurrent); connect(ui->actionZoomFitBestCurrent, &QAction::triggered, this, &MainWindow::ZoomFitBestCurrent);
connect(ui->actionPreviousPatternPiece, &QAction::triggered, this, &MainWindow::PreviousPatternPiece); connect(ui->actionPreviousPatternPiece, &QAction::triggered, this, &MainWindow::PreviousPatternPiece);
connect(ui->actionNextPatternPiece, &QAction::triggered, this, &MainWindow::NextPatternPiece); connect(ui->actionNextPatternPiece, &QAction::triggered, this, &MainWindow::NextPatternPiece);
ui->actionIncreaseLabelFont->setShortcut( m_shortcutActions.insert(VShortcutAction::IncreaseLabelFont, ui->actionIncreaseLabelFont);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ShiftModifier | Qt::Key_Plus));
#else
QKeySequence(Qt::ShiftModifier + Qt::Key_Plus));
#endif
connect(ui->actionIncreaseLabelFont, &QAction::triggered, this, connect(ui->actionIncreaseLabelFont, &QAction::triggered, this,
[this]() [this]()
{ {
@ -3036,12 +2986,7 @@ void MainWindow::ToolBarTools()
} }
}); });
ui->actionDecreaseLabelFont->setShortcut( m_shortcutActions.insert(VShortcutAction::DecreaseLabelFont, ui->actionDecreaseLabelFont);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ShiftModifier | Qt::Key_Minus));
#else
QKeySequence(Qt::ShiftModifier + Qt::Key_Minus));
#endif
connect(ui->actionDecreaseLabelFont, &QAction::triggered, this, connect(ui->actionDecreaseLabelFont, &QAction::triggered, this,
[this]() [this]()
{ {
@ -3058,12 +3003,7 @@ void MainWindow::ToolBarTools()
} }
}); });
ui->actionOriginalLabelFont->setShortcut( m_shortcutActions.insert(VShortcutAction::OriginalLabelFont, ui->actionOriginalLabelFont);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ShiftModifier | Qt::Key_0));
#else
QKeySequence(Qt::ShiftModifier + Qt::Key_0));
#endif
connect(ui->actionOriginalLabelFont, &QAction::triggered, this, connect(ui->actionOriginalLabelFont, &QAction::triggered, this,
[this]() [this]()
{ {
@ -3080,12 +3020,7 @@ void MainWindow::ToolBarTools()
} }
}); });
ui->actionHideLabels->setShortcut( m_shortcutActions.insert(VShortcutAction::HideLabels, ui->actionHideLabels);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::AltModifier | Qt::Key_L));
#else
QKeySequence(Qt::AltModifier + Qt::Key_L));
#endif
ui->actionHideLabels->setChecked(VAbstractValApplication::VApp()->ValentinaSettings()->GetHideLabels()); ui->actionHideLabels->setChecked(VAbstractValApplication::VApp()->ValentinaSettings()->GetHideLabels());
connect(ui->actionHideLabels, &QAction::triggered, this, connect(ui->actionHideLabels, &QAction::triggered, this,
[this](bool checked) [this](bool checked)
@ -3101,8 +3036,6 @@ void MainWindow::ToolBarTools()
m_sceneDetails->update(); m_sceneDetails->update();
} }
}); });
QT_WARNING_POP
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -3438,6 +3371,28 @@ void MainWindow::InitToolButtons()
connect(ui->actionPlaceLabelTool, &QAction::triggered, this, &MainWindow::ToolPlaceLabel); connect(ui->actionPlaceLabelTool, &QAction::triggered, this, &MainWindow::ToolPlaceLabel);
} }
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::InitActionShortcuts()
{
m_shortcutActions.insert(VShortcutAction::New, ui->actionNew);
m_shortcutActions.insert(VShortcutAction::Open, ui->actionOpen);
m_shortcutActions.insert(VShortcutAction::Save, ui->actionSave);
m_shortcutActions.insert(VShortcutAction::SaveAs, ui->actionSaveAs);
m_shortcutActions.insert(VShortcutAction::DrawMode, ui->actionDraw);
m_shortcutActions.insert(VShortcutAction::DetailsMode, ui->actionDetails);
m_shortcutActions.insert(VShortcutAction::LayoutMode, ui->actionLayout);
m_shortcutActions.insert(VShortcutAction::NewPatternPiece, ui->actionNewDraw);
m_shortcutActions.insert(VShortcutAction::NextPatternPiece, ui->actionNextPatternPiece);
m_shortcutActions.insert(VShortcutAction::PreviusPatternPiece, ui->actionPreviousPatternPiece);
m_shortcutActions.insert(VShortcutAction::InteractiveTools, ui->actionInteractiveTools);
m_shortcutActions.insert(VShortcutAction::TableOfVariables, ui->actionTable);
m_shortcutActions.insert(VShortcutAction::PatternHistory, ui->actionHistory);
m_shortcutActions.insert(VShortcutAction::Quit, ui->actionExit);
m_shortcutActions.insert(VShortcutAction::LastTool, ui->actionLast_tool);
m_shortcutActions.insert(VShortcutAction::CurveDetails, ui->actionShowCurveDetails);
m_shortcutActions.insert(VShortcutAction::FinalMeasurements, ui->actionFinalMeasurements);
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief mouseMove save mouse position and show user. * @brief mouseMove save mouse position and show user.
@ -5202,6 +5157,15 @@ void MainWindow::ActionOpenTape_triggered()
VApplication::StartDetachedProcess(VApplication::TapeFilePath(), arguments); VApplication::StartDetachedProcess(VApplication::TapeFilePath(), arguments);
} }
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::UpdateShortcuts()
{
if (VAbstractShortcutManager *manager = VAbstractValApplication::VApp()->GetShortcutManager())
{
manager->UpdateActionShortcuts(m_shortcutActions);
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void MainWindow::InitDimensionControls() void MainWindow::InitDimensionControls()
{ {
@ -5643,6 +5607,11 @@ void MainWindow::ReadSettings()
QFont f = ui->plainTextEditPatternMessages->font(); QFont f = ui->plainTextEditPatternMessages->font();
f.setPointSize(qMax(settings->GetPatternMessageFontSize(f.pointSize()), 1)); f.setPointSize(qMax(settings->GetPatternMessageFontSize(f.pointSize()), 1));
ui->plainTextEditPatternMessages->setFont(f); ui->plainTextEditPatternMessages->setFont(f);
if (VAbstractShortcutManager *manager = VAbstractValApplication::VApp()->GetShortcutManager())
{
manager->UpdateShortcuts();
}
} }
else else
{ {
@ -5736,14 +5705,14 @@ void MainWindow::CreateMenus()
// Add Undo/Redo actions. // Add Undo/Redo actions.
undoAction = VAbstractApplication::VApp()->getUndoStack()->createUndoAction(this, tr("&Undo")); undoAction = VAbstractApplication::VApp()->getUndoStack()->createUndoAction(this, tr("&Undo"));
connect(undoAction, &QAction::triggered, m_toolOptions, &VToolOptionsPropertyBrowser::RefreshOptions); connect(undoAction, &QAction::triggered, m_toolOptions, &VToolOptionsPropertyBrowser::RefreshOptions);
undoAction->setShortcuts(QKeySequence::Undo); m_shortcutActions.insert(VShortcutAction::Undo, undoAction);
undoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo"))); undoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo")));
ui->menuPatternPiece->insertAction(ui->actionLast_tool, undoAction); ui->menuPatternPiece->insertAction(ui->actionLast_tool, undoAction);
ui->toolBarTools->addAction(undoAction); ui->toolBarTools->addAction(undoAction);
redoAction = VAbstractApplication::VApp()->getUndoStack()->createRedoAction(this, tr("&Redo")); redoAction = VAbstractApplication::VApp()->getUndoStack()->createRedoAction(this, tr("&Redo"));
connect(redoAction, &QAction::triggered, m_toolOptions, &VToolOptionsPropertyBrowser::RefreshOptions); connect(redoAction, &QAction::triggered, m_toolOptions, &VToolOptionsPropertyBrowser::RefreshOptions);
redoAction->setShortcuts(QKeySequence::Redo); m_shortcutActions.insert(VShortcutAction::Redo, redoAction);
redoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-redo"))); redoAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-redo")));
ui->menuPatternPiece->insertAction(ui->actionLast_tool, redoAction); ui->menuPatternPiece->insertAction(ui->actionLast_tool, redoAction);
ui->toolBarTools->addAction(redoAction); ui->toolBarTools->addAction(redoAction);

View File

@ -30,6 +30,7 @@
#define MAINWINDOW_H #define MAINWINDOW_H
#include "../vformat/vdimensions.h" #include "../vformat/vdimensions.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vlockguard.h" #include "../vmisc/vlockguard.h"
#include "core/vcmdexport.h" #include "core/vcmdexport.h"
#include "mainwindowsnogui.h" #include "mainwindowsnogui.h"
@ -254,6 +255,8 @@ private slots:
void ActionShowMainPath_triggered(bool checked); void ActionShowMainPath_triggered(bool checked);
void ActionOpenTape_triggered(); void ActionOpenTape_triggered();
void UpdateShortcuts();
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(MainWindow) // NOLINT Q_DISABLE_COPY_MOVE(MainWindow) // NOLINT
@ -338,6 +341,8 @@ private:
bool m_patternMessagesActive{false}; bool m_patternMessagesActive{false};
bool m_backgroundImagesActive{false}; bool m_backgroundImagesActive{false};
QMultiHash<VShortcutAction, QAction *> m_shortcutActions{};
void InitDimensionControls(); void InitDimensionControls();
void InitDimensionGradation(int index, const MeasurementDimension_p &dimension, const QPointer<QComboBox> &control); void InitDimensionGradation(int index, const MeasurementDimension_p &dimension, const QPointer<QComboBox> &control);
static void InitDimensionXGradation(const QVector<qreal> &bases, const DimesionLabels &labels, static void InitDimensionXGradation(const QVector<qreal> &bases, const DimesionLabels &labels,
@ -351,6 +356,7 @@ private:
void ToolBarTools(); void ToolBarTools();
void ToolBarDrawTools(); void ToolBarDrawTools();
void InitToolButtons(); void InitToolButtons();
void InitActionShortcuts();
void CancelTool(); void CancelTool();
void SetupDrawToolsIcons(); void SetupDrawToolsIcons();

View File

@ -10,7 +10,8 @@ include(core/core.pri)
SOURCES += \ SOURCES += \
$$PWD/main.cpp \ $$PWD/main.cpp \
$$PWD/mainwindow.cpp \ $$PWD/mainwindow.cpp \
$$PWD/mainwindowsnogui.cpp $$PWD/mainwindowsnogui.cpp \
$$PWD/vvalentinashortcutmanager.cpp
*msvc*:SOURCES += $$PWD/stable.cpp *msvc*:SOURCES += $$PWD/stable.cpp
@ -19,7 +20,8 @@ HEADERS += \
$$PWD/mainwindow.h \ $$PWD/mainwindow.h \
$$PWD/stable.h \ $$PWD/stable.h \
$$PWD/version.h \ $$PWD/version.h \
$$PWD/mainwindowsnogui.h $$PWD/mainwindowsnogui.h \
$$PWD/vvalentinashortcutmanager.h
# Main forms # Main forms
FORMS += \ FORMS += \

View File

@ -161,12 +161,13 @@ VToolApp {
"vformulapropertyeditor.h", "vformulapropertyeditor.h",
"vtooloptionspropertybrowser.h", "vtooloptionspropertybrowser.h",
"vcmdexport.h", "vcmdexport.h",
"vapplication.cpp", "vapplication.cpp",
"vformulaproperty.cpp", "vformulaproperty.cpp",
"vformulapropertyeditor.cpp", "vformulapropertyeditor.cpp",
"vtooloptionspropertybrowser.cpp", "vtooloptionspropertybrowser.cpp",
"vcmdexport.cpp" "vcmdexport.cpp",
"vvalentinashortcutmanager.cpp",
"vvalentinashortcutmanager.h",
] ]
} }

View File

@ -0,0 +1,139 @@
/************************************************************************
**
** @file vshortcutdialog.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 21 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vshortcutdialog.h"
#include "../vabstractapplication.h"
#include "ui_vshortcutdialog.h"
#include <QMessageBox>
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
#include "../compatibility.h"
#endif
using namespace Qt::Literals::StringLiterals;
namespace
{
//---------------------------------------------------------------------------------------------------------------------
auto ShortcutAlreadyBound(const QKeySequence &chosenSequence, const VShortcutAction &exemptShortcut) -> QString
{
if (chosenSequence.isEmpty())
{
return {};
}
VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager();
if (manager == nullptr)
{
return {};
}
const auto &shortcutsList = manager->GetShortcutsList();
for (const auto &shortcut : shortcutsList)
{
auto sequenceList = VAbstractShortcutManager::StringListToKeySequenceList(shortcut.shortcuts);
if (sequenceList.contains(chosenSequence) && shortcut.type != exemptShortcut)
{
return VAbstractShortcutManager::ReadableName(shortcut.type);
}
}
return {};
}
} // namespace
//---------------------------------------------------------------------------------------------------------------------
VShortcutDialog::VShortcutDialog(int index, QWidget *parent)
: QDialog(parent),
ui(new Ui::VShortcutDialog),
m_index(index)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint | Qt::CustomizeWindowHint));
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &VShortcutDialog::ButtonBoxClicked);
m_shortcutObject = VAbstractApplication::VApp()->GetShortcutManager()->GetShortcutsList().value(index);
ui->keySequenceEdit->setKeySequence(m_shortcutObject.shortcuts.join(", "_L1));
}
//---------------------------------------------------------------------------------------------------------------------
VShortcutDialog::~VShortcutDialog()
{
delete ui;
}
//---------------------------------------------------------------------------------------------------------------------
void VShortcutDialog::AcceptValidated()
{
QDialog::done(1);
}
//---------------------------------------------------------------------------------------------------------------------
void VShortcutDialog::ButtonBoxClicked(QAbstractButton *button)
{
if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
{
QStringList shortcutsStringList = ui->keySequenceEdit->keySequence().toString().split(", "_L1);
const auto sequenceList = VAbstractShortcutManager::StringListToKeySequenceList(shortcutsStringList);
for (const auto &sequence : sequenceList)
{
auto conflictingShortcut = ShortcutAlreadyBound(sequence, m_shortcutObject.type);
if (!conflictingShortcut.isEmpty())
{
QString nativeShortcutString = sequence.toString(QKeySequence::NativeText);
QMessageBox::warning(
this, tr("Shortcut Already Used"),
tr(R"("%1" is already bound to "%2")").arg(nativeShortcutString, conflictingShortcut));
return;
}
}
AcceptValidated();
emit ShortcutsListChanged(m_index, shortcutsStringList);
}
else if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole)
{
ui->keySequenceEdit->setKeySequence(m_shortcutObject.defaultShortcuts.join(", "_L1));
}
}
//---------------------------------------------------------------------------------------------------------------------
void VShortcutDialog::done(int r)
{
if (r == QDialog::Accepted)
{
return;
}
QDialog::done(r);
}

View File

@ -0,0 +1,67 @@
/************************************************************************
**
** @file vshortcutdialog.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 21 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VSHORTCUTDIALOG_H
#define VSHORTCUTDIALOG_H
#include <QDialog>
#include "../vabstractshortcutmanager.h"
namespace Ui
{
class VShortcutDialog;
}
class QAbstractButton;
class VShortcutDialog : public QDialog
{
Q_OBJECT // NOLINT
public:
explicit VShortcutDialog(int index, QWidget *parent = nullptr);
~VShortcutDialog() override;
signals:
void ShortcutsListChanged(int index, QStringList shortcutsStringList);
private slots:
void ButtonBoxClicked(QAbstractButton *button);
private:
Q_DISABLE_COPY_MOVE(VShortcutDialog) // NOLINT
Ui::VShortcutDialog *ui;
VAbstractShortcutManager::VSShortcut m_shortcutObject{};
int m_index;
void AcceptValidated();
void done(int r) override;
};
#endif // VSHORTCUTDIALOG_H

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VShortcutDialog</class>
<widget class="QDialog" name="VShortcutDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>366</width>
<height>74</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QKeySequenceEdit" name="keySequenceEdit">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>VShortcutDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>VShortcutDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -443,6 +443,12 @@ auto VAbstractApplication::AppUptime() const -> qint64
return m_uptimeTimer.elapsed(); return m_uptimeTimer.elapsed();
} }
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractApplication::GetShortcutManager() const -> VAbstractShortcutManager *
{
return m_shortcutManager;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractApplication::TextCodecCache(QStringConverter::Encoding encoding) const -> VTextCodec * auto VAbstractApplication::TextCodecCache(QStringConverter::Encoding encoding) const -> VTextCodec *

View File

@ -50,6 +50,7 @@ class VAbstractApplication; // use in define
class VCommonSettings; class VCommonSettings;
class VSvgFontDatabase; class VSvgFontDatabase;
class QFileSystemWatcher; class QFileSystemWatcher;
class VAbstractShortcutManager;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
class VTextCodec; class VTextCodec;
@ -106,6 +107,8 @@ public:
auto AppUptime() const -> qint64; auto AppUptime() const -> qint64;
auto GetShortcutManager() const -> VAbstractShortcutManager *;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays, modernize-avoid-c-arrays) // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays, modernize-avoid-c-arrays)
static auto IsOptionSet(int argc, char *argv[], const char *option) -> bool; static auto IsOptionSet(int argc, char *argv[], const char *option) -> bool;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays, modernize-avoid-c-arrays) // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays, modernize-avoid-c-arrays)
@ -129,6 +132,8 @@ protected:
QElapsedTimer m_uptimeTimer{}; QElapsedTimer m_uptimeTimer{};
VAbstractShortcutManager *m_shortcutManager{nullptr};
virtual void InitTrVars() = 0; virtual void InitTrVars() = 0;
static void CheckSystemLocale(); static void CheckSystemLocale();

View File

@ -0,0 +1,345 @@
/************************************************************************
**
** @file vabstractshortcutmanager.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 20 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vabstractshortcutmanager.h"
#include <QAbstractButton>
#include <QAction>
#include <QMultiHash>
#include "qassert.h"
#include "qtpreprocessorsupport.h"
#include "vabstractapplication.h"
#include "vcommonsettings.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
#include "compatibility.h"
#endif
using namespace Qt::Literals::StringLiterals;
//---------------------------------------------------------------------------------------------------------------------
VAbstractShortcutManager::VAbstractShortcutManager(QObject *parent)
: QObject{parent}
{
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractShortcutManager::UpdateShortcuts()
{
VCommonSettings *settings = VAbstractApplication::VApp()->Settings();
// Set all shortcuts to the user-set shortcut or the default
for (auto &shortcut : m_shortcutsList)
{
shortcut.shortcuts =
settings->GetActionShortcuts(ShortcutActionToString(shortcut.type), shortcut.defaultShortcuts);
}
emit shortcutsUpdated();
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractShortcutManager::UpdateActionShortcuts(const QMultiHash<VShortcutAction, QAction *> &actions)
{
for (const auto &shortcut : m_shortcutsList)
{
const auto actionList = actions.values(shortcut.type);
for (const auto &action : actionList)
{
if (action)
{
action->setShortcuts(StringListToKeySequenceList(shortcut.shortcuts));
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractShortcutManager::UpdateButtonShortcut(const QMultiHash<VShortcutAction, QAbstractButton *> &buttons)
{
for (const auto &shortcut : m_shortcutsList)
{
const auto buttonList = buttons.values(shortcut.type);
for (const auto &button : buttonList)
{
if (button)
{
QList<QKeySequence> keySequence = StringListToKeySequenceList(shortcut.shortcuts);
if (!keySequence.isEmpty())
{
button->setShortcut(keySequence.constFirst());
}
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractShortcutManager::GetShortcutsList() const -> QList<VAbstractShortcutManager::VSShortcut>
{
return m_shortcutsList;
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractShortcutManager::ShortcutActionToString(VShortcutAction type) -> QString
{
Q_STATIC_ASSERT_X(static_cast<int>(VShortcutAction::LAST_ONE_DO_NOT_USE) == 35, "Convert all actions.");
switch (type)
{
case VShortcutAction::ZoomIn:
return "zoomin"_L1;
case VShortcutAction::ZoomOut:
return "zoomout"_L1;
case VShortcutAction::ZoomOriginal:
return "zoomoriginal"_L1;
case VShortcutAction::ZoomFitBest:
return "zoomfitbest"_L1;
case VShortcutAction::ZoomFitBestCurrent:
return "zoomfitbestcurrent"_L1;
case VShortcutAction::IncreaseLabelFont:
return "increaselabelfont"_L1;
case VShortcutAction::DecreaseLabelFont:
return "decreaselabelfont"_L1;
case VShortcutAction::OriginalLabelFont:
return "originallabelfont"_L1;
case VShortcutAction::HideLabels:
return "hidelabels"_L1;
case VShortcutAction::Undo:
return "undo"_L1;
case VShortcutAction::Redo:
return "redo"_L1;
case VShortcutAction::New:
return "new"_L1;
case VShortcutAction::Open:
return "open"_L1;
case VShortcutAction::Save:
return "save"_L1;
case VShortcutAction::SaveAs:
return "saveas"_L1;
case VShortcutAction::DrawMode:
return "drawmode"_L1;
case VShortcutAction::DetailsMode:
return "detailsmode"_L1;
case VShortcutAction::LayoutMode:
return "layoutmode"_L1;
case VShortcutAction::NewPatternPiece:
return "newpatternpiece"_L1;
case VShortcutAction::NextPatternPiece:
return "nextpatternpiece"_L1;
case VShortcutAction::PreviusPatternPiece:
return "previuspatternpiece"_L1;
case VShortcutAction::InteractiveTools:
return "interactivetools"_L1;
case VShortcutAction::TableOfVariables:
return "tableofvariables"_L1;
case VShortcutAction::PatternHistory:
return "patternhistory"_L1;
case VShortcutAction::Quit:
return "quit"_L1;
case VShortcutAction::LastTool:
return "lasttool"_L1;
case VShortcutAction::CurveDetails:
return "curvedetails"_L1;
case VShortcutAction::FinalMeasurements:
return "finalmeasurements"_L1;
case VShortcutAction::CaseSensitiveMatch:
return "casesensitivematch"_L1;
case VShortcutAction::WholeWordMatch:
return "wholewordmatch"_L1;
case VShortcutAction::RegexMatch:
return "regexmatch"_L1;
case VShortcutAction::SearchHistory:
return "searchhistory"_L1;
case VShortcutAction::RegexMatchUnicodeProperties:
return "regexmatchunicodeproperties"_L1;
case VShortcutAction::FindNext:
return "findnext"_L1;
case VShortcutAction::FindPrevious:
return "findprevious"_L1;
case VShortcutAction::LAST_ONE_DO_NOT_USE:
Q_UNREACHABLE();
break;
};
return {};
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractShortcutManager::ReadableName(VShortcutAction type) -> QString
{
Q_STATIC_ASSERT_X(static_cast<int>(VShortcutAction::LAST_ONE_DO_NOT_USE) == 35, "Translate all actions.");
switch (type)
{
case VShortcutAction::ZoomIn:
return tr("Zoom in", "shortcut for action");
case VShortcutAction::ZoomOut:
return tr("Zoom out", "shortcut for action");
case VShortcutAction::ZoomOriginal:
return tr("Zoom original", "shortcut for action");
case VShortcutAction::ZoomFitBest:
return tr("Zoom fit best", "shortcut for action");
case VShortcutAction::ZoomFitBestCurrent:
return tr("Zoom fit best current", "shortcut for action");
case VShortcutAction::IncreaseLabelFont:
return tr("Increase point label font size", "shortcut for action");
case VShortcutAction::DecreaseLabelFont:
return tr("Decrease point label font size", "shortcut for action");
case VShortcutAction::OriginalLabelFont:
return tr("Original point label font size", "shortcut for action");
case VShortcutAction::HideLabels:
return tr("Hide point labels", "shortcut for action");
case VShortcutAction::Undo:
return tr("Undo", "shortcut for action");
case VShortcutAction::Redo:
return tr("Redo", "shortcut for action");
case VShortcutAction::New:
return tr("New", "shortcut for action");
case VShortcutAction::Open:
return tr("Open", "shortcut for action");
case VShortcutAction::Save:
return tr("Save", "shortcut for action");
case VShortcutAction::SaveAs:
return tr("Save as", "shortcut for action");
case VShortcutAction::DrawMode:
return tr("Draw mode", "shortcut for action");
case VShortcutAction::DetailsMode:
return tr("Details mode", "shortcut for action");
case VShortcutAction::LayoutMode:
return tr("Layout mode", "shortcut for action");
case VShortcutAction::NewPatternPiece:
return tr("New pattern piece", "shortcut for action");
case VShortcutAction::NextPatternPiece:
return tr("Next pattern piece", "shortcut for action");
case VShortcutAction::PreviusPatternPiece:
return tr("Previous pattern piece", "shortcut for action");
case VShortcutAction::InteractiveTools:
return tr("Interactive tools mode", "shortcut for action");
case VShortcutAction::TableOfVariables:
return tr("Open Table of variables dialog", "shortcut for action");
case VShortcutAction::PatternHistory:
return tr("Open pattern history dialog", "shortcut for action");
case VShortcutAction::Quit:
return tr("Quit app", "shortcut for action");
case VShortcutAction::LastTool:
return tr("activate last used tool", "shortcut for action");
case VShortcutAction::CurveDetails:
return tr("Show curve details", "shortcut for action");
case VShortcutAction::FinalMeasurements:
return tr("Open final measurements dialog", "shortcut for action");
case VShortcutAction::CaseSensitiveMatch:
return tr("Case sensitive match", "shortcut for action");
case VShortcutAction::WholeWordMatch:
return tr("Whole word match", "shortcut for action");
case VShortcutAction::RegexMatch:
return tr("Regex match", "shortcut for action");
case VShortcutAction::SearchHistory:
return tr("Search history", "shortcut for action");
case VShortcutAction::RegexMatchUnicodeProperties:
return tr("Regex match by unicode properties", "shortcut for action");
case VShortcutAction::FindNext:
return tr("Find next match", "shortcut for action");
case VShortcutAction::FindPrevious:
return tr("Find previus match", "shortcut for action");
case VShortcutAction::LAST_ONE_DO_NOT_USE:
Q_UNREACHABLE(); //-V501
break;
};
return {};
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractShortcutManager::StringListToReadableString(const QStringList &stringList) -> QString
{
QString s = QKeySequence::fromString(stringList.join(", "_L1)).toString(QKeySequence::NativeText);
return s;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractShortcutManager::AddShortcut(const VSShortcut &shortcut)
{
m_shortcutsList.append(shortcut);
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractShortcutManager::CustomKeyBindings(QKeySequence::StandardKey sequence) -> QList<QKeySequence>
{
QT_WARNING_PUSH
#if !defined(Q_OS_MACOS) && defined(Q_CC_CLANG)
QT_WARNING_DISABLE_CLANG("-Wenum-enum-conversion")
#endif
/*
* Because keypad "-" and "+" not the same keys like in main keypad, shortcut Ctrl+"-" or "+" from keypad will not
* working with standard shortcut (QKeySequence::ZoomIn or QKeySequence::ZoomOut). For examle "+" is Qt::Key_Plus +
* Qt::KeypadModifier for keypad. Also for me don't work Qt:CTRL and work Qt::ControlModifier.
*/
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
switch (sequence)
{
case QKeySequence::ZoomIn:
return {QKeySequence(Qt::ControlModifier + Qt::Key_Plus + Qt::KeypadModifier)};
case QKeySequence::ZoomOut:
return {QKeySequence(Qt::ControlModifier + Qt::Key_Minus + Qt::KeypadModifier)};
default:
break;
}
#else
Q_UNUSED(sequence)
#endif
return {};
QT_WARNING_POP
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractShortcutManager::KeyBindingsToStringList(QKeySequence::StandardKey sequence) -> QStringList
{
const auto seqList = QKeySequence::keyBindings(sequence) + CustomKeyBindings(sequence);
QStringList strings;
strings.reserve(seqList.size());
for (const auto &seq : seqList)
{
strings << seq.toString();
}
return strings;
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractShortcutManager::StringListToKeySequenceList(const QStringList &stringList) -> QList<QKeySequence>
{
QList<QKeySequence> keySequences;
keySequences.reserve(stringList.size());
for (const auto &string : stringList)
{
keySequences << QKeySequence::fromString(string);
}
return keySequences;
}

View File

@ -0,0 +1,140 @@
/************************************************************************
**
** @file vabstractshortcutmanager.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 20 10, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VABSTRACTSHORTCUTMANAGER_H
#define VABSTRACTSHORTCUTMANAGER_H
#include <QKeySequence>
#include <QObject>
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <QtCore/QHashFunctions>
#endif
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
#include "defglobal.h"
#endif
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#define QKEY_SEQUENCE_OP |
#else
#define QKEY_SEQUENCE_OP +
#endif
enum class VShortcutAction
{
ZoomIn,
ZoomOut,
ZoomOriginal,
ZoomFitBest,
ZoomFitBestCurrent,
IncreaseLabelFont,
DecreaseLabelFont,
OriginalLabelFont,
HideLabels,
Undo,
Redo,
New,
Open,
Save,
SaveAs,
DrawMode,
DetailsMode,
LayoutMode,
NewPatternPiece,
NextPatternPiece,
PreviusPatternPiece,
InteractiveTools,
TableOfVariables,
PatternHistory,
Quit,
LastTool,
CurveDetails,
FinalMeasurements,
CaseSensitiveMatch,
WholeWordMatch,
RegexMatch,
SearchHistory,
RegexMatchUnicodeProperties,
FindNext,
FindPrevious,
LAST_ONE_DO_NOT_USE
};
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_DECL_CONST_FUNCTION inline auto qHash(VShortcutAction key, uint seed = 0) noexcept -> uint
{
auto underlyingValue = static_cast<typename std::underlying_type<VShortcutAction>::type>(key);
return ::qHash(underlyingValue, seed);
}
#endif
class QAction;
class QAbstractButton;
class VAbstractShortcutManager : public QObject
{
Q_OBJECT // NOLINT
public:
struct VSShortcut
{
VShortcutAction type{};
QStringList defaultShortcuts{};
QStringList shortcuts{};
};
explicit VAbstractShortcutManager(QObject *parent = nullptr);
~VAbstractShortcutManager() override = default;
void UpdateShortcuts();
void UpdateActionShortcuts(const QMultiHash<VShortcutAction, QAction *> &actions);
void UpdateButtonShortcut(const QMultiHash<VShortcutAction, QAbstractButton *> &buttons);
auto GetShortcutsList() const -> QList<VSShortcut>;
static auto ShortcutActionToString(VShortcutAction type) -> QString;
static auto ReadableName(VShortcutAction type) -> QString;
static auto StringListToReadableString(const QStringList &stringList) -> QString;
static auto StringListToKeySequenceList(const QStringList &stringList) -> QList<QKeySequence>;
signals:
void shortcutsUpdated();
protected:
void AddShortcut(const VSShortcut &shortcut);
static auto CustomKeyBindings(QKeySequence::StandardKey sequence) -> QList<QKeySequence>;
static auto KeyBindingsToStringList(QKeySequence::StandardKey sequence) -> QStringList;
private:
Q_DISABLE_COPY_MOVE(VAbstractShortcutManager) // NOLINT
QList<VSShortcut> m_shortcutsList{};
};
#endif // VABSTRACTSHORTCUTMANAGER_H

View File

@ -122,7 +122,7 @@ public:
auto GetDimensionWaistLabel() const -> QString; auto GetDimensionWaistLabel() const -> QString;
void SetDimensionWaistLabel(const QString &label); void SetDimensionWaistLabel(const QString &label);
virtual void OpenSettings() override; void OpenSettings() override;
auto ValentinaSettings() -> VValentinaSettings *; auto ValentinaSettings() -> VValentinaSettings *;
static auto VApp() -> VAbstractValApplication *; static auto VApp() -> VAbstractValApplication *;

View File

@ -1650,3 +1650,20 @@ void VCommonSettings::SetTranslateFormula(bool value)
settings.setValue(*settingsPatternTranslateFormula, value); settings.setValue(*settingsPatternTranslateFormula, value);
settings.sync(); settings.sync();
} }
//---------------------------------------------------------------------------------------------------------------------
auto VCommonSettings::GetActionShortcuts(const QString &name, const QStringList &defaultShortcuts) -> QStringList
{
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
settings.beginGroup("shortcuts"_L1);
return settings.value(name, defaultShortcuts).toStringList();
}
//---------------------------------------------------------------------------------------------------------------------
void VCommonSettings::SetActionShortcuts(const QString &name, const QStringList &shortcuts)
{
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
settings.beginGroup("shortcuts"_L1);
settings.setValue(name, shortcuts);
settings.sync();
}

View File

@ -335,6 +335,9 @@ public:
auto IsTranslateFormula() const -> bool; auto IsTranslateFormula() const -> bool;
void SetTranslateFormula(bool value); void SetTranslateFormula(bool value);
auto GetActionShortcuts(const QString &name, const QStringList &defaultShortcuts) -> QStringList;
void SetActionShortcuts(const QString &name, const QStringList &shortcuts);
signals: signals:
void SVGFontsPathChanged(const QString &oldPath, const QString &newPath); void SVGFontsPathChanged(const QString &oldPath, const QString &newPath);

View File

@ -30,7 +30,8 @@ SOURCES += \
$$PWD/dialogs/dialogexporttocsv.cpp \ $$PWD/dialogs/dialogexporttocsv.cpp \
$$PWD/literals.cpp \ $$PWD/literals.cpp \
$$PWD/vmodifierkey.cpp \ $$PWD/vmodifierkey.cpp \
$$PWD/dialogs/dialogselectlanguage.cpp $$PWD/dialogs/dialogselectlanguage.cpp \
$$PWD/vabstractshortcutmanager.cpp
*msvc*:SOURCES += $$PWD/stable.cpp *msvc*:SOURCES += $$PWD/stable.cpp
@ -123,7 +124,8 @@ HEADERS += \
$$PWD/backport/text.h \ $$PWD/backport/text.h \
$$PWD/dialogs/dialogselectlanguage.h \ $$PWD/dialogs/dialogselectlanguage.h \
$$PWD/fpm/fixed.hpp \ $$PWD/fpm/fixed.hpp \
$$PWD/fpm/math.hpp $$PWD/fpm/math.hpp \
$$PWD/vabstractshortcutmanager.cpp
contains(DEFINES, APPIMAGE) { contains(DEFINES, APPIMAGE) {
SOURCES += \ SOURCES += \

View File

@ -42,6 +42,8 @@ VLib {
"vdatastreamenum.h", "vdatastreamenum.h",
"vmodifierkey.h", "vmodifierkey.h",
"typedef.h", "typedef.h",
"vabstractshortcutmanager.h",
"vabstractshortcutmanager.cpp",
] ]
if (Utilities.versionCompare(Qt.core.version, "6") >= 0) { if (Utilities.versionCompare(Qt.core.version, "6") >= 0) {
@ -75,6 +77,9 @@ VLib {
"dialogselectlanguage.h", "dialogselectlanguage.h",
"dialogexporttocsv.ui", "dialogexporttocsv.ui",
"dialogselectlanguage.ui", "dialogselectlanguage.ui",
"vshortcutdialog.cpp",
"vshortcutdialog.h",
"vshortcutdialog.ui",
] ]
} }

View File

@ -69,7 +69,7 @@ public:
/** Returns a string representation for user interface purposes. /** Returns a string representation for user interface purposes.
* *
* This operator is intented to be used for implicit type casts. */ * This operator is intented to be used for implicit type casts. */
operator QString() const; operator QString() const; // NOLINT(google-explicit-constructor)
/** Returns a shared Alt modifier key. */ /** Returns a shared Alt modifier key. */
static auto Alt() -> const VModifierKey &; static auto Alt() -> const VModifierKey &;