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.
- Tape app. Custom measurement name.
- Tape app. Show variables in order they were added.
- Shortcuts manager.
# Valentina 0.7.52 September 12, 2022
- Fix crash when default locale is ru.

View File

@ -29,7 +29,9 @@
#include "puzzlepreferencesconfigurationpage.h"
#include "../../vpapplication.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/dialogs/vshortcutdialog.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "ui_puzzlepreferencesconfigurationpage.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
@ -79,6 +81,12 @@ PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *
//----------------------- Update
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
ui->spinBoxDuration->setMinimum(VCommonSettings::scrollingDurationMin);
ui->spinBoxDuration->setMaximum(VCommonSettings::scrollingDurationMax);
@ -193,6 +201,19 @@ auto PuzzlePreferencesConfigurationPage::Apply() -> QStringList
}
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
settings->SetScrollingDuration(ui->spinBoxDuration->value());
settings->SetScrollingUpdateInterval(ui->spinBoxUpdateInterval->value());
@ -213,12 +234,27 @@ void PuzzlePreferencesConfigurationPage::changeEvent(QEvent *event)
if (event->type() == QEvent::LanguageChange)
{
// retranslate designer form (single inheritance approach)
RetranslateShortcutsTable();
ui->retranslateUi(this);
}
// remember to call base class implementation
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()
{
@ -227,3 +263,75 @@ void PuzzlePreferencesConfigurationPage::SetThemeModeComboBox()
ui->comboBoxThemeMode->addItem(tr("Dark", "theme"), static_cast<int>(VThemeMode::Dark));
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:
void changeEvent(QEvent *event) override;
private slots:
void ShortcutCellDoubleClicked(int row, int column);
private:
// cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(PuzzlePreferencesConfigurationPage) // NOLINT
Ui::PuzzlePreferencesConfigurationPage *ui;
bool m_langChanged{false};
QList<QStringList> m_transientShortcuts{};
void SetThemeModeComboBox();
void InitShortcuts(bool defaults = false);
void UpdateShortcutsTable();
void RetranslateShortcutsTable();
};
#endif // PUZZLEPREFERENCESCONFIGURATIONPAGE_H

View File

@ -235,6 +235,87 @@ This option will take an affect after restart.</string>
</item>
</layout>
</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">
<attribute name="title">
<string>Scrolling</string>

View File

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

View File

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

View File

@ -40,6 +40,7 @@
#include "../vmisc/vsysexits.h"
#include "version.h"
#include "vpmainwindow.h"
#include "vpuzzleshortcutmanager.h"
#include <QCommandLineParser>
#include <QFileOpenEvent>
@ -459,6 +460,8 @@ void VPApplication::InitOptions()
statistic->SetApiSecret(GA_API_SECRET);
statistic->SetRepoRevision(QLatin1String(BUILD_REVISION));
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);
}
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)
// File
// -------------------- connects the actions for the file menu
ui->actionNew->setShortcuts(QKeySequence::New);
ui->actionSave->setShortcuts(QKeySequence::Save);
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs);
m_actionShortcuts.insert(VShortcutAction::New, ui->actionNew);
m_actionShortcuts.insert(VShortcutAction::Open, ui->actionOpen);
m_actionShortcuts.insert(VShortcutAction::Save, ui->actionSave);
m_actionShortcuts.insert(VShortcutAction::SaveAs, ui->actionSaveAs);
m_recentFileActs.fill(nullptr);
for (auto &recentFileAct : m_recentFileActs)
@ -689,7 +696,7 @@ void VPMainWindow::SetupMenu()
UpdateRecentFileActions();
connect(ui->actionExit, &QAction::triggered, this, &VPMainWindow::close);
ui->actionExit->setShortcuts(QKeySequence::Quit);
m_actionShortcuts.insert(VShortcutAction::Quit, ui->actionExit);
// Layout
connect(ui->actionExportLayout, &QAction::triggered, this, &VPMainWindow::on_ExportLayout);
@ -705,13 +712,13 @@ void VPMainWindow::SetupMenu()
// Add Undo/Redo actions.
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")));
ui->menuSheet->addAction(undoAction);
ui->toolBarUndoCommands->addAction(undoAction);
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")));
ui->menuSheet->addAction(redoAction);
ui->toolBarUndoCommands->addAction(redoAction);
@ -1586,61 +1593,18 @@ void VPMainWindow::InitZoomToolBar()
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
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);
m_actionShortcuts.insert(VShortcutAction::ZoomIn, ui->actionZoomIn);
connect(ui->actionZoomIn, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomIn);
QList<QKeySequence> zoomOutShortcuts;
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);
m_actionShortcuts.insert(VShortcutAction::ZoomOut, ui->actionZoomOut);
connect(ui->actionZoomOut, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOut);
QList<QKeySequence> zoomOriginalShortcuts;
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);
m_actionShortcuts.insert(VShortcutAction::ZoomOriginal, ui->actionZoomOriginal);
connect(ui->actionZoomOriginal, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOriginal);
QList<QKeySequence> zoomFitBestShortcuts;
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);
m_actionShortcuts.insert(VShortcutAction::ZoomFitBest, ui->actionZoomFitBest);
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)
void VPMainWindow::AboutToShowDockMenu()

View File

@ -36,6 +36,7 @@
#include "../vlayout/dialogs/vabstractlayoutdialog.h"
#include "../vlayout/vlayoutpiece.h"
#include "../vmisc/def.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vlockguard.h"
#include "../vwidgets/vabstractmainwindow.h"
#include "carousel/vpcarrousel.h"
@ -294,6 +295,8 @@ private slots:
void LayoutWarningPiecesSuperposition_toggled(bool checked);
void LayoutWarningPiecesOutOfBound_toggled(bool checked);
void UpdateShortcuts();
private:
Q_DISABLE_COPY_MOVE(VPMainWindow) // NOLINT
Ui::VPMainWindow *ui;
@ -339,6 +342,8 @@ private:
QFileSystemWatcher *m_watermarkWatcher{nullptr};
QMultiHash<VShortcutAction, QAction *> m_actionShortcuts{};
struct VPLayoutPrinterPage
{
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 "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/dialogs/vshortcutdialog.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vpatterndb/pmsystems.h"
#include "ui_tapepreferencesconfigurationpage.h"
@ -105,6 +107,12 @@ TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *pare
//----------------------- Update
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
ui->checkBoxSendUsageStatistics->setChecked(settings->IsCollectStatistic());
}
@ -181,6 +189,19 @@ auto TapePreferencesConfigurationPage::Apply() -> QStringList
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
settings->SetCollectStatistic(ui->checkBoxSendUsageStatistics->isChecked());
VGAnalytics::Instance()->Enable(ui->checkBoxSendUsageStatistics->isChecked());
@ -201,6 +222,20 @@ void TapePreferencesConfigurationPage::changeEvent(QEvent *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()
{
@ -215,6 +250,8 @@ void TapePreferencesConfigurationPage::RetranslateUi()
ui->systemCombo->blockSignals(false);
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("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:
void changeEvent(QEvent *event) override;
private slots:
void ShortcutCellDoubleClicked(int row, int column);
private:
// cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(TapePreferencesConfigurationPage) // NOLINT
Ui::TapePreferencesConfigurationPage *ui;
bool m_langChanged;
bool m_systemChanged;
QList<QStringList> m_transientShortcuts{};
void RetranslateUi();
void SetThemeModeComboBox();
void InitShortcuts(bool defaults = false);
void UpdateShortcutsTable();
void RetranslateShortcutsTable();
};
#endif // TAPEPREFERENCESCONFIGURATIONPAGE_H

View File

@ -249,6 +249,87 @@
</item>
</layout>
</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">
<attribute name="title">
<string>Privacy</string>

View File

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

View File

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

View File

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

View File

@ -316,6 +316,20 @@ TMainWindow::TMainWindow(QWidget *parent)
{
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()
{
// File
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->actionOpenMultisize, &QAction::triggered, this, &TMainWindow::OpenMultisize);
@ -2877,10 +2902,10 @@ void TMainWindow::SetupMenu()
connect(ui->actionCreateFromExisting, &QAction::triggered, this, &TMainWindow::CreateFromExisting);
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);
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs);
m_actionShortcuts.insert(VShortcutAction::SaveAs, ui->actionSaveAs);
connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportDataToCSV);
connect(ui->actionImportFromCSV, &QAction::triggered, this, &TMainWindow::ImportDataFromCSV);
@ -2930,7 +2955,7 @@ void TMainWindow::SetupMenu()
ui->menuFile->insertAction(ui->actionPreferences, m_separatorAct);
connect(ui->actionQuit, &QAction::triggered, this, &TMainWindow::close);
ui->actionQuit->setShortcuts(QKeySequence::Quit);
m_actionShortcuts.insert(VShortcutAction::Quit, ui->actionQuit);
// Measurements
connect(ui->actionAddCustom, &QAction::triggered, this, &TMainWindow::AddCustom);
@ -5043,12 +5068,18 @@ void TMainWindow::SaveSearchRequest()
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::UpdateSearchControlsTooltips()
{
auto UpdateToolTip = [](QAbstractButton *button)
auto UpdateToolTip = [this](QAbstractButton *button)
{
if (button->toolTip().contains("%1"_L1))
{
m_serachButtonTooltips.insert(button, button->toolTip());
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);

View File

@ -35,6 +35,7 @@
#include "../vformat/vmeasurements.h"
#include "../vmisc/def.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vlockguard.h"
#include "../vmisc/vtablesearch.h"
#include "../vwidgets/vabstractmainwindow.h"
@ -47,6 +48,7 @@ class TMainWindow;
class QLabel;
class QxtCsvModel;
class VMeasurement;
class QAbstractButton;
class TMainWindow : public VAbstractMainWindow
{
@ -155,6 +157,8 @@ private slots:
void AskDefaultSettings();
void UpdateShortcuts();
private:
// cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(TMainWindow) // NOLINT
@ -201,6 +205,10 @@ private:
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 InitWindow();
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/vsysexits.h"
#include "../vmisc/vvalentinasettings.h"
#include "vvalentinashortcutmanager.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
#include "../vmisc/backport/text.h"
@ -53,6 +54,7 @@
#include <QIcon>
#include <QLoggingCategory>
#include <QMessageBox>
#include <QObject>
#include <QProcess>
#include <QStandardPaths>
#include <QStyleFactory>
@ -704,6 +706,8 @@ void VApplication::InitOptions()
VTheme::InitApplicationStyle();
VTheme::SetIconTheme();
VTheme::InitThemeMode();
m_shortcutManager = new VValentinaShortcutManager(this);
}
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 "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/dialogs/vshortcutdialog.h"
#include "../vmisc/literals.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vvalentinasettings.h"
#include "../vpatterndb/pmsystems.h"
#include "qpushbutton.h"
#include "ui_preferencesconfigurationpage.h"
#include "vcommonsettings.h"
@ -161,6 +164,12 @@ PreferencesConfigurationPage::PreferencesConfigurationPage(QWidget *parent)
//----------------------- Update
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
ui->spinBoxDuration->setMinimum(VCommonSettings::scrollingDurationMin);
ui->spinBoxDuration->setMaximum(VCommonSettings::scrollingDurationMax);
@ -294,6 +303,19 @@ auto PreferencesConfigurationPage::Apply() -> QStringList
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
settings->SetScrollingDuration(ui->spinBoxDuration->value());
settings->SetScrollingUpdateInterval(ui->spinBoxUpdateInterval->value());
@ -321,6 +343,20 @@ void PreferencesConfigurationPage::changeEvent(QEvent *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)
{
@ -387,4 +423,78 @@ void PreferencesConfigurationPage::RetranslateUi()
ui->comboBoxPieceLbelLanguage->blockSignals(false);
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:
void changeEvent(QEvent *event) override;
private slots:
void ShortcutCellDoubleClicked(int row, int column);
private:
// cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(PreferencesConfigurationPage) // NOLINT
@ -62,12 +65,16 @@ private:
bool m_systemChanged{false};
bool m_unitChanged{false};
bool m_labelLangChanged{false};
QList<QStringList> m_transientShortcuts{};
void SetLabelComboBox(const QStringList &list);
void SetThemeModeComboBox();
void SetPointerModeComboBox();
void InitUnits();
void RetranslateUi();
void InitShortcuts(bool defaults = false);
void UpdateShortcutsTable();
void RetranslateShortcutsTable();
};
#endif // PREFERENCESCONFIGURATIONPAGE_H

View File

@ -17,7 +17,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
@ -33,7 +33,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-163</y>
<y>0</y>
<width>624</width>
<height>995</height>
</rect>
@ -443,6 +443,87 @@
</item>
</layout>
</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">
<attribute name="title">
<string>Scrolling</string>

View File

@ -104,6 +104,21 @@ DialogFinalMeasurements::DialogFinalMeasurements(VPattern *doc, QWidget *parent)
{
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());
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::UpdateShortcuts()
{
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
manager->UpdateButtonShortcut(m_shortcuts);
UpdateSearchControlsTooltips();
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::FillFinalMeasurements(bool freshCall)
{
@ -906,12 +931,18 @@ void DialogFinalMeasurements::SaveSearchRequest()
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::UpdateSearchControlsTooltips()
{
auto UpdateToolTip = [](QAbstractButton *button)
auto UpdateToolTip = [this](QAbstractButton *button)
{
if (button->toolTip().contains("%1"_L1))
{
m_serachButtonTooltips.insert(button, button->toolTip());
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);

View File

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

View File

@ -88,6 +88,21 @@ DialogHistory::DialogHistory(VContainer *data, VPattern *doc, QWidget *parent)
ShowPoint();
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)
}
//---------------------------------------------------------------------------------------------------------------------
void DialogHistory::UpdateShortcuts()
{
if (VAbstractShortcutManager *manager = VAbstractApplication::VApp()->GetShortcutManager())
{
manager->UpdateButtonShortcut(m_shortcuts);
UpdateSearchControlsTooltips();
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogHistory::RetranslateUi()
{
@ -784,12 +809,18 @@ void DialogHistory::SaveSearchRequest()
//---------------------------------------------------------------------------------------------------------------------
void DialogHistory::UpdateSearchControlsTooltips()
{
auto UpdateToolTip = [](QAbstractButton *button)
auto UpdateToolTip = [this](QAbstractButton *button)
{
if (button->toolTip().contains("%1"_L1))
{
m_serachButtonTooltips.insert(button, button->toolTip());
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);

View File

@ -29,6 +29,7 @@
#ifndef DIALOGHISTORY_H
#define DIALOGHISTORY_H
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vtools/dialogs/tools/dialogtool.h"
#include <QDomElement>
@ -80,6 +81,9 @@ protected:
auto IsValid() const -> bool final { return true; }
void showEvent(QShowEvent *event) override;
private slots:
void UpdateShortcuts();
private:
// cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(DialogHistory) // NOLINT
@ -96,6 +100,9 @@ private:
QMenu *m_searchHistory;
QMultiHash<VShortcutAction, QAbstractButton *> m_shortcuts{};
QHash<QAbstractButton *, QString> m_serachButtonTooltips{};
void FillTable();
auto Record(const VToolRecord &tool) const -> HistoryRecord;
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);
}
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()
{
auto UpdateToolTip = [](QAbstractButton *button)
auto UpdateToolTip = [this](QAbstractButton *button)
{
if (button->toolTip().contains("%1"_L1))
{
m_serachButtonTooltips.insert(button, button->toolTip());
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);
@ -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,
const QMap<QString, QSharedPointer<VIncrement>> &increments,

View File

@ -29,6 +29,7 @@
#ifndef DIALOGINCREMENTS_H
#define DIALOGINCREMENTS_H
#include "../vmisc/vabstractshortcutmanager.h"
#include "../vmisc/vtablesearch.h"
#include "../vtools/dialogs/tools/dialogtool.h"
#include "../xml/vpattern.h"
@ -82,6 +83,7 @@ private slots:
void DeployFormula();
void Fx();
void RefreshPattern();
void UpdateShortcuts();
private:
// cppcheck-suppress unknownMacro
@ -112,6 +114,9 @@ private:
QMenu *m_searchHistory;
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);
static void FillIncrementsTable(QTableWidget *table, const QMap<QString, QSharedPointer<VIncrement>> &increments,

View File

@ -193,6 +193,7 @@
#include "dialogs/vwidgetgroups.h"
#include "ui_mainwindow.h"
#include "vabstractapplication.h"
#include "vabstractshortcutmanager.h"
#include "vsinglelineoutlinechar.h"
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@ -396,6 +397,7 @@ MainWindow::MainWindow(QWidget *parent)
ToolBarStages();
ToolBarDrawTools();
InitToolButtons();
InitActionShortcuts();
connect(ui->actionAddBackgroundImage, &QAction::triggered, this, &MainWindow::ActionAddBackgroundImage);
connect(ui->actionExportFontCorrections, &QAction::triggered, this, &MainWindow::ActionExportFontCorrections);
@ -533,6 +535,12 @@ MainWindow::MainWindow(QWidget *parent)
}
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()
{
/*First we will try use Standard Shortcuts from Qt, but 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.*/
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);
m_shortcutActions.insert(VShortcutAction::ZoomIn, ui->actionZoomIn);
connect(ui->actionZoomIn, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomIn);
QList<QKeySequence> zoomOutShortcuts;
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);
m_shortcutActions.insert(VShortcutAction::ZoomOut, ui->actionZoomOut);
connect(ui->actionZoomOut, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomOut);
QList<QKeySequence> zoomOriginalShortcuts;
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);
m_shortcutActions.insert(VShortcutAction::ZoomOriginal, ui->actionZoomOriginal);
connect(ui->actionZoomOriginal, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomOriginal);
QList<QKeySequence> zoomFitBestShortcuts;
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);
m_shortcutActions.insert(VShortcutAction::ZoomFitBest, ui->actionZoomFitBest);
connect(ui->actionZoomFitBest, &QAction::triggered, ui->view, &VMainGraphicsView::ZoomFitBest);
QList<QKeySequence> zoomFitBestCurrentShortcuts;
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);
m_shortcutActions.insert(VShortcutAction::ZoomFitBestCurrent, ui->actionZoomFitBestCurrent);
connect(ui->actionZoomFitBestCurrent, &QAction::triggered, this, &MainWindow::ZoomFitBestCurrent);
connect(ui->actionPreviousPatternPiece, &QAction::triggered, this, &MainWindow::PreviousPatternPiece);
connect(ui->actionNextPatternPiece, &QAction::triggered, this, &MainWindow::NextPatternPiece);
ui->actionIncreaseLabelFont->setShortcut(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ShiftModifier | Qt::Key_Plus));
#else
QKeySequence(Qt::ShiftModifier + Qt::Key_Plus));
#endif
m_shortcutActions.insert(VShortcutAction::IncreaseLabelFont, ui->actionIncreaseLabelFont);
connect(ui->actionIncreaseLabelFont, &QAction::triggered, this,
[this]()
{
@ -3036,12 +2986,7 @@ void MainWindow::ToolBarTools()
}
});
ui->actionDecreaseLabelFont->setShortcut(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ShiftModifier | Qt::Key_Minus));
#else
QKeySequence(Qt::ShiftModifier + Qt::Key_Minus));
#endif
m_shortcutActions.insert(VShortcutAction::DecreaseLabelFont, ui->actionDecreaseLabelFont);
connect(ui->actionDecreaseLabelFont, &QAction::triggered, this,
[this]()
{
@ -3058,12 +3003,7 @@ void MainWindow::ToolBarTools()
}
});
ui->actionOriginalLabelFont->setShortcut(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::ShiftModifier | Qt::Key_0));
#else
QKeySequence(Qt::ShiftModifier + Qt::Key_0));
#endif
m_shortcutActions.insert(VShortcutAction::OriginalLabelFont, ui->actionOriginalLabelFont);
connect(ui->actionOriginalLabelFont, &QAction::triggered, this,
[this]()
{
@ -3080,12 +3020,7 @@ void MainWindow::ToolBarTools()
}
});
ui->actionHideLabels->setShortcut(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QKeySequence(Qt::AltModifier | Qt::Key_L));
#else
QKeySequence(Qt::AltModifier + Qt::Key_L));
#endif
m_shortcutActions.insert(VShortcutAction::HideLabels, ui->actionHideLabels);
ui->actionHideLabels->setChecked(VAbstractValApplication::VApp()->ValentinaSettings()->GetHideLabels());
connect(ui->actionHideLabels, &QAction::triggered, this,
[this](bool checked)
@ -3101,8 +3036,6 @@ void MainWindow::ToolBarTools()
m_sceneDetails->update();
}
});
QT_WARNING_POP
}
//---------------------------------------------------------------------------------------------------------------------
@ -3438,6 +3371,28 @@ void MainWindow::InitToolButtons()
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.
@ -5202,6 +5157,15 @@ void MainWindow::ActionOpenTape_triggered()
VApplication::StartDetachedProcess(VApplication::TapeFilePath(), arguments);
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::UpdateShortcuts()
{
if (VAbstractShortcutManager *manager = VAbstractValApplication::VApp()->GetShortcutManager())
{
manager->UpdateActionShortcuts(m_shortcutActions);
}
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::InitDimensionControls()
{
@ -5643,6 +5607,11 @@ void MainWindow::ReadSettings()
QFont f = ui->plainTextEditPatternMessages->font();
f.setPointSize(qMax(settings->GetPatternMessageFontSize(f.pointSize()), 1));
ui->plainTextEditPatternMessages->setFont(f);
if (VAbstractShortcutManager *manager = VAbstractValApplication::VApp()->GetShortcutManager())
{
manager->UpdateShortcuts();
}
}
else
{
@ -5736,14 +5705,14 @@ void MainWindow::CreateMenus()
// Add Undo/Redo actions.
undoAction = VAbstractApplication::VApp()->getUndoStack()->createUndoAction(this, tr("&Undo"));
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")));
ui->menuPatternPiece->insertAction(ui->actionLast_tool, undoAction);
ui->toolBarTools->addAction(undoAction);
redoAction = VAbstractApplication::VApp()->getUndoStack()->createRedoAction(this, tr("&Redo"));
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")));
ui->menuPatternPiece->insertAction(ui->actionLast_tool, redoAction);
ui->toolBarTools->addAction(redoAction);

View File

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

View File

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

View File

@ -161,12 +161,13 @@ VToolApp {
"vformulapropertyeditor.h",
"vtooloptionspropertybrowser.h",
"vcmdexport.h",
"vapplication.cpp",
"vformulaproperty.cpp",
"vformulapropertyeditor.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();
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractApplication::GetShortcutManager() const -> VAbstractShortcutManager *
{
return m_shortcutManager;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractApplication::TextCodecCache(QStringConverter::Encoding encoding) const -> VTextCodec *

View File

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

View File

@ -1650,3 +1650,20 @@ void VCommonSettings::SetTranslateFormula(bool value)
settings.setValue(*settingsPatternTranslateFormula, value);
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;
void SetTranslateFormula(bool value);
auto GetActionShortcuts(const QString &name, const QStringList &defaultShortcuts) -> QStringList;
void SetActionShortcuts(const QString &name, const QStringList &shortcuts);
signals:
void SVGFontsPathChanged(const QString &oldPath, const QString &newPath);

View File

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

View File

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

View File

@ -69,7 +69,7 @@ public:
/** Returns a string representation for user interface purposes.
*
* 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. */
static auto Alt() -> const VModifierKey &;