From 1513856c5c822ce45f54b27624ebc316142121cf Mon Sep 17 00:00:00 2001 From: vsv Date: Tue, 20 May 2014 18:10:57 +0400 Subject: [PATCH] Provide Rename command in object browser --- src/XGUI/XGUI_ContextMenuMgr.cpp | 1 + src/XGUI/XGUI_DocumentDataModel.cpp | 9 ++ src/XGUI/XGUI_DocumentDataModel.h | 2 + src/XGUI/XGUI_ObjectsBrowser.cpp | 130 ++++++++++++++++++++++++---- src/XGUI/XGUI_ObjectsBrowser.h | 12 ++- src/XGUI/XGUI_PartDataModel.cpp | 50 +++++------ 6 files changed, 161 insertions(+), 43 deletions(-) diff --git a/src/XGUI/XGUI_ContextMenuMgr.cpp b/src/XGUI/XGUI_ContextMenuMgr.cpp index f5d55c8db..60d6e9f83 100644 --- a/src/XGUI/XGUI_ContextMenuMgr.cpp +++ b/src/XGUI/XGUI_ContextMenuMgr.cpp @@ -103,6 +103,7 @@ QMenu* XGUI_ContextMenuMgr::objectBrowserMenu() const } } } + aActions.append(myWorkshop->objectBrowser()->actions()); if (aActions.size() > 0) { QMenu* aMenu = new QMenu(); aMenu->addActions(aActions); diff --git a/src/XGUI/XGUI_DocumentDataModel.cpp b/src/XGUI/XGUI_DocumentDataModel.cpp index 2c4470cce..e459f9cc2 100644 --- a/src/XGUI/XGUI_DocumentDataModel.cpp +++ b/src/XGUI/XGUI_DocumentDataModel.cpp @@ -465,3 +465,12 @@ void XGUI_DocumentDataModel::deactivatePart() myActivePart = 0; myModel->setItemsColor(ACTIVE_COLOR); } + +Qt::ItemFlags XGUI_DocumentDataModel::flags(const QModelIndex& theIndex) const +{ + Qt::ItemFlags aFlags = QAbstractItemModel::flags(theIndex); + if (feature(theIndex)) { + aFlags |= Qt::ItemIsEditable; + } + return aFlags; +} \ No newline at end of file diff --git a/src/XGUI/XGUI_DocumentDataModel.h b/src/XGUI/XGUI_DocumentDataModel.h index f6ce80eac..ee76b86ce 100644 --- a/src/XGUI/XGUI_DocumentDataModel.h +++ b/src/XGUI/XGUI_DocumentDataModel.h @@ -50,6 +50,8 @@ public: bool removeRows(int theRow, int theCount, const QModelIndex& theParent = QModelIndex()); + Qt::ItemFlags flags(const QModelIndex& theIndex) const; + //! Returns Feature object by the given Model index. //! Returns 0 if the given index is not index of a feature FeaturePtr feature(const QModelIndex& theIndex) const; diff --git a/src/XGUI/XGUI_ObjectsBrowser.cpp b/src/XGUI/XGUI_ObjectsBrowser.cpp index dd9706048..f526690b4 100644 --- a/src/XGUI/XGUI_ObjectsBrowser.cpp +++ b/src/XGUI/XGUI_ObjectsBrowser.cpp @@ -2,12 +2,16 @@ #include "XGUI_DocumentDataModel.h" #include +#include +#include #include #include +#include #include #include #include +#include @@ -71,6 +75,16 @@ void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent) emit contextMenuRequested(theEvent); } +void XGUI_DataTree::commitData(QWidget* theEditor) +{ + QLineEdit* aEditor = dynamic_cast(theEditor); + if (aEditor) { + QString aRes = aEditor->text(); + FeaturePtr aFeature = mySelectedData.first(); + aFeature->data()->setName(qPrintable(aRes)); + } +} + //******************************************************************** //******************************************************************** //******************************************************************** @@ -100,8 +114,14 @@ XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent) aLabelLay->addWidget(aLbl); - myActiveDocLbl = new QLabel(tr("Part set"), aLabelWgt); - myActiveDocLbl->setMargin(2); + PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); + DocumentPtr aDoc = aMgr->rootDocument(); + // TODO: Find a name of the root document + + myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt); + myActiveDocLbl->setReadOnly(true); + myActiveDocLbl->setFrame(false); + //myActiveDocLbl->setMargin(2); myActiveDocLbl->setContextMenuPolicy(Qt::CustomContextMenu); myActiveDocLbl->installEventFilter(this); @@ -127,44 +147,85 @@ XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent) this, SLOT(onContextMenuRequested(QContextMenuEvent*))); onActivePartChanged(FeaturePtr()); -} + // Create internal actions + QAction* aAction = new QAction(tr("Rename"), this); + aAction->setData("RENAME_CMD"); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem())); + addAction(aAction); +} +//*************************************************** XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser() { } - +//*************************************************** void XGUI_ObjectsBrowser::onActivePartChanged(FeaturePtr thePart) { QPalette aPalet = myActiveDocLbl->palette(); if (thePart) { - //myActiveDocLbl->setText(tr("Activate Part set")); - aPalet.setColor(QPalette::Foreground, Qt::black); - //myActiveDocLbl->setCursor(Qt::PointingHandCursor); + aPalet.setColor(QPalette::Text, Qt::black); } else { - //myActiveDocLbl->setText(tr("Part set is active")); - aPalet.setColor(QPalette::Foreground, QColor(0, 72, 140)); - //myActiveDocLbl->unsetCursor(); + aPalet.setColor(QPalette::Text, QColor(0, 72, 140)); } myActiveDocLbl->setPalette(aPalet); } +//*************************************************** bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent) { if (obj == myActiveDocLbl) { - if (theEvent->type() == QEvent::MouseButtonDblClick) { - if (myDocModel->activePartIndex().isValid()) { - myTreeView->setExpanded(myDocModel->activePartIndex(), false); + if (myActiveDocLbl->isReadOnly()) { + if (theEvent->type() == QEvent::MouseButtonDblClick) { + if (myDocModel->activePartIndex().isValid()) { + myTreeView->setExpanded(myDocModel->activePartIndex(), false); + } + myDocModel->deactivatePart(); + onActivePartChanged(FeaturePtr()); + emit activePartChanged(FeaturePtr()); + } + } else { + // End of editing by mouse click + if (theEvent->type() == QEvent::MouseButtonRelease) { + QMouseEvent* aEvent = (QMouseEvent*) theEvent; + QPoint aPnt = mapFromGlobal(aEvent->globalPos()); + if (childAt(aPnt) != myActiveDocLbl) { + closeDocNameEditing(false); + } + } else if (theEvent->type() == QEvent::KeyRelease) { + QKeyEvent* aEvent = (QKeyEvent*) theEvent; + switch (aEvent->key()) { + case Qt::Key_Return: // Accept current input + closeDocNameEditing(true); + break; + case Qt::Key_Escape: // Cancel the input + closeDocNameEditing(false); + break; + } } - myDocModel->deactivatePart(); - onActivePartChanged(FeaturePtr()); - emit activePartChanged(FeaturePtr()); } } return QWidget::eventFilter(obj, theEvent); } +//*************************************************** +void XGUI_ObjectsBrowser::closeDocNameEditing(bool toSave) +{ + myActiveDocLbl->deselect(); + myActiveDocLbl->clearFocus(); + myActiveDocLbl->releaseMouse(); + myActiveDocLbl->setReadOnly(true); + if (toSave) { + // TODO: Save the name of root document + PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); + DocumentPtr aDoc = aMgr->rootDocument(); + } else { + myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString()); + } +} + +//*************************************************** void XGUI_ObjectsBrowser::activateCurrentPart(bool toActivate) { if (toActivate) { @@ -192,18 +253,55 @@ void XGUI_ObjectsBrowser::activateCurrentPart(bool toActivate) } } +//*************************************************** void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent) { myFeaturesList = myTreeView->selectedFeatures(); + bool toEnable = myFeaturesList.size() > 0; + foreach(QAction* aCmd, actions()) { + aCmd->setEnabled(toEnable); + } emit contextMenuRequested(theEvent); } +//*************************************************** void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt) { myFeaturesList.clear(); //Empty feature pointer means that selected root document myFeaturesList.append(FeaturePtr()); + foreach(QAction* aCmd, actions()) { + aCmd->setEnabled(true); + } QContextMenuEvent aEvent( QContextMenuEvent::Mouse, thePnt, myActiveDocLbl->mapToGlobal(thePnt) ); emit contextMenuRequested(&aEvent); +} + +//*************************************************** +void XGUI_ObjectsBrowser::onEditItem() +{ + if (myFeaturesList.size() > 0) { + FeaturePtr aFeature = myFeaturesList.first(); + if (aFeature) { // Selection happens in TreeView + // Find index which corresponds the feature + QModelIndex aIndex; + foreach(QModelIndex aIdx, selectedIndexes()) { + if (dataModel()->feature(aIdx) == aFeature) { + aIndex = aIdx; + break; + } + } + if (aIndex.isValid()) { + myTreeView->setCurrentIndex(aIndex); + myTreeView->edit(aIndex); + } + } else { //Selection happens in Upper label + myActiveDocLbl->setReadOnly(false); + myActiveDocLbl->setFocus(); + myActiveDocLbl->selectAll(); + myActiveDocLbl->grabMouse(); + myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text()); + } + } } \ No newline at end of file diff --git a/src/XGUI/XGUI_ObjectsBrowser.h b/src/XGUI/XGUI_ObjectsBrowser.h index c1907e34d..fa30d2b82 100644 --- a/src/XGUI/XGUI_ObjectsBrowser.h +++ b/src/XGUI/XGUI_ObjectsBrowser.h @@ -9,7 +9,7 @@ #include class XGUI_DocumentDataModel; -class QLabel; +class QLineEdit; class XGUI_DataTree: public QTreeView @@ -32,6 +32,9 @@ signals: //! Emited on context menu request void contextMenuRequested(QContextMenuEvent* theEvent); +protected slots: + virtual void commitData(QWidget* theEditor); + protected: virtual void mouseDoubleClickEvent(QMouseEvent* theEvent); virtual void contextMenuEvent(QContextMenuEvent* theEvent); @@ -90,11 +93,16 @@ private slots: void onContextMenuRequested(QContextMenuEvent* theEvent); void onLabelContextMenuRequested(const QPoint& thePnt); + //! Called on Edit command request + void onEditItem(); + private: + void closeDocNameEditing(bool toSave); + //! Internal model XGUI_DocumentDataModel* myDocModel; - QLabel* myActiveDocLbl; + QLineEdit* myActiveDocLbl; XGUI_DataTree* myTreeView; QFeatureList myFeaturesList; diff --git a/src/XGUI/XGUI_PartDataModel.cpp b/src/XGUI/XGUI_PartDataModel.cpp index 532d88d78..ff0f8aad8 100644 --- a/src/XGUI/XGUI_PartDataModel.cpp +++ b/src/XGUI/XGUI_PartDataModel.cpp @@ -12,13 +12,13 @@ #include -FeaturePtr featureObj(const FeaturePtr& theFeature) -{ - ObjectPtr aObject = boost::dynamic_pointer_cast(theFeature); - if (aObject) - return aObject->featureRef(); - return theFeature; -} +//FeaturePtr featureObj(const FeaturePtr& theFeature) +//{ +// ObjectPtr aObject = boost::dynamic_pointer_cast(theFeature); +// if (aObject) +// return aObject->featureRef(); +// return theFeature; +//} XGUI_TopDataModel::XGUI_TopDataModel(const DocumentPtr& theDocument, QObject* theParent) @@ -41,7 +41,7 @@ QVariant XGUI_TopDataModel::data(const QModelIndex& theIndex, int theRole) const return tr("Parameters") + QString(" (%1)").arg(rowCount(theIndex)); case ParamObject: { - FeaturePtr aFeature = featureObj(myDocument->feature(PARAMETERS_GROUP, theIndex.row())); + FeaturePtr aFeature = myDocument->feature(PARAMETERS_GROUP, theIndex.row(), true); if (aFeature) return aFeature->data()->getName().c_str(); } @@ -49,7 +49,7 @@ QVariant XGUI_TopDataModel::data(const QModelIndex& theIndex, int theRole) const return tr("Constructions") + QString(" (%1)").arg(rowCount(theIndex)); case ConstructObject: { - FeaturePtr aFeature = featureObj(myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row())); + FeaturePtr aFeature = myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true); if (aFeature) return aFeature->data()->getName().c_str(); } @@ -65,7 +65,7 @@ QVariant XGUI_TopDataModel::data(const QModelIndex& theIndex, int theRole) const return QIcon(":pictures/constr_folder.png"); case ConstructObject: { - FeaturePtr aFeature = featureObj(myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row())); + FeaturePtr aFeature = myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true); if (aFeature) return QIcon(XGUI_Workshop::featureIcon(aFeature->getKind())); } @@ -152,9 +152,9 @@ FeaturePtr XGUI_TopDataModel::feature(const QModelIndex& theIndex) const case ConstructFolder: return FeaturePtr(); case ParamObject: - return featureObj(myDocument->feature(PARAMETERS_GROUP, theIndex.row())); + return myDocument->feature(PARAMETERS_GROUP, theIndex.row(), true); case ConstructObject: - return featureObj(myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row())); + return myDocument->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true); } return FeaturePtr(); } @@ -202,7 +202,7 @@ QVariant XGUI_PartDataModel::data(const QModelIndex& theIndex, int theRole) cons switch (theIndex.internalId()) { case MyRoot: { - FeaturePtr aFeature = featureObj(myDocument->feature(PARTS_GROUP, myId)); + FeaturePtr aFeature = myDocument->feature(PARTS_GROUP, myId, true); if (aFeature) return aFeature->data()->getName().c_str(); } @@ -214,19 +214,19 @@ QVariant XGUI_PartDataModel::data(const QModelIndex& theIndex, int theRole) cons return tr("Bodies") + QString(" (%1)").arg(rowCount(theIndex)); case ParamObject: { - FeaturePtr aFeature = featureObj(featureDocument()->feature(PARAMETERS_GROUP, theIndex.row())); + FeaturePtr aFeature = featureDocument()->feature(PARAMETERS_GROUP, theIndex.row(), true); if (aFeature) return aFeature->data()->getName().c_str(); } case ConstructObject: { - FeaturePtr aFeature = featureObj(featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row())); + FeaturePtr aFeature = featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true); if (aFeature) return aFeature->data()->getName().c_str(); } case HistoryObject: { - FeaturePtr aFeature = featureObj(featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3)); + FeaturePtr aFeature = featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3, true); if (aFeature) return aFeature->data()->getName().c_str(); } @@ -244,13 +244,13 @@ QVariant XGUI_PartDataModel::data(const QModelIndex& theIndex, int theRole) cons return QIcon(":pictures/constr_folder.png"); case ConstructObject: { - FeaturePtr aFeature = featureObj(featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row())); + FeaturePtr aFeature = featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true); if (aFeature) return QIcon(XGUI_Workshop::featureIcon(aFeature->getKind())); } case HistoryObject: { - FeaturePtr aFeature = featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3); + FeaturePtr aFeature = featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3, true); if (aFeature) return QIcon(XGUI_Workshop::featureIcon(aFeature->getKind())); } @@ -274,7 +274,7 @@ QVariant XGUI_PartDataModel::headerData(int section, Qt::Orientation orientation int XGUI_PartDataModel::rowCount(const QModelIndex& parent) const { if (!parent.isValid()) - if (myDocument->feature(PARTS_GROUP, myId)) + if (myDocument->feature(PARTS_GROUP, myId, true)) return 1; else return 0; @@ -350,7 +350,7 @@ bool XGUI_PartDataModel::hasChildren(const QModelIndex& theParent) const DocumentPtr XGUI_PartDataModel::featureDocument() const { - FeaturePtr aFeature = featureObj(myDocument->feature(PARTS_GROUP, myId)); + FeaturePtr aFeature = myDocument->feature(PARTS_GROUP, myId, true); return aFeature->data()->docRef("PartDocument")->value(); } @@ -359,16 +359,16 @@ FeaturePtr XGUI_PartDataModel::feature(const QModelIndex& theIndex) const switch (theIndex.internalId()) { case MyRoot: if (theIndex.row() < 3) { - return featureObj(myDocument->feature(PARTS_GROUP, myId)); + return myDocument->feature(PARTS_GROUP, myId, true); } else - return featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3); + return featureDocument()->feature(FEATURES_GROUP, theIndex.row() - 3, true); case ParamsFolder: case ConstructFolder: return FeaturePtr(); case ParamObject: - return featureObj(featureDocument()->feature(PARAMETERS_GROUP, theIndex.row())); + return featureDocument()->feature(PARAMETERS_GROUP, theIndex.row(), true); case ConstructObject: - return featureObj(featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row())); + return featureDocument()->feature(CONSTRUCTIONS_GROUP, theIndex.row(), true); } return FeaturePtr(); } @@ -401,5 +401,5 @@ QModelIndex XGUI_PartDataModel::findGroup(const std::string& theGroup) const FeaturePtr XGUI_PartDataModel::part() const { - return featureObj(myDocument->feature(PARTS_GROUP, myId)); + return myDocument->feature(PARTS_GROUP, myId, true); } \ No newline at end of file -- 2.39.2