diff --git a/3rdparty/unioncode-qscintilla214/src/Qsci/qscicommand.h b/3rdparty/unioncode-qscintilla214/src/Qsci/qscicommand.h index 563fb562e..6d2725981 100644 --- a/3rdparty/unioncode-qscintilla214/src/Qsci/qscicommand.h +++ b/3rdparty/unioncode-qscintilla214/src/Qsci/qscicommand.h @@ -36,8 +36,9 @@ class QsciScintilla; //! Methods are provided to change the keys bound to the command and to remove //! a key binding. Each command has a user friendly description of the command //! for use in key mapping dialogs. -class QSCINTILLA_EXPORT QsciCommand +class QSCINTILLA_EXPORT QsciCommand : public QObject { + Q_OBJECT public: //! This enum defines the different commands that can be assigned to a key. enum Command { @@ -343,6 +344,7 @@ class QSCINTILLA_EXPORT QsciCommand //! Reverse the selected lines. ReverseLines = QsciScintillaBase::SCI_LINEREVERSE, }; + Q_ENUM(Command) //! Return the command that will be executed by this instance. Command command() const {return scicmd;} diff --git a/3rdparty/unioncode-qscintilla214/src/qscicommandset.cpp b/3rdparty/unioncode-qscintilla214/src/qscicommandset.cpp index 8757ffc29..a8854566b 100644 --- a/3rdparty/unioncode-qscintilla214/src/qscicommandset.cpp +++ b/3rdparty/unioncode-qscintilla214/src/qscicommandset.cpp @@ -58,33 +58,6 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs) #endif QT_TRANSLATE_NOOP("QsciCommand", "Move down one line") }, - { - QsciCommand::LineDownExtend, - Qt::Key_Down | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_N | Qt::META | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", "Extend selection down one line") - }, - { - QsciCommand::LineDownRectExtend, - Qt::Key_Down | Qt::ALT | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_N | Qt::META | Qt::ALT | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", - "Extend rectangular selection down one line") - }, - { - QsciCommand::LineScrollDown, - Qt::Key_Down | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Scroll view down one line") - }, { QsciCommand::LineUp, Qt::Key_Up, @@ -95,765 +68,24 @@ QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs) #endif QT_TRANSLATE_NOOP("QsciCommand", "Move up one line") }, - { - QsciCommand::LineUpExtend, - Qt::Key_Up | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_P | Qt::META | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", "Extend selection up one line") - }, - { - QsciCommand::LineUpRectExtend, - Qt::Key_Up | Qt::ALT | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_P | Qt::META | Qt::ALT | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", - "Extend rectangular selection up one line") - }, - { - QsciCommand::LineScrollUp, - Qt::Key_Up | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Scroll view up one line") - }, - { - QsciCommand::ScrollToStart, -#if defined(USING_OSX_KEYS) - Qt::Key_Home, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Scroll to start of document") - }, - { - QsciCommand::ScrollToEnd, -#if defined(USING_OSX_KEYS) - Qt::Key_End, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Scroll to end of document") - }, - { - QsciCommand::VerticalCentreCaret, -#if defined(USING_OSX_KEYS) - Qt::Key_L | Qt::META, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Scroll vertically to centre current line") - }, - { - QsciCommand::ParaDown, - Qt::Key_BracketRight | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move down one paragraph") - }, - { - QsciCommand::ParaDownExtend, - Qt::Key_BracketRight | Qt::CTRL | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection down one paragraph") - }, - { - QsciCommand::ParaUp, - Qt::Key_BracketLeft | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move up one paragraph") - }, - { - QsciCommand::ParaUpExtend, - Qt::Key_BracketLeft | Qt::CTRL | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection up one paragraph") - }, - { - QsciCommand::CharLeft, - Qt::Key_Left, -#if defined(USING_OSX_KEYS) - Qt::Key_B | Qt::META, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", "Move left one character") - }, - { - QsciCommand::CharLeftExtend, - Qt::Key_Left | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_B | Qt::META | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection left one character") - }, - { - QsciCommand::CharLeftRectExtend, - Qt::Key_Left | Qt::ALT | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_B | Qt::META | Qt::ALT | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", - "Extend rectangular selection left one character") - }, - { - QsciCommand::CharRight, - Qt::Key_Right, -#if defined(USING_OSX_KEYS) - Qt::Key_F | Qt::META, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", "Move right one character") - }, - { - QsciCommand::CharRightExtend, - Qt::Key_Right | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_F | Qt::META | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection right one character") - }, - { - QsciCommand::CharRightRectExtend, - Qt::Key_Right | Qt::ALT | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_F | Qt::META | Qt::ALT | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", - "Extend rectangular selection right one character") - }, - { - QsciCommand::WordLeft, -#if defined(USING_OSX_KEYS) - Qt::Key_Left | Qt::ALT, -#else - Qt::Key_Left | Qt::CTRL, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move left one word") - }, - { - QsciCommand::WordLeftExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_Left | Qt::ALT | Qt::SHIFT, -#else - Qt::Key_Left | Qt::CTRL | Qt::SHIFT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Extend selection left one word") - }, - { - QsciCommand::WordRight, -#if defined(USING_OSX_KEYS) - 0, -#else - Qt::Key_Right | Qt::CTRL, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move right one word") - }, - { - QsciCommand::WordRightExtend, - Qt::Key_Right | Qt::CTRL | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Extend selection right one word") - }, - { - QsciCommand::WordLeftEnd, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move to end of previous word") - }, - { - QsciCommand::WordLeftEndExtend, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to end of previous word") - }, - { - QsciCommand::WordRightEnd, -#if defined(USING_OSX_KEYS) - Qt::Key_Right | Qt::ALT, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move to end of next word") - }, - { - QsciCommand::WordRightEndExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_Right | Qt::ALT | Qt::SHIFT, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to end of next word") - }, - //{ - // QsciCommand::WordPartLeft, - // Qt::Key_Slash | Qt::CTRL, - // 0, - // QT_TRANSLATE_NOOP("QsciCommand", "Move left one word part") - //}, - { - QsciCommand::WordPartLeftExtend, - Qt::Key_Slash | Qt::CTRL | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection left one word part") - }, - { - QsciCommand::WordPartRight, - Qt::Key_Backslash | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move right one word part") - }, - { - QsciCommand::WordPartRightExtend, - Qt::Key_Backslash | Qt::CTRL | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection right one word part") - }, - { - QsciCommand::Home, -#if defined(USING_OSX_KEYS) - Qt::Key_A | Qt::META, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move to start of document line") - }, - { - QsciCommand::HomeExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_A | Qt::META | Qt::SHIFT, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to start of document line") - }, - { - QsciCommand::HomeRectExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_A | Qt::META | Qt::ALT | Qt::SHIFT, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend rectangular selection to start of document line") - }, - { - QsciCommand::HomeDisplay, -#if defined(USING_OSX_KEYS) - Qt::Key_Left | Qt::CTRL, -#else - Qt::Key_Home | Qt::ALT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move to start of display line") - }, - { - QsciCommand::HomeDisplayExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_Left | Qt::CTRL | Qt::SHIFT, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to start of display line") - }, - { - QsciCommand::HomeWrap, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Move to start of display or document line") - }, - { - QsciCommand::HomeWrapExtend, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to start of display or document line") - }, - { - QsciCommand::VCHome, -#if defined(USING_OSX_KEYS) - 0, -#else - Qt::Key_Home, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Move to first visible character in document line") - }, - { - QsciCommand::VCHomeExtend, -#if defined(USING_OSX_KEYS) - 0, -#else - Qt::Key_Home | Qt::SHIFT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to first visible character in document line") - }, - { - QsciCommand::VCHomeRectExtend, -#if defined(USING_OSX_KEYS) - 0, -#else - Qt::Key_Home | Qt::ALT | Qt::SHIFT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend rectangular selection to first visible character in document line") - }, - { - QsciCommand::VCHomeWrap, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Move to first visible character of display in document line") - }, - { - QsciCommand::VCHomeWrapExtend, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to first visible character in display or document line") - }, - { - QsciCommand::LineEnd, -#if defined(USING_OSX_KEYS) - Qt::Key_E | Qt::META, -#else - Qt::Key_End, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move to end of document line") - }, - { - QsciCommand::LineEndExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_E | Qt::META | Qt::SHIFT, -#else - Qt::Key_End | Qt::SHIFT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to end of document line") - }, - { - QsciCommand::LineEndRectExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_E | Qt::META | Qt::ALT | Qt::SHIFT, -#else - Qt::Key_End | Qt::ALT | Qt::SHIFT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend rectangular selection to end of document line") - }, - { - QsciCommand::LineEndDisplay, -#if defined(USING_OSX_KEYS) - Qt::Key_Right | Qt::CTRL, -#else - Qt::Key_End | Qt::ALT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move to end of display line") - }, - { - QsciCommand::LineEndDisplayExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_Right | Qt::CTRL | Qt::SHIFT, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to end of display line") - }, - { - QsciCommand::LineEndWrap, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Move to end of display or document line") - }, - { - QsciCommand::LineEndWrapExtend, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to end of display or document line") - }, - { - QsciCommand::DocumentStart, -#if defined(USING_OSX_KEYS) - Qt::Key_Up | Qt::CTRL, -#else - Qt::Key_Home | Qt::CTRL, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move to start of document") - }, - { - QsciCommand::DocumentStartExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_Up | Qt::CTRL | Qt::SHIFT, -#else - Qt::Key_Home | Qt::CTRL | Qt::SHIFT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to start of document") - }, - { - QsciCommand::DocumentEnd, -#if defined(USING_OSX_KEYS) - Qt::Key_Down | Qt::CTRL, -#else - Qt::Key_End | Qt::CTRL, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move to end of document") - }, - { - QsciCommand::DocumentEndExtend, -#if defined(USING_OSX_KEYS) - Qt::Key_Down | Qt::CTRL | Qt::SHIFT, -#else - Qt::Key_End | Qt::CTRL | Qt::SHIFT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend selection to end of document") - }, - { - QsciCommand::PageUp, - Qt::Key_PageUp, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move up one page") - }, - { - QsciCommand::PageUpExtend, - Qt::Key_PageUp | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Extend selection up one page") - }, - { - QsciCommand::PageUpRectExtend, - Qt::Key_PageUp | Qt::ALT | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Extend rectangular selection up one page") - }, - { - QsciCommand::PageDown, - Qt::Key_PageDown, -#if defined(USING_OSX_KEYS) - Qt::Key_V | Qt::META, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", "Move down one page") - }, - { - QsciCommand::PageDownExtend, - Qt::Key_PageDown | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_V | Qt::META | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", "Extend selection down one page") - }, - { - QsciCommand::PageDownRectExtend, - Qt::Key_PageDown | Qt::ALT | Qt::SHIFT, -#if defined(USING_OSX_KEYS) - Qt::Key_V | Qt::META | Qt::ALT | Qt::SHIFT, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", - "Extend rectangular selection down one page") - }, - { - QsciCommand::StutteredPageUp, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Stuttered move up one page") - }, - { - QsciCommand::StutteredPageUpExtend, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Stuttered extend selection up one page") - }, - { - QsciCommand::StutteredPageDown, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Stuttered move down one page") - }, - { - QsciCommand::StutteredPageDownExtend, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Stuttered extend selection down one page") - }, - { - QsciCommand::Delete, - Qt::Key_Delete, -#if defined(USING_OSX_KEYS) - Qt::Key_D | Qt::META, -#else - 0, -#endif - QT_TRANSLATE_NOOP("QsciCommand", "Delete current character") - }, - { - QsciCommand::DeleteBack, - Qt::Key_Backspace, -#if defined(USING_OSX_KEYS) - Qt::Key_H | Qt::META, -#else - Qt::Key_Backspace | Qt::SHIFT, -#endif - QT_TRANSLATE_NOOP("QsciCommand", "Delete previous character") - }, - { - QsciCommand::DeleteBackNotLine, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Delete previous character if not at start of line") - }, - { - QsciCommand::DeleteWordLeft, - Qt::Key_Backspace | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Delete word to left") - }, - { - QsciCommand::DeleteWordRight, - Qt::Key_Delete | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Delete word to right") - }, - { - QsciCommand::DeleteWordRightEnd, -#if defined(USING_OSX_KEYS) - Qt::Key_Delete | Qt::ALT, -#else - 0, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Delete right to end of next word") - }, - { - QsciCommand::DeleteLineLeft, - Qt::Key_Backspace | Qt::CTRL | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Delete line to left") - }, - { - QsciCommand::DeleteLineRight, -#if defined(USING_OSX_KEYS) - Qt::Key_K | Qt::META, -#else - Qt::Key_Delete | Qt::CTRL | Qt::SHIFT, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Delete line to right") - }, - { - QsciCommand::LineDelete, - Qt::Key_L | Qt::CTRL | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Delete current line") - }, - { - QsciCommand::LineCut, - Qt::Key_L | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Cut current line") - }, - { - QsciCommand::LineCopy, - Qt::Key_T | Qt::CTRL | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Copy current line") - }, - { - QsciCommand::LineTranspose, - Qt::Key_T | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Transpose current and previous lines") - }, - { - QsciCommand::LineDuplicate, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Duplicate the current line") - }, - { - QsciCommand::SelectAll, - Qt::Key_A | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Select all") - }, - { - QsciCommand::MoveSelectedLinesUp, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Move selected lines up one line") - }, - { - QsciCommand::MoveSelectedLinesDown, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", - "Move selected lines down one line") - }, - { - QsciCommand::SelectionDuplicate, - Qt::Key_D | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Duplicate selection") - }, - { - QsciCommand::SelectionLowerCase, - Qt::Key_U | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Convert selection to lower case") - }, - { - QsciCommand::SelectionUpperCase, - Qt::Key_U | Qt::CTRL | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Convert selection to upper case") - }, - { - QsciCommand::SelectionCut, - Qt::Key_X | Qt::CTRL, - Qt::Key_Delete | Qt::SHIFT, - QT_TRANSLATE_NOOP("QsciCommand", "Cut selection") - }, - { - QsciCommand::SelectionCopy, - Qt::Key_C | Qt::CTRL, - Qt::Key_Insert | Qt::CTRL, - QT_TRANSLATE_NOOP("QsciCommand", "Copy selection") - }, - { - QsciCommand::Paste, - Qt::Key_V | Qt::CTRL, - Qt::Key_Insert | Qt::SHIFT, - QT_TRANSLATE_NOOP("QsciCommand", "Paste") - }, - { - QsciCommand::EditToggleOvertype, - Qt::Key_Insert, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Toggle insert/overtype") - }, { QsciCommand::Newline, Qt::Key_Return, Qt::Key_Return | Qt::SHIFT, QT_TRANSLATE_NOOP("QsciCommand", "Insert newline") }, - { - QsciCommand::Formfeed, - 0, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Formfeed") - }, { QsciCommand::Tab, Qt::Key_Tab, 0, QT_TRANSLATE_NOOP("QsciCommand", "Indent one level") }, - { - QsciCommand::Backtab, - Qt::Key_Tab | Qt::SHIFT, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "De-indent one level") - }, { QsciCommand::Cancel, Qt::Key_Escape, 0, QT_TRANSLATE_NOOP("QsciCommand", "Cancel") - }, - { - QsciCommand::Undo, - Qt::Key_Z | Qt::CTRL, - Qt::Key_Backspace | Qt::ALT, - QT_TRANSLATE_NOOP("QsciCommand", "Undo last command") - }, - { - QsciCommand::Redo, -#if defined(USING_OSX_KEYS) - Qt::Key_Z | Qt::CTRL | Qt::SHIFT, -#else - Qt::Key_Y | Qt::CTRL, -#endif - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Redo last command") - }, - { - QsciCommand::ZoomIn, - Qt::Key_Plus | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Zoom in") - }, - { - QsciCommand::ZoomOut, - Qt::Key_Minus | Qt::CTRL, - 0, - QT_TRANSLATE_NOOP("QsciCommand", "Zoom out") - }, + } }; // Clear the default map. diff --git a/src/common/actionmanager/actionmanager.cpp b/src/common/actionmanager/actionmanager.cpp index 96e74c0d2..f486f616f 100644 --- a/src/common/actionmanager/actionmanager.cpp +++ b/src/common/actionmanager/actionmanager.cpp @@ -123,7 +123,7 @@ void ActionManagerPrivate::saveSettings(Command *cmd) settings.setValue(settingsKey, keys.first().toString()); } else { QStringList shortcutList; - std::transform(keys.begin(), keys.end(), shortcutList.begin(), + std::transform(keys.begin(), keys.end(), std::back_inserter(shortcutList), [](const QKeySequence &k) { return k.toString(); }); @@ -142,7 +142,7 @@ void ActionManagerPrivate::readUserSettings(const QString &id, Command *cmd) if (QMetaType::Type(v.type()) == QMetaType::QStringList) { auto list = v.toStringList(); QList keySequenceList; - std::transform(list.begin(), list.end(), keySequenceList.begin(), + std::transform(list.begin(), list.end(), std::back_inserter(keySequenceList), [](const QString &s) { return QKeySequence::fromString(s); }); diff --git a/src/plugins/binarytools/configure/binarytoolsmanager.cpp b/src/plugins/binarytools/configure/binarytoolsmanager.cpp index 1a1898547..622675f50 100644 --- a/src/plugins/binarytools/configure/binarytoolsmanager.cpp +++ b/src/plugins/binarytools/configure/binarytoolsmanager.cpp @@ -425,7 +425,8 @@ void BinaryToolsManager::updateToolMenu(const BinaryTools &tools) for (const auto &tool : iter.value()) { auto act = new QAction(QIcon::fromTheme(tool.icon), tool.name, mGroup); - auto cmd = ActionManager::instance()->registerAction(act, tool.id); + auto actId = QString("BinaryTools.Tool.%1").arg(tool.id); + auto cmd = ActionManager::instance()->registerAction(act, actId); mGroup->addAction(cmd); connect(act, &QAction::triggered, this, std::bind(&BinaryToolsManager::executeTool, this, tool.id)); @@ -578,7 +579,8 @@ void BinaryToolsManager::addToToolBar(const ToolInfo &tool) act->setIcon(QIcon::fromTheme(tool.icon)); connect(act, &QAction::triggered, this, std::bind(&BinaryToolsManager::executeTool, this, tool.id)); - auto cmd = ActionManager::instance()->registerAction(act, tool.id); + auto actId = QString("BinaryTools.Tool.%1").arg(tool.id); + auto cmd = ActionManager::instance()->registerAction(act, actId); return cmd; }; diff --git a/src/plugins/codeeditor/codeeditor.cpp b/src/plugins/codeeditor/codeeditor.cpp index dc49ab0a2..a3abfef76 100644 --- a/src/plugins/codeeditor/codeeditor.cpp +++ b/src/plugins/codeeditor/codeeditor.cpp @@ -117,38 +117,38 @@ void CodeEditor::initActions() QAction *backAction = new QAction(tr("Backward"), this); connect(backAction, &QAction::triggered, EditorCallProxy::instance(), &EditorCallProxy::reqBack); - auto cmd = EditorUtils::registerShortcut(backAction, "Editor.back", QKeySequence(Qt::ALT | Qt::Key_Left)); + auto cmd = EditorUtils::registerShortcut(backAction, "TextEditor.back", QKeySequence(Qt::ALT | Qt::Key_Left)); mEdit->addAction(cmd); QAction *forwardAction = new QAction(tr("Forward"), this); connect(forwardAction, &QAction::triggered, EditorCallProxy::instance(), &EditorCallProxy::reqForward); - cmd = EditorUtils::registerShortcut(forwardAction, "Editor.forward", QKeySequence(Qt::ALT | Qt::Key_Right)); + cmd = EditorUtils::registerShortcut(forwardAction, "TextEditor.forward", QKeySequence(Qt::ALT | Qt::Key_Right)); mEdit->addAction(cmd); QAction *closeAction = new QAction(tr("Close Current Editor"), this); connect(closeAction, &QAction::triggered, EditorCallProxy::instance(), &EditorCallProxy::reqCloseCurrentEditor); - cmd = EditorUtils::registerShortcut(closeAction, "Editor.close", QKeySequence(Qt::CTRL | Qt::Key_W)); + cmd = EditorUtils::registerShortcut(closeAction, "TextEditor.close", QKeySequence(Qt::CTRL | Qt::Key_W)); mEdit->addAction(cmd, G_EDIT_OTHER); QAction *switchHeaderSourceAction = new QAction(tr("Switch Header/Source"), this); connect(switchHeaderSourceAction, &QAction::triggered, EditorCallProxy::instance(), &EditorCallProxy::reqSwitchHeaderSource); - EditorUtils::registerShortcut(switchHeaderSourceAction, "Editor.switchHS", QKeySequence(Qt::Key_F4)); + EditorUtils::registerShortcut(switchHeaderSourceAction, "TextEditor.switchHS", QKeySequence(Qt::Key_F4)); QAction *follSymbolAction = new QAction(tr("Follow Symbol Under Cursor"), this); connect(follSymbolAction, &QAction::triggered, EditorCallProxy::instance(), &EditorCallProxy::reqFollowSymbolUnderCursor); - EditorUtils::registerShortcut(follSymbolAction, "Editor.followSymbol", QKeySequence(Qt::Key_F2)); + EditorUtils::registerShortcut(follSymbolAction, "TextEditor.followSymbol", QKeySequence(Qt::Key_F2)); QAction *toggleBreakpointAction = new QAction(tr("Toggle Breakpoint"), this); connect(toggleBreakpointAction, &QAction::triggered, EditorCallProxy::instance(), &EditorCallProxy::reqToggleBreakpoint); - EditorUtils::registerShortcut(toggleBreakpointAction, "Editor.toggleBreak", QKeySequence(Qt::Key_F9)); + EditorUtils::registerShortcut(toggleBreakpointAction, "TextEditor.toggleBreak", QKeySequence(Qt::Key_F9)); QAction *findUsageAction = new QAction(tr("Find Usages"), this); connect(findUsageAction, &QAction::triggered, EditorCallProxy::instance(), &EditorCallProxy::reqFindUsage); - EditorUtils::registerShortcut(findUsageAction, "Editor.findUsage", QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_G)); + EditorUtils::registerShortcut(findUsageAction, "TextEditor.findUsage", QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_G)); QAction *renameAction = new QAction(tr("Rename Symbol Under Cursor"), this); connect(renameAction, &QAction::triggered, EditorCallProxy::instance(), &EditorCallProxy::reqRenameSymbol); - EditorUtils::registerShortcut(renameAction, "Editor.rename", QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_R)); + EditorUtils::registerShortcut(renameAction, "TextEditor.rename", QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_R)); } void CodeEditor::initEditorService() diff --git a/src/plugins/codeeditor/find/editordocumentfind.cpp b/src/plugins/codeeditor/find/editordocumentfind.cpp index 3cac5e45a..2c949d59f 100644 --- a/src/plugins/codeeditor/find/editordocumentfind.cpp +++ b/src/plugins/codeeditor/find/editordocumentfind.cpp @@ -56,7 +56,7 @@ TabWidget *EditorDocumentFindPrivate::tabWidget() const QWidget *EditorDocumentFindPrivate::autoAdjustCurrentEditor() { - auto w = tabWidget()->currentWidget(); + auto w = tabWidget()->currentEditor(); if (w != curEditor) { curEditor = w; isFindFirst = true; diff --git a/src/plugins/codeeditor/gui/private/workspacewidget_p.h b/src/plugins/codeeditor/gui/private/workspacewidget_p.h index 972bac218..e85c9e881 100644 --- a/src/plugins/codeeditor/gui/private/workspacewidget_p.h +++ b/src/plugins/codeeditor/gui/private/workspacewidget_p.h @@ -11,6 +11,7 @@ #include "base/abstracteditwidget.h" #include "common/util/eventdefinitions.h" #include "services/window/windowservice.h" +#include "Qsci/qscicommand.h" #include diff --git a/src/plugins/codeeditor/gui/tabwidget.cpp b/src/plugins/codeeditor/gui/tabwidget.cpp index 9674e0e72..f0e01dcab 100644 --- a/src/plugins/codeeditor/gui/tabwidget.cpp +++ b/src/plugins/codeeditor/gui/tabwidget.cpp @@ -857,7 +857,7 @@ void TabWidget::updateZoomValue(int value) } } -QWidget *TabWidget::currentWidget() const +TextEditor *TabWidget::currentEditor() const { return d->currentTextEditor(); } diff --git a/src/plugins/codeeditor/gui/tabwidget.h b/src/plugins/codeeditor/gui/tabwidget.h index 79a75e4aa..d6b909659 100644 --- a/src/plugins/codeeditor/gui/tabwidget.h +++ b/src/plugins/codeeditor/gui/tabwidget.h @@ -65,7 +65,7 @@ class TabWidget : public QWidget int zoomValue(); void updateZoomValue(int value); - QWidget *currentWidget() const; + TextEditor *currentEditor() const; TextEditor *findEditor(const QString &fileName); public slots: diff --git a/src/plugins/codeeditor/gui/workspacewidget.cpp b/src/plugins/codeeditor/gui/workspacewidget.cpp index 05732ca91..6e21bd60c 100644 --- a/src/plugins/codeeditor/gui/workspacewidget.cpp +++ b/src/plugins/codeeditor/gui/workspacewidget.cpp @@ -7,7 +7,6 @@ #include "transceiver/codeeditorreceiver.h" #include "settings/editorsettings.h" #include "settings/settingsdefine.h" -#include "base/abstractaction.h" #include "symbol/symbolwidget.h" #include "texteditor.h" @@ -18,6 +17,8 @@ #include #include +constexpr char TextEditorContext[] { "Text Editor" }; + using namespace dpfservice; DWIDGET_USE_NAMESPACE @@ -67,15 +68,388 @@ void WorkspaceWidgetPrivate::initActions() // add/del comment QAction *commentAction = new QAction(tr("Add/Delete Comment"), q); - auto cmd = ActionManager::instance()->registerAction(commentAction, "Editor.AddAndRemoveComment"); + auto cmd = ActionManager::instance()->registerAction(commentAction, "TextEditor.AddAndRemoveComment"); cmd->setDefaultKeySequence(Qt::CTRL | Qt::Key_Slash); connect(commentAction, &QAction::triggered, this, &WorkspaceWidgetPrivate::handleSetComment); // show opened files QAction *showOpenedAction = new QAction(tr("Show opened files"), q); - cmd = ActionManager::instance()->registerAction(commentAction, "Editor.ShowOpenedFiles"); + cmd = ActionManager::instance()->registerAction(showOpenedAction, "TextEditor.ShowOpenedFiles"); cmd->setDefaultKeySequence(Qt::CTRL | Qt::Key_Tab); connect(showOpenedAction, &QAction::triggered, this, &WorkspaceWidgetPrivate::handleShowOpenedFiles); + + QMetaEnum me = QMetaEnum::fromType(); + for (int i = 0; i < me.keyCount(); ++i) { + QList ksList; + QString actionText; + QsciCommand::Command val = static_cast(me.value(i)); + switch (val) { + case QsciCommand::LineDownExtend: + actionText = tr("Extend selection down one line"); + ksList.append(Qt::Key_Down | Qt::SHIFT); + break; + case QsciCommand::LineDownRectExtend: + actionText = tr("Extend rectangular selection down one line"); + ksList.append(Qt::Key_Down | Qt::ALT | Qt::SHIFT); + break; + case QsciCommand::LineScrollDown: + actionText = tr("Scroll view down one line"); + ksList.append(Qt::Key_Down | Qt::CTRL); + break; + case QsciCommand::LineUpExtend: + actionText = tr("Extend selection up one line"); + ksList.append(Qt::Key_Up | Qt::SHIFT); + break; + case QsciCommand::LineUpRectExtend: + actionText = tr("Extend rectangular selection up one line"); + ksList.append(Qt::Key_Up | Qt::ALT | Qt::SHIFT); + break; + case QsciCommand::LineScrollUp: + actionText = tr("Scroll view up one line"); + ksList.append(Qt::Key_Up | Qt::CTRL); + break; + case QsciCommand::ScrollToStart: + actionText = tr("Scroll to start of document"); + break; + case QsciCommand::ScrollToEnd: + actionText = tr("Scroll to end of document"); + break; + case QsciCommand::VerticalCentreCaret: + actionText = tr("Scroll vertically to centre current line"); + break; + case QsciCommand::ParaDown: + actionText = tr("Move down one paragraph"); + ksList.append(Qt::Key_BracketRight | Qt::CTRL); + break; + case QsciCommand::ParaDownExtend: + actionText = tr("Extend selection down one paragraph"); + ksList.append(Qt::Key_BracketRight | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::ParaUp: + actionText = tr("Move up one paragraph"); + ksList.append(Qt::Key_BracketLeft | Qt::CTRL); + break; + case QsciCommand::ParaUpExtend: + actionText = tr("Extend selection up one paragraph"); + ksList.append(Qt::Key_BracketLeft | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::CharLeft: + actionText = tr("Move left one character"); + ksList.append(Qt::Key_Left); + break; + case QsciCommand::CharLeftExtend: + actionText = tr("Extend selection left one character"); + ksList.append(Qt::Key_Left | Qt::SHIFT); + break; + case QsciCommand::CharLeftRectExtend: + actionText = tr("Extend rectangular selection left one character"); + ksList.append(Qt::Key_Left | Qt::ALT | Qt::SHIFT); + break; + case QsciCommand::CharRight: + actionText = tr("Move right one character"); + ksList.append(Qt::Key_Right); + break; + case QsciCommand::CharRightExtend: + actionText = tr("Extend selection right one character"); + ksList.append(Qt::Key_Right | Qt::SHIFT); + break; + case QsciCommand::CharRightRectExtend: + actionText = tr("Extend rectangular selection right one character"); + ksList.append(Qt::Key_Right | Qt::ALT | Qt::SHIFT); + break; + case QsciCommand::WordLeft: + actionText = tr("Move left one word"); + ksList.append(Qt::Key_Left | Qt::CTRL); + break; + case QsciCommand::WordLeftExtend: + actionText = tr("Extend selection left one word"); + ksList.append(Qt::Key_Left | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::WordRight: + actionText = tr("Move right one word"); + ksList.append(Qt::Key_Right | Qt::CTRL); + break; + case QsciCommand::WordRightExtend: + actionText = tr("Extend selection right one word"); + ksList.append(Qt::Key_Right | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::WordLeftEnd: + actionText = tr("Move to end of previous word"); + break; + case QsciCommand::WordLeftEndExtend: + actionText = tr("Extend selection to end of previous word"); + break; + case QsciCommand::WordRightEnd: + actionText = tr("Move to end of next word"); + break; + case QsciCommand::WordRightEndExtend: + actionText = tr("Extend selection to end of next word"); + break; + case QsciCommand::WordPartLeft: + actionText = tr("Move left one word part"); + break; + case QsciCommand::WordPartLeftExtend: + actionText = tr("Extend selection left one word part"); + ksList.append(Qt::Key_Slash | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::WordPartRight: + actionText = tr("Move right one word part"); + ksList.append(Qt::Key_Backslash | Qt::CTRL); + break; + case QsciCommand::WordPartRightExtend: + actionText = tr("Extend selection right one word part"); + ksList.append(Qt::Key_Backslash | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::Home: + actionText = tr("Move to start of document line"); + break; + case QsciCommand::HomeExtend: + actionText = tr("Extend selection to start of document line"); + break; + case QsciCommand::HomeRectExtend: + actionText = tr("Extend rectangular selection to start of document line"); + break; + case QsciCommand::HomeDisplay: + actionText = tr("Move to start of display line"); + ksList.append(Qt::Key_Home | Qt::ALT); + break; + case QsciCommand::HomeDisplayExtend: + actionText = tr("Extend selection to start of display line"); + break; + case QsciCommand::HomeWrap: + actionText = tr("Move to start of display or document line"); + break; + case QsciCommand::HomeWrapExtend: + actionText = tr("Extend selection to start of display or document line"); + break; + case QsciCommand::VCHome: + actionText = tr("Move to first visible character in document line"); + ksList.append(Qt::Key_Home); + break; + case QsciCommand::VCHomeExtend: + actionText = tr("Extend selection to first visible character in document line"); + ksList.append(Qt::Key_Home | Qt::SHIFT); + break; + case QsciCommand::VCHomeRectExtend: + actionText = tr("Extend rectangular selection to first visible character in document line"); + ksList.append(Qt::Key_Home | Qt::ALT | Qt::SHIFT); + break; + case QsciCommand::VCHomeWrap: + actionText = tr("Move to first visible character of display in document line"); + break; + case QsciCommand::VCHomeWrapExtend: + actionText = tr("Extend selection to first visible character in display or document line"); + break; + case QsciCommand::LineEnd: + actionText = tr("Move to end of document line"); + ksList.append(Qt::Key_End); + break; + case QsciCommand::LineEndExtend: + actionText = tr("Extend selection to end of document line"); + ksList.append(Qt::Key_End | Qt::SHIFT); + break; + case QsciCommand::LineEndRectExtend: + actionText = tr("Extend rectangular selection to end of document line"); + ksList.append(Qt::Key_End | Qt::ALT | Qt::SHIFT); + break; + case QsciCommand::LineEndDisplay: + actionText = tr("Move to end of display line"); + ksList.append(Qt::Key_End | Qt::ALT); + break; + case QsciCommand::LineEndDisplayExtend: + actionText = tr("Extend selection to end of display line"); + break; + case QsciCommand::LineEndWrap: + actionText = tr("Move to end of display or document line"); + break; + case QsciCommand::LineEndWrapExtend: + actionText = tr("Extend selection to end of display or document line"); + break; + case QsciCommand::DocumentStart: + actionText = tr("Move to start of document"); + ksList.append(Qt::Key_Home | Qt::CTRL); + break; + case QsciCommand::DocumentStartExtend: + actionText = tr("Extend selection to start of document"); + ksList.append(Qt::Key_Home | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::DocumentEnd: + actionText = tr("Move to end of document"); + ksList.append(Qt::Key_End | Qt::CTRL); + break; + case QsciCommand::DocumentEndExtend: + actionText = tr("Extend selection to end of document"); + ksList.append(Qt::Key_End | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::PageUp: + actionText = tr("Move up one page"); + ksList.append(Qt::Key_PageUp); + break; + case QsciCommand::PageUpExtend: + actionText = tr("Extend selection up one page"); + ksList.append(Qt::Key_PageUp | Qt::SHIFT); + break; + case QsciCommand::PageUpRectExtend: + actionText = tr("Extend rectangular selection up one page"); + ksList.append(Qt::Key_PageUp | Qt::ALT | Qt::SHIFT); + break; + case QsciCommand::PageDown: + actionText = tr("Move down one page"); + ksList.append(Qt::Key_PageDown); + break; + case QsciCommand::PageDownExtend: + actionText = tr("Extend selection down one page"); + ksList.append(Qt::Key_PageDown | Qt::SHIFT); + break; + case QsciCommand::PageDownRectExtend: + actionText = tr("Extend rectangular selection down one page"); + ksList.append(Qt::Key_PageDown | Qt::ALT | Qt::SHIFT); + break; + case QsciCommand::StutteredPageUp: + actionText = tr("Stuttered move up one page"); + break; + case QsciCommand::StutteredPageUpExtend: + actionText = tr("Stuttered extend selection up one page"); + break; + case QsciCommand::StutteredPageDown: + actionText = tr("Stuttered move down one page"); + break; + case QsciCommand::StutteredPageDownExtend: + actionText = tr("Stuttered extend selection down one page"); + break; + case QsciCommand::Delete: + actionText = tr("Delete current character"); + ksList.append(Qt::Key_Delete); + break; + case QsciCommand::DeleteBack: + actionText = tr("Delete previous character"); + ksList.append(Qt::Key_Backspace); + break; + case QsciCommand::DeleteBackNotLine: + actionText = tr("Delete previous character if not at start of line"); + break; + case QsciCommand::DeleteWordLeft: + actionText = tr("Delete word to left"); + ksList.append(Qt::Key_Backspace | Qt::CTRL); + break; + case QsciCommand::DeleteWordRight: + actionText = tr("Delete word to right"); + ksList.append(Qt::Key_Delete | Qt::CTRL); + break; + case QsciCommand::DeleteWordRightEnd: + actionText = tr("Delete right to end of next word"); + break; + case QsciCommand::DeleteLineLeft: + actionText = tr("Delete line to left"); + ksList.append(Qt::Key_Backspace | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::DeleteLineRight: + actionText = tr("Delete line to right"); + ksList.append(Qt::Key_Delete | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::LineDelete: + actionText = tr("Delete current line"); + ksList.append(Qt::Key_L | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::LineCut: + actionText = tr("Cut current line"); + ksList.append(Qt::Key_L | Qt::CTRL); + break; + case QsciCommand::LineCopy: + actionText = tr("Copy current line"); + ksList.append(Qt::Key_T | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::LineTranspose: + actionText = tr("Transpose current and previous lines"); + break; + case QsciCommand::LineDuplicate: + actionText = tr("Duplicate the current line"); + break; + case QsciCommand::SelectAll: + actionText = tr("Select all"); + ksList.append(Qt::Key_A | Qt::CTRL); + break; + case QsciCommand::MoveSelectedLinesUp: + actionText = tr("Move selected lines up one line"); + break; + case QsciCommand::MoveSelectedLinesDown: + actionText = tr("Move selected lines down one line"); + break; + case QsciCommand::SelectionDuplicate: + actionText = tr("Duplicate selection"); + ksList.append(Qt::Key_D | Qt::CTRL); + break; + case QsciCommand::SelectionLowerCase: + actionText = tr("Convert selection to lower case"); + ksList.append(Qt::Key_U | Qt::CTRL); + break; + case QsciCommand::SelectionUpperCase: + actionText = tr("Convert selection to upper case"); + ksList.append(Qt::Key_U | Qt::CTRL | Qt::SHIFT); + break; + case QsciCommand::SelectionCut: + actionText = tr("Cut selection"); + ksList.append(Qt::Key_X | Qt::CTRL); + ksList.append(Qt::Key_Delete | Qt::SHIFT); + break; + case QsciCommand::SelectionCopy: + actionText = tr("Copy selection"); + ksList.append(Qt::Key_C | Qt::CTRL); + ksList.append(Qt::Key_Insert | Qt::CTRL); + break; + case QsciCommand::Paste: + actionText = tr("Paste"); + ksList.append(Qt::Key_V | Qt::CTRL); + ksList.append(Qt::Key_Insert | Qt::SHIFT); + break; + case QsciCommand::EditToggleOvertype: + actionText = tr("Toggle insert/overtype"); + ksList.append(Qt::Key_Insert); + break; + case QsciCommand::Formfeed: + actionText = tr("Formfeed"); + break; + case QsciCommand::Backtab: + actionText = tr("De-indent one level"); + ksList.append(Qt::Key_Tab | Qt::SHIFT); + break; + case QsciCommand::Undo: + actionText = tr("Undo last command"); + ksList.append(Qt::Key_Z | Qt::CTRL); + ksList.append(Qt::Key_Backspace | Qt::ALT); + break; + case QsciCommand::Redo: + actionText = tr("Redo last command"); + ksList.append(Qt::Key_Y | Qt::CTRL); + break; + case QsciCommand::ZoomIn: + actionText = tr("Zoom in"); + ksList.append(Qt::Key_Plus | Qt::CTRL); + break; + case QsciCommand::ZoomOut: + actionText = tr("Zoom out"); + ksList.append(Qt::Key_Minus | Qt::CTRL); + break; + default: + break; + } + + if (!actionText.isEmpty()) { + auto id = QString("TextEditor.%1").arg(me.valueToKey(val)); + auto act = new QAction(actionText, q); + auto cmd = ActionManager::instance()->registerAction(act, id, { TextEditorContext }); + if (!ksList.isEmpty()) + cmd->setDefaultKeySequences(ksList); + connect(act, &QAction::triggered, this, [val, this] { + auto tabWidget = currentTabWidget(); + if (!tabWidget) + return; + + if (auto editor = tabWidget->currentEditor()) + editor->SendScintilla(val); + }); + } + } } void WorkspaceWidgetPrivate::handleSetComment() @@ -355,7 +729,7 @@ void WorkspaceWidgetPrivate::onCloseRequested() tabWidgetList.last()->setFocus(); editor.switchedFile(tabWidgetList.last()->currentFile()); auto symbolWidget = SymbolWidgetGenerator::instance()->symbolWidget(); - symbolWidget->setEditor(qobject_cast(tabWidgetList.last()->currentWidget())); + symbolWidget->setEditor(tabWidgetList.last()->currentEditor()); } if (tabWidgetList.size() == 1) @@ -514,18 +888,23 @@ void WorkspaceWidgetPrivate::onFocusChanged(QWidget *old, QWidget *now) { Q_UNUSED(old) - if (!now) + if (!now) { + ActionManager::instance()->removeContext({ TextEditorContext }); return; + } // the `now` is TextEditor auto tabWidget = qobject_cast(now->parentWidget()); - if (!tabWidget) + if (!tabWidget) { + ActionManager::instance()->removeContext({ TextEditorContext }); return; + } + ActionManager::instance()->addContext({ TextEditorContext }); focusTabWidget = tabWidget; editor.switchedFile(focusTabWidget->currentFile()); auto symbolWidget = SymbolWidgetGenerator::instance()->symbolWidget(); - symbolWidget->setEditor(qobject_cast(tabWidget->currentWidget())); + symbolWidget->setEditor(tabWidget->currentEditor()); } void WorkspaceWidgetPrivate::onZoomValueChanged() diff --git a/src/plugins/codeeditor/symbol/symbollocator.cpp b/src/plugins/codeeditor/symbol/symbollocator.cpp index 9661206d3..69cf4978c 100644 --- a/src/plugins/codeeditor/symbol/symbollocator.cpp +++ b/src/plugins/codeeditor/symbol/symbollocator.cpp @@ -46,8 +46,8 @@ TextEditor *SymbolLocatorPrivate::currentEditor() auto tabWidget = workspace->currentTabWidget(); if (!tabWidget) return nullptr; - - return qobject_cast(tabWidget->currentWidget()); + + return tabWidget->currentEditor(); } void SymbolLocatorPrivate::createSymbolItem(const newlsp::DocumentSymbol &symbol) diff --git a/src/plugins/core/locator/actionlocator.cpp b/src/plugins/core/locator/actionlocator.cpp index e557523a0..26c3e77cc 100644 --- a/src/plugins/core/locator/actionlocator.cpp +++ b/src/plugins/core/locator/actionlocator.cpp @@ -23,6 +23,9 @@ void ActionLocator::prepareSearch(const QString &searchText) commandList = ActionManager::instance()->commandList(); foreach (auto command, commandList) { + if (command->action() && command->action()->isSeparator()) + continue; + baseLocatorItem item(this); item.id = command->id(); item.displayName = command->description(); @@ -39,7 +42,7 @@ QList ActionLocator::matchesFor(const QString &inputText) foreach (auto item, locatorList) { auto match = regexp.match(item.displayName); - if(match.hasMatch()) + if (match.hasMatch()) matchResult.append(item); } @@ -49,7 +52,7 @@ QList ActionLocator::matchesFor(const QString &inputText) void ActionLocator::accept(baseLocatorItem item) { foreach (auto command, commandList) { - if(command->id() == item.id) + if (command->id() == item.id) command->action()->trigger(); } } diff --git a/src/plugins/debugger/interface/menumanager.cpp b/src/plugins/debugger/interface/menumanager.cpp index 96d2700ff..56c234c09 100644 --- a/src/plugins/debugger/interface/menumanager.cpp +++ b/src/plugins/debugger/interface/menumanager.cpp @@ -30,8 +30,9 @@ void MenuManager::initialize(WindowService *windowService) QKeySequence key, const QString &iconName = {}) -> Command * { action->setIcon(QIcon::fromTheme(iconName)); auto cmd = ActionManager::instance()->registerAction(action, id); - cmd->setDefaultKeySequence(key); cmd->setDescription(description); + if (!key.isEmpty()) + cmd->setDefaultKeySequence(key); return cmd; }; diff --git a/src/plugins/git/utils/gitmenumanager.cpp b/src/plugins/git/utils/gitmenumanager.cpp index 9f1151f24..0576ae0c5 100644 --- a/src/plugins/git/utils/gitmenumanager.cpp +++ b/src/plugins/git/utils/gitmenumanager.cpp @@ -149,17 +149,17 @@ void GitMenuManager::createFileSubMenu() { auto mCurFile = ActionManager::instance()->actionContainer(M_GIT_FILE); auto fileLogAct = new QAction(this); - auto cmd = registerShortcut(fileLogAct, A_GIT_LOG_FILE, tr("Git Log"), QKeySequence(Qt::ALT | Qt::SHIFT | Qt::Key_L)); + auto cmd = registerShortcut(fileLogAct, A_GIT_LOG_FILE, tr("Git Log"), QKeySequence("Alt+G,Alt+L")); mCurFile->addAction(cmd); connect(fileLogAct, &QAction::triggered, this, std::bind(&GitMenuManager::actionHandler, this, cmd, GitLog)); auto fileBlameAct = new QAction(this); - cmd = registerShortcut(fileBlameAct, A_GIT_BLAME_FILE, tr("Git Blame"), QKeySequence(Qt::ALT | Qt::SHIFT | Qt::Key_B)); + cmd = registerShortcut(fileBlameAct, A_GIT_BLAME_FILE, tr("Git Blame"), QKeySequence("Alt+G,Alt+B")); mCurFile->addAction(cmd); connect(fileBlameAct, &QAction::triggered, this, std::bind(&GitMenuManager::actionHandler, this, cmd, GitBlame)); auto fileDiffAct = new QAction(this); - cmd = registerShortcut(fileDiffAct, A_GIT_DIFF_FILE, tr("Git Diff"), QKeySequence(Qt::ALT | Qt::SHIFT | Qt::Key_D)); + cmd = registerShortcut(fileDiffAct, A_GIT_DIFF_FILE, tr("Git Diff"), QKeySequence("Alt+G,Alt+D")); mCurFile->addAction(cmd); connect(fileDiffAct, &QAction::triggered, this, std::bind(&GitMenuManager::actionHandler, this, cmd, GitDiff)); } diff --git a/src/plugins/option/optioncore/CMakeLists.txt b/src/plugins/option/optioncore/CMakeLists.txt index b57a4c75e..0a26afcab 100644 --- a/src/plugins/option/optioncore/CMakeLists.txt +++ b/src/plugins/option/optioncore/CMakeLists.txt @@ -4,43 +4,19 @@ project(optioncore) find_package(Qt5 COMPONENTS Xml REQUIRED) -set(CXX_CPP - - mainframe/shortcutsettingwidget.cpp - mainframe/persistentsettings.cpp - mainframe/optionsdialog.cpp - mainframe/optiondefaultkeeper.cpp - mainframe/profilesettingwidget.cpp - - mainframe/optionprofilesettinggenerator.cpp - mainframe/optionshortcutsettinggenerator.cpp - mainframe/navigationdelegate.cpp - mainframe/shortcutedit.cpp - optioncore.cpp - optioncore.json - ) - -set(CXX_H - - mainframe/shortcutsettingwidget.h - mainframe/persistentsettings.h - mainframe/optionsdialog.h - mainframe/optiondefaultkeeper.h - mainframe/profilesettingwidget.h - - mainframe/optionprofilesettinggenerator.h - mainframe/optionshortcutsettinggenerator.h - mainframe/navigationdelegate.h - mainframe/shortcutedit.h - optioncore.h - ) +FILE(GLOB_RECURSE PROJECT_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/*.h" + "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/*/*.h" + "${CMAKE_CURRENT_SOURCE_DIR}/*/*.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/*.json" +) add_library(${PROJECT_NAME} SHARED - ${CXX_CPP} - ${CXX_H} + ${PROJECT_SOURCES} optioncore.qrc - ) +) target_link_libraries(${PROJECT_NAME} framework @@ -50,6 +26,6 @@ target_link_libraries(${PROJECT_NAME} ${QtUseModules} ${PkgUserModules} Qt5::Xml - ) +) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) diff --git a/src/plugins/option/optioncore/icons/shortcut_group_128px.svg b/src/plugins/option/optioncore/icons/shortcut_group_128px.svg new file mode 100644 index 000000000..218ace246 --- /dev/null +++ b/src/plugins/option/optioncore/icons/shortcut_group_128px.svg @@ -0,0 +1,151 @@ + + + ICON / action /shortcut_group + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/plugins/option/optioncore/mainframe/optionshortcutsettinggenerator.cpp b/src/plugins/option/optioncore/mainframe/optionshortcutsettinggenerator.cpp deleted file mode 100644 index 6787aa359..000000000 --- a/src/plugins/option/optioncore/mainframe/optionshortcutsettinggenerator.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "optionshortcutsettinggenerator.h" -#include "shortcutsettingwidget.h" - -OptionShortcutsettingGenerator::OptionShortcutsettingGenerator() -{ -} - -QWidget *OptionShortcutsettingGenerator::optionWidget() -{ - return new ShortcutSettingWidget(); -} diff --git a/src/plugins/option/optioncore/mainframe/optionshortcutsettinggenerator.h b/src/plugins/option/optioncore/mainframe/optionshortcutsettinggenerator.h deleted file mode 100644 index 7a5609258..000000000 --- a/src/plugins/option/optioncore/mainframe/optionshortcutsettinggenerator.h +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef OPTIONSHORTCUTSETTINGGENERATOR_H -#define OPTIONSHORTCUTSETTINGGENERATOR_H - -#include "services/option/optiongenerator.h" - -class OptionShortcutsettingGenerator : public dpfservice::OptionGenerator -{ - Q_OBJECT -public: - OptionShortcutsettingGenerator(); - inline static QString kitName() {return QObject::tr("Commands");} - virtual QWidget *optionWidget() override; -}; - -#endif // OPTIONSHORTCUTSETTINGGENERATOR_H diff --git a/src/plugins/option/optioncore/mainframe/shortcutdialog.cpp b/src/plugins/option/optioncore/mainframe/shortcutdialog.cpp new file mode 100644 index 000000000..f4ae1839b --- /dev/null +++ b/src/plugins/option/optioncore/mainframe/shortcutdialog.cpp @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "shortcutdialog.h" + +#include +#include + +#include +#include + +DWIDGET_USE_NAMESPACE + +ShortcutDialog::ShortcutDialog(QWidget *parent) + : DDialog(parent) +{ + initUI(); +} + +void ShortcutDialog::initUI() +{ + setIcon(QIcon::fromTheme("ide")); + setWindowTitle(tr("Add Shortcut")); + setWordWrapMessage(true); + setMessage(tr("Press desired key combination to add shortcut")); + layout()->setSizeConstraint(QLayout::SetMinAndMaxSize); + + keyEdit = new DLineEdit(this); + keyEdit->installEventFilter(this); + keyEdit->lineEdit()->installEventFilter(this); + connect(keyEdit, &DLineEdit::textChanged, this, &ShortcutDialog::keyValueChanged); + + msgLabel = new DLabel(this); + msgLabel->setVisible(false); + msgLabel->setWordWrap(true); + msgLabel->setAlignment(Qt::AlignCenter); + msgLabel->setForegroundRole(QPalette::Highlight); + auto f = msgLabel->font(); + f.setUnderline(true); + msgLabel->setFont(f); + + QWidget *contentWidget = new QWidget(this); + QVBoxLayout *vLayout = new QVBoxLayout(contentWidget); + vLayout->setContentsMargins(0, 0, 0, 0); + vLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); + vLayout->addWidget(keyEdit); + vLayout->addWidget(msgLabel); + + addContent(contentWidget); + addButton(tr("Cancel", "button")); + addButton(tr("Ok", "button"), true, DDialog::ButtonRecommend); + setFocusProxy(keyEdit); +} + +void ShortcutDialog::keyValueChanged() +{ + if (keyEdit->text().isEmpty()) + resetState(); + + if (!checkHandler) + return; + + int count = checkHandler(shortcutKey); + if (count > 0) { + QString msg = count == 1 ? tr("1 same shortcut command exist") + : tr("%1 same shortcut commands exist").arg(count); + msgLabel->setText(msg); + } + msgLabel->setVisible(count != 0); +} + +void ShortcutDialog::resetState() +{ + keyNum = 0; + shortcutKey = QKeySequence(); + keyEdit->clear(); + keyArray.fill(0); +} + +int ShortcutDialog::translateModifiers(Qt::KeyboardModifiers state, const QString &text) +{ + int result = 0; + if ((state & Qt::ShiftModifier) + && (text.isEmpty() + || !text.at(0).isPrint() + || text.at(0).isLetterOrNumber() + || text.at(0).isSpace())) + result |= Qt::SHIFT; + if (state & Qt::ControlModifier) + result |= Qt::CTRL; + if (state & Qt::MetaModifier) + result |= Qt::META; + if (state & Qt::AltModifier) + result |= Qt::ALT; + return result; +} + +QKeySequence ShortcutDialog::keySequece() const +{ + return shortcutKey; +} + +void ShortcutDialog::setConflictCheckHandler(ConflictCheckHandler handler) +{ + checkHandler = handler; +} + +bool ShortcutDialog::eventFilter(QObject *watched, QEvent *event) +{ + if (keyEdit && watched != keyEdit && watched != keyEdit->lineEdit()) + return DDialog::eventFilter(watched, event); + + if (keyEdit && event->type() == QEvent::KeyPress) { + auto k = static_cast(event); + int nextKey = k->key(); + if (keyNum > 3) + resetState(); + + if (nextKey == Qt::Key_Control + || nextKey == Qt::Key_Shift + || nextKey == Qt::Key_Meta + || nextKey == Qt::Key_Alt) { + return false; + } + + nextKey |= translateModifiers(k->modifiers(), k->text()); + switch (keyNum) { + case 0: + keyArray[0] = nextKey; + break; + case 1: + keyArray[1] = nextKey; + break; + case 2: + keyArray[2] = nextKey; + break; + case 3: + keyArray[3] = nextKey; + break; + default: + break; + } + keyNum++; + k->accept(); + shortcutKey = QKeySequence(keyArray[0], keyArray[1], keyArray[2], keyArray[3]); + keyEdit->setText(shortcutKey.toString(QKeySequence::NativeText)); + return true; + } + + return DDialog::eventFilter(watched, event); +} diff --git a/src/plugins/option/optioncore/mainframe/shortcutdialog.h b/src/plugins/option/optioncore/mainframe/shortcutdialog.h new file mode 100644 index 000000000..1a60caea1 --- /dev/null +++ b/src/plugins/option/optioncore/mainframe/shortcutdialog.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +DWIDGET_BEGIN_NAMESPACE +class DLineEdit; +class DLabel; +DWIDGET_END_NAMESPACE + +class ShortcutItem; +class ShortcutDialog : public DTK_WIDGET_NAMESPACE::DDialog +{ + Q_OBJECT +public: + explicit ShortcutDialog(QWidget *parent = nullptr); + + QKeySequence keySequece() const; + using ConflictCheckHandler = std::function; + void setConflictCheckHandler(ConflictCheckHandler handler); + +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + void initUI(); + void keyValueChanged(); + void resetState(); + int translateModifiers(Qt::KeyboardModifiers state, const QString &text); + + DTK_WIDGET_NAMESPACE::DLineEdit *keyEdit { nullptr }; + DTK_WIDGET_NAMESPACE::DLabel *msgLabel { nullptr }; + ConflictCheckHandler checkHandler { nullptr }; + QKeySequence shortcutKey; + std::array keyArray { 0 }; + int keyNum { 0 }; +}; diff --git a/src/plugins/option/optioncore/mainframe/shortcutedit.cpp b/src/plugins/option/optioncore/mainframe/shortcutedit.cpp deleted file mode 100644 index 06d5e9a2f..000000000 --- a/src/plugins/option/optioncore/mainframe/shortcutedit.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "shortcutedit.h" - -ShortCutEdit::ShortCutEdit(QWidget *parent) - : DKeySequenceEdit(parent) -{ - menu = new DMenu(this); - QAction *clearAction = menu->addAction(tr("Clear")); - connect(clearAction, &QAction::triggered, this, &ShortCutEdit::clearText); -} - -void ShortCutEdit::clearText() -{ - this->clear(); - emit shortcutCleared(); -} \ No newline at end of file diff --git a/src/plugins/option/optioncore/mainframe/shortcutedit.h b/src/plugins/option/optioncore/mainframe/shortcutedit.h deleted file mode 100644 index 42be6d41c..000000000 --- a/src/plugins/option/optioncore/mainframe/shortcutedit.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include -#include - -#include -#include - -using Dtk::Widget::DMenu; - -class ShortCutEdit : public Dtk::Widget::DKeySequenceEdit -{ - Q_OBJECT -public: - ShortCutEdit(QWidget *parent = nullptr); - -protected: - void contextMenuEvent(QContextMenuEvent *event) override - { - menu->exec(event->globalPos()); - } - -signals: - void shortcutCleared(); - -private slots: - void clearText(); - -private: - DMenu *menu = nullptr; -}; - diff --git a/src/plugins/option/optioncore/mainframe/shortcutitem.cpp b/src/plugins/option/optioncore/mainframe/shortcutitem.cpp new file mode 100644 index 000000000..9697c63fa --- /dev/null +++ b/src/plugins/option/optioncore/mainframe/shortcutitem.cpp @@ -0,0 +1,102 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "shortcutitem.h" + +#include +#include +#ifdef DTKWIDGET_CLASS_DPaletteHelper +# include +#endif + +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +KeyLabel::KeyLabel(QWidget *parent) + : DFrame(parent) +{ + label = new DLabel(this); + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setContentsMargins(layout->contentsMargins().left(), 0, layout->contentsMargins().right(), 0); + layout->setSpacing(0); + label->setForegroundRole(QPalette::ButtonText); + layout->addWidget(label); +} + +void KeyLabel::setKeySquece(const QString &keySequece) +{ + label->setText(keySequece); + update(); +} + +void KeyLabel::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + QStyleOptionFrame opt; + initStyleOption(&opt); + QPainter p(this); + drawShadow(&p, event->rect() - contentsMargins(), QColor(0, 0, 0, 20)); + + opt.features |= QStyleOptionFrame::Rounded; + +#ifdef DTKWIDGET_CLASS_DPaletteHelper + const DPalette &dp = DPaletteHelper::instance()->palette(this); +#else + const DPalette &dp = DGuiApplicationHelper::instance()->applicationPalette(); +#endif + + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) { + p.setBackground(QColor(255, 255, 255)); + } else { + QColor bgColor(109, 109, 109); + if ((opt.state & QStyle::State_Active) == 0) { + auto inactive_mask_color = dp.color(QPalette::Window); + inactive_mask_color.setAlphaF(0.6); + bgColor = DGuiApplicationHelper::blendColor(bgColor, inactive_mask_color); + } + p.setBackground(bgColor); + } + + p.setPen(QPen(dp.frameBorder(), opt.lineWidth)); + style()->drawControl(QStyle::CE_ShapedFrame, &opt, &p, this); +} + +void KeyLabel::drawShadow(QPainter *p, const QRect &rect, const QColor &color) const +{ + DStyle dstyle; + int frame_radius = dstyle.pixelMetric(DStyle::PM_FrameRadius); + int shadow_xoffset = dstyle.pixelMetric(DStyle::PM_ShadowHOffset); + int shadow_yoffset = dstyle.pixelMetric(DStyle::PM_ShadowVOffset); + + QRect shadow = rect; + QPoint pointOffset(rect.center().x() + shadow_xoffset, rect.center().y() + shadow_yoffset); + shadow.moveCenter(pointOffset); + + p->setBrush(color); + p->setPen(Qt::NoPen); + p->setRenderHint(QPainter::Antialiasing); + p->drawRoundedRect(shadow, frame_radius, frame_radius); +} + +ShortcutLabel::ShortcutLabel(QWidget *parent) + : QWidget(parent) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(10); +} + +void ShortcutLabel::setKeySqueces(const QStringList &keySequeces) +{ + for (int i = 0; i < keySequeces.size(); ++i) { + auto keyLabel = new KeyLabel(this); + keyLabel->setKeySquece(keySequeces[i]); + layout()->addWidget(keyLabel); + } + + qobject_cast(layout())->addStretch(1); +} diff --git a/src/plugins/option/optioncore/mainframe/shortcutitem.h b/src/plugins/option/optioncore/mainframe/shortcutitem.h new file mode 100644 index 000000000..160671e81 --- /dev/null +++ b/src/plugins/option/optioncore/mainframe/shortcutitem.h @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef SHORTCUTITEM_H +#define SHORTCUTITEM_H + +#include "common/actionmanager/command.h" + +#include +#include + +#include + +struct ShortcutItem +{ + Command *cmd { nullptr }; + QList shortcutKeys; + QTreeWidgetItem *item { nullptr }; +}; + +class KeyLabel : public DTK_WIDGET_NAMESPACE::DFrame +{ + Q_OBJECT +public: + explicit KeyLabel(QWidget *parent = nullptr); + + void setKeySquece(const QString &keySequece); + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + void drawShadow(QPainter *p, const QRect &rect, const QColor &color) const; + +private: + DTK_WIDGET_NAMESPACE::DLabel *label { nullptr }; +}; + +class ShortcutLabel : public QWidget +{ + Q_OBJECT +public: + explicit ShortcutLabel(QWidget *parent = nullptr); + + void setKeySqueces(const QStringList &keySequeces); +}; + +Q_DECLARE_METATYPE(ShortcutItem *) +#endif // SHORTCUTITEM_H diff --git a/src/plugins/option/optioncore/mainframe/shortcutsettingwidget.cpp b/src/plugins/option/optioncore/mainframe/shortcutsettingwidget.cpp index 6c26b2faa..d499f7dbb 100644 --- a/src/plugins/option/optioncore/mainframe/shortcutsettingwidget.cpp +++ b/src/plugins/option/optioncore/mainframe/shortcutsettingwidget.cpp @@ -3,337 +3,658 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "shortcutsettingwidget.h" -#include "shortcutedit.h" -#include "common/common.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include +#include "shortcutitem.h" +#include "shortcutdialog.h" + +#include "common/actionmanager/actionmanager.h" +#include "base/baseitemdelegate.h" + +#include +#include +#include + #include +#include +#include +#include +#include +#include +#include + +constexpr char kKeyboardShortcuts[] = "KeyboardShortcuts"; DWIDGET_USE_NAMESPACE -class ShortCutPrivate +QWidget *OptionShortcutsettingGenerator::optionWidget() { - QMap shortcutItemMap; - QMap shortcutItemShadowMap; - QString configFilePath; - QVBoxLayout *vlayout = nullptr; - QVBoxLayout *bgGplayout = nullptr; - DBackgroundGroup *bgGroup = nullptr; + return new ShortcutSettingWidget; +} - friend class ShortCut; +class ShortcutSettingWidgetPrivate : public QObject +{ +public: + struct Tr + { + Q_DECLARE_TR_FUNCTIONS(ShortcutSettingWidget); + }; + + explicit ShortcutSettingWidgetPrivate(ShortcutSettingWidget *qq); + + void initUI(); + void inintConnection(); + + void apply(); + void clear(); + void updateCommands(); + void updateShortcut(QTreeWidgetItem *item, const QList &keyList); + void showMenu(const QPoint &pos); + + void addShortcut(QTreeWidgetItem *item); + void changeShortcut(QTreeWidgetItem *item, int index); + void removeShortcut(QTreeWidgetItem *item, int index); + void removeAllShortcut(QTreeWidgetItem *item); + void resetShortcut(QTreeWidgetItem *item); + void exportAction(); + void importAction(); + void handleKeyRecord(); + void handleFilterChanged(const QString &f); + bool filter(const QString &filterString, QTreeWidgetItem *item); + bool filterColumn(const QString &filterString, QTreeWidgetItem *item, int column); + + ShortcutItem *shortcutItem(QTreeWidgetItem *item); + int checkConflict(const QKeySequence &key, int index); + QStringList keySequencesToNativeString(const QList &sequences); + void setModified(QTreeWidgetItem *item, bool modified); + void resetRecordState(); + int translateModifiers(Qt::KeyboardModifiers state, const QString &text); + QString createPlaceholderString(const QStringList &list); + +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + +public: + ShortcutSettingWidget *q; + + DSearchEdit *searchEdit { nullptr }; + DToolButton *recordKeyBtn { nullptr }; + DIconButton *exportBtn { nullptr }; + DIconButton *importBtn { nullptr }; + QTreeWidget *commandWidget { nullptr }; + QList shortcutItems; + + // for key record + std::array keyArray { 0 }; + int keyNum { 0 }; }; -ShortCut::ShortCut(QWidget *parent) - : DFrame(parent), d(new ShortCutPrivate()) +ShortcutSettingWidgetPrivate::ShortcutSettingWidgetPrivate(ShortcutSettingWidget *qq) + : q(qq) { - d->configFilePath = (CustomPaths::user(CustomPaths::Flags::Configures) - + QDir::separator() + QString("shortcut.support")); - readShortcut(); - setFrameShape(QFrame::NoFrame); +} - d->vlayout = new QVBoxLayout(this); - d->bgGplayout = new QVBoxLayout; - d->bgGroup = new DBackgroundGroup(d->bgGplayout); - d->bgGroup->setBackgroundRole(QPalette::Window); - d->bgGroup->setUseWidgetBackground(false); - d->vlayout->addWidget(d->bgGroup); - updateUi(); +void ShortcutSettingWidgetPrivate::initUI() +{ + QVBoxLayout *mainLayout = new QVBoxLayout(q); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + + QHBoxLayout *hSearchLayout = new QHBoxLayout; + searchEdit = new DSearchEdit(q); + searchEdit->setPlaceholderText(Tr::tr("Type to search in keybindings")); + searchEdit->installEventFilter(this); + searchEdit->lineEdit()->installEventFilter(this); + + recordKeyBtn = new DToolButton(q); + recordKeyBtn->setCheckable(true); + recordKeyBtn->setIcon(QIcon::fromTheme("shortcut_search")); + recordKeyBtn->setToolTip(Tr::tr("Record Keys")); + hSearchLayout->addWidget(searchEdit); + hSearchLayout->addWidget(recordKeyBtn); + + commandWidget = new QTreeWidget(q); + commandWidget->setHeaderLabels({ Tr::tr("Command"), Tr::tr("Label"), Tr::tr("Shortcut") }); + commandWidget->setColumnWidth(0, 290); + commandWidget->setColumnWidth(1, 250); + commandWidget->setAlternatingRowColors(true); + commandWidget->setIconSize({ 16, 16 }); + commandWidget->setFrameShape(QFrame::NoFrame); + commandWidget->header()->setStretchLastSection(false); + commandWidget->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); + commandWidget->setMinimumHeight(360); + commandWidget->setItemDelegate(new BaseItemDelegate(commandWidget)); + commandWidget->setContextMenuPolicy(Qt::CustomContextMenu); + commandWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + exportBtn = new DIconButton(q); + exportBtn->setIconSize({ 16, 16 }); + exportBtn->setFlat(true); + exportBtn->setToolTip(Tr::tr("Export")); + exportBtn->setIcon(QIcon::fromTheme("export")); + + importBtn = new DIconButton(q); + importBtn->setIconSize({ 16, 16 }); + importBtn->setFlat(true); + importBtn->setToolTip(Tr::tr("Import")); + importBtn->setIcon(QIcon::fromTheme("import")); + + QHBoxLayout *hBtnLayout = new QHBoxLayout; + hBtnLayout->setAlignment(Qt::AlignRight); + hBtnLayout->setContentsMargins(0, 6, 20, 6); + hBtnLayout->setSpacing(10); + hBtnLayout->addWidget(importBtn); + hBtnLayout->addWidget(exportBtn); + + DFrame *frame = new DFrame(q); + QVBoxLayout *frameLayout = new QVBoxLayout(frame); + frameLayout->setSpacing(0); + frameLayout->setContentsMargins(0, 0, 0, 0); + frameLayout->addWidget(commandWidget); + frameLayout->addWidget(new DHorizontalLine(q)); + frameLayout->addLayout(hBtnLayout); + + mainLayout->addLayout(hSearchLayout); + mainLayout->addSpacing(10); + mainLayout->addWidget(frame); +} - QObject::connect(&dpf::Listener::instance(), &dpf::Listener::pluginsStarted, [=] { - updateDescriptions(); - }); +void ShortcutSettingWidgetPrivate::inintConnection() +{ + connect(ActionManager::instance(), &ActionManager::commandListChanged, + this, &ShortcutSettingWidgetPrivate::updateCommands); + connect(commandWidget, &QTreeWidget::customContextMenuRequested, this, &ShortcutSettingWidgetPrivate::showMenu); + connect(importBtn, &DIconButton::clicked, this, &ShortcutSettingWidgetPrivate::importAction); + connect(exportBtn, &DIconButton::clicked, this, &ShortcutSettingWidgetPrivate::exportAction); + connect(recordKeyBtn, &DToolButton::clicked, this, &ShortcutSettingWidgetPrivate::handleKeyRecord); + connect(searchEdit, &DSearchEdit::textChanged, this, &ShortcutSettingWidgetPrivate::handleFilterChanged); } -ShortCut::~ShortCut() +void ShortcutSettingWidgetPrivate::apply() { + for (const auto item : std::as_const(shortcutItems)) + item->cmd->setKeySequences(item->shortcutKeys); } -void ShortCut::updateUi() +void ShortcutSettingWidgetPrivate::clear() { - //更新配置时先删除旧项 - if (d->bgGplayout->count()) { - while (auto layout = d->bgGplayout->takeAt(0)) - delete layout->widget(); + for (int i = commandWidget->topLevelItemCount() - 1; i >= 0; --i) { + delete commandWidget->takeTopLevelItem(i); } - QStringList ids = d->shortcutItemMap.keys(); - - for (auto id : ids) { - QStringList valueList = d->shortcutItemMap.value(id); - QString description = valueList.first(); - QString shortcut = valueList.last(); - - auto keyEdit = new ShortCutEdit(this); - keyEdit->setKeySequence(QKeySequence(shortcut)); - keyEdit->setFixedWidth(300); - keyEdit->ShortcutDirection(Qt::AlignLeft); - keyEdit->setFocusPolicy(Qt::StrongFocus); - - auto label = new DLabel(description, this); - auto wrapper = new DWidget; - auto hlayout = new QHBoxLayout(wrapper); - hlayout->setSpacing(0); - hlayout->setContentsMargins(0, 0, 0, 0); - hlayout->addWidget(label); - hlayout->addWidget(keyEdit); - hlayout->setAlignment(keyEdit, Qt::AlignRight); - - d->bgGplayout->addWidget(wrapper); - connect(keyEdit, &ShortCutEdit::shortcutCleared, [=]() { - updateShortcut(id, ""); - }); - connect(keyEdit, &DKeySequenceEdit::editingFinished, this, [=](const QKeySequence &sequence) { - bool inValid = keySequenceIsInvalid(sequence); - QString oldShortcut = d->shortcutItemMap.value(id).last(); - QKeySequence oldSequence(oldShortcut); - - if (inValid) { - showWarning(tr("Shortcut Invalid"), tr("Shortcut Invalid, Please enter again!")); - qWarning() << "keySequence is invalid"; - if (oldSequence.isEmpty()) { - keyEdit->clear(); - } else { - keyEdit->setKeySequence(oldSequence); - } - return; - } - bool isRepeat = shortcutRepeat(sequence.toString()); - if (isRepeat) { - showWarning(tr("Shortcut Repeated"), tr("Shortcut Repeated, Please enter again!")); - qWarning() << "isRepeat!!"; - if (oldSequence.isEmpty()) { - keyEdit->clear(); - } else { - keyEdit->setKeySequence(oldSequence); - } - return; - } - updateShortcut(id, sequence.toString()); - }); - } + qDeleteAll(shortcutItems); + shortcutItems.clear(); } -inline void ShortCut::showWarning(const QString &title, const QString &message) +void ShortcutSettingWidgetPrivate::updateCommands() { - DDialog warningDialog; - warningDialog.setWindowTitle(title); - warningDialog.setMessage(message); - warningDialog.setIcon(QIcon::fromTheme("dialog-warning")); - warningDialog.addButton(tr("OK")); - warningDialog.exec(); - return; + clear(); + QMap sectionMap; + + auto commands = ActionManager::instance()->commandList(); + for (auto cmd : commands) { + if (cmd->hasAttribute(Command::CA_NonConfigurable)) + continue; + if (cmd->action() && cmd->action()->isSeparator()) + continue; + + QTreeWidgetItem *item = new QTreeWidgetItem; + item->setSizeHint(0, { 0, 24 }); + ShortcutItem *shortcutItem = new ShortcutItem; + shortcutItem->cmd = cmd; + shortcutItem->item = item; + shortcutItem->shortcutKeys = cmd->keySequences(); + + const QString identifier = cmd->id(); + int pos = identifier.indexOf(QLatin1Char('.')); + const QString section = identifier.left(pos); + const QString subId = identifier.mid(pos + 1); + if (!sectionMap.contains(section)) { + auto groupItem = new QTreeWidgetItem(commandWidget, QStringList(section)); + sectionMap.insert(section, groupItem); + groupItem->setIcon(0, QIcon::fromTheme("shortcut_group")); + commandWidget->expandItem(groupItem); + } + sectionMap[section]->addChild(item); + + item->setData(0, Qt::UserRole, QVariant::fromValue(shortcutItem)); + item->setText(0, subId); + item->setText(1, cmd->description()); + updateShortcut(item, shortcutItem->shortcutKeys); + shortcutItems << shortcutItem; + } + + commandWidget->sortByColumn(0, Qt::AscendingOrder); } -int ShortCut::rowCount() const +void ShortcutSettingWidgetPrivate::updateShortcut(QTreeWidgetItem *item, const QList &keyList) { - return d->shortcutItemMap.size(); + auto scItem = shortcutItem(item); + if (!scItem) + return; + + setModified(item, scItem->cmd->defaultKeySequences() != keyList); + scItem->shortcutKeys = keyList; + commandWidget->removeItemWidget(item, 2); + if (keyList.isEmpty()) { + item->setText(2, ""); + return; + } + + const auto &keyStrList = keySequencesToNativeString(scItem->shortcutKeys); + ShortcutLabel *keyLabel = new ShortcutLabel(q); + keyLabel->setKeySqueces(keyStrList); + commandWidget->setItemWidget(item, 2, keyLabel); + + // for auto-adjusting the column width + item->setText(2, createPlaceholderString(keyStrList)); } -bool ShortCut::keySequenceIsInvalid(const QKeySequence &sequence) const +void ShortcutSettingWidgetPrivate::showMenu(const QPoint &pos) { - for (uint i = 0; i < static_cast(sequence.count()); i++) { - if (Qt::Key_unknown == sequence[i]) { - return true; - } + auto item = commandWidget->itemAt(pos); + auto scItem = shortcutItem(item); + if (!scItem) + return; + + QMenu menu; + menu.addAction(Tr::tr("Add Shortcut"), this, std::bind(&ShortcutSettingWidgetPrivate::addShortcut, this, item)); + + // change action + for (int i = 0; i < scItem->shortcutKeys.size(); ++i) { + QString keyText = Tr::tr("Change %1"); + menu.addAction(keyText.arg(scItem->shortcutKeys[i].toString(QKeySequence::NativeText)), + this, std::bind(&ShortcutSettingWidgetPrivate::changeShortcut, this, item, i)); + } + menu.addSeparator(); + // remove action + for (int i = 0; i < scItem->shortcutKeys.size(); ++i) { + QString keyText = Tr::tr("Remove %1"); + menu.addAction(keyText.arg(scItem->shortcutKeys[i].toString(QKeySequence::NativeText)), + this, std::bind(&ShortcutSettingWidgetPrivate::removeShortcut, this, item, i)); } + menu.addSeparator(); + if (scItem->shortcutKeys.size() > 1) + menu.addAction(Tr::tr("Remove All Shortcut"), this, std::bind(&ShortcutSettingWidgetPrivate::removeAllShortcut, this, item)); - return false; + if (scItem->shortcutKeys != scItem->cmd->defaultKeySequences()) + menu.addAction(Tr::tr("Reset Shortcut"), this, std::bind(&ShortcutSettingWidgetPrivate::resetShortcut, this, item)); + + menu.exec(QCursor::pos()); } -bool ShortCut::shortcutRepeat(const QString &text) const +void ShortcutSettingWidgetPrivate::addShortcut(QTreeWidgetItem *item) { - int count = 0; - foreach (QString key, d->shortcutItemMap.keys()) { - QStringList valueList = d->shortcutItemMap.value(key); - if (0 == text.compare(valueList.last(), Qt::CaseInsensitive)) { - if (++count > 0) - return true; - } - } + auto scItem = shortcutItem(item); + if (!scItem) + return; + + ShortcutDialog dlg; + dlg.setConflictCheckHandler(std::bind(&ShortcutSettingWidgetPrivate::checkConflict, + this, std::placeholders::_1, scItem->shortcutKeys.size())); + if (dlg.exec() != 1) + return; + + const auto &key = dlg.keySequece(); + scItem->shortcutKeys << key; + updateShortcut(item, scItem->shortcutKeys); +} - return false; +void ShortcutSettingWidgetPrivate::changeShortcut(QTreeWidgetItem *item, int index) +{ + auto scItem = shortcutItem(item); + if (!scItem) + return; + + ShortcutDialog dlg; + dlg.setConflictCheckHandler(std::bind(&ShortcutSettingWidgetPrivate::checkConflict, + this, std::placeholders::_1, index)); + if (dlg.exec() != 1) + return; + + const auto &key = dlg.keySequece(); + scItem->shortcutKeys.replace(index, key); + updateShortcut(item, scItem->shortcutKeys); } -void ShortCut::updateShortcut(QString id, QString shortcut) +void ShortcutSettingWidgetPrivate::removeShortcut(QTreeWidgetItem *item, int index) { - if (d->shortcutItemMap.keys().contains(id)) { - QStringList valueList = d->shortcutItemMap.value(id); - QStringList newValueList = { valueList.first(), shortcut }; - d->shortcutItemMap[id] = newValueList; - } + auto scItem = shortcutItem(item); + if (!scItem || index >= scItem->shortcutKeys.size()) + return; + + scItem->shortcutKeys.removeAt(index); + updateShortcut(item, scItem->shortcutKeys); } -void ShortCut::resetAllShortcut() +void ShortcutSettingWidgetPrivate::removeAllShortcut(QTreeWidgetItem *item) { - d->shortcutItemMap = d->shortcutItemShadowMap; + updateShortcut(item, {}); } -void ShortCut::saveShortcut() +void ShortcutSettingWidgetPrivate::resetShortcut(QTreeWidgetItem *item) { - ShortcutUtil::writeToJson(d->configFilePath, d->shortcutItemMap); + auto scItem = shortcutItem(item); + if (!scItem) + return; + + updateShortcut(item, scItem->cmd->defaultKeySequences()); +} - QList commandList = ActionManager::instance()->commandList(); - for (auto cmd : commandList) { - QString id = cmd->id(); - if (d->shortcutItemMap.contains(id)) { - QStringList valueList = d->shortcutItemMap[id]; - cmd->setKeySequences({ QKeySequence(valueList.last()) }); +void ShortcutSettingWidgetPrivate::exportAction() +{ + const auto &filePath = QFileDialog::getSaveFileName(q, Tr::tr("Export Keyboard Mapping Scheme"), + QStandardPaths::writableLocation(QStandardPaths::HomeLocation), + Tr::tr("Keyboard Mapping Scheme (*.kms)")); + if (filePath.isEmpty()) + return; + + QSettings settings(filePath, QSettings::IniFormat); + for (auto item : qAsConst(shortcutItems)) { + const auto &id = item->cmd->id(); + const auto settingsKey = QString(kKeyboardShortcuts) + '/' + id; + const QList keys = item->shortcutKeys; + if (keys.isEmpty()) { + settings.setValue(settingsKey, QString()); + } else if (keys.size() == 1) { + settings.setValue(settingsKey, keys.first().toString()); + } else { + QStringList shortcutList; + std::transform(keys.begin(), keys.end(), std::back_inserter(shortcutList), + [](const QKeySequence &k) { + return k.toString(); + }); + settings.setValue(settingsKey, shortcutList); } } } -void ShortCut::readShortcut() +void ShortcutSettingWidgetPrivate::importAction() { - QList commandList = ActionManager::instance()->commandList(); - for (auto cmd : commandList) { - QString id = cmd->id(); - QStringList valueList = QStringList { cmd->description(), cmd->keySequence().toString() }; - d->shortcutItemMap[id] = valueList; + const auto &filePath = QFileDialog::getOpenFileName(q, Tr::tr("Import Keyboard Mapping Scheme"), + QStandardPaths::writableLocation(QStandardPaths::HomeLocation), + Tr::tr("Keyboard Mapping Scheme (*.kms)")); + if (filePath.isEmpty()) + return; + + // read shortcut from `filePath` + QMap> mapping; + QSettings settings(filePath, QSettings::IniFormat); + settings.beginGroup(kKeyboardShortcuts); + QStringList keys = settings.allKeys(); + for (const QString &key : keys) { + const QVariant v = settings.value(key); + if (QMetaType::Type(v.type()) == QMetaType::QStringList) { + auto list = v.toStringList(); + QList keySequenceList; + std::transform(list.begin(), list.end(), std::back_inserter(keySequenceList), + [](const QString &s) { + return QKeySequence::fromString(s); + }); + mapping.insert(key, keySequenceList); + } else { + mapping.insert(key, { QKeySequence::fromString(v.toString()) }); + } } + settings.endGroup(); - QMap shortcutItemMap; - ShortcutUtil::readFromJson(d->configFilePath, shortcutItemMap); - foreach (const QString key, shortcutItemMap.keys()) { - if (d->shortcutItemMap[key].isEmpty()) - d->shortcutItemMap[key] = shortcutItemMap.value(key); - else - d->shortcutItemMap[key].last() = shortcutItemMap.value(key).last(); + // set shortcut + for (ShortcutItem *item : std::as_const(shortcutItems)) { + QString sid = item->cmd->id(); + if (mapping.contains(sid)) + updateShortcut(item->item, mapping.value(sid)); + } +} + +void ShortcutSettingWidgetPrivate::handleKeyRecord() +{ + if (recordKeyBtn->isChecked()) { + searchEdit->setPlaceholderText(Tr::tr("Recording Keys. Press Escape to exit")); + } else { + searchEdit->setPlaceholderText(Tr::tr("Type to search in keybindings")); } - d->shortcutItemShadowMap = d->shortcutItemMap; + searchEdit->setFocus(); + searchEdit->lineEdit()->selectAll(); } -void ShortCut::updateDescriptions() +void ShortcutSettingWidgetPrivate::handleFilterChanged(const QString &f) { - QList commandList = ActionManager::instance()->commandList(); - bool update = false; - for (auto cmd : commandList) { - QString id = cmd->id(); - //已存在该Id的快捷键,但描述不同 -- 比如 配置中为中文 但应用为英文,显示会异常。 - if (!d->shortcutItemMap[id].isEmpty() && (d->shortcutItemMap[id].first() != cmd->description())) { - d->shortcutItemMap[id].first() = cmd->description(); - update = true; - } + if (f.isEmpty()) + resetRecordState(); + + for (int i = 0; i < commandWidget->topLevelItemCount(); ++i) { + QTreeWidgetItem *item = commandWidget->topLevelItem(i); + filter(f, item); } +} - if (update) { - updateUi(); - d->shortcutItemShadowMap = d->shortcutItemMap; +bool ShortcutSettingWidgetPrivate::filter(const QString &filterString, QTreeWidgetItem *item) +{ + bool visible = filterString.isEmpty(); + int columnCount = item->columnCount(); + for (int i = 0; !visible && i < columnCount; ++i) + visible |= !filterColumn(filterString, item, i); + + int childCount = item->childCount(); + if (childCount > 0) { + // force visibility if this item matches + QString tmpFilterString = visible ? QString() : filterString; + for (int i = 0; i < childCount; ++i) { + QTreeWidgetItem *citem = item->child(i); + // parent visible if any child visible + visible |= !filter(tmpFilterString, citem); + } } + item->setHidden(!visible); + return !visible; } -void ShortCut::importExternalJson(const QString &filePath) +bool ShortcutSettingWidgetPrivate::filterColumn(const QString &filterString, QTreeWidgetItem *item, int column) { - QMap shortcutItemMap; - ShortcutUtil::readFromJson(filePath, shortcutItemMap); - foreach (QString key, shortcutItemMap.keys()) { - d->shortcutItemMap[key] = shortcutItemMap.value(key); + const auto scItem = shortcutItem(item); + // shortcut + if (column == item->columnCount() - 1) { + if (!scItem) + return true; + + for (const auto &k : scItem->shortcutKeys) { + const auto &keyString = k.toString(QKeySequence::PortableText); + bool found = keyString.contains(filterString, Qt::CaseInsensitive); + if (found) + return false; + } + return true; } - d->shortcutItemShadowMap = d->shortcutItemMap; - updateUi(); + QString text; + // command id + if (column == 0 && scItem) { + text = scItem->cmd->id(); + } else { + text = item->text(column); + } + return !text.contains(filterString, Qt::CaseInsensitive); } -void ShortCut::exportExternalJson(const QString &filePath) +ShortcutItem *ShortcutSettingWidgetPrivate::shortcutItem(QTreeWidgetItem *item) { - ShortcutUtil::writeToJson(filePath, d->shortcutItemMap); + if (!item) + return nullptr; + return item->data(0, Qt::UserRole).value(); } -class ShortCut; -class ShortcutSettingWidgetPrivate +int ShortcutSettingWidgetPrivate::checkConflict(const QKeySequence &key, int index) { - ShortcutSettingWidgetPrivate(); - ShortCut *shortcut; + if (key.isEmpty()) + return 0; + + QTreeWidgetItem *current = commandWidget->currentItem(); + ShortcutItem *item = shortcutItem(current); + if (!item) + return 0; + + int conflictCount = 0; + for (ShortcutItem *currentItem : std::as_const(shortcutItems)) { + if (item == currentItem) + continue; + + for (const auto &k : qAsConst(currentItem->shortcutKeys)) { + if (k == key) + conflictCount++; + } + } - friend class ShortcutSettingWidget; -}; + return conflictCount; +} -ShortcutSettingWidgetPrivate::ShortcutSettingWidgetPrivate() - : shortcut(nullptr) +QStringList ShortcutSettingWidgetPrivate::keySequencesToNativeString(const QList &sequences) { + QList validSequences; + std::copy_if(sequences.begin(), sequences.end(), std::back_inserter(validSequences), + [](const QKeySequence &k) { + return !k.isEmpty(); + }); + + QStringList keyList; + std::transform(validSequences.begin(), validSequences.end(), std::back_inserter(keyList), + [](const QKeySequence &k) { + return k.toString(QKeySequence::NativeText); + }); + + return keyList; } -ShortcutSettingWidget::ShortcutSettingWidget(QWidget *parent) - : PageWidget(parent), d(new ShortcutSettingWidgetPrivate()) +void ShortcutSettingWidgetPrivate::setModified(QTreeWidgetItem *item, bool modified) { - setupUi(); - readConfig(); + QFont f = item->font(0); + f.setItalic(modified); + item->setFont(0, f); + item->setFont(1, f); + f.setBold(modified); + item->setFont(2, f); } -ShortcutSettingWidget::~ShortcutSettingWidget() +void ShortcutSettingWidgetPrivate::resetRecordState() { + keyNum = 0; + searchEdit->clear(); + keyArray.fill(0); } -void ShortcutSettingWidget::setupUi() +int ShortcutSettingWidgetPrivate::translateModifiers(Qt::KeyboardModifiers state, const QString &text) { - QVBoxLayout *vLayout = new QVBoxLayout(this); - - auto shortcutFrame = new DFrame(this); - auto shortcutLayout = new QVBoxLayout(shortcutFrame); - - d->shortcut = new ShortCut(shortcutFrame); + int result = 0; + if ((state & Qt::ShiftModifier) + && (text.isEmpty() + || !text.at(0).isPrint() + || text.at(0).isLetterOrNumber() + || text.at(0).isSpace())) + result |= Qt::SHIFT; + if (state & Qt::ControlModifier) + result |= Qt::CTRL; + if (state & Qt::MetaModifier) + result |= Qt::META; + if (state & Qt::AltModifier) + result |= Qt::ALT; + return result; +} - shortcutLayout->addWidget(d->shortcut); +QString ShortcutSettingWidgetPrivate::createPlaceholderString(const QStringList &list) +{ + if (list.isEmpty()) + return {}; + + QFontMetrics metrics(q->font()); + QString placeholderString(20, ' '); + for (int i = 0; i < list.size(); ++i) { + if (i != 0) + placeholderString.append(QString(22, ' ')); + + placeholderString.append(QString(list[i].size(), ' ')); + int width = metrics.horizontalAdvance(list[i]); + while (metrics.horizontalAdvance(placeholderString) < width) { + placeholderString.append(' '); + } + } - vLayout->addWidget(shortcutFrame); + return placeholderString; +} - DCommandLinkButton *resetbtn = new DCommandLinkButton(tr("Reset All")); - DCommandLinkButton *exportbtn = new DCommandLinkButton(tr("Export")); - DCommandLinkButton *importbtn = new DCommandLinkButton(tr("Import")); +bool ShortcutSettingWidgetPrivate::eventFilter(QObject *watched, QEvent *event) +{ + if (!searchEdit || !recordKeyBtn || (watched != searchEdit && watched != searchEdit->lineEdit())) + return QObject::eventFilter(watched, event); + + if (recordKeyBtn->isChecked() && event->type() == QEvent::KeyPress) { + auto k = static_cast(event); + int nextKey = k->key(); + if (nextKey == Qt::Key_Escape) { + recordKeyBtn->click(); + return true; + } - auto spliter = new DVerticalLine(this); + if (keyNum > 3) + resetRecordState(); - auto hlayout = new QHBoxLayout; - hlayout->setAlignment(Qt::AlignRight); - hlayout->addWidget(resetbtn); - hlayout->addWidget(spliter); - hlayout->addWidget(exportbtn); - hlayout->addWidget(importbtn); + if (nextKey == Qt::Key_Control + || nextKey == Qt::Key_Shift + || nextKey == Qt::Key_Meta + || nextKey == Qt::Key_Alt) { + return false; + } - vLayout->addLayout(hlayout); + nextKey |= translateModifiers(k->modifiers(), k->text()); + switch (keyNum) { + case 0: + keyArray[0] = nextKey; + break; + case 1: + keyArray[1] = nextKey; + break; + case 2: + keyArray[2] = nextKey; + break; + case 3: + keyArray[3] = nextKey; + break; + default: + break; + } + keyNum++; + k->accept(); + QKeySequence shortcutKey(keyArray[0], keyArray[1], keyArray[2], keyArray[3]); + searchEdit->setText(shortcutKey.toString(QKeySequence::NativeText)); + return true; + } - connect(resetbtn, &DCommandLinkButton::clicked, this, &ShortcutSettingWidget::onBtnResetAllClicked); - connect(exportbtn, &DCommandLinkButton::clicked, this, &ShortcutSettingWidget::onBtnExportClicked); - connect(importbtn, &DCommandLinkButton::clicked, this, &ShortcutSettingWidget::onBtnImportClicked); + return QObject::eventFilter(watched, event); } -void ShortcutSettingWidget::onBtnResetAllClicked() +ShortcutSettingWidget::ShortcutSettingWidget(QWidget *parent) + : PageWidget(parent), + d(new ShortcutSettingWidgetPrivate(this)) { - d->shortcut->resetAllShortcut(); - d->shortcut->updateUi(); + d->initUI(); + d->inintConnection(); + d->updateCommands(); } -void ShortcutSettingWidget::saveConfig() +ShortcutSettingWidget::~ShortcutSettingWidget() { - d->shortcut->saveShortcut(); + delete d; } void ShortcutSettingWidget::readConfig() { - d->shortcut->readShortcut(); -} - -void ShortcutSettingWidget::onBtnImportClicked() -{ - QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), tr(""), tr("Json File(*.json)")); - if (!fileName.isEmpty()) { - d->shortcut->importExternalJson(fileName); + // Updated the shortcut key display name + // For scenarios that are not saved after modification + for (auto item : qAsConst(d->shortcutItems)) { + if (item->shortcutKeys != item->cmd->keySequences()) + d->updateShortcut(item->item, item->cmd->keySequences()); } } -void ShortcutSettingWidget::onBtnExportClicked() +void ShortcutSettingWidget::saveConfig() { - QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), tr(""), tr("Json File(*.json)")); - if (!fileName.isEmpty()) { - d->shortcut->exportExternalJson(fileName); - } + d->apply(); + ActionManager::instance()->saveSettings(); } diff --git a/src/plugins/option/optioncore/mainframe/shortcutsettingwidget.h b/src/plugins/option/optioncore/mainframe/shortcutsettingwidget.h index 2fb7d69af..7881ea335 100644 --- a/src/plugins/option/optioncore/mainframe/shortcutsettingwidget.h +++ b/src/plugins/option/optioncore/mainframe/shortcutsettingwidget.h @@ -5,47 +5,15 @@ #ifndef SHORTCUTSETTINGWIDGET_H #define SHORTCUTSETTINGWIDGET_H -#include -#include -#include -#include -#include +#include "common/widget/pagewidget.h" +#include "services/option/optiongenerator.h" -enum ColumnID -{ - - kDescriptions, - kShortcut, - _KCount -}; - -class ShortCutPrivate; -class ShortCut : public DTK_WIDGET_NAMESPACE::DFrame +class OptionShortcutsettingGenerator : public dpfservice::OptionGenerator { Q_OBJECT public: - explicit ShortCut(QWidget *parent = nullptr); - virtual ~ShortCut(); - - int rowCount() const; - int columnCount() const; - - void updateUi(); - void updateShortcut(QString id, QString shortcut); - void resetAllShortcut(); - void saveShortcut(); - void readShortcut(); - void importExternalJson(const QString &filePath); - void exportExternalJson(const QString &filePath); - void updateDescriptions(); - bool shortcutRepeat(const QString &text) const; - bool keySequenceIsInvalid(const QKeySequence &sequence) const; - void showWarning(const QString& title, const QString& message); - -signals: - -private: - ShortCutPrivate *d; + inline static QString kitName() { return QObject::tr("Commands"); } + virtual QWidget *optionWidget() override; }; class ShortcutSettingWidgetPrivate; @@ -55,19 +23,12 @@ class ShortcutSettingWidget : public PageWidget public: explicit ShortcutSettingWidget(QWidget *parent = nullptr); virtual ~ShortcutSettingWidget(); - void saveConfig(); - void readConfig(); - void checkShortcutValidity(const int row, const QString &shortcut); -signals: + void readConfig() override; + void saveConfig() override; -public slots: - void onBtnResetAllClicked(); - void onBtnImportClicked(); - void onBtnExportClicked(); private: - void setupUi(); ShortcutSettingWidgetPrivate *const d; }; -#endif // SHORTCUTSETTINGWIDGET_H +#endif // SHORTCUTSETTINGWIDGET_H diff --git a/src/plugins/option/optioncore/optioncore.cpp b/src/plugins/option/optioncore/optioncore.cpp index 4515e5e4c..9f67c9113 100644 --- a/src/plugins/option/optioncore/optioncore.cpp +++ b/src/plugins/option/optioncore/optioncore.cpp @@ -5,7 +5,7 @@ #include "optioncore.h" #include "mainframe/optiondefaultkeeper.h" #include "mainframe/optionprofilesettinggenerator.h" -#include "mainframe/optionshortcutsettinggenerator.h" +#include "mainframe/shortcutsettingwidget.h" #include "common/common.h" #include "base/abstractwidget.h" diff --git a/src/plugins/option/optioncore/optioncore.qrc b/src/plugins/option/optioncore/optioncore.qrc index b886efe29..a11183b12 100644 --- a/src/plugins/option/optioncore/optioncore.qrc +++ b/src/plugins/option/optioncore/optioncore.qrc @@ -1,6 +1,11 @@ - + icons/options_alert_16px.svg texts/options_setting_32px.svg + texts/edit_16px.svg + texts/export_16px.svg + texts/import_16px.svg + texts/shortcut_search_16px.svg + icons/shortcut_group_128px.svg diff --git a/src/plugins/option/optioncore/texts/edit_16px.svg b/src/plugins/option/optioncore/texts/edit_16px.svg new file mode 100644 index 000000000..0b0f3beab --- /dev/null +++ b/src/plugins/option/optioncore/texts/edit_16px.svg @@ -0,0 +1,9 @@ + + + ICON / action /edit + + + + + + \ No newline at end of file diff --git a/src/plugins/option/optioncore/texts/export_16px.svg b/src/plugins/option/optioncore/texts/export_16px.svg new file mode 100644 index 000000000..aa0d4cd7d --- /dev/null +++ b/src/plugins/option/optioncore/texts/export_16px.svg @@ -0,0 +1,7 @@ + + + ICON / action /export + + + + \ No newline at end of file diff --git a/src/plugins/option/optioncore/texts/import_16px.svg b/src/plugins/option/optioncore/texts/import_16px.svg new file mode 100644 index 000000000..9caa7bc4f --- /dev/null +++ b/src/plugins/option/optioncore/texts/import_16px.svg @@ -0,0 +1,7 @@ + + + ICON / action /import + + + + \ No newline at end of file diff --git a/src/plugins/option/optioncore/texts/shortcut_search_16px.svg b/src/plugins/option/optioncore/texts/shortcut_search_16px.svg new file mode 100644 index 000000000..45a186cd0 --- /dev/null +++ b/src/plugins/option/optioncore/texts/shortcut_search_16px.svg @@ -0,0 +1,7 @@ + + + ICON / action /shortcut_search + + + + \ No newline at end of file