Salome HOME
[bos #40644][CEA](2024-T1) Feature search.
authordish <dmitrii.shvydkoi@opencascade.com>
Thu, 7 Mar 2024 12:25:21 +0000 (12:25 +0000)
committerdish <dmitrii.shvydkoi@opencascade.com>
Thu, 7 Mar 2024 12:25:21 +0000 (12:25 +0000)
Renaming.

src/Qtx/CMakeLists.txt
src/Qtx/QtxFeatureSearch.cxx [deleted file]
src/Qtx/QtxFeatureSearch.h [deleted file]
src/Qtx/QtxFindActionDialog.cxx [new file with mode: 0644]
src/Qtx/QtxFindActionDialog.h [new file with mode: 0644]
src/Qtx/resources/Qtx_msg_fr.ts
src/Qtx/resources/Qtx_msg_ja.ts
src/SUIT/SUIT_ShortcutMgr.h
src/SalomeApp/SalomeApp_Application.cxx

index 9d1ae2f6371631a35cc0e0d41af61ac410b372e8..78b104718bed3af22955d0ca4a86445738cbe964 100644 (file)
@@ -53,7 +53,7 @@ SET(_moc_HEADERS
   QtxDockWidget.h
   QtxDoubleSpinBox.h
   QtxDoubleSpinSlider.h
-  QtxFeatureSearch.h
+  QtxFindActionDialog.h
   QtxFontEdit.h
   QtxGridBox.h
   QtxGroupBox.h
@@ -148,7 +148,7 @@ SET(_other_SOURCES
   QtxDoubleSpinBox.cxx
   QtxDoubleSpinSlider.cxx
   QtxEvalExpr.cxx
-  QtxFeatureSearch.cxx
+  QtxFindActionDialog.cxx
   QtxFontEdit.cxx
   QtxGridBox.cxx
   QtxGroupBox.cxx
diff --git a/src/Qtx/QtxFeatureSearch.cxx b/src/Qtx/QtxFeatureSearch.cxx
deleted file mode 100644 (file)
index 839b582..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 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
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-#include "QtxFeatureSearch.h"
-
-#include <QAction>
-#include <QWidget>
-#include <QLayout>
-#include <QList>
-#include <QMap>
-
-#include <QCollator>
-
-#include <QCheckBox>
-#include <QLineEdit>
-#include <QBrush>
-#include <QColor>
-#include <QHeaderView>
-
-#include <algorithm>
-
-
-QtxFeatureSearchDialog::QtxFeatureSearchDialog(QWidget* theParent)
-: QDialog(theParent)
-{
-  setMinimumWidth(500);
-  setWindowTitle(tr("Search action"));
-  QVBoxLayout* layout = new QVBoxLayout(this);
-
-  myQueryLineEdit = new QLineEdit(this);
-  layout->addWidget(myQueryLineEdit);
-  myQueryLineEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
-  setFocusProxy(myQueryLineEdit);
-
-  QHBoxLayout* searchOptionsLayout = new QHBoxLayout(this);
-  layout->addLayout(searchOptionsLayout);
-  myIncludeUnavailableActionsCB = new QCheckBox(tr("Unavailable actions"), this);
-  myIncludeUnavailableActionsCB->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-  myIncludeUnavailableActionsCB->setCheckState(Qt::CheckState::Checked);
-  myActionSearcher.includeDisabledActions(true);
-  myIncludeInactiveModulesCB = new QCheckBox(tr("Inactive modules"), this);
-  myIncludeInactiveModulesCB->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-  myIncludeInactiveModulesCB->setCheckState(Qt::CheckState::Unchecked);
-  searchOptionsLayout->addWidget(myIncludeUnavailableActionsCB);
-  searchOptionsLayout->addWidget(myIncludeInactiveModulesCB);
-
-  myFoundActionsTree = new QtxFoundActionTree();
-  layout->addWidget(myFoundActionsTree);
-
-  connect(myQueryLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onQueryChanged(const QString&)));
-  connect(myIncludeUnavailableActionsCB, SIGNAL(stateChanged(int)), this, SLOT(onSearchOptionUnavailableActionsChanged(int)));
-  connect(myIncludeInactiveModulesCB, SIGNAL(stateChanged(int)), this, SLOT(onSearchOptionInactiveModulesChanged(int)));
-}
-
-void QtxFeatureSearchDialog::setActiveModuleID(const QString& theModuleID)
-{
-  myActiveModuleID = theModuleID;
-  if(myActionSearcher.setIncludedModuleIDs(std::set<QString>({SUIT_ShortcutMgr::ROOT_MODULE_ID, myActiveModuleID})))
-    updateUI();
-}
-
-void QtxFeatureSearchDialog::onQueryChanged(const QString& theQuery)
-{
-  if (myActionSearcher.setQuery(theQuery))
-    updateUI();
-}
-
-void QtxFeatureSearchDialog::onSearchOptionUnavailableActionsChanged(int theState)
-{
-  ShCutDbg("QtxFeatureSearchDialog::onSearchOptionUnavailableActionsChanged");
-
-  if (myActionSearcher.includeDisabledActions(theState == Qt::CheckState::Checked))
-    updateUI();
-}
-
-void QtxFeatureSearchDialog::onSearchOptionInactiveModulesChanged(int theState)
-{
-  bool resultsChanged = false;
-  if (theState == Qt::CheckState::Checked)
-    resultsChanged = myActionSearcher.setIncludedModuleIDs(SUIT_ShortcutMgr::get()->getShortcutContainer().getIDsOfAllModules());
-  else
-    resultsChanged = myActionSearcher.setIncludedModuleIDs(std::set<QString>({SUIT_ShortcutMgr::ROOT_MODULE_ID, myActiveModuleID}));
-
-  if (resultsChanged)
-    updateUI();
-}
-
-void QtxFeatureSearchDialog::updateUI()
-{
-  myFoundActionsTree->updateItems(myActionSearcher.getSearchResults());
-}
-
-
-
-QtxFoundActionTree::QtxFoundActionTree()
-{
-  setColumnCount(2);
-  setSelectionMode(QAbstractItemView::SingleSelection);
-  setSortingEnabled(false); // Items are sorted in the same way, as in ShortcutContainer.
-  header()->setSectionResizeMode(QHeaderView::Interactive);
-  {
-    QMap<int, QString> labelMap;
-    labelMap[QtxFoundActionTree::ElementIdx::Name]    = tr("Action");
-    labelMap[QtxFoundActionTree::ElementIdx::ToolTip] = tr("Description");
-    setHeaderLabels(labelMap.values());
-  }
-  setExpandsOnDoubleClick(false); // Open shortcut editor on double click instead.
-  setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
-  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-
-  setColumnWidth(QtxFoundActionTree::ElementIdx::Name, 120);
-  setColumnWidth(QtxFoundActionTree::ElementIdx::Name, 250);
-  setMinimumHeight(300);
-
-  setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
-
-  connect(this, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(onItemDoubleClicked(QTreeWidgetItem*, int)));
-}
-
-void QtxFoundActionTree::updateItems(const std::map<QString, std::map<QString, SUIT_ActionSearcher::AssetsAndSearchData>>& theAssets)
-{
-  clear();
-
-  const auto shortcutMgr = SUIT_ShortcutMgr::get();
-  const QString lang = SUIT_ShortcutMgr::getLang();
-
-  for (const auto& moduleIDAndAssets : theAssets) {
-    const QString& moduleID = moduleIDAndAssets.first;
-    const auto& moduleAssets = moduleIDAndAssets.second;
-    if (moduleAssets.empty())
-      continue;
-
-    const auto moduleItem = new QtxFoundActionTreeFolder(moduleID);
-    moduleItem->setAssets(shortcutMgr->getModuleAssets(moduleID), lang);
-    addTopLevelItem(moduleItem);
-    moduleItem->setFlags(Qt::ItemIsEnabled);
-    for (const auto& actionIDAndAssets : moduleAssets) {
-      const QString& inModuleActionID = actionIDAndAssets.first;
-      const SUIT_ActionSearcher::AssetsAndSearchData& assetsAndSearchData = actionIDAndAssets.second;
-
-      auto actionItem = QtxFoundActionTreeAction::create(moduleID, inModuleActionID);
-      if (!actionItem) {
-        ShCutDbg("QtxFoundActionTree can't create child item for action ID = \"" + SUIT_ShortcutMgr::makeActionID(moduleID, inModuleActionID) + "\".");
-        continue;
-      }
-
-      actionItem->setAssets(assetsAndSearchData.myAssets, lang);
-      moduleItem->addChild(actionItem);
-    }
-    moduleItem->setExpanded(true); // Make tree expanded on first show.
-  }
-}
-
-std::pair<QtxFoundActionTreeFolder*, int> QtxFoundActionTree::findModuleFolderItem(const QString& theModuleID) const
-{
-  for (int moduleIdx = 0; moduleIdx < topLevelItemCount(); moduleIdx++) {
-    QtxFoundActionTreeFolder* moduleItem = static_cast<QtxFoundActionTreeFolder*>(topLevelItem(moduleIdx));
-    if (moduleItem->myModuleID == theModuleID)
-      return std::pair<QtxFoundActionTreeFolder*, int>(moduleItem, moduleIdx);
-  }
-  return std::pair<QtxFoundActionTreeFolder*, int>(nullptr, -1);
-}
-
-void QtxFoundActionTree::onItemDoubleClicked(QTreeWidgetItem* theItem, int theColIdx)
-{
-  {
-    QtxFoundActionTreeItem* const item = static_cast<QtxFoundActionTreeItem*>(theItem);
-    // Do not react if folder-item is clicked.
-    if (item->type() != QtxFoundActionTreeItem::Type::Action)
-      return;
-  }
-
-  QtxFoundActionTreeAction* const actionItem = static_cast<QtxFoundActionTreeAction*>(theItem);
-  actionItem->trigger();
-}
-
-
-QtxFoundActionTreeItem::QtxFoundActionTreeItem(const QString& theModuleID)
-: QTreeWidgetItem(), myModuleID(theModuleID)
-{ }
-
-QString QtxFoundActionTreeItem::name() const
-{
-  return text(QtxFoundActionTree::ElementIdx::Name);
-}
-
-QString QtxFoundActionTreeItem::toolTip() const
-{
-  return text(QtxFoundActionTree::ElementIdx::ToolTip);
-}
-
-
-QtxFoundActionTreeFolder::QtxFoundActionTreeFolder(const QString& theModuleID)
-: QtxFoundActionTreeItem(theModuleID)
-{
-  QFont f = font(QtxFoundActionTree::ElementIdx::Name);
-  f.setBold(true);
-  setFont(QtxFoundActionTree::ElementIdx::Name, f);
-  setText(QtxFoundActionTree::ElementIdx::Name, theModuleID);
-}
-
-void QtxFoundActionTreeFolder::setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang)
-{
-  if (!theAssets)
-    return;
-
-  setIcon(QtxFoundActionTree::ElementIdx::Name, theAssets->myIcon);
-
-  const auto& ldaMap = theAssets->myLangDependentAssets;
-  if (ldaMap.empty()) {
-    setText(QtxFoundActionTree::ElementIdx::Name, myModuleID);
-    return;
-  }
-
-  auto itLDA = ldaMap.find(theLang);
-  if (itLDA == ldaMap.end())
-    itLDA = ldaMap.begin();
-
-  const SUIT_ActionAssets::LangDependentAssets& lda = itLDA->second;
-  const QString& name = lda.myName.isEmpty() ? myModuleID : lda.myName;
-  setText(QtxFoundActionTree::ElementIdx::Name, name);
-}
-
-QString QtxFoundActionTreeFolder::getValue(QtxFoundActionTree::SortKey theKey) const
-{
-  switch (theKey) {
-    case QtxFoundActionTree::SortKey::ID:
-      return myModuleID;
-    case QtxFoundActionTree::SortKey::Name:
-      return name();
-    case QtxFoundActionTree::SortKey::ToolTip:
-      return toolTip();
-    default:
-      return QString();
-  }
-}
-
-bool QtxFoundActionTreeFolder::isEnabled() const
-{
-  return true;
-}
-
-
-QtxFoundActionTreeAction::QtxFoundActionTreeAction(const QString& theModuleID, const QString& theInModuleActionID)
-: QtxFoundActionTreeItem(theModuleID), myInModuleActionID(theInModuleActionID)
-{
-  setText(QtxFoundActionTree::ElementIdx::Name, theInModuleActionID);
-}
-
-/*static*/ QtxFoundActionTreeAction* QtxFoundActionTreeAction::create(const QString& theModuleID, const QString& theInModuleActionID)
-{
-  if (theInModuleActionID.isEmpty()) {
-    ShCutDbg("QtxFoundActionTreeItem: attempt to create item with empty action ID.");
-    return nullptr;
-  }
-
-  return new QtxFoundActionTreeAction(theModuleID, theInModuleActionID);
-}
-
-void QtxFoundActionTreeAction::setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang)
-{
-  ShCutDbg("QtxFoundActionTreeAction::setAssets()");
-
-  if (!theAssets)
-    return;
-
-  setIcon(QtxFoundActionTree::ElementIdx::Name, theAssets->myIcon);
-
-  const auto& ldaMap = theAssets->myLangDependentAssets;
-  if (ldaMap.empty()) {
-    setText(QtxFoundActionTree::ElementIdx::Name, myInModuleActionID);
-    return;
-  }
-
-  auto itLDA = ldaMap.find(theLang);
-  if (itLDA == ldaMap.end())
-    itLDA = ldaMap.begin();
-
-  const SUIT_ActionAssets::LangDependentAssets& lda = itLDA->second;
-  const QString& name = lda.myName.isEmpty() ? myInModuleActionID : lda.myName;
-  setText(QtxFoundActionTree::ElementIdx::Name, name);
-
-  setText(QtxFoundActionTree::ElementIdx::ToolTip, lda.myToolTip);
-
-  if (isEnabled()) {
-    ShCutDbg("QtxFoundActionTreeAction::setAssets(): Action \"" + name + "\" is enabled.");
-
-    setToolTip(
-      QtxFoundActionTree::ElementIdx::Name,
-      QtxFoundActionTree::tr("Double click to start")
-    );
-
-    setToolTip(
-      QtxFoundActionTree::ElementIdx::ToolTip,
-      QtxFoundActionTree::tr("Double click to start")
-    );
-  }
-  else {
-    ShCutDbg("QtxFoundActionTreeAction::setAssets(): Action \"" + name + "\" is disabled.");
-
-    static const QBrush greyedOutBrush = QBrush(Qt::gray);
-    setForeground(QtxFoundActionTree::ElementIdx::Name,    greyedOutBrush);
-    setForeground(QtxFoundActionTree::ElementIdx::ToolTip, greyedOutBrush);
-  }
-}
-
-QString QtxFoundActionTreeAction::getValue(QtxFoundActionTree::SortKey theKey) const
-{
-  switch (theKey) {
-    case QtxFoundActionTree::SortKey::ID:
-      return myInModuleActionID;
-    case QtxFoundActionTree::SortKey::Name:
-      return name();
-    case QtxFoundActionTree::SortKey::ToolTip:
-      return toolTip();
-    default:
-      return QString();
-  }
-}
-
-bool QtxFoundActionTreeAction::isEnabled() const
-{
-  ShCutDbg("QtxFoundActionTreeAction::isEnabled(): " + myModuleID + "/" + myInModuleActionID + ".");
-  const auto& actions = SUIT_ShortcutMgr::get()->getActions(myModuleID, myInModuleActionID);
-  ShCutDbg("QtxFoundActionTreeAction::isEnabled(): num of actions = " + QString::number(actions.size()));
-  return std::find_if(actions.begin(), actions.end(), [](const QAction* const theAction){ return theAction->isEnabled(); }) != actions.end();
-}
-
-void QtxFoundActionTreeAction::trigger() const
-{
-  const auto& actions = SUIT_ShortcutMgr::get()->getActions(myModuleID, myInModuleActionID);
-  for (const auto& action : actions) {
-    if (action->isEnabled())
-      action->trigger();
-  }
-}
diff --git a/src/Qtx/QtxFeatureSearch.h b/src/Qtx/QtxFeatureSearch.h
deleted file mode 100644 (file)
index c5d3ac5..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 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
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-#ifndef QTXFEATURESEARCH_H
-#define QTXFEATURESEARCH_H
-
-#include "Qtx.h"
-#include <QDialog>
-#include <QFrame>
-#include <QTreeWidget>
-#include "SUIT_ShortcutMgr.h"
-#include <memory>
-#include <map>
-#include <set>
-#include <functional>
-
-
-class QCheckBox;
-class QLineEdit;
-class QLabel;
-class QPushButton;
-class QtxFoundActionTree;
-
-
-class QTX_EXPORT QtxFeatureSearchDialog : public QDialog
-{
-  Q_OBJECT
-
-public:
-  QtxFeatureSearchDialog(QWidget* theParent);
-  QtxFeatureSearchDialog(const QtxFeatureSearchDialog&) = delete;
-  QtxFeatureSearchDialog& operator=(const QtxFeatureSearchDialog&) = delete;
-  virtual ~QtxFeatureSearchDialog() = default;
-
-  void setActiveModuleID(const QString& theModuleID = SUIT_ShortcutMgr::ROOT_MODULE_ID);
-
-private slots:
-  void onQueryChanged(const QString& theKeyword);
-  void onSearchOptionUnavailableActionsChanged(int);
-  void onSearchOptionInactiveModulesChanged(int);
-
-private:
-  void updateUI();
-
-  QLineEdit* myQueryLineEdit;
-  QCheckBox* myIncludeUnavailableActionsCB;
-  QCheckBox* myIncludeInactiveModulesCB;
-  QtxFoundActionTree* myFoundActionsTree;
-
-  QString myActiveModuleID;
-  SUIT_ActionSearcher myActionSearcher;
-};
-
-
-class QtxFoundActionTreeItem;
-class QtxFoundActionTreeFolder;
-class QtxFoundActionTreeAction;;
-
-
-class QTX_EXPORT QtxFoundActionTree : public QTreeWidget
-{
-  Q_OBJECT
-
-public:
-  enum ElementIdx {
-    Name = 0,
-    ToolTip = 1
-  };
-
-  enum class SortKey {
-    ID,
-    Name,
-    ToolTip
-  };
-
-  QtxFoundActionTree();
-  QtxFoundActionTree(const QtxFoundActionTree&) = delete;
-  QtxFoundActionTree& operator=(const QtxFoundActionTree&) = delete;
-  virtual ~QtxFoundActionTree() = default;
-
-  void updateItems(const std::map<QString, std::map<QString, SUIT_ActionSearcher::AssetsAndSearchData>>& theAssets);
-
-private:
-  std::pair<QtxFoundActionTreeFolder*, int> findModuleFolderItem(const QString& theModuleID) const;
-
-private slots:
-  void onItemDoubleClicked(QTreeWidgetItem* theWidgetItem, int theColIdx);
-};
-
-
-class QtxFoundActionTreeItem : public QTreeWidgetItem
-{
-public:
-  enum Type {
-    Folder = 0,
-    Action = 1,
-  };
-
-protected:
-  QtxFoundActionTreeItem(const QString& theModuleID);
-
-public:
-  virtual ~QtxFoundActionTreeItem() = default;
-  virtual QtxFoundActionTreeItem::Type type() const = 0;
-
-  virtual void setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang) = 0;
-  QString name() const;
-  QString toolTip() const;
-
-  virtual QString getValue(QtxFoundActionTree::SortKey theKey) const = 0;
-
-  virtual bool isEnabled() const = 0;
-
-public:
-  const QString myModuleID;
-};
-
-
-class QtxFoundActionTreeFolder : public QtxFoundActionTreeItem
-{
-public:
-  QtxFoundActionTreeFolder(const QString& theModuleID);
-  virtual ~QtxFoundActionTreeFolder() = default;
-  virtual QtxFoundActionTreeItem::Type type() const { return QtxFoundActionTreeItem::Type::Folder; };
-
-  virtual void setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang);
-
-  virtual QString getValue(QtxFoundActionTree::SortKey theKey) const;
-
-  virtual bool isEnabled() const;
-};
-
-
-class QtxFoundActionTreeAction : public QtxFoundActionTreeItem
-{
-private:
-  QtxFoundActionTreeAction(const QString& theModuleID, const QString& theInModuleActionID);
-
-public:
-  static QtxFoundActionTreeAction* create(const QString& theModuleID, const QString& theInModuleActionID);
-  virtual ~QtxFoundActionTreeAction() = default;
-  virtual QtxFoundActionTreeItem::Type type() const { return QtxFoundActionTreeItem::Type::Action; };
-
-  virtual void setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang);
-
-  virtual QString getValue(QtxFoundActionTree::SortKey theKey) const;
-
-  virtual bool isEnabled() const;
-
-  void trigger() const;
-
-  const QString myInModuleActionID;
-};
-
-#endif // QTXFEATURESEARCH_H
diff --git a/src/Qtx/QtxFindActionDialog.cxx b/src/Qtx/QtxFindActionDialog.cxx
new file mode 100644 (file)
index 0000000..6f903a1
--- /dev/null
@@ -0,0 +1,342 @@
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtxFindActionDialog.h"
+
+#include <QAction>
+#include <QWidget>
+#include <QLayout>
+#include <QList>
+#include <QMap>
+
+#include <QCollator>
+
+#include <QCheckBox>
+#include <QLineEdit>
+#include <QBrush>
+#include <QColor>
+#include <QHeaderView>
+
+#include <algorithm>
+
+
+QtxFindActionDialog::QtxFindActionDialog(QWidget* theParent)
+: QDialog(theParent)
+{
+  setMinimumWidth(500);
+  setWindowTitle(tr("Find action"));
+  QVBoxLayout* layout = new QVBoxLayout(this);
+
+  myQueryLineEdit = new QLineEdit(this);
+  layout->addWidget(myQueryLineEdit);
+  myQueryLineEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+  setFocusProxy(myQueryLineEdit);
+
+  QHBoxLayout* searchOptionsLayout = new QHBoxLayout(this);
+  layout->addLayout(searchOptionsLayout);
+  myIncludeUnavailableActionsCB = new QCheckBox(tr("Unavailable actions"), this);
+  myIncludeUnavailableActionsCB->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+  myIncludeUnavailableActionsCB->setCheckState(Qt::CheckState::Checked);
+  myActionSearcher.includeDisabledActions(true);
+  myIncludeInactiveModulesCB = new QCheckBox(tr("Inactive modules"), this);
+  myIncludeInactiveModulesCB->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+  myIncludeInactiveModulesCB->setCheckState(Qt::CheckState::Unchecked);
+  searchOptionsLayout->addWidget(myIncludeUnavailableActionsCB);
+  searchOptionsLayout->addWidget(myIncludeInactiveModulesCB);
+
+  myFoundActionsTree = new QtxFoundActionTree();
+  layout->addWidget(myFoundActionsTree);
+
+  connect(myQueryLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onQueryChanged(const QString&)));
+  connect(myIncludeUnavailableActionsCB, SIGNAL(stateChanged(int)), this, SLOT(onSearchOptionUnavailableActionsChanged(int)));
+  connect(myIncludeInactiveModulesCB, SIGNAL(stateChanged(int)), this, SLOT(onSearchOptionInactiveModulesChanged(int)));
+}
+
+void QtxFindActionDialog::setActiveModuleID(const QString& theModuleID)
+{
+  myActiveModuleID = theModuleID;
+  if(myActionSearcher.setIncludedModuleIDs(std::set<QString>({SUIT_ShortcutMgr::ROOT_MODULE_ID, myActiveModuleID})))
+    updateUI();
+}
+
+void QtxFindActionDialog::onQueryChanged(const QString& theQuery)
+{
+  if (myActionSearcher.setQuery(theQuery))
+    updateUI();
+}
+
+void QtxFindActionDialog::onSearchOptionUnavailableActionsChanged(int theState)
+{
+  if (myActionSearcher.includeDisabledActions(theState == Qt::CheckState::Checked))
+    updateUI();
+}
+
+void QtxFindActionDialog::onSearchOptionInactiveModulesChanged(int theState)
+{
+  bool resultsChanged = false;
+  if (theState == Qt::CheckState::Checked)
+    resultsChanged = myActionSearcher.setIncludedModuleIDs(SUIT_ShortcutMgr::get()->getShortcutContainer().getIDsOfAllModules());
+  else
+    resultsChanged = myActionSearcher.setIncludedModuleIDs(std::set<QString>({SUIT_ShortcutMgr::ROOT_MODULE_ID, myActiveModuleID}));
+
+  if (resultsChanged)
+    updateUI();
+}
+
+void QtxFindActionDialog::updateUI()
+{
+  myFoundActionsTree->updateItems(myActionSearcher.getSearchResults());
+}
+
+
+
+QtxFoundActionTree::QtxFoundActionTree()
+{
+  setColumnCount(2);
+  setSelectionMode(QAbstractItemView::SingleSelection);
+  setSortingEnabled(false); // Items are sorted in the same way, as in ShortcutContainer.
+  header()->setSectionResizeMode(QHeaderView::Interactive);
+  {
+    QMap<int, QString> labelMap;
+    labelMap[QtxFoundActionTree::ElementIdx::Name]    = QtxFindActionDialog::tr("Action");
+    labelMap[QtxFoundActionTree::ElementIdx::ToolTip] = QtxFindActionDialog::tr("Description");
+    setHeaderLabels(labelMap.values());
+  }
+  setExpandsOnDoubleClick(false); // Open shortcut editor on double click instead.
+  setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
+  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+  setColumnWidth(QtxFoundActionTree::ElementIdx::Name, 120);
+  setColumnWidth(QtxFoundActionTree::ElementIdx::Name, 250);
+  setMinimumHeight(300);
+
+  setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
+
+  connect(this, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(onItemDoubleClicked(QTreeWidgetItem*, int)));
+}
+
+void QtxFoundActionTree::updateItems(const std::map<QString, std::map<QString, SUIT_ActionSearcher::AssetsAndSearchData>>& theAssets)
+{
+  clear();
+
+  const auto shortcutMgr = SUIT_ShortcutMgr::get();
+  const QString lang = SUIT_ShortcutMgr::getLang();
+
+  for (const auto& moduleIDAndAssets : theAssets) {
+    const QString& moduleID = moduleIDAndAssets.first;
+    const auto& moduleAssets = moduleIDAndAssets.second;
+    if (moduleAssets.empty())
+      continue;
+
+    const auto moduleItem = new QtxFoundActionTreeFolder(moduleID);
+    moduleItem->setAssets(shortcutMgr->getModuleAssets(moduleID), lang);
+    addTopLevelItem(moduleItem);
+    moduleItem->setFlags(Qt::ItemIsEnabled);
+    for (const auto& actionIDAndAssets : moduleAssets) {
+      const QString& inModuleActionID = actionIDAndAssets.first;
+      const SUIT_ActionSearcher::AssetsAndSearchData& assetsAndSearchData = actionIDAndAssets.second;
+
+      auto actionItem = QtxFoundActionTreeAction::create(moduleID, inModuleActionID);
+      if (!actionItem) {
+        ShCutDbg("QtxFoundActionTree can't create child item for action ID = \"" + SUIT_ShortcutMgr::makeActionID(moduleID, inModuleActionID) + "\".");
+        continue;
+      }
+
+      actionItem->setAssets(assetsAndSearchData.myAssets, lang);
+      moduleItem->addChild(actionItem);
+    }
+    moduleItem->setExpanded(true); // Make tree expanded on first show.
+  }
+}
+
+std::pair<QtxFoundActionTreeFolder*, int> QtxFoundActionTree::findModuleFolderItem(const QString& theModuleID) const
+{
+  for (int moduleIdx = 0; moduleIdx < topLevelItemCount(); moduleIdx++) {
+    QtxFoundActionTreeFolder* moduleItem = static_cast<QtxFoundActionTreeFolder*>(topLevelItem(moduleIdx));
+    if (moduleItem->myModuleID == theModuleID)
+      return std::pair<QtxFoundActionTreeFolder*, int>(moduleItem, moduleIdx);
+  }
+  return std::pair<QtxFoundActionTreeFolder*, int>(nullptr, -1);
+}
+
+void QtxFoundActionTree::onItemDoubleClicked(QTreeWidgetItem* theItem, int theColIdx)
+{
+  {
+    QtxFoundActionTreeItem* const item = static_cast<QtxFoundActionTreeItem*>(theItem);
+    // Do not react if folder-item is clicked.
+    if (item->type() != QtxFoundActionTreeItem::Type::Action)
+      return;
+  }
+
+  QtxFoundActionTreeAction* const actionItem = static_cast<QtxFoundActionTreeAction*>(theItem);
+  actionItem->trigger();
+}
+
+
+QtxFoundActionTreeItem::QtxFoundActionTreeItem(const QString& theModuleID)
+: QTreeWidgetItem(), myModuleID(theModuleID)
+{ }
+
+QString QtxFoundActionTreeItem::name() const
+{
+  return text(QtxFoundActionTree::ElementIdx::Name);
+}
+
+QString QtxFoundActionTreeItem::toolTip() const
+{
+  return text(QtxFoundActionTree::ElementIdx::ToolTip);
+}
+
+
+QtxFoundActionTreeFolder::QtxFoundActionTreeFolder(const QString& theModuleID)
+: QtxFoundActionTreeItem(theModuleID)
+{
+  QFont f = font(QtxFoundActionTree::ElementIdx::Name);
+  f.setBold(true);
+  setFont(QtxFoundActionTree::ElementIdx::Name, f);
+  setText(QtxFoundActionTree::ElementIdx::Name, theModuleID);
+}
+
+void QtxFoundActionTreeFolder::setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang)
+{
+  if (!theAssets)
+    return;
+
+  setIcon(QtxFoundActionTree::ElementIdx::Name, theAssets->myIcon);
+
+  const auto& ldaMap = theAssets->myLangDependentAssets;
+  if (ldaMap.empty()) {
+    setText(QtxFoundActionTree::ElementIdx::Name, myModuleID);
+    return;
+  }
+
+  auto itLDA = ldaMap.find(theLang);
+  if (itLDA == ldaMap.end())
+    itLDA = ldaMap.begin();
+
+  const SUIT_ActionAssets::LangDependentAssets& lda = itLDA->second;
+  const QString& name = lda.myName.isEmpty() ? myModuleID : lda.myName;
+  setText(QtxFoundActionTree::ElementIdx::Name, name);
+}
+
+QString QtxFoundActionTreeFolder::getValue(QtxFoundActionTree::SortKey theKey) const
+{
+  switch (theKey) {
+    case QtxFoundActionTree::SortKey::ID:
+      return myModuleID;
+    case QtxFoundActionTree::SortKey::Name:
+      return name();
+    case QtxFoundActionTree::SortKey::ToolTip:
+      return toolTip();
+    default:
+      return QString();
+  }
+}
+
+bool QtxFoundActionTreeFolder::isEnabled() const
+{
+  return true;
+}
+
+
+QtxFoundActionTreeAction::QtxFoundActionTreeAction(const QString& theModuleID, const QString& theInModuleActionID)
+: QtxFoundActionTreeItem(theModuleID), myInModuleActionID(theInModuleActionID)
+{
+  setText(QtxFoundActionTree::ElementIdx::Name, theInModuleActionID);
+}
+
+/*static*/ QtxFoundActionTreeAction* QtxFoundActionTreeAction::create(const QString& theModuleID, const QString& theInModuleActionID)
+{
+  if (theInModuleActionID.isEmpty()) {
+    ShCutDbg("QtxFoundActionTreeItem: attempt to create item with empty action ID.");
+    return nullptr;
+  }
+
+  return new QtxFoundActionTreeAction(theModuleID, theInModuleActionID);
+}
+
+void QtxFoundActionTreeAction::setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang)
+{
+  if (!theAssets)
+    return;
+
+  setIcon(QtxFoundActionTree::ElementIdx::Name, theAssets->myIcon);
+
+  const auto& ldaMap = theAssets->myLangDependentAssets;
+  if (ldaMap.empty()) {
+    setText(QtxFoundActionTree::ElementIdx::Name, myInModuleActionID);
+    return;
+  }
+
+  auto itLDA = ldaMap.find(theLang);
+  if (itLDA == ldaMap.end())
+    itLDA = ldaMap.begin();
+
+  const SUIT_ActionAssets::LangDependentAssets& lda = itLDA->second;
+  const QString& name = lda.myName.isEmpty() ? myInModuleActionID : lda.myName;
+  setText(QtxFoundActionTree::ElementIdx::Name, name);
+
+  setText(QtxFoundActionTree::ElementIdx::ToolTip, lda.myToolTip);
+
+  if (isEnabled()) {
+    setToolTip(
+      QtxFoundActionTree::ElementIdx::Name,
+      QtxFoundActionTree::tr("Double click to start")
+    );
+
+    setToolTip(
+      QtxFoundActionTree::ElementIdx::ToolTip,
+      QtxFoundActionTree::tr("Double click to start")
+    );
+  }
+  else {
+    static const QBrush greyedOutBrush = QBrush(Qt::gray);
+    setForeground(QtxFoundActionTree::ElementIdx::Name,    greyedOutBrush);
+    setForeground(QtxFoundActionTree::ElementIdx::ToolTip, greyedOutBrush);
+  }
+}
+
+QString QtxFoundActionTreeAction::getValue(QtxFoundActionTree::SortKey theKey) const
+{
+  switch (theKey) {
+    case QtxFoundActionTree::SortKey::ID:
+      return myInModuleActionID;
+    case QtxFoundActionTree::SortKey::Name:
+      return name();
+    case QtxFoundActionTree::SortKey::ToolTip:
+      return toolTip();
+    default:
+      return QString();
+  }
+}
+
+bool QtxFoundActionTreeAction::isEnabled() const
+{
+  const auto& actions = SUIT_ShortcutMgr::get()->getActions(myModuleID, myInModuleActionID);
+  return std::find_if(actions.begin(), actions.end(), [](const QAction* const theAction){ return theAction->isEnabled(); }) != actions.end();
+}
+
+void QtxFoundActionTreeAction::trigger() const
+{
+  const auto& actions = SUIT_ShortcutMgr::get()->getActions(myModuleID, myInModuleActionID);
+  for (const auto& action : actions) {
+    if (action->isEnabled())
+      action->trigger();
+  }
+}
\ No newline at end of file
diff --git a/src/Qtx/QtxFindActionDialog.h b/src/Qtx/QtxFindActionDialog.h
new file mode 100644 (file)
index 0000000..c69fcca
--- /dev/null
@@ -0,0 +1,171 @@
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef QTXFINDACTIONDIALOG_H
+#define QTXFINDACTIONDIALOG_H
+
+#include "Qtx.h"
+#include <QDialog>
+#include <QFrame>
+#include <QTreeWidget>
+#include "SUIT_ShortcutMgr.h"
+#include <memory>
+#include <map>
+#include <set>
+#include <functional>
+
+
+class QCheckBox;
+class QLineEdit;
+class QLabel;
+class QPushButton;
+class QtxFoundActionTree;
+
+
+class QTX_EXPORT QtxFindActionDialog : public QDialog
+{
+  Q_OBJECT
+
+public:
+  QtxFindActionDialog(QWidget* theParent);
+  QtxFindActionDialog(const QtxFindActionDialog&) = delete;
+  QtxFindActionDialog& operator=(const QtxFindActionDialog&) = delete;
+  virtual ~QtxFindActionDialog() = default;
+
+  void setActiveModuleID(const QString& theModuleID = SUIT_ShortcutMgr::ROOT_MODULE_ID);
+
+private slots:
+  void onQueryChanged(const QString& theKeyword);
+  void onSearchOptionUnavailableActionsChanged(int);
+  void onSearchOptionInactiveModulesChanged(int);
+
+private:
+  void updateUI();
+
+  QLineEdit* myQueryLineEdit;
+  QCheckBox* myIncludeUnavailableActionsCB;
+  QCheckBox* myIncludeInactiveModulesCB;
+  QtxFoundActionTree* myFoundActionsTree;
+
+  QString myActiveModuleID;
+  SUIT_ActionSearcher myActionSearcher;
+};
+
+
+class QtxFoundActionTreeItem;
+class QtxFoundActionTreeFolder;
+class QtxFoundActionTreeAction;;
+
+
+class QTX_EXPORT QtxFoundActionTree : public QTreeWidget
+{
+  Q_OBJECT
+
+public:
+  enum ElementIdx {
+    Name = 0,
+    ToolTip = 1
+  };
+
+  enum class SortKey {
+    ID,
+    Name,
+    ToolTip
+  };
+
+  QtxFoundActionTree();
+  QtxFoundActionTree(const QtxFoundActionTree&) = delete;
+  QtxFoundActionTree& operator=(const QtxFoundActionTree&) = delete;
+  virtual ~QtxFoundActionTree() = default;
+
+  void updateItems(const std::map<QString, std::map<QString, SUIT_ActionSearcher::AssetsAndSearchData>>& theAssets);
+
+private:
+  std::pair<QtxFoundActionTreeFolder*, int> findModuleFolderItem(const QString& theModuleID) const;
+
+private slots:
+  void onItemDoubleClicked(QTreeWidgetItem* theWidgetItem, int theColIdx);
+};
+
+
+class QtxFoundActionTreeItem : public QTreeWidgetItem
+{
+public:
+  enum Type {
+    Folder = 0,
+    Action = 1,
+  };
+
+protected:
+  QtxFoundActionTreeItem(const QString& theModuleID);
+
+public:
+  virtual ~QtxFoundActionTreeItem() = default;
+  virtual QtxFoundActionTreeItem::Type type() const = 0;
+
+  virtual void setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang) = 0;
+  QString name() const;
+  QString toolTip() const;
+
+  virtual QString getValue(QtxFoundActionTree::SortKey theKey) const = 0;
+
+  virtual bool isEnabled() const = 0;
+
+public:
+  const QString myModuleID;
+};
+
+
+class QtxFoundActionTreeFolder : public QtxFoundActionTreeItem
+{
+public:
+  QtxFoundActionTreeFolder(const QString& theModuleID);
+  virtual ~QtxFoundActionTreeFolder() = default;
+  virtual QtxFoundActionTreeItem::Type type() const { return QtxFoundActionTreeItem::Type::Folder; };
+
+  virtual void setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang);
+
+  virtual QString getValue(QtxFoundActionTree::SortKey theKey) const;
+
+  virtual bool isEnabled() const;
+};
+
+
+class QtxFoundActionTreeAction : public QtxFoundActionTreeItem
+{
+private:
+  QtxFoundActionTreeAction(const QString& theModuleID, const QString& theInModuleActionID);
+
+public:
+  static QtxFoundActionTreeAction* create(const QString& theModuleID, const QString& theInModuleActionID);
+  virtual ~QtxFoundActionTreeAction() = default;
+  virtual QtxFoundActionTreeItem::Type type() const { return QtxFoundActionTreeItem::Type::Action; };
+
+  virtual void setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang);
+
+  virtual QString getValue(QtxFoundActionTree::SortKey theKey) const;
+
+  virtual bool isEnabled() const;
+
+  void trigger() const;
+
+  const QString myInModuleActionID;
+};
+
+#endif // QTXFINDACTIONDIALOG_H
index 2ea62824ee145c9d24c536a9b8c6d00140f5b8cc..a0b359e49b5319802962e0a367020afc16976bf2 100644 (file)
         <translation>Echelle de couleurs</translation>
     </message>
 </context>
+<context>
+    <name>QtxFindActionDialog</name>
+    <message>
+        <source>Find action</source>
+        <translation>Trouver une action</translation>
+    </message>
+    <message>
+        <source>Unavailable actions</source>
+        <translation>Actions indisponibles</translation>
+    </message>
+    <message>
+        <source>Inactive modules</source>
+        <translation>Modules inactifs</translation>
+    </message>
+    <message>
+        <source>Action</source>
+        <translation>Action</translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation>Description</translation>
+    </message>
+</context>
 <context>
     <name>QtxBackgroundTool</name>
     <message>
index 36900402a7cc12635914783b079578f185c3f9b7..e7e67a371a84af4b3815bbdaf4cf74988bf03987 100644 (file)
       <translation>カラースケール</translation>
     </message>
   </context>
+  <context>
+    <name>QtxFindActionDialog</name>
+    <message>
+        <source>Find action</source>
+        <translation>検索アクション</translation>
+    </message>
+    <message>
+        <source>Unavailable actions</source>
+        <translation>利用できないアクション</translation>
+    </message>
+    <message>
+        <source>Inactive modules</source>
+        <translation>非アクティブなモジュール</translation>
+    </message>
+    <message>
+        <source>Action</source>
+        <translation>アクション</translation>
+    </message>
+    <message>
+        <source>Description</source>
+        <translation>説明</translation>
+    </message>
+  </context>
   <context>
     <name>QtxBackgroundTool</name>
     <message>
index 49dfdf16d25cb81b3d7f362e7e4017249c14b22c..fddc4c419b78c0fc0bc5901af6e52083ceb8ac62 100644 (file)
@@ -44,7 +44,7 @@ class QJsonObject;
 #endif
 
 // Define SHORTCUT_MGR_DBG to enable SUIT_ShortcutMgr debug logging.
-#define SHORTCUT_MGR_DBG
+// #define SHORTCUT_MGR_DBG
 /*! \returns true, if SUIT_ShortcutMgr debug logging is enabled. */
 SUIT_EXPORT extern inline bool ShCutDbg() {
 #ifdef SHORTCUT_MGR_DBG
index fa4054c3d4e934d0cb3782beaa8a84d8c3854716..64a379301a2d3a201bef945a4a425abf76da54a6 100644 (file)
@@ -73,7 +73,7 @@
 #include <SUIT_OverrideCursor.h>
 
 #include <QtxTreeView.h>
-#include <QtxFeatureSearch.h>
+#include <QtxFindActionDialog.h>
 
 #include <SALOME_EventFilter.h>
 
@@ -1592,7 +1592,7 @@ void SalomeApp_Application::onFindAction()
     // Keep this conditional block until ParaViS's actions are not added to ShortcutMgr resource and asset files.
   }
 
-  QtxFeatureSearchDialog aDlg( desktop() );
+  QtxFindActionDialog aDlg( desktop() );
   if (pActiveModule)
     aDlg.setActiveModuleID(pActiveModule->name());
   else