Gui: move CommandCompleter into its own source file
This commit is contained in:
@@ -213,11 +213,12 @@ void Action::setToolTip(const QString & s, const QString & title)
|
||||
title.isEmpty() ? _action->text() : title,
|
||||
_action->font(),
|
||||
_action->shortcut().toString(QKeySequence::NativeText),
|
||||
this));
|
||||
_pcCmd));
|
||||
}
|
||||
|
||||
static QString & actionTitle(QString & title)
|
||||
QString Action::cleanTitle(const QString & text)
|
||||
{
|
||||
QString title(text);
|
||||
// Deal with QAction title mnemonic
|
||||
static QRegularExpression re(QStringLiteral("&(.)"));
|
||||
title.replace(re, QStringLiteral("\\1"));
|
||||
@@ -227,19 +228,63 @@ static QString & actionTitle(QString & title)
|
||||
return title;
|
||||
}
|
||||
|
||||
static inline QString actionTitle(const QString &title)
|
||||
QString Action::commandToolTip(const Command *cmd, bool richFormat)
|
||||
{
|
||||
QString text(title);
|
||||
return actionTitle(text);
|
||||
if (!cmd)
|
||||
return QString();
|
||||
|
||||
if (richFormat) {
|
||||
if (auto action = cmd->getAction())
|
||||
return action->_action->toolTip();
|
||||
}
|
||||
|
||||
QString title, tooltip;
|
||||
if (dynamic_cast<const MacroCommand*>(cmd)) {
|
||||
if (auto txt = cmd->getMenuText())
|
||||
title = QString::fromUtf8(txt);
|
||||
if (auto txt = cmd->getToolTipText())
|
||||
tooltip = QString::fromUtf8(txt);
|
||||
} else {
|
||||
if (auto txt = cmd->getMenuText())
|
||||
title = qApp->translate(cmd->className(), txt);
|
||||
if (auto txt = cmd->getToolTipText())
|
||||
tooltip = qApp->translate(cmd->className(), txt);
|
||||
}
|
||||
|
||||
if (!richFormat)
|
||||
return tooltip;
|
||||
return createToolTip(tooltip, title, QFont(), cmd->getShortcut(), cmd);
|
||||
}
|
||||
|
||||
QString Action::commandMenuText(const Command *cmd)
|
||||
{
|
||||
if (!cmd)
|
||||
return QString();
|
||||
|
||||
QString title;
|
||||
if (auto action = cmd->getAction())
|
||||
title = action->text();
|
||||
else if (dynamic_cast<const MacroCommand*>(cmd)) {
|
||||
if (auto txt = cmd->getMenuText())
|
||||
title = QString::fromUtf8(txt);
|
||||
} else {
|
||||
if (auto txt = cmd->getMenuText())
|
||||
title = qApp->translate(cmd->className(), txt);
|
||||
}
|
||||
if (title.isEmpty())
|
||||
title = QString::fromUtf8(cmd->getName());
|
||||
else
|
||||
title = cleanTitle(title);
|
||||
return title;
|
||||
}
|
||||
|
||||
QString Action::createToolTip(QString _tooltip,
|
||||
const QString & title,
|
||||
const QFont &font,
|
||||
const QString &sc,
|
||||
Action *act)
|
||||
const Command *pcCmd)
|
||||
{
|
||||
QString text = actionTitle(title);
|
||||
QString text = cleanTitle(title);
|
||||
|
||||
if (text.isEmpty())
|
||||
return _tooltip;
|
||||
@@ -263,17 +308,18 @@ QString Action::createToolTip(QString _tooltip,
|
||||
text.toHtmlEscaped(), shortcut.toHtmlEscaped());
|
||||
|
||||
QString cmdName;
|
||||
auto pcCmd = act ? act->_pcCmd : nullptr;
|
||||
if (pcCmd && pcCmd->getName()) {
|
||||
cmdName = QString::fromLatin1(pcCmd->getName());
|
||||
if (auto groupcmd = dynamic_cast<GroupCommand*>(pcCmd)) {
|
||||
int idx = act->property("defaultAction").toInt();
|
||||
auto cmd = groupcmd->getCommand(idx);
|
||||
if (cmd && cmd->getName())
|
||||
cmdName = QStringLiteral("%1 (%2:%3)")
|
||||
.arg(QString::fromLatin1(cmd->getName()))
|
||||
.arg(cmdName)
|
||||
.arg(idx);
|
||||
if (auto groupcmd = dynamic_cast<const GroupCommand*>(pcCmd)) {
|
||||
if (auto act = pcCmd->getAction()) {
|
||||
int idx = act->property("defaultAction").toInt();
|
||||
auto cmd = groupcmd->getCommand(idx);
|
||||
if (cmd && cmd->getName())
|
||||
cmdName = QStringLiteral("%1 (%2:%3)")
|
||||
.arg(QString::fromLatin1(cmd->getName()))
|
||||
.arg(cmdName)
|
||||
.arg(idx);
|
||||
}
|
||||
}
|
||||
cmdName = QStringLiteral("<p style='white-space:pre; margin-top:0.5em;'><i>%1</i></p>")
|
||||
.arg(cmdName.toHtmlEscaped());
|
||||
@@ -1367,201 +1413,4 @@ void WindowAction::addTo ( QWidget * w )
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
struct CmdInfo {
|
||||
Command *cmd = nullptr;
|
||||
QString text;
|
||||
QString tooltip;
|
||||
QIcon icon;
|
||||
bool iconChecked = false;
|
||||
};
|
||||
static std::vector<CmdInfo> _Commands;
|
||||
static int _CommandRevision;
|
||||
static const int CommandNameRole = Qt::UserRole;
|
||||
|
||||
class CommandModel : public QAbstractItemModel
|
||||
{
|
||||
public:
|
||||
CommandModel(QObject* parent)
|
||||
: QAbstractItemModel(parent)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
auto &manager = Application::Instance->commandManager();
|
||||
if (_CommandRevision == manager.getRevision())
|
||||
return;
|
||||
beginResetModel();
|
||||
_CommandRevision = manager.getRevision();
|
||||
_Commands.clear();
|
||||
for (auto &v : manager.getCommands()) {
|
||||
_Commands.emplace_back();
|
||||
auto &info = _Commands.back();
|
||||
info.cmd = v.second;
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
virtual QModelIndex parent(const QModelIndex &) const
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
virtual QVariant data(const QModelIndex & index, int role) const
|
||||
{
|
||||
if (index.row() < 0 || index.row() >= (int)_Commands.size())
|
||||
return QVariant();
|
||||
|
||||
auto &info = _Commands[index.row()];
|
||||
|
||||
switch(role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
if (info.text.isEmpty()) {
|
||||
info.text = QStringLiteral("%2 (%1)").arg(
|
||||
QString::fromLatin1(info.cmd->getName()),
|
||||
qApp->translate(info.cmd->className(), info.cmd->getMenuText()));
|
||||
actionTitle(info.text);
|
||||
if (info.text.isEmpty())
|
||||
info.text = QString::fromLatin1(info.cmd->getName());
|
||||
}
|
||||
return info.text;
|
||||
|
||||
case Qt::DecorationRole:
|
||||
if (!info.iconChecked) {
|
||||
info.iconChecked = true;
|
||||
if(info.cmd->getPixmap())
|
||||
info.icon = BitmapFactory().iconFromTheme(info.cmd->getPixmap());
|
||||
}
|
||||
return info.icon;
|
||||
|
||||
case Qt::ToolTipRole:
|
||||
if (info.tooltip.isEmpty()) {
|
||||
info.tooltip = QString::fromLatin1("%1: %2").arg(
|
||||
QString::fromLatin1(info.cmd->getName()),
|
||||
qApp->translate(info.cmd->className(), info.cmd->getMenuText()));
|
||||
QString tooltip = qApp->translate(info.cmd->className(), info.cmd->getToolTipText());
|
||||
if (tooltip.size())
|
||||
info.tooltip += QString::fromLatin1("\n\n") + tooltip;
|
||||
}
|
||||
return info.tooltip;
|
||||
|
||||
case CommandNameRole:
|
||||
return QByteArray(info.cmd->getName());
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
virtual QModelIndex index(int row, int, const QModelIndex &) const
|
||||
{
|
||||
return this->createIndex(row, 0);
|
||||
}
|
||||
|
||||
virtual int rowCount(const QModelIndex &) const
|
||||
{
|
||||
return (int)(_Commands.size());
|
||||
}
|
||||
|
||||
virtual int columnCount(const QModelIndex &) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
CommandCompleter::CommandCompleter(QLineEdit *lineedit, QObject *parent)
|
||||
: QCompleter(parent)
|
||||
{
|
||||
this->setModel(new CommandModel(this));
|
||||
this->setFilterMode(Qt::MatchContains);
|
||||
this->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
this->setCompletionMode(QCompleter::PopupCompletion);
|
||||
this->setWidget(lineedit);
|
||||
connect(lineedit, SIGNAL(textEdited(QString)), this, SLOT(onTextChanged(QString)));
|
||||
connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(onCommandActivated(QModelIndex)));
|
||||
connect(this, SIGNAL(highlighted(QString)), lineedit, SLOT(setText(QString)));
|
||||
}
|
||||
|
||||
bool CommandCompleter::eventFilter(QObject *o, QEvent *ev)
|
||||
{
|
||||
if (ev->type() == QEvent::KeyPress
|
||||
&& (o == this->widget() || o == this->popup()))
|
||||
{
|
||||
QKeyEvent * ke = static_cast<QKeyEvent*>(ev);
|
||||
switch(ke->key()) {
|
||||
case Qt::Key_Escape: {
|
||||
auto edit = qobject_cast<QLineEdit*>(this->widget());
|
||||
if (edit && edit->text().size()) {
|
||||
edit->setText(QString());
|
||||
popup()->hide();
|
||||
return true;
|
||||
} else if (popup()->isVisible()) {
|
||||
popup()->hide();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Tab: {
|
||||
if (this->popup()->isVisible()) {
|
||||
QKeyEvent kevent(ke->type(),Qt::Key_Down,0);
|
||||
qApp->sendEvent(this->popup(), &kevent);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Backtab: {
|
||||
if (this->popup()->isVisible()) {
|
||||
QKeyEvent kevent(ke->type(),Qt::Key_Up,0);
|
||||
qApp->sendEvent(this->popup(), &kevent);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
if (o == this->widget()) {
|
||||
auto index = currentIndex();
|
||||
if (index.isValid())
|
||||
onCommandActivated(index);
|
||||
else
|
||||
complete();
|
||||
ev->setAccepted(true);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QCompleter::eventFilter(o, ev);
|
||||
}
|
||||
|
||||
void CommandCompleter::onCommandActivated(const QModelIndex &index)
|
||||
{
|
||||
QByteArray name = completionModel()->data(index, CommandNameRole).toByteArray();
|
||||
Q_EMIT commandActivated(name);
|
||||
}
|
||||
|
||||
void CommandCompleter::onTextChanged(const QString &txt)
|
||||
{
|
||||
// Do not activate completer if less than 3 characters for better
|
||||
// performance.
|
||||
if (txt.size() < 3 || !widget())
|
||||
return;
|
||||
|
||||
static_cast<CommandModel*>(this->model())->update();
|
||||
|
||||
this->setCompletionPrefix(txt);
|
||||
QRect rect = widget()->rect();
|
||||
if (rect.width() < 300)
|
||||
rect.setWidth(300);
|
||||
this->complete(rect);
|
||||
}
|
||||
|
||||
#include "moc_Action.cpp"
|
||||
|
||||
@@ -81,7 +81,23 @@ public:
|
||||
const QString &title,
|
||||
const QFont &font,
|
||||
const QString &shortcut,
|
||||
Action *action = nullptr);
|
||||
const Command *cmd = nullptr);
|
||||
|
||||
/** Obtain tool tip of a given command
|
||||
* @param cmd: input command
|
||||
* @param richFormat: whether to output rich text formatted tooltip
|
||||
*/
|
||||
static QString commandToolTip(const Command *cmd, bool richFormat = true);
|
||||
|
||||
/** Obtain the menu text of a given command
|
||||
* @param cmd: input command
|
||||
* @return Return the command menu text that is stripped with its mnemonic
|
||||
* symbol '&' and ending punctuations
|
||||
*/
|
||||
static QString commandMenuText(const Command *cmd);
|
||||
|
||||
/// Clean the title by stripping the mnemonic symbol '&' and ending punctuations
|
||||
static QString cleanTitle(const QString &title);
|
||||
|
||||
Command *command() const {
|
||||
return _pcCmd;
|
||||
@@ -371,26 +387,6 @@ private:
|
||||
QMenu* _menu;
|
||||
};
|
||||
|
||||
/**
|
||||
* Command name completer.
|
||||
*/
|
||||
class GuiExport CommandCompleter : public QCompleter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CommandCompleter(QLineEdit *edit, QObject *parent = nullptr);
|
||||
|
||||
Q_SIGNALS:
|
||||
void commandActivated(const QByteArray &name);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onTextChanged(const QString &);
|
||||
void onCommandActivated(const QModelIndex &);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *, QEvent *ev);
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
#endif // GUI_ACTION_H
|
||||
|
||||
@@ -385,6 +385,7 @@ SET(Command_CPP_SRCS
|
||||
CommandLink.cpp
|
||||
CommandPyImp.cpp
|
||||
ShortcutManager.cpp
|
||||
CommandCompleter.cpp
|
||||
)
|
||||
SET(Command_SRCS
|
||||
${Command_CPP_SRCS}
|
||||
@@ -393,6 +394,7 @@ SET(Command_SRCS
|
||||
Command.h
|
||||
CommandT.h
|
||||
ShortcutManager.h
|
||||
CommandCompleter.h
|
||||
)
|
||||
SOURCE_GROUP("Command" FILES ${Command_SRCS})
|
||||
|
||||
|
||||
239
src/Gui/CommandCompleter.cpp
Normal file
239
src/Gui/CommandCompleter.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2022 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <QApplication>
|
||||
# include <QKeyEvent>
|
||||
# include <QLineEdit>
|
||||
# include <QAbstractItemView>
|
||||
#endif
|
||||
|
||||
#include "Application.h"
|
||||
#include "ShortcutManager.h"
|
||||
#include "Command.h"
|
||||
#include "Action.h"
|
||||
#include "BitmapFactory.h"
|
||||
#include "CommandCompleter.h"
|
||||
|
||||
using namespace Gui;
|
||||
|
||||
namespace {
|
||||
|
||||
struct CmdInfo {
|
||||
Command *cmd = nullptr;
|
||||
QIcon icon;
|
||||
bool iconChecked = false;
|
||||
};
|
||||
std::vector<CmdInfo> _Commands;
|
||||
int _CommandRevision;
|
||||
const int CommandNameRole = Qt::UserRole;
|
||||
bool _ShortcutSignalConnected = false;
|
||||
|
||||
class CommandModel : public QAbstractItemModel
|
||||
{
|
||||
int revision = 0;
|
||||
|
||||
public:
|
||||
CommandModel(QObject* parent)
|
||||
: QAbstractItemModel(parent)
|
||||
{
|
||||
update();
|
||||
if (!_ShortcutSignalConnected) {
|
||||
_ShortcutSignalConnected = true;
|
||||
QObject::connect(ShortcutManager::instance(), &ShortcutManager::shortcutChanged, []{_CommandRevision = 0;});
|
||||
}
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
auto &manager = Application::Instance->commandManager();
|
||||
if (revision == _CommandRevision && _CommandRevision == manager.getRevision())
|
||||
return;
|
||||
beginResetModel();
|
||||
revision = manager.getRevision();
|
||||
if (revision != _CommandRevision) {
|
||||
_CommandRevision = revision;
|
||||
_CommandRevision = manager.getRevision();
|
||||
_Commands.clear();
|
||||
for (auto &v : manager.getCommands()) {
|
||||
_Commands.emplace_back();
|
||||
auto &info = _Commands.back();
|
||||
info.cmd = v.second;
|
||||
}
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
virtual QModelIndex parent(const QModelIndex &) const
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
virtual QVariant data(const QModelIndex & index, int role) const
|
||||
{
|
||||
if (index.row() < 0 || index.row() >= (int)_Commands.size())
|
||||
return QVariant();
|
||||
|
||||
auto &info = _Commands[index.row()];
|
||||
|
||||
switch(role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole: {
|
||||
QString title = QStringLiteral("%1 (%2)").arg(
|
||||
Action::commandMenuText(info.cmd),
|
||||
QString::fromUtf8(info.cmd->getName()));
|
||||
QString shortcut = info.cmd->getShortcut();
|
||||
if (!shortcut.isEmpty())
|
||||
title += QStringLiteral(" (%1)").arg(shortcut);
|
||||
return title;
|
||||
}
|
||||
case Qt::ToolTipRole:
|
||||
return Action::commandToolTip(info.cmd);
|
||||
|
||||
case Qt::DecorationRole:
|
||||
if (!info.iconChecked) {
|
||||
info.iconChecked = true;
|
||||
if(info.cmd->getPixmap())
|
||||
info.icon = BitmapFactory().iconFromTheme(info.cmd->getPixmap());
|
||||
}
|
||||
return info.icon;
|
||||
|
||||
case CommandNameRole:
|
||||
return QByteArray(info.cmd->getName());
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
virtual QModelIndex index(int row, int, const QModelIndex &) const
|
||||
{
|
||||
return this->createIndex(row, 0);
|
||||
}
|
||||
|
||||
virtual int rowCount(const QModelIndex &) const
|
||||
{
|
||||
return (int)(_Commands.size());
|
||||
}
|
||||
|
||||
virtual int columnCount(const QModelIndex &) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
CommandCompleter::CommandCompleter(QLineEdit *lineedit, QObject *parent)
|
||||
: QCompleter(parent)
|
||||
{
|
||||
this->setModel(new CommandModel(this));
|
||||
this->setFilterMode(Qt::MatchContains);
|
||||
this->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
this->setCompletionMode(QCompleter::PopupCompletion);
|
||||
this->setWidget(lineedit);
|
||||
connect(lineedit, SIGNAL(textEdited(QString)), this, SLOT(onTextChanged(QString)));
|
||||
connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(onCommandActivated(QModelIndex)));
|
||||
connect(this, SIGNAL(highlighted(QString)), lineedit, SLOT(setText(QString)));
|
||||
}
|
||||
|
||||
bool CommandCompleter::eventFilter(QObject *o, QEvent *ev)
|
||||
{
|
||||
if (ev->type() == QEvent::KeyPress
|
||||
&& (o == this->widget() || o == this->popup()))
|
||||
{
|
||||
QKeyEvent * ke = static_cast<QKeyEvent*>(ev);
|
||||
switch(ke->key()) {
|
||||
case Qt::Key_Escape: {
|
||||
auto edit = qobject_cast<QLineEdit*>(this->widget());
|
||||
if (edit && edit->text().size()) {
|
||||
edit->setText(QString());
|
||||
popup()->hide();
|
||||
return true;
|
||||
} else if (popup()->isVisible()) {
|
||||
popup()->hide();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Tab: {
|
||||
if (this->popup()->isVisible()) {
|
||||
QKeyEvent kevent(ke->type(),Qt::Key_Down,0);
|
||||
qApp->sendEvent(this->popup(), &kevent);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Backtab: {
|
||||
if (this->popup()->isVisible()) {
|
||||
QKeyEvent kevent(ke->type(),Qt::Key_Up,0);
|
||||
qApp->sendEvent(this->popup(), &kevent);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
if (o == this->widget()) {
|
||||
auto index = currentIndex();
|
||||
if (index.isValid())
|
||||
onCommandActivated(index);
|
||||
else
|
||||
complete();
|
||||
ev->setAccepted(true);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QCompleter::eventFilter(o, ev);
|
||||
}
|
||||
|
||||
void CommandCompleter::onCommandActivated(const QModelIndex &index)
|
||||
{
|
||||
QByteArray name = completionModel()->data(index, CommandNameRole).toByteArray();
|
||||
Q_EMIT commandActivated(name);
|
||||
}
|
||||
|
||||
void CommandCompleter::onTextChanged(const QString &txt)
|
||||
{
|
||||
// Do not activate completer if less than 3 characters for better
|
||||
// performance.
|
||||
if (txt.size() < 3 || !widget())
|
||||
return;
|
||||
|
||||
static_cast<CommandModel*>(this->model())->update();
|
||||
|
||||
this->setCompletionPrefix(txt);
|
||||
QRect rect = widget()->rect();
|
||||
if (rect.width() < 300)
|
||||
rect.setWidth(300);
|
||||
this->complete(rect);
|
||||
}
|
||||
|
||||
#include "moc_CommandCompleter.cpp"
|
||||
59
src/Gui/CommandCompleter.h
Normal file
59
src/Gui/CommandCompleter.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2022 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef GUI_COMMAND_COMPLETER_H
|
||||
#define GUI_COMMAND_COMPLETER_H
|
||||
|
||||
#include <QCompleter>
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
namespace Gui {
|
||||
|
||||
/**
|
||||
* Command name auto completer.
|
||||
*
|
||||
* This class provides an auto completer for a QLineEdit widget. The auto
|
||||
* completer supports keyword search in command title, internal name, and
|
||||
* shortcut.
|
||||
*/
|
||||
class GuiExport CommandCompleter : public QCompleter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CommandCompleter(QLineEdit *edit, QObject *parent = nullptr);
|
||||
|
||||
Q_SIGNALS:
|
||||
/// Triggered when a command is selected in the completer
|
||||
void commandActivated(const QByteArray &name);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onTextChanged(const QString &);
|
||||
void onCommandActivated(const QModelIndex &);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *, QEvent *ev);
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
#endif
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "Window.h"
|
||||
#include "PrefWidgets.h"
|
||||
#include "ShortcutManager.h"
|
||||
#include "CommandCompleter.h"
|
||||
|
||||
|
||||
using namespace Gui::Dialog;
|
||||
@@ -146,19 +147,14 @@ DlgCustomKeyboardImp::initCommandList(QTreeWidget *commandTreeWidget, QComboBox
|
||||
|
||||
commandTreeWidget->clear();
|
||||
CommandManager & cCmdMgr = Application::Instance->commandManager();
|
||||
QString group = combo->itemData(index, Qt::UserRole).toString();
|
||||
auto cmds = group == QStringLiteral("All") ? cCmdMgr.getAllCommands()
|
||||
: cCmdMgr.getGroupCommands(group.toLatin1());
|
||||
auto group = combo->itemData(index, Qt::UserRole).toByteArray();
|
||||
auto cmds = group == "All" ? cCmdMgr.getAllCommands()
|
||||
: cCmdMgr.getGroupCommands(group.constData());
|
||||
QTreeWidgetItem *currentItem = nullptr;
|
||||
for (const Command *cmd : cmds) {
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(commandTreeWidget);
|
||||
if (dynamic_cast<const MacroCommand*>(cmd)) {
|
||||
item->setText(1, QString::fromUtf8(cmd->getMenuText()));
|
||||
item->setToolTip(1, QString::fromUtf8(cmd->getToolTipText()));
|
||||
} else {
|
||||
item->setText(1, qApp->translate(cmd->className(), cmd->getMenuText()));
|
||||
item->setToolTip(1, qApp->translate(cmd->className(), cmd->getToolTipText()));
|
||||
}
|
||||
item->setText(1, Action::commandMenuText(cmd));
|
||||
item->setToolTip(1, Action::commandToolTip(cmd));
|
||||
item->setData(1, Qt::UserRole, QByteArray(cmd->getName()));
|
||||
item->setSizeHint(0, QSize(32, 32));
|
||||
if (auto pixmap = cmd->getPixmap())
|
||||
@@ -287,7 +283,7 @@ void DlgCustomKeyboardImp::populatePriorityList(QTreeWidget *priorityList,
|
||||
continue;
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(priorityList);
|
||||
item->setText(0, QString::fromUtf8(info.first));
|
||||
item->setText(1, info.second->text());
|
||||
item->setText(1, Action::cleanTitle(info.second->text()));
|
||||
item->setToolTip(0, info.second->toolTip());
|
||||
item->setIcon(0, info.second->icon());
|
||||
item->setData(0, Qt::UserRole, info.first);
|
||||
@@ -374,7 +370,7 @@ void DlgCustomKeyboardImp::on_commandTreeWidget_currentItemChanged(QTreeWidgetIt
|
||||
ui->buttonReset->setEnabled((ks != ks2));
|
||||
}
|
||||
|
||||
ui->textLabelDescription->setText(item->toolTip(1));
|
||||
ui->textLabelDescription->setText(Action::commandToolTip(cmd, false));
|
||||
}
|
||||
|
||||
/** Shows all commands of this category */
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "Application.h"
|
||||
#include "BitmapFactory.h"
|
||||
#include "Command.h"
|
||||
#include "Action.h"
|
||||
#include "ToolBarManager.h"
|
||||
#include "MainWindow.h"
|
||||
#include "ToolBarManager.h"
|
||||
#include "Widgets.h"
|
||||
@@ -205,9 +207,10 @@ void DlgCustomToolbars::importCustomToolbars(const QByteArray& name)
|
||||
Command* pCmd = rMgr.getCommandByName(it2.first.c_str());
|
||||
if (pCmd) {
|
||||
// command name
|
||||
auto item = new QTreeWidgetItem(toplevel);
|
||||
item->setText(0, qApp->translate(pCmd->className(), pCmd->getMenuText()));
|
||||
item->setData(0, Qt::UserRole, QByteArray(it2.first.c_str()));
|
||||
auto* item = new QTreeWidgetItem(toplevel);
|
||||
item->setText(0, Action::commandMenuText(pCmd));
|
||||
item->setToolTip(0, Action::commandToolTip(pCmd));
|
||||
item->setData(0, Qt::UserRole, QByteArray(it2->first.c_str()));
|
||||
if (pCmd->getPixmap())
|
||||
item->setIcon(0, BitmapFactory().iconFromTheme(pCmd->getPixmap()));
|
||||
item->setSizeHint(0, QSize(32, 32));
|
||||
|
||||
Reference in New Issue
Block a user