Fix search list update.
<parameter name="PRP_CREATE_NEW_WINDOW_FOR_VIEWER_5" value="Alt+C"/>
<parameter name="PRP_CREATE_NEW_WINDOW_FOR_VIEWER_6" value="Alt+A"/>
<parameter name="PRP_CREATE_NEW_WINDOW_FOR_VIEWER_7" value="Alt+Y"/>
+ <parameter name="PRP_DESK_FIND_ACTION" value="Ctrl+Space"/>
<parameter name="PRP_CREATE_NEW_WINDOW_FOR_VIEWER_8" value="Alt+3"/>
<parameter name="#General/Object(s)/Show" value="Ctrl+Alt+S"/>
<parameter name="#General/Object(s)/Hide" value="Ctrl+Alt+H"/>
#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)
void QtxFoundActionTreeAction::setAssets(std::shared_ptr<const SUIT_ActionAssets> theAssets, const QString& theLang)
{
+ ShCutDbg("QtxFoundActionTreeAction::setAssets()");
+
if (!theAssets)
return;
const QString& name = lda.myName.isEmpty() ? myInModuleActionID : lda.myName;
setText(QtxFoundActionTree::ElementIdx::Name, name);
- const QString& actionToolTip = lda.myToolTip.isEmpty() ? name : lda.myToolTip;
- setText(QtxFoundActionTree::ElementIdx::ToolTip, actionToolTip);
+ setText(QtxFoundActionTree::ElementIdx::ToolTip, lda.myToolTip);
if (isEnabled()) {
- setToolTip(
+ ShCutDbg("QtxFoundActionTreeAction::setAssets(): Action \"" + name + "\" is enabled.");
+
+ setToolTip(
QtxFoundActionTree::ElementIdx::Name,
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::Name, greyedOutBrush);
setForeground(QtxFoundActionTree::ElementIdx::ToolTip, greyedOutBrush);
}
}
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();
}
action->trigger();
}
}
-
-
-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);
- 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(Qt::CheckState)), this, SLOT(onSearchOptionUnavailableActionsChanged(Qt::CheckState)));
- connect(myIncludeInactiveModulesCB, SIGNAL(stateChanged(Qt::CheckState)), this, SLOT(onSearchOptionInactiveModulesChanged(Qt::CheckState)));
-}
-
-void QtxFeatureSearchDialog::setActiveModuleID(const QString& 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(Qt::CheckState theState)
-{
- if (myActionSearcher.includeDisabledActions(theState == Qt::CheckState::Checked))
- updateUI();
-}
-
-void QtxFeatureSearchDialog::onSearchOptionInactiveModulesChanged(Qt::CheckState 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()
-{
-
-}
-
#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;;
ToolTip
};
- enum class SortOrder {
- Ascending,
- Descending
- };
-
QtxFoundActionTree();
QtxFoundActionTree(const QtxFoundActionTree&) = delete;
QtxFoundActionTree& operator=(const QtxFoundActionTree&) = delete;
virtual ~QtxFoundActionTree() = default;
- void sort(QtxFoundActionTree::SortKey theKey, QtxFoundActionTree::SortOrder theOrder);
+ void updateItems(const std::map<QString, std::map<QString, SUIT_ActionSearcher::AssetsAndSearchData>>& theAssets);
private:
- void updateItems();
std::pair<QtxFoundActionTreeFolder*, int> findModuleFolderItem(const QString& theModuleID) const;
- std::set<QtxFoundActionTreeItem*, std::function<bool(QtxFoundActionTreeItem*, QtxFoundActionTreeItem*)>> getSortedChildren(QtxFoundActionTreeFolder* theParentItem);
-
- void insertChild(
- QtxFoundActionTreeFolder* theParentItem,
- std::set<QtxFoundActionTreeItem*, std::function<bool(QtxFoundActionTreeItem*, QtxFoundActionTreeItem*)>>& theSortedChildren,
- QtxFoundActionTreeItem* theChildItem
- );
-
private slots:
void onItemDoubleClicked(QTreeWidgetItem* theWidgetItem, int theColIdx);
-
-public:
- static const QList<std::pair<QtxFoundActionTree::SortKey, QtxFoundActionTree::SortOrder>> DEFAULT_SORT_SCHEMA;
-
-private:
- QtxFoundActionTree::SortKey mySortKey;
- QtxFoundActionTree::SortOrder mySortOrder;
};
const QString myInModuleActionID;
};
-
-class QCheckBox;
-class QLineEdit;
-class QLabel;
-class QPushButton;
-
-
-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);
-
-private slots:
- void onQueryChanged(const QString& theKeyword);
- void onSearchOptionUnavailableActionsChanged(Qt::CheckState theState);
- void onSearchOptionInactiveModulesChanged(Qt::CheckState theState);
-
-private:
- void updateUI();
-
- QLineEdit* myQueryLineEdit;
- QCheckBox* myIncludeUnavailableActionsCB;
- QCheckBox* myIncludeInactiveModulesCB;
- QtxFoundActionTree* myFoundActionsTree;
-
- QString myActiveModuleID;
- SUIT_ActionSearcher myActionSearcher;
-};
-
#endif // QTXFEATURESEARCH_H
auto itAssets = moduleActionAssets.find(inModuleActionID);
if (itAssets == moduleActionAssets.end()) {
auto pAssets = std::shared_ptr<SUIT_ActionAssets>(new SUIT_ActionAssets(actionAssets));
- itAssets = moduleActionAssets.emplace(actionID, pAssets).first;
+ itAssets = moduleActionAssets.emplace(inModuleActionID, pAssets).first;
}
else
itAssets->second->merge(actionAssets, true);
return;
myUseExactWordOrder = theOn;
- if (!myWords || theOn)
+ if (theOn) {
+ myPermutatedSentences.clear();
+ myFuzzyPermutatedSentences.clear();
return;
-
- if (!myPermutatedSentences) {
- myPermutatedSentences.reset(new QList<QStringList>());
- SUIT_SentenceMatcher::makePermutatedSentences(*myWords, *myPermutatedSentences);
}
- if (myUseFuzzyWords && !myFuzzyPermutatedSentences) {
- myFuzzyPermutatedSentences.reset(new QList<QStringList>());
- SUIT_SentenceMatcher::makePermutatedSentences(*myFuzzyWords, *myFuzzyPermutatedSentences);
- }
+ if (myPermutatedSentences.isEmpty())
+ SUIT_SentenceMatcher::makePermutatedSentences(myWords, myPermutatedSentences);
+
+ if (myUseFuzzyWords && myFuzzyPermutatedSentences.isEmpty())
+ SUIT_SentenceMatcher::makePermutatedSentences(myFuzzyWords, myFuzzyPermutatedSentences);
}
void SUIT_SentenceMatcher::setUseFuzzyWords(bool theOn)
return;
myUseFuzzyWords = theOn;
- if (!myWords || !theOn || myFuzzyWords)
+ if (myWords.isEmpty() || !theOn) {
+ myFuzzyWords.clear();
+ myFuzzyPermutatedSentences.clear();
return;
+ }
- myFuzzyWords.reset(new QStringList());
- SUIT_SentenceMatcher::makeFuzzyWords(*myWords, *myFuzzyWords);
+ myFuzzyWords.clear();
+ SUIT_SentenceMatcher::makeFuzzyWords(myWords, myFuzzyWords);
if (!myUseExactWordOrder) {
- myFuzzyPermutatedSentences.reset(new QList<QStringList>());
- SUIT_SentenceMatcher::makePermutatedSentences(*myFuzzyWords, *myFuzzyPermutatedSentences);
+ myFuzzyPermutatedSentences.clear();
+ SUIT_SentenceMatcher::makePermutatedSentences(myFuzzyWords, myFuzzyPermutatedSentences);
}
}
return;
myQuery = theQuery;
-
- { // Set exact words.
- if (myWords)
- myWords->clear();
- else
- myWords.reset(new QStringList());
-
- *myWords = theQuery.split(" ", QString::SkipEmptyParts);
- }
+ myWords = theQuery.split(" ", QString::SkipEmptyParts);
{ // Set permutated sentences.
- if (myUseExactWordOrder)
- myPermutatedSentences.reset(nullptr);
- else {
- if (!myPermutatedSentences)
- myPermutatedSentences.reset(new QList<QStringList>());
-
- SUIT_SentenceMatcher::makePermutatedSentences(*myWords, *myPermutatedSentences);
- }
+ myPermutatedSentences.clear();
+ if (!myUseExactWordOrder)
+ SUIT_SentenceMatcher::makePermutatedSentences(myWords, myPermutatedSentences);
}
// Set fuzzy words and sentences.
- if (myUseFuzzyWords) {
- if (!myFuzzyWords)
- myFuzzyWords.reset(new QStringList());
-
- SUIT_SentenceMatcher::makeFuzzyWords(*myWords, *myFuzzyWords);
+ myFuzzyWords.clear();
+ myFuzzyPermutatedSentences.clear();
- if (myUseExactWordOrder)
- myFuzzyPermutatedSentences.reset(nullptr);
- else {
- if (!myFuzzyPermutatedSentences)
- myFuzzyPermutatedSentences.reset(new QList<QStringList>());
-
- SUIT_SentenceMatcher::makePermutatedSentences(*myFuzzyWords, *myFuzzyPermutatedSentences);
- }
- }
- else {
- myFuzzyWords.reset(nullptr);
- myFuzzyPermutatedSentences.reset(nullptr);
+ if (myUseFuzzyWords) {
+ SUIT_SentenceMatcher::makeFuzzyWords(myWords, myFuzzyWords);
+ if (!myUseExactWordOrder)
+ SUIT_SentenceMatcher::makePermutatedSentences(myFuzzyWords, myFuzzyPermutatedSentences);
}
}
{
size_t n = 0;
if (myUseExactWordOrder) {
- n = SUIT_SentenceMatcher::match(theInputString, *myWords, myIsCaseSensitive);
+ n = SUIT_SentenceMatcher::match(theInputString, myWords, myIsCaseSensitive);
if (n > 0)
return n;
if (myUseFuzzyWords) {
- n = SUIT_SentenceMatcher::match(theInputString, *myFuzzyWords, myIsCaseSensitive);
+ n = SUIT_SentenceMatcher::match(theInputString, myFuzzyWords, myIsCaseSensitive);
if (n > 0)
return n;
}
}
else /* if match with permutated query sentences */ {
- n = SUIT_SentenceMatcher::match(theInputString, *myPermutatedSentences, myIsCaseSensitive);
+ n = SUIT_SentenceMatcher::match(theInputString, myPermutatedSentences, myIsCaseSensitive);
if (n > 0)
return n;
if (myUseFuzzyWords) {
- n = SUIT_SentenceMatcher::match(theInputString, *myFuzzyPermutatedSentences, myIsCaseSensitive);
+ n = SUIT_SentenceMatcher::match(theInputString, myFuzzyPermutatedSentences, myIsCaseSensitive);
if (n > 0)
return n;
}
return n;
}
+QString SUIT_SentenceMatcher::toString() const
+{
+ QString res = QString("myUseExactWordOrder: ") + (myUseExactWordOrder ? "true" : "false") + ";\n";
+ res += QString("myUseFuzzyWords: ") + (myUseFuzzyWords ? "true" : "false") + ";\n";
+ res += QString("myIsCaseSensitive: ") + (myIsCaseSensitive ? "true" : "false") + ";\n";
+ res += QString("myQuery: ") + myQuery + ";\n";
+ res += QString("myWords: ") + myWords.join(", ") + ";\n";
+ res += QString("myFuzzyWords: ") + myFuzzyWords.join(", ") + ";\n";
+
+ res += "myPermutatedSentences:\n";
+ for (const auto& sentence : myPermutatedSentences) {
+ res += "\t" + sentence.join(", ") + ";\n";
+ }
+
+ res += "myFuzzyPermutatedSentences:\n";
+ for (const auto& sentence : myFuzzyPermutatedSentences) {
+ res += "\t" + sentence.join(", ") + ";\n";
+ }
+
+ res += ".";
+ return res;
+}
+
/*static*/ bool SUIT_SentenceMatcher::makePermutatedSentences(const QStringList& theWords, QList<QStringList>& theSentences)
{
theSentences.clear();
if (n > 0)
return n;
- if (theSentences.size())
+ if (theSentences.size() > 0)
return SUIT_SentenceMatcher::matchAtLeastOneWord(theInputString, theSentences[0], theCaseSensitive);
else
return 0;
: myAssets(theAssets), myNumOfMatchingWords(theNumOfMatchingWords)
{}
+void SUIT_ActionSearcher::AssetsAndSearchData::toJSON(QJsonObject& oJsonObject) const
+{
+ oJsonObject["myNumOfMatchingWords"] = int(myNumOfMatchingWords);
+
+ if (myAssets) {
+ QJsonObject assetsJSON;
+ myAssets->toJSON(assetsJSON);
+ oJsonObject["myAssets"] = assetsJSON;
+ }
+}
+
+QString SUIT_ActionSearcher::AssetsAndSearchData::toString() const
+{
+ QJsonObject json;
+ toJSON(json);
+ QJsonDocument doc(json);
+ return QString(doc.toJson(QJsonDocument::Indented));
+}
+
SUIT_ActionSearcher::SUIT_ActionSearcher()
{
myIncludedModuleIDs = { SUIT_ShortcutMgr::ROOT_MODULE_ID };
bool SUIT_ActionSearcher::setIncludedModuleIDs(std::set<QString> theIncludedModuleIDs)
{
+ ShCutDbg("SUIT_ActionSearcher::setIncludedModuleIDs");
+
if (myIncludedModuleIDs == theIncludedModuleIDs)
return false;
myIncludedModuleIDs = theIncludedModuleIDs;
bool res = false;
- // Erase search results with excluded modules. Erase IDs of modules, which are already in search results, from theIncludedModuleIDs.
+ // Erase search results from excluded modules. Erase IDs of modules, which are already in search results, from theIncludedModuleIDs.
for (auto itFound = mySearchResults.begin(); itFound != mySearchResults.end(); ) {
const auto itModuleID = theIncludedModuleIDs.find(itFound->first);
if (itModuleID == theIncludedModuleIDs.end()) {
- mySearchResults.erase(itFound);
+ itFound = mySearchResults.erase(itFound);
res = true;
}
else {
}
}
+ ShCutDbg() && ShCutDbg(toString());
+
return res;
}
bool SUIT_ActionSearcher::includeDisabledActions(bool theOn)
{
+ ShCutDbg("SUIT_ActionSearcher::includeDisabledActions");
+
if (myIncludeDisabledActions == theOn)
return false;
myIncludeDisabledActions = theOn;
+ bool res;
if (myIncludeDisabledActions)
- return extendResults();
+ res = extendResults();
else
- return filterResults().first;
+ res = filterResults().first;
+
+ ShCutDbg() && ShCutDbg(toString());
+ return res;
}
bool SUIT_ActionSearcher::setFieldsToMatch(const std::set<SUIT_ActionSearcher::MatchField>& theFields)
myFieldsToMatch = theFields;
+ bool res;
if (narrows)
- return filterResults().first;
+ res = filterResults().first;
else if (extends)
- return extendResults();
+ res = extendResults();
else
- return filter().first;
+ res = filter().first;
+
+ ShCutDbg() && ShCutDbg(toString());
+ return res;
}
bool SUIT_ActionSearcher::setCaseSensitive(bool theOn)
myMatcher.setCaseSensitive(theOn);
+ bool res;
if (theOn)
- return filterResults().first;
+ res = filterResults().first;
else
- return extendResults();
+ res = extendResults();
+
+ ShCutDbg() && ShCutDbg(toString());
+ return res;
}
bool SUIT_ActionSearcher::setQuery(const QString& theQuery)
{
+ ShCutDbg("SUIT_ActionSearcher::setQuery");
+
if (theQuery.simplified() == myMatcher.getQuery().simplified())
return false;
myMatcher.setQuery(theQuery);
- return filter().first;
+ bool res = filter().first;
+ ShCutDbg() && ShCutDbg(toString());
+ return res;
}
const std::map<QString, std::map<QString, SUIT_ActionSearcher::AssetsAndSearchData>>& SUIT_ActionSearcher::getSearchResults() const
std::pair<bool, bool> SUIT_ActionSearcher::filter()
{
+ ShCutDbg("SUIT_ActionSearcher::filter()");
+
auto res = std::pair<bool, bool>(false, false);
for (const auto& moduleIDAndAssets : SUIT_ShortcutMgr::get()->getActionAssets()) {
SUIT_ActionSearcher::AssetsAndSearchData& assetsAndSearchData = itActionIDAndAssets->second;
const size_t n = matchAction(moduleID, inModuleActionID, assetsAndSearchData.myAssets);
if (n == 0) {
- actionIDsAndAssets.erase(itActionIDAndAssets);
+ itActionIDAndAssets = actionIDsAndAssets.erase(itActionIDAndAssets);
res.first = true;
}
else {
}
if (actionIDsAndAssets.empty())
- mySearchResults.erase(itFoundModuleIDAndAssets);
+ itFoundModuleIDAndAssets = mySearchResults.erase(itFoundModuleIDAndAssets);
else
itFoundModuleIDAndAssets++;
}
bool SUIT_ActionSearcher::extendResults()
{
+ ShCutDbg("SUIT_ActionSearcher::extendResults()");
+
bool res = false;
for (const auto& moduleIDAndAssets : SUIT_ShortcutMgr::get()->getActionAssets()) {
const auto& moduleID = moduleIDAndAssets.first;
continue; // Action is already in search results.
}
+ ShCutDbg() && ShCutDbg("SUIT_ActionSearcher::extendResults(): " + moduleID + "/" + inModuleActionID + "." );
const size_t n = matchAction(moduleID, inModuleActionID, actionIDAndAssets.second);
if (n > 0) {
+ ShCutDbg("SUIT_ActionSearcher::extendResults(): match");
if (itFoundModuleIDAndAssets == mySearchResults.end())
itFoundModuleIDAndAssets = mySearchResults.emplace(moduleID, std::map<QString, SUIT_ActionSearcher::AssetsAndSearchData>()).first;
size_t SUIT_ActionSearcher::matchAction(const QString& theModuleID, const QString& theInModuleActionID, std::shared_ptr<SUIT_ActionAssets> theAssets)
{
+ if (!theAssets) {
+ ShCutDbg("WARNING: SUIT_ActionSearcher::matchAction: theAssets is nullptr.");
+ return 0;
+ }
+
if (!myIncludeDisabledActions) {
const auto& actions = SUIT_ShortcutMgr::get()->getActions(theModuleID, theInModuleActionID);
const bool actionEnabled = std::find_if(actions.begin(), actions.end(), [](const QAction* const theAction){ return theAction->isEnabled(); } ) != actions.end();
}
return false;
+}
+
+QString SUIT_ActionSearcher::toString() const
+{
+ QString res;
+
+ res += "myMatcher: {\n";
+ res += myMatcher.toString();
+ res += "};\n";
+
+ res += "myIncludedModuleIDs: ";
+ for (const QString& moduleID : myIncludedModuleIDs) {
+ res += moduleID + ", ";
+ }
+ res += ";\n";
+
+ res += QString("myIncludeDisabledActions: ") + (myIncludeDisabledActions ? "true" : "false") + ";\n";
+
+ res += "myFieldsToMatch: ";
+ for (const auto& field : myFieldsToMatch) {
+ res += QString::number(int(field)) + ", ";
+ }
+ res += ";\n";
+
+ res += "mySearchResults:\n";
+ for (const auto& moduleIDAndAssets : mySearchResults ) {
+ res += "\tModule ID: " + moduleIDAndAssets.first + ":\n";
+ for (const auto& actionIDAndAssets : moduleIDAndAssets.second) {
+ const auto& assetsAndSearchData = actionIDAndAssets.second;
+ res += "\t\tAction ID: " + actionIDAndAssets.first + ": {";
+ res += "\t\t: " + actionIDAndAssets.second.toString();
+ res += "\t\t}";
+ }
+ }
+
+ return res;
}
\ No newline at end of file
/*! \returns number of matched words. */
size_t match(const QString& theInputString) const;
+ QString toString() const;
+
private:
static bool makePermutatedSentences(const QStringList& theWords, QList<QStringList>& theSentences);
static void makeFuzzyWords(const QStringList& theWords, QStringList& theFuzzyWords);
bool myIsCaseSensitive;
QString myQuery;
- std::unique_ptr<QStringList> myWords; // It is also original search sentence.
- std::unique_ptr<QList<QStringList>> myPermutatedSentences;
+ QStringList myWords; // It is also original search sentence.
+ QList<QStringList> myPermutatedSentences;
- std::unique_ptr<QStringList> myFuzzyWords; // Regexes.
- std::unique_ptr<QList<QStringList>> myFuzzyPermutatedSentences;
+ QStringList myFuzzyWords; // Regexes.
+ QList<QStringList> myFuzzyPermutatedSentences;
};
std::shared_ptr<SUIT_ActionAssets> myAssets;
size_t myNumOfMatchingWords;
+
+ void toJSON(QJsonObject& oJsonObject) const;
+ QString toString() const;
};
/*! Default config:
size_t matchAction(const QString& theModuleID, const QString& theInModuleActionID, std::shared_ptr<SUIT_ActionAssets> theAssets);
+ QString toString() const;
+
std::set<QString> myIncludedModuleIDs;
bool myIncludeDisabledActions;
}
}
},
+ "/PRP_DESK_FIND_ACTION": {
+ "iconPath": "",
+ "langDependentAssets": {
+ "en": {
+ "name": "Find action",
+ "tooltip": "Opens action search dialog"
+ },
+ "fr": {
+ "name": "Trouver une action",
+ "tooltip": "Ouvre la boîte de dialogue de recherche d'action"
+ },
+ "ja": {
+ "name": "検索アクション",
+ "tooltip": "アクション検索ダイアログを開きます"
+ }
+ }
+ },
"/PRP_DESK_CONNECT": {
"iconPath": "",
"langDependentAssets": {
#include <SUIT_OverrideCursor.h>
#include <QtxTreeView.h>
+#include <QtxFeatureSearch.h>
#include <SALOME_EventFilter.h>
#include <ToolsGUI_RegWidget.h>
#include <vector>
+#include <iostream>
#include <SALOMEDS_Tool.hxx>
tr( "MEN_DESK_REGISTRY_DISPLAY" ), tr( "PRP_DESK_REGISTRY_DISPLAY" ),
/*Qt::SHIFT+Qt::Key_D*/0, desk, false, this, SLOT( onRegDisplay() ) );
+ //! Find action dialog
+ createAction( FindActionId, tr( "TOT_DESK_FIND_ACTION" ), QIcon(),
+ tr( "MEN_DESK_FIND_ACTION" ), tr( "PRP_DESK_FIND_ACTION" ),
+ QKeySequence::UnknownKey, desk, false, this, SLOT( onFindAction() ), "/PRP_DESK_FIND_ACTION" );
+
createAction( ConnectId, tr( "TOT_DESK_CONNECT_STUDY" ), QIcon(),
tr( "MEN_DESK_CONNECT" ), tr( "PRP_DESK_CONNECT" ),
QKeySequence::UnknownKey, desk, false, this, SLOT( onLoadDoc() ), "/PRP_DESK_CONNECT" );
int toolsMenu = createMenu( tr( "MEN_DESK_TOOLS" ), -1, MenuToolsId, 50 );
createMenu( CatalogGenId, toolsMenu, 10, -1 );
createMenu( RegDisplayId, toolsMenu, 10, -1 );
+ createMenu( FindActionId, toolsMenu, 10, -1 );
createMenu( separator(), toolsMenu, -1, 15, -1 );
createExtraActions();
regWnd->activateWindow();
}
+/*!Display Action Search dialog */
+void SalomeApp_Application::onFindAction()
+{
+ const auto pActiveModule = activeModule();
+ if (pActiveModule && pActiveModule->name() == "PARAVIS") {
+ return;
+ // ParaViS module has its own action search dialog (Quick Launch dialog).
+ // Keep this conditional block until ParaViS's actions are not added to ShortcutMgr resource and asset files.
+ }
+
+ QtxFeatureSearchDialog aDlg( desktop() );
+ if (pActiveModule)
+ aDlg.setActiveModuleID(pActiveModule->name());
+ else
+ aDlg.setActiveModuleID();
+
+ aDlg.exec();
+}
+
/*!find original object by double click on item */
void SalomeApp_Application::onDblClick( SUIT_DataObject* theObj )
{
public:
enum { MenuToolsId = 5 };
enum { DumpStudyId = LightApp_Application::UserID, LoadScriptId, PropertiesId,
- CatalogGenId, RegDisplayId, SaveGUIStateId, ConnectId, DisconnectId,
+ CatalogGenId, RegDisplayId, FindActionId, SaveGUIStateId, ConnectId, DisconnectId,
UserID };
typedef enum { WT_NoteBook = LightApp_Application::WT_User,
void onCatalogGen();
void onRegDisplay();
+ void onFindAction();
void onOpenWith();
void onExtAction();
<source>MEN_DESK_REGISTRY_DISPLAY</source>
<translation>Registry &Display</translation>
</message>
+ <message>
+ <source>MEN_DESK_FIND_ACTION</source>
+ <translation>Find action</translation>
+ </message>
<message>
<source>TOT_DESK_FILE_LOAD_SCRIPT</source>
<translation>Load python script</translation>
<source>PRP_DESK_REGISTRY_DISPLAY</source>
<translation>Displays content of the Registry CORBA server</translation>
</message>
+ <message>
+ <source>PRP_DESK_FIND_ACTION</source>
+ <translation>Opens action search dialog</translation>
+ </message>
<message>
<source>APPCLOSE_DESCRIPTION</source>
<translation>Do you want to save study before closing?</translation>
<source>TOT_DESK_REGISTRY_DISPLAY</source>
<translation>Registry display</translation>
</message>
+ <message>
+ <source>TOT_DESK_FIND_ACTION</source>
+ <translation>Find action</translation>
+ </message>
<message>
<source>OBJ_BROWSER_COLUMN_0</source>
<translation>Entry</translation>
<source>MEN_DESK_REGISTRY_DISPLAY</source>
<translation>Affichage du registre CORBA</translation>
</message>
+ <message>
+ <source>MEN_DESK_FIND_ACTION</source>
+ <translation>Trouver une action</translation>
+ </message>
<message>
<source>TOT_DESK_FILE_LOAD_SCRIPT</source>
<translation>Exécuter un script python</translation>
<source>PRP_DESK_REGISTRY_DISPLAY</source>
<translation>Visualiser le contenu du registre du serveur CORBA</translation>
</message>
+ <message>
+ <source>PRP_DESK_FIND_ACTION</source>
+ <translation>Ouvre la boîte de dialogue de recherche d'action</translation>
+ </message>
<message>
<source>APPCLOSE_DESCRIPTION</source>
<translation>Voulez-vous sauvegarder l'étude avant de quitter ?</translation>
<source>TOT_DESK_REGISTRY_DISPLAY</source>
<translation>Visualiser le registre CORBA</translation>
</message>
+ <message>
+ <source>TOT_DESK_FIND_ACTION</source>
+ <translation>Trouver une action</translation>
+ </message>
<message>
<source>OBJ_BROWSER_COLUMN_0</source>
<translation>Entrée</translation>
<source>MEN_DESK_REGISTRY_DISPLAY</source>
<translation>レジストリの表示(&D)</translation>
</message>
+ <message>
+ <source>MEN_DESK_FIND_ACTION</source>
+ <translation>検索アクション</translation>
+ </message>
<message>
<source>TOT_DESK_FILE_LOAD_SCRIPT</source>
<translation>Python スクリプトを実行</translation>
<source>PRP_DESK_REGISTRY_DISPLAY</source>
<translation>CORBAサーバーの登録内容を表示</translation>
</message>
+ <message>
+ <source>PRP_DESK_FIND_ACTION</source>
+ <translation>アクション検索ダイアログを開きます</translation>
+ </message>
<message>
<source>APPCLOSE_DESCRIPTION</source>
<translation>閉じる、または閉じる前にスタディをアンロードしますか?</translation>
<source>TOT_DESK_REGISTRY_DISPLAY</source>
<translation>レジストリの表示</translation>
</message>
+ <message>
+ <source>TOT_DESK_FIND_ACTION</source>
+ <translation>検索アクション</translation>
+ </message>
<message>
<source>OBJ_BROWSER_COLUMN_0</source>
<translation>エントリ</translation>