mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-27 20:44:13 +02:00
Merge pull request #1053 from ispyisail/feature/shortcut-bar
Add a shortcut bar that opens at the cursor with S
This commit is contained in:
@@ -285,6 +285,8 @@ set(QET_SRC_FILES
|
||||
${QET_DIR}/sources/recentfiles.h
|
||||
${QET_DIR}/sources/shortcutmanager.cpp
|
||||
${QET_DIR}/sources/shortcutmanager.h
|
||||
${QET_DIR}/sources/shortcutbarsettings.cpp
|
||||
${QET_DIR}/sources/shortcutbarsettings.h
|
||||
${QET_DIR}/sources/commandsearchpopup.cpp
|
||||
${QET_DIR}/sources/commandsearchpopup.h
|
||||
${QET_DIR}/sources/titleblockcell.cpp
|
||||
@@ -801,6 +803,8 @@ set(QET_SRC_FILES
|
||||
${QET_DIR}/sources/ui/configpage/guidespropertieswidget.h
|
||||
${QET_DIR}/sources/ui/configpage/shortcutsconfigpage.cpp
|
||||
${QET_DIR}/sources/ui/configpage/shortcutsconfigpage.h
|
||||
${QET_DIR}/sources/ui/configpage/shortcutbarconfigpage.cpp
|
||||
${QET_DIR}/sources/ui/configpage/shortcutbarconfigpage.h
|
||||
|
||||
${QET_DIR}/sources/undocommand/addelementtextcommand.cpp
|
||||
${QET_DIR}/sources/undocommand/addelementtextcommand.h
|
||||
|
||||
@@ -19,7 +19,10 @@
|
||||
|
||||
#include "elementscollectionwidget.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QGuiApplication>
|
||||
#include <QHBoxLayout>
|
||||
#include <QToolButton>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
@@ -58,6 +61,13 @@ ElementPickerPopup::ElementPickerPopup(ElementsCollectionWidget *source,
|
||||
layout->setContentsMargins(6, 6, 6, 6);
|
||||
layout->setSpacing(4);
|
||||
|
||||
//Command row, shown when the picker is opened as the shortcut bar
|
||||
m_commands = new QWidget(this);
|
||||
m_commands_layout = new QHBoxLayout(m_commands);
|
||||
m_commands_layout->setContentsMargins(0, 0, 0, 0);
|
||||
m_commands_layout->setSpacing(2);
|
||||
m_commands->hide();
|
||||
|
||||
m_search = new QLineEdit(this);
|
||||
m_search->setPlaceholderText(tr("Rechercher un élément…"));
|
||||
m_search->setClearButtonEnabled(true);
|
||||
@@ -73,6 +83,7 @@ ElementPickerPopup::ElementPickerPopup(ElementsCollectionWidget *source,
|
||||
m_hint = new QLabel(tr("Entrée pour insérer · Échap pour fermer"), this);
|
||||
m_hint->setEnabled(false);
|
||||
|
||||
layout->addWidget(m_commands);
|
||||
layout->addWidget(m_search);
|
||||
layout->addWidget(m_view);
|
||||
layout->addWidget(m_hint);
|
||||
@@ -97,8 +108,10 @@ ElementPickerPopup::ElementPickerPopup(ElementsCollectionWidget *source,
|
||||
focused and any previous query cleared.
|
||||
@param global_pos
|
||||
*/
|
||||
void ElementPickerPopup::popUpAt(const QPoint &global_pos)
|
||||
void ElementPickerPopup::popUpAt(const QPoint &global_pos,
|
||||
const QList<QAction *> &commands)
|
||||
{
|
||||
setCommands(commands);
|
||||
m_search->clear();
|
||||
m_model->clear();
|
||||
showPalette();
|
||||
@@ -121,6 +134,53 @@ void ElementPickerPopup::popUpAt(const QPoint &global_pos)
|
||||
m_search->setFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementPickerPopup::setCommands
|
||||
Show @a commands as a row of buttons above the search field, or hide the
|
||||
row when there are none. A disabled command keeps its place, greyed out,
|
||||
so the row looks the same every time for a given selection.
|
||||
|
||||
Clicking a button closes the picker first, then triggers the action: a
|
||||
command such as "add a line" starts a mode on the folio, which needs the
|
||||
focus the popup holds.
|
||||
@param commands
|
||||
*/
|
||||
void ElementPickerPopup::setCommands(const QList<QAction *> &commands)
|
||||
{
|
||||
while (QLayoutItem *item = m_commands_layout->takeAt(0)) {
|
||||
delete item->widget();
|
||||
delete item;
|
||||
}
|
||||
|
||||
for (QAction *action : commands)
|
||||
{
|
||||
auto *button = new QToolButton(m_commands);
|
||||
button->setAutoRaise(true);
|
||||
button->setIconSize(QSize(24, 24));
|
||||
const QString text = action->text().remove(QLatin1Char('&'));
|
||||
if (action->icon().isNull()) {
|
||||
button->setText(text);
|
||||
button->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
} else {
|
||||
button->setIcon(action->icon());
|
||||
}
|
||||
const QKeySequence key = action->shortcut();
|
||||
button->setToolTip(key.isEmpty()
|
||||
? text
|
||||
: QStringLiteral("%1 (%2)").arg(
|
||||
text, key.toString(QKeySequence::NativeText)));
|
||||
button->setEnabled(action->isEnabled());
|
||||
button->setFocusPolicy(Qt::NoFocus);
|
||||
connect(button, &QToolButton::clicked, this, [this, action]() {
|
||||
hide();
|
||||
action->trigger();
|
||||
});
|
||||
m_commands_layout->addWidget(button);
|
||||
}
|
||||
m_commands_layout->addStretch();
|
||||
m_commands->setVisible(!commands.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementPickerPopup::runSearch
|
||||
*/
|
||||
|
||||
@@ -27,6 +27,8 @@ class QLineEdit;
|
||||
class QListView;
|
||||
class QStandardItemModel;
|
||||
class QLabel;
|
||||
class QAction;
|
||||
class QHBoxLayout;
|
||||
|
||||
/**
|
||||
@brief A cursor-anchored element picker.
|
||||
@@ -49,7 +51,8 @@ class ElementPickerPopup : public QFrame
|
||||
explicit ElementPickerPopup(ElementsCollectionWidget *source,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
void popUpAt(const QPoint &global_pos);
|
||||
void popUpAt(const QPoint &global_pos,
|
||||
const QList<QAction *> &commands = {});
|
||||
|
||||
signals:
|
||||
/// Emitted when the user picks an element; the popup has closed
|
||||
@@ -62,6 +65,7 @@ class ElementPickerPopup : public QFrame
|
||||
void runSearch();
|
||||
void chooseCurrent();
|
||||
void showPalette();
|
||||
void setCommands(const QList<QAction *> &commands);
|
||||
int loadPaletteDir(const QString &dir_path, const QString &prefix,
|
||||
int depth);
|
||||
|
||||
@@ -70,6 +74,8 @@ class ElementPickerPopup : public QFrame
|
||||
QListView *m_view = nullptr;
|
||||
QStandardItemModel *m_model = nullptr;
|
||||
QLabel *m_hint = nullptr;
|
||||
QWidget *m_commands = nullptr;
|
||||
QHBoxLayout *m_commands_layout = nullptr;
|
||||
bool m_palette_mode = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "ui/aboutqetdialog.h"
|
||||
#include "ui/configpage/generalconfigurationpage.h"
|
||||
#include "ui/configpage/shortcutsconfigpage.h"
|
||||
#include "ui/configpage/shortcutbarconfigpage.h"
|
||||
#include "machine_info.h"
|
||||
#include "TerminalStrip/ui/terminalstripeditorwindow.h"
|
||||
#include "qetversion.h"
|
||||
@@ -2213,6 +2214,7 @@ void QETApp::configureQET()
|
||||
cd.addPage(new ExportConfigPage());
|
||||
cd.addPage(new PrintConfigPage());
|
||||
cd.addPage(new ShortcutsConfigPage());
|
||||
cd.addPage(new ShortcutBarConfigPage());
|
||||
#ifdef QET_SPACEMOUSE_SUPPORT
|
||||
cd.addPage(new SpaceMouseConfigPage());
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <QToolButton>
|
||||
#include "ElementsCollection/elementscollectionwidget.h"
|
||||
#include "ElementsCollection/elementpickerpopup.h"
|
||||
#include "shortcutbarsettings.h"
|
||||
#include "qetgraphicsitem/conductor.h"
|
||||
#include "commandsearchpopup.h"
|
||||
#include "QWidgetAnimation/qwidgetanimation.h"
|
||||
#include "autoNum/ui/autonumberingdockwidget.h"
|
||||
@@ -77,6 +79,7 @@
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
#include <algorithm>
|
||||
#ifdef BUILD_WITHOUT_KF
|
||||
# include "ui/nokde/kautosavefile.h"
|
||||
#else
|
||||
@@ -873,6 +876,20 @@ void QETDiagramEditor::setUpActions()
|
||||
this, &QETDiagramEditor::showElementPicker);
|
||||
addAction(m_show_element_picker);
|
||||
|
||||
//The picker with a row of commands above it, chosen by what is
|
||||
//selected -- the SolidWorks "S" shortcut bar. S is unbound in this
|
||||
//editor.
|
||||
m_show_shortcut_bar = new QAction(tr("Barre de raccourcis"), this);
|
||||
m_show_shortcut_bar->setStatusTip(
|
||||
tr("Ouvre à la position du curseur les commandes utiles pour la sélection, et le sélecteur d'éléments",
|
||||
"status bar tip"));
|
||||
ShortcutManager::instance().registerAction(
|
||||
m_show_shortcut_bar, "diagrameditor.show_shortcut_bar",
|
||||
tr("Éditeur de schémas"), Qt::Key_S);
|
||||
connect(m_show_shortcut_bar, &QAction::triggered,
|
||||
this, &QETDiagramEditor::showShortcutBar);
|
||||
addAction(m_show_shortcut_bar);
|
||||
|
||||
m_delete_selection->setStatusTip( tr("Enlève les éléments sélectionnés du folio", "status bar tip"));
|
||||
m_rotate_selection->setStatusTip( tr("Pivote les éléments et textes sélectionnés", "status bar tip"));
|
||||
m_rotate_group_selection->setStatusTip( tr("Pivote la sélection comme un groupe autour de son centre, au lieu de chaque élément sur place", "status bar tip"));
|
||||
@@ -1005,7 +1022,8 @@ void QETDiagramEditor::setUpActions()
|
||||
|
||||
connect(&m_add_item_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::addItemGroupTriggered);
|
||||
//No default key, but an id: they can then be found by the command
|
||||
//search and bound in the Shortcuts page, like every other command.
|
||||
//search, bound in the Shortcuts page and placed on the shortcut bar,
|
||||
//like every other command.
|
||||
for (QAction *action : m_add_item_actions_group.actions()) {
|
||||
ShortcutManager::instance().registerAction(
|
||||
action, "diagrameditor.add_" + action->data().toString(),
|
||||
@@ -1166,6 +1184,7 @@ void QETDiagramEditor::setUpMenu()
|
||||
menu_edition -> addAction(m_configure_duplicate);
|
||||
menu_edition -> addAction(m_insert_last_element);
|
||||
menu_edition -> addAction(m_show_element_picker);
|
||||
menu_edition -> addAction(m_show_shortcut_bar);
|
||||
menu_edition -> addAction(m_command_search);
|
||||
menu_edition -> addSeparator();
|
||||
//The same actions the "Ajouter" toolbar holds. They were toolbar-only,
|
||||
@@ -2077,6 +2096,7 @@ void QETDiagramEditor::slot_updateActions()
|
||||
m_add_item_actions_group. setEnabled(editable_project);
|
||||
m_insert_last_element-> setEnabled(opened_diagram && editable_project && !m_last_inserted_element.isNull());
|
||||
m_show_element_picker-> setEnabled(opened_diagram && editable_project);
|
||||
m_show_shortcut_bar-> setEnabled(opened_diagram && editable_project);
|
||||
m_row_column_actions_group. setEnabled(editable_project);
|
||||
m_background_color_button-> setEnabled(opened_diagram);
|
||||
m_draw_grid-> setEnabled(opened_diagram);
|
||||
@@ -3130,18 +3150,12 @@ void QETDiagramEditor::insertLastElement()
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETDiagramEditor::showElementPicker
|
||||
Open the element picker where the mouse is.
|
||||
|
||||
Built lazily: most sessions of the diagram editor never open it, and it
|
||||
holds a list view and a model of its own.
|
||||
@brief QETDiagramEditor::elementPicker
|
||||
@return the element picker, built on first use: most sessions never open
|
||||
it, and it holds a list view and a model of its own.
|
||||
*/
|
||||
void QETDiagramEditor::showElementPicker()
|
||||
ElementPickerPopup *QETDiagramEditor::elementPicker()
|
||||
{
|
||||
if (!currentDiagramView()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_element_picker)
|
||||
{
|
||||
m_element_picker = new ElementPickerPopup(m_element_collection_widget,
|
||||
@@ -3149,7 +3163,56 @@ void QETDiagramEditor::showElementPicker()
|
||||
connect(m_element_picker, &ElementPickerPopup::elementChosen,
|
||||
this, &QETDiagramEditor::insertElementFromCollection);
|
||||
}
|
||||
m_element_picker->popUpAt(QCursor::pos());
|
||||
return m_element_picker;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETDiagramEditor::showElementPicker
|
||||
Open the element picker where the mouse is.
|
||||
*/
|
||||
void QETDiagramEditor::showElementPicker()
|
||||
{
|
||||
if (!currentDiagramView()) {
|
||||
return;
|
||||
}
|
||||
|
||||
elementPicker()->popUpAt(QCursor::pos());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETDiagramEditor::showShortcutBar
|
||||
Open the element picker where the mouse is, with a row of commands above
|
||||
it chosen by what is selected: the folio's commands with nothing
|
||||
selected, conductor commands when only conductors are, and selection
|
||||
commands otherwise. The commands are ShortcutManager ids, listed in
|
||||
ShortcutBarSettings and editable in the configuration dialog.
|
||||
*/
|
||||
void QETDiagramEditor::showShortcutBar()
|
||||
{
|
||||
DiagramView *dv = currentDiagramView();
|
||||
if (!dv) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QList<QGraphicsItem *> selection = dv->diagram()->selectedItems();
|
||||
ShortcutBarSettings::Context context = ShortcutBarSettings::Canvas;
|
||||
if (!selection.isEmpty())
|
||||
{
|
||||
const bool only_conductors = std::all_of(
|
||||
selection.cbegin(), selection.cend(),
|
||||
[](QGraphicsItem *item) { return item->type() == Conductor::Type; });
|
||||
context = only_conductors ? ShortcutBarSettings::Conductor
|
||||
: ShortcutBarSettings::Selection;
|
||||
}
|
||||
|
||||
QList<QAction *> commands;
|
||||
for (const QString &id : ShortcutBarSettings::ids(context)) {
|
||||
if (QAction *action = ShortcutManager::instance().action(id, this)) {
|
||||
commands << action;
|
||||
}
|
||||
}
|
||||
|
||||
elementPicker()->popUpAt(QCursor::pos(), commands);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -133,6 +133,7 @@ class QETDiagramEditor : public QETMainWindow
|
||||
void insertLastElement();
|
||||
void rememberPlacedElement(const ElementsLocation &location);
|
||||
void showElementPicker();
|
||||
void showShortcutBar();
|
||||
void generateTerminalBlock();
|
||||
void setWindowedMode();
|
||||
void setTabbedMode();
|
||||
@@ -276,7 +277,9 @@ class QETDiagramEditor : public QETMainWindow
|
||||
*m_qdw_elmt_collection,
|
||||
*qdw_undo; /// Dock for the undo list
|
||||
|
||||
ElementPickerPopup *elementPicker();
|
||||
QAction *m_show_element_picker = nullptr;
|
||||
QAction *m_show_shortcut_bar = nullptr;
|
||||
ElementPickerPopup *m_element_picker = nullptr; ///< Built on first use
|
||||
QAction *m_command_search = nullptr;
|
||||
CommandSearchPopup *m_command_search_popup = nullptr; ///< Built on first use
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech 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 QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "shortcutbarsettings.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QSettings>
|
||||
|
||||
namespace {
|
||||
QString settingsKey(ShortcutBarSettings::Context context)
|
||||
{
|
||||
switch (context)
|
||||
{
|
||||
case ShortcutBarSettings::Canvas:
|
||||
return QStringLiteral("diagrameditor/shortcut_bar/canvas");
|
||||
case ShortcutBarSettings::Selection:
|
||||
return QStringLiteral("diagrameditor/shortcut_bar/selection");
|
||||
case ShortcutBarSettings::Conductor:
|
||||
return QStringLiteral("diagrameditor/shortcut_bar/conductor");
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@return every context, in the order they are shown to the user
|
||||
*/
|
||||
QList<ShortcutBarSettings::Context> ShortcutBarSettings::contexts()
|
||||
{
|
||||
return {Canvas, Selection, Conductor};
|
||||
}
|
||||
|
||||
/**
|
||||
@return the name of @a context, for the configuration page
|
||||
*/
|
||||
QString ShortcutBarSettings::title(Context context)
|
||||
{
|
||||
switch (context)
|
||||
{
|
||||
case Canvas:
|
||||
return QCoreApplication::translate("ShortcutBarSettings", "Folio, rien de sélectionné");
|
||||
case Selection:
|
||||
return QCoreApplication::translate("ShortcutBarSettings", "Éléments sélectionnés");
|
||||
case Conductor:
|
||||
return QCoreApplication::translate("ShortcutBarSettings", "Conducteurs sélectionnés");
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
/**
|
||||
@return the ids to show for @a context: the user's list if they saved
|
||||
one, the defaults otherwise. A saved empty list stays empty.
|
||||
*/
|
||||
QStringList ShortcutBarSettings::ids(Context context)
|
||||
{
|
||||
QSettings settings;
|
||||
const QString key = settingsKey(context);
|
||||
if (!settings.contains(key)) {
|
||||
return defaultIds(context);
|
||||
}
|
||||
return settings.value(key).toStringList();
|
||||
}
|
||||
|
||||
/**
|
||||
@return the commands a new user sees for @a context
|
||||
*/
|
||||
QStringList ShortcutBarSettings::defaultIds(Context context)
|
||||
{
|
||||
switch (context)
|
||||
{
|
||||
case Canvas:
|
||||
return {QStringLiteral("diagrameditor.insert_last_element"),
|
||||
QStringLiteral("diagrameditor.show_element_picker"),
|
||||
QStringLiteral("diagrameditor.add_text"),
|
||||
QStringLiteral("diagrameditor.add_line"),
|
||||
QStringLiteral("diagrameditor.add_rectangle"),
|
||||
QStringLiteral("diagrameditor.add_terminal_strip"),
|
||||
QStringLiteral("diagrameditor.paste"),
|
||||
QStringLiteral("diagrameditor.edit_diagram_properties")};
|
||||
case Selection:
|
||||
return {QStringLiteral("diagrameditor.rotate_selection"),
|
||||
QStringLiteral("diagrameditor.rotate_texts"),
|
||||
QStringLiteral("diagrameditor.edit_selection"),
|
||||
QStringLiteral("diagrameditor.copy"),
|
||||
QStringLiteral("diagrameditor.cut"),
|
||||
QStringLiteral("diagrameditor.delete_selection")};
|
||||
case Conductor:
|
||||
return {QStringLiteral("diagrameditor.conductor_reset"),
|
||||
QStringLiteral("diagrameditor.edit_selection"),
|
||||
QStringLiteral("diagrameditor.delete_selection")};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ShortcutBarSettings::setIds
|
||||
Save @a ids for @a context. Saving the defaults removes the key, so a
|
||||
later change of defaults still reaches this user.
|
||||
*/
|
||||
void ShortcutBarSettings::setIds(Context context, const QStringList &ids)
|
||||
{
|
||||
QSettings settings;
|
||||
if (ids == defaultIds(context)) {
|
||||
settings.remove(settingsKey(context));
|
||||
} else {
|
||||
settings.setValue(settingsKey(context), ids);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech 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 QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SHORTCUTBARSETTINGS_H
|
||||
#define SHORTCUTBARSETTINGS_H
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
/**
|
||||
@brief The commands shown on the diagram editor's shortcut bar.
|
||||
|
||||
The bar opens at the cursor and shows a different row of commands
|
||||
depending on what is selected. Each row is a list of ShortcutManager ids,
|
||||
so any registered command can go on it and the bar needs no command list
|
||||
of its own. Stored in QSettings, one key per context; a context the user
|
||||
never changed uses the defaults below.
|
||||
*/
|
||||
class ShortcutBarSettings
|
||||
{
|
||||
public:
|
||||
enum Context {
|
||||
Canvas, ///< nothing selected
|
||||
Selection, ///< elements, texts or shapes selected
|
||||
Conductor ///< only conductors selected
|
||||
};
|
||||
|
||||
static QList<Context> contexts();
|
||||
static QString title(Context context);
|
||||
static QStringList ids(Context context);
|
||||
static QStringList defaultIds(Context context);
|
||||
static void setIds(Context context, const QStringList &ids);
|
||||
};
|
||||
|
||||
#endif // SHORTCUTBARSETTINGS_H
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech 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 QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "shortcutbarconfigpage.h"
|
||||
|
||||
#include "../../qeticons.h"
|
||||
#include "../../shortcutmanager.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QComboBox>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace {
|
||||
/// The bar can hold any diagram editor command, except the one that
|
||||
/// opens it.
|
||||
bool offerable(const QString &id)
|
||||
{
|
||||
return id.startsWith(QLatin1String("diagrameditor."))
|
||||
&& id != QLatin1String("diagrameditor.show_shortcut_bar");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ShortcutBarConfigPage::ShortcutBarConfigPage
|
||||
@param parent
|
||||
*/
|
||||
ShortcutBarConfigPage::ShortcutBarConfigPage(QWidget *parent) :
|
||||
ConfigPage(parent)
|
||||
{
|
||||
for (const ShortcutManager::ShortcutInfo &info :
|
||||
ShortcutManager::instance().allShortcuts()) {
|
||||
if (offerable(info.id)) {
|
||||
m_descriptions.insert(info.id, info.description);
|
||||
}
|
||||
}
|
||||
for (const ShortcutBarSettings::Context c : ShortcutBarSettings::contexts()) {
|
||||
m_pending.insert(c, ShortcutBarSettings::ids(c));
|
||||
}
|
||||
|
||||
auto *explanation = new QLabel(
|
||||
tr("La barre de raccourcis s'ouvre à la position du curseur "
|
||||
"(touche S par défaut). Elle montre les commandes choisies "
|
||||
"ici selon ce qui est sélectionné, puis le sélecteur "
|
||||
"d'éléments."), this);
|
||||
explanation->setWordWrap(true);
|
||||
|
||||
m_context = new QComboBox(this);
|
||||
for (const ShortcutBarSettings::Context c : ShortcutBarSettings::contexts()) {
|
||||
m_context->addItem(ShortcutBarSettings::title(c), c);
|
||||
}
|
||||
|
||||
m_available = new QListWidget(this);
|
||||
m_available->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
m_available->setSortingEnabled(true);
|
||||
m_chosen = new QListWidget(this);
|
||||
m_chosen->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
m_chosen->setDragDropMode(QAbstractItemView::InternalMove);
|
||||
|
||||
auto *add = new QPushButton(tr("Ajouter →"), this);
|
||||
auto *remove = new QPushButton(tr("← Retirer"), this);
|
||||
auto *up = new QPushButton(tr("Monter"), this);
|
||||
auto *down = new QPushButton(tr("Descendre"), this);
|
||||
auto *reset = new QPushButton(tr("Valeurs par défaut"), this);
|
||||
|
||||
auto *buttons = new QVBoxLayout();
|
||||
buttons->addStretch();
|
||||
buttons->addWidget(add);
|
||||
buttons->addWidget(remove);
|
||||
buttons->addSpacing(12);
|
||||
buttons->addWidget(up);
|
||||
buttons->addWidget(down);
|
||||
buttons->addStretch();
|
||||
|
||||
auto *grid = new QGridLayout();
|
||||
grid->addWidget(new QLabel(tr("Commandes disponibles"), this), 0, 0);
|
||||
grid->addWidget(new QLabel(tr("Dans la barre, dans l'ordre"), this), 0, 2);
|
||||
grid->addWidget(m_available, 1, 0);
|
||||
grid->addLayout(buttons, 1, 1);
|
||||
grid->addWidget(m_chosen, 1, 2);
|
||||
|
||||
auto *context_row = new QHBoxLayout();
|
||||
context_row->addWidget(new QLabel(tr("Contexte :"), this));
|
||||
context_row->addWidget(m_context, 1);
|
||||
context_row->addWidget(reset);
|
||||
|
||||
auto *layout = new QVBoxLayout(this);
|
||||
layout->addWidget(explanation);
|
||||
layout->addLayout(context_row);
|
||||
layout->addLayout(grid);
|
||||
|
||||
connect(m_context, qOverload<int>(&QComboBox::currentIndexChanged), this, [this]() {
|
||||
storeContext();
|
||||
showContext();
|
||||
});
|
||||
connect(add, &QPushButton::clicked, this, &ShortcutBarConfigPage::addSelected);
|
||||
connect(remove, &QPushButton::clicked, this, &ShortcutBarConfigPage::removeSelected);
|
||||
connect(up, &QPushButton::clicked, this, [this]() { moveSelected(-1); });
|
||||
connect(down, &QPushButton::clicked, this, [this]() { moveSelected(1); });
|
||||
connect(reset, &QPushButton::clicked, this, &ShortcutBarConfigPage::resetContext);
|
||||
connect(m_available, &QListWidget::itemDoubleClicked, this, &ShortcutBarConfigPage::addSelected);
|
||||
connect(m_chosen, &QListWidget::itemDoubleClicked, this, &ShortcutBarConfigPage::removeSelected);
|
||||
|
||||
showContext();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ShortcutBarConfigPage::applyConf
|
||||
Save every context's list.
|
||||
*/
|
||||
void ShortcutBarConfigPage::applyConf()
|
||||
{
|
||||
storeContext();
|
||||
for (const ShortcutBarSettings::Context c : ShortcutBarSettings::contexts()) {
|
||||
ShortcutBarSettings::setIds(c, m_pending.value(c));
|
||||
}
|
||||
}
|
||||
|
||||
QString ShortcutBarConfigPage::title() const
|
||||
{
|
||||
return tr("Barre de raccourcis", "configuration page title");
|
||||
}
|
||||
|
||||
QIcon ShortcutBarConfigPage::icon() const
|
||||
{
|
||||
return QET::Icons::ConfigureShortcuts;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ShortcutBarConfigPage::showContext
|
||||
Fill both lists for the context chosen in the combo box.
|
||||
*/
|
||||
void ShortcutBarConfigPage::showContext()
|
||||
{
|
||||
m_shown = static_cast<ShortcutBarSettings::Context>(
|
||||
m_context->currentData().toInt());
|
||||
const QStringList chosen = m_pending.value(m_shown);
|
||||
|
||||
m_available->clear();
|
||||
m_chosen->clear();
|
||||
for (const QString &id : chosen) {
|
||||
appendItem(m_chosen, id);
|
||||
}
|
||||
for (auto it = m_descriptions.cbegin(); it != m_descriptions.cend(); ++it) {
|
||||
if (!chosen.contains(it.key())) {
|
||||
appendItem(m_available, it.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ShortcutBarConfigPage::storeContext
|
||||
Keep the shown context's list, in the order on screen.
|
||||
*/
|
||||
void ShortcutBarConfigPage::storeContext()
|
||||
{
|
||||
QStringList ids;
|
||||
for (int i = 0 ; i < m_chosen->count() ; ++i) {
|
||||
ids << m_chosen->item(i)->data(Qt::UserRole).toString();
|
||||
}
|
||||
m_pending.insert(m_shown, ids);
|
||||
}
|
||||
|
||||
void ShortcutBarConfigPage::addSelected()
|
||||
{
|
||||
for (QListWidgetItem *item : m_available->selectedItems()) {
|
||||
m_chosen->addItem(m_available->takeItem(m_available->row(item)));
|
||||
}
|
||||
}
|
||||
|
||||
void ShortcutBarConfigPage::removeSelected()
|
||||
{
|
||||
for (QListWidgetItem *item : m_chosen->selectedItems()) {
|
||||
m_available->addItem(m_chosen->takeItem(m_chosen->row(item)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ShortcutBarConfigPage::moveSelected
|
||||
Move the selected command @a step rows, keeping it selected.
|
||||
*/
|
||||
void ShortcutBarConfigPage::moveSelected(int step)
|
||||
{
|
||||
const int row = m_chosen->currentRow();
|
||||
const int target = row + step;
|
||||
if (row < 0 || target < 0 || target >= m_chosen->count()) {
|
||||
return;
|
||||
}
|
||||
QListWidgetItem *item = m_chosen->takeItem(row);
|
||||
m_chosen->insertItem(target, item);
|
||||
m_chosen->setCurrentRow(target);
|
||||
}
|
||||
|
||||
void ShortcutBarConfigPage::resetContext()
|
||||
{
|
||||
m_pending.insert(m_shown, ShortcutBarSettings::defaultIds(m_shown));
|
||||
showContext();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ShortcutBarConfigPage::appendItem
|
||||
Add @a id to @a list with the command's text and icon. An id no live
|
||||
action carries (a command from a build without it) is still listed, by
|
||||
its id, so saving does not silently drop it.
|
||||
*/
|
||||
void ShortcutBarConfigPage::appendItem(QListWidget *list, const QString &id)
|
||||
{
|
||||
QAction *action = ShortcutManager::instance().action(id, nullptr);
|
||||
const QString text = m_descriptions.value(id, id);
|
||||
auto *item = new QListWidgetItem(action ? action->icon() : QIcon(), text);
|
||||
item->setData(Qt::UserRole, id);
|
||||
list->addItem(item);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright 2006-2026 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech 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 QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SHORTCUTBARCONFIGPAGE_H
|
||||
#define SHORTCUTBARCONFIGPAGE_H
|
||||
|
||||
#include "configpage.h"
|
||||
#include "../../shortcutbarsettings.h"
|
||||
|
||||
#include <QHash>
|
||||
|
||||
class QComboBox;
|
||||
class QListWidget;
|
||||
|
||||
/**
|
||||
@brief The ShortcutBarConfigPage class
|
||||
Choose which commands the diagram editor's shortcut bar shows, and in
|
||||
what order, for each selection context. Any command registered with
|
||||
ShortcutManager by the diagram editor can be added. Changes are kept
|
||||
per context while the dialog is open and saved by applyConf().
|
||||
*/
|
||||
class ShortcutBarConfigPage : public ConfigPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ShortcutBarConfigPage(QWidget *parent = nullptr);
|
||||
|
||||
void applyConf() override;
|
||||
QString title() const override;
|
||||
QIcon icon() const override;
|
||||
|
||||
private:
|
||||
void showContext();
|
||||
void storeContext();
|
||||
void addSelected();
|
||||
void removeSelected();
|
||||
void moveSelected(int step);
|
||||
void resetContext();
|
||||
void appendItem(QListWidget *list, const QString &id);
|
||||
|
||||
QComboBox *m_context;
|
||||
QListWidget *m_available;
|
||||
QListWidget *m_chosen;
|
||||
ShortcutBarSettings::Context m_shown = ShortcutBarSettings::Canvas;
|
||||
QHash<int, QStringList> m_pending;
|
||||
QHash<QString, QString> m_descriptions;
|
||||
};
|
||||
|
||||
#endif // SHORTCUTBARCONFIGPAGE_H
|
||||
Reference in New Issue
Block a user