X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_ObjectsBrowser.cpp;h=58e5fb3deb0ac43294b6e69fb9a9d5303bd4ecd2;hb=8f09d362a50ccbc085841c24af2e755121e458ba;hp=125e1aaf4bc17cd6d52adda9f90296f88e671bb0;hpb=8a9a3ae0793503abf21a2c1b0a08d47d85449fc4;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_ObjectsBrowser.cpp b/src/XGUI/XGUI_ObjectsBrowser.cpp index 125e1aaf4..58e5fb3de 100644 --- a/src/XGUI/XGUI_ObjectsBrowser.cpp +++ b/src/XGUI/XGUI_ObjectsBrowser.cpp @@ -1,11 +1,16 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + #include "XGUI_ObjectsBrowser.h" -#include "XGUI_DocumentDataModel.h" #include "XGUI_Tools.h" +#include "XGUI_DataModel.h" #include -#include +#include #include -#include +#include + +#include +#include #include #include @@ -14,94 +19,166 @@ #include #include #include +#include +#include +/// Width of second column (minimum acceptable = 27) +#define SECOND_COL_WIDTH 30 + + +/** +* \ingroup GUI +* Tree item delegate for definition of data in column items editor +*/ +class XGUI_TreeViewItemDelegate: public QStyledItemDelegate +{ +public: + /// Constructor + /// \param theParent a parent of the delegate + XGUI_TreeViewItemDelegate(XGUI_DataTree* theParent):QStyledItemDelegate(theParent), myTreedView(theParent) {} + + /// Set data for item editor (name of the item) + /// \param editor a widget of editor + /// \param index the tree item index + virtual void setEditorData ( QWidget* editor, const QModelIndex& index ) const + { + QLineEdit* aEditor = dynamic_cast(editor); + if (aEditor) { + ModuleBase_IDocumentDataModel* aModel = myTreedView->dataModel(); + ObjectPtr aObj = aModel->object(index); + if (aObj.get() != NULL) { + aEditor->setText(aObj->data()->name().c_str()); + return; + } + } + QStyledItemDelegate::setEditorData(editor, index); + } + +private: + XGUI_DataTree* myTreedView; +}; XGUI_DataTree::XGUI_DataTree(QWidget* theParent) - : QTreeView(theParent) + : QTreeView(theParent) { setHeaderHidden(true); - setModel(new XGUI_DocumentDataModel(this)); setEditTriggers(QAbstractItemView::NoEditTriggers); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::ExtendedSelection); - connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&))); + setItemDelegateForColumn(0, new XGUI_TreeViewItemDelegate(this)); + +#ifndef ModuleDataModel + connect(this, SIGNAL(doubleClicked(const QModelIndex&)), + SLOT(onDoubleClick(const QModelIndex&))); +#endif } XGUI_DataTree::~XGUI_DataTree() { } -XGUI_DocumentDataModel* XGUI_DataTree::dataModel() const -{ - return static_cast(model()); +ModuleBase_IDocumentDataModel* XGUI_DataTree::dataModel() const +{ + return static_cast(model()); } +void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent) +{ + emit contextMenuRequested(theEvent); +} -void XGUI_DataTree::onSelectionChanged(const QItemSelection& theSelected, - const QItemSelection& theDeselected) +void XGUI_DataTree::commitData(QWidget* theEditor) { - mySelectedData.clear(); - QModelIndexList aIndexes = selectionModel()->selectedIndexes(); - XGUI_DocumentDataModel* aModel = dataModel(); - QModelIndexList::const_iterator aIt; - for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) { - FeaturePtr aFeature = aModel->feature(*aIt); - if (aFeature) - mySelectedData.append(aFeature); + QLineEdit* aEditor = dynamic_cast(theEditor); + if (aEditor) { + QString aName = aEditor->text(); + QModelIndexList aIndexList = selectionModel()->selectedIndexes(); + ModuleBase_IDocumentDataModel* aModel = dataModel(); + ObjectPtr aObj = aModel->object(aIndexList.first()); + SessionPtr aMgr = ModelAPI_Session::get(); + aMgr->startOperation("Rename"); + + if (!XGUI_Tools::canRename(this, aObj, aName)) { + aMgr->abortOperation(); + return; + } + + aObj->data()->setName(qPrintable(aName)); + aMgr->finishOperation(); } - emit selectionChanged(); } -void XGUI_DataTree::mouseDoubleClickEvent(QMouseEvent* theEvent) +void XGUI_DataTree::clear() { - if (theEvent->button() == Qt::LeftButton) { - QModelIndex aIndex = currentIndex(); - XGUI_DocumentDataModel* aModel = dataModel(); - - if ((aModel->activePartIndex() != aIndex) && aModel->activePartIndex().isValid()) { - setExpanded(aModel->activePartIndex(), false); - } - bool isChanged = aModel->activatedIndex(aIndex); - QTreeView::mouseDoubleClickEvent(theEvent); - if (isChanged) { - if (aModel->activePartIndex().isValid()) - setExpanded(aIndex, true); - emit activePartChanged(aModel->activePart()); - } - } else - QTreeView::mouseDoubleClickEvent(theEvent); + ModuleBase_IDocumentDataModel* aModel = dataModel(); + aModel->clear(); + reset(); } -void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent) +void XGUI_DataTree::resizeEvent(QResizeEvent* theEvent) { - emit contextMenuRequested(theEvent); + QSize aSize = theEvent->size(); + if (aSize.isValid()) { + setColumnWidth(0, aSize.width() - SECOND_COL_WIDTH); + setColumnWidth(1, SECOND_COL_WIDTH); + } } -void XGUI_DataTree::commitData(QWidget* theEditor) +void XGUI_DataTree::onDoubleClick(const QModelIndex& theIndex) { - QLineEdit* aEditor = dynamic_cast(theEditor); - if (aEditor) { - QString aRes = aEditor->text(); - FeaturePtr aFeature = mySelectedData.first(); - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - aMgr->rootDocument()->startOperation(); - if (!XGUI_Tools::isModelObject(aFeature)) - aFeature->data()->setName(qPrintable(aRes)); - else - boost::dynamic_pointer_cast(aFeature)->setName(qPrintable(aRes)); - aMgr->rootDocument()->finishOperation(); + if (theIndex.column() != 1) + return; + ModuleBase_IDocumentDataModel* aModel = dataModel(); + if (aModel->flags(theIndex) == 0) + return; + ObjectPtr aObj = aModel->object(theIndex); + + SessionPtr aMgr = ModelAPI_Session::get(); + DocumentPtr aDoc = aMgr->activeDocument(); + + QModelIndex aOldIndex = aModel->lastHistoryIndex(); + + std::string aOpName = tr("History change").toStdString(); + if (aObj.get()) { + if (aObj->document() != aDoc) + return; + aMgr->startOperation(aOpName); + aDoc->setCurrentFeature(std::dynamic_pointer_cast(aObj), true); + aMgr->finishOperation(); + } else { + // Ignore clicks on folders outside current document + if ((theIndex.internalId() == -1) && (aDoc != aMgr->moduleDocument())) + // Clicked folder under root but active document is another + return; + if ((theIndex.internalId() != -1) && (aDoc.get() != theIndex.internalPointer())) + // Cliced not on active document folder + return; + + aMgr->startOperation(aOpName); + aDoc->setCurrentFeature(FeaturePtr(), true); + aMgr->finishOperation(); } + QModelIndex aNewIndex = aModel->lastHistoryIndex(); + QModelIndex aParent = theIndex.parent(); + int aStartRow = std::min(aOldIndex.row(), aNewIndex.row()); + int aEndRow = std::max(aOldIndex.row(), aNewIndex.row()); + for (int i = aStartRow; i <= aEndRow; i++) { + update(aModel->index(i, 0, aParent)); + } + update(aOldIndex); + update(aNewIndex); } //******************************************************************** //******************************************************************** //******************************************************************** XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent) - : QWidget(theParent) + : QWidget(theParent), myDocModel(0) { QVBoxLayout* aLayout = new QVBoxLayout(this); - aLayout->setContentsMargins(0, 0, 0, 0); + ModuleBase_Tools::zeroMargins(aLayout); aLayout->setSpacing(0); QFrame* aLabelWgt = new QFrame(this); @@ -112,7 +189,7 @@ XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent) aLayout->addWidget(aLabelWgt); QHBoxLayout* aLabelLay = new QHBoxLayout(aLabelWgt); - aLabelLay->setContentsMargins(0, 0, 0, 0); + ModuleBase_Tools::zeroMargins(aLabelLay); aLabelLay->setSpacing(0); QLabel* aLbl = new QLabel(aLabelWgt); @@ -123,8 +200,8 @@ XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent) aLabelLay->addWidget(aLbl); - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - DocumentPtr aDoc = aMgr->rootDocument(); + SessionPtr aMgr = ModelAPI_Session::get(); + DocumentPtr aDoc = aMgr->moduleDocument(); // TODO: Find a name of the root document myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt); @@ -136,32 +213,18 @@ XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent) myActiveDocLbl->installEventFilter(this); aLabelLay->addWidget(myActiveDocLbl); - aLabelLay->setStretch(1,1); + aLabelLay->setStretch(1, 1); myTreeView = new XGUI_DataTree(this); aLayout->addWidget(myTreeView); - myDocModel = myTreeView->dataModel(); - aLabelWgt->setFrameShape(myTreeView->frameShape()); aLabelWgt->setFrameShadow(myTreeView->frameShadow()); - connect(myTreeView, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); - connect(myTreeView, SIGNAL(activePartChanged(FeaturePtr)), this, SLOT(onActivePartChanged(FeaturePtr))); - connect(myTreeView, SIGNAL(activePartChanged(FeaturePtr)), this, SIGNAL(activePartChanged(FeaturePtr))); - - connect(myActiveDocLbl, SIGNAL(customContextMenuRequested(const QPoint&)), - this, SLOT(onLabelContextMenuRequested(const QPoint&))); - connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), - this, SLOT(onContextMenuRequested(QContextMenuEvent*))); - - onActivePartChanged(FeaturePtr()); - - // Create internal actions - QAction* aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this); - aAction->setData("RENAME_CMD"); - connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem())); - addAction(aAction); + connect(myActiveDocLbl, SIGNAL(customContextMenuRequested(const QPoint&)), this, + SLOT(onLabelContextMenuRequested(const QPoint&))); + connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), this, + SLOT(onContextMenuRequested(QContextMenuEvent*))); } //*************************************************** @@ -169,32 +232,11 @@ XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser() { } -//*************************************************** -void XGUI_ObjectsBrowser::onActivePartChanged(FeaturePtr thePart) -{ - QPalette aPalet = myActiveDocLbl->palette(); - if (thePart) { - aPalet.setColor(QPalette::Text, Qt::black); - } else { - aPalet.setColor(QPalette::Text, QColor(0, 72, 140)); - } - myActiveDocLbl->setPalette(aPalet); -} - //*************************************************** bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent) { if (obj == myActiveDocLbl) { - 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 { + if (!myActiveDocLbl->isReadOnly()) { // End of editing by mouse click if (theEvent->type() == QEvent::MouseButtonRelease) { QMouseEvent* aEvent = (QMouseEvent*) theEvent; @@ -205,14 +247,20 @@ bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent) } 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; - } + case Qt::Key_Return: + case Qt::Key_Enter: // Accept current input + closeDocNameEditing(true); + break; + case Qt::Key_Escape: // Cancel the input + closeDocNameEditing(false); + break; + } } + } else { + if (theEvent->type() == QEvent::MouseButtonDblClick) { + emit headerMouseDblClicked(QModelIndex()); + return true; + } } } return QWidget::eventFilter(obj, theEvent); @@ -227,47 +275,23 @@ void XGUI_ObjectsBrowser::closeDocNameEditing(bool toSave) myActiveDocLbl->setReadOnly(true); if (toSave) { // TODO: Save the name of root document - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - DocumentPtr aDoc = aMgr->rootDocument(); + SessionPtr aMgr = ModelAPI_Session::get(); + DocumentPtr aDoc = aMgr->moduleDocument(); } else { myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString()); } } //*************************************************** -void XGUI_ObjectsBrowser::activatePart(const FeaturePtr& thePart) +void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent) { - if (thePart) { - QModelIndex aIndex = myDocModel->partIndex(thePart); - - if ((myDocModel->activePartIndex() != aIndex) && myDocModel->activePartIndex().isValid()) { - myTreeView->setExpanded(myDocModel->activePartIndex(), false); - } - bool isChanged = myDocModel->activatedIndex(aIndex); - if (isChanged) { - if (myDocModel->activePartIndex().isValid()) { - myTreeView->setExpanded(aIndex.parent(), true); - myTreeView->setExpanded(aIndex, true); - onActivePartChanged(myDocModel->feature(aIndex)); - } else { - onActivePartChanged(FeaturePtr()); - } - } - } else { - QModelIndex aIndex = myDocModel->activePartIndex(); - if (aIndex.isValid()) { - myDocModel->activatedIndex(aIndex); - myTreeView->setExpanded(aIndex, false); - onActivePartChanged(FeaturePtr()); - } + QModelIndexList aIndexes; + QObjectPtrList aSelectedData = selectedObjects(&aIndexes); + bool toEnable = false; + if (aSelectedData.size() == 1) { + Qt::ItemFlags aFlags = dataModel()->flags(aIndexes.first()); + toEnable = ((aFlags & Qt::ItemIsEditable) != 0); } -} - -//*************************************************** -void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent) -{ - myFeaturesList = myTreeView->selectedFeatures(); - bool toEnable = myFeaturesList.size() > 0; foreach(QAction* aCmd, actions()) { aCmd->setEnabled(toEnable); } @@ -277,28 +301,33 @@ void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent) //*************************************************** void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt) { - myFeaturesList.clear(); + myTreeView->selectionModel()->clearSelection(); //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) ); + 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 + QObjectPtrList aSelectedData = selectedObjects(); + if (aSelectedData.size() > 0) { + ObjectPtr aFeature = aSelectedData.first(); + if (aFeature) { // Selection happens in TreeView + QObjectPtrList aList; + aList.append(aFeature); + // check whether the object can be deleted. There should not be parts which are not loaded + if (!XGUI_Tools::canRemoveOrRename((QWidget*)parent(), aList)) + return; + // Find index which corresponds the feature QModelIndex aIndex; foreach(QModelIndex aIdx, selectedIndexes()) { - FeaturePtr aFea = dataModel()->feature(aIdx); - if (dataModel()->feature(aIdx)->isSame(aFeature)) { + ObjectPtr aFea = dataModel()->object(aIdx); + if (dataModel()->object(aIdx)->isSame(aFeature)) { aIndex = aIdx; break; } @@ -307,12 +336,84 @@ void XGUI_ObjectsBrowser::onEditItem() 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()); + return; + } + } + //Selection happens in Upper label + myActiveDocLbl->setReadOnly(false); + myActiveDocLbl->setFocus(); + myActiveDocLbl->selectAll(); + myActiveDocLbl->grabMouse(); + myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text()); +} + +//*************************************************** +void XGUI_ObjectsBrowser::rebuildDataTree() +{ + myDocModel->rebuildDataTree(); + update(); +} + +//*************************************************** +void XGUI_ObjectsBrowser::setObjectsSelected(const QObjectPtrList& theObjects) +{ + QList theIndexes; + QItemSelectionModel* aSelectModel = myTreeView->selectionModel(); + aSelectModel->clear(); + + foreach(ObjectPtr aFeature, theObjects) + { + QModelIndex aIndex = myDocModel->objectIndex(aFeature); + if (aIndex.isValid()) { + aSelectModel->select(aIndex, QItemSelectionModel::Select); + } + } +} + +//*************************************************** +void XGUI_ObjectsBrowser::clearContent() +{ + myTreeView->clear(); +} + +void XGUI_ObjectsBrowser::setDataModel(ModuleBase_IDocumentDataModel* theModel) +{ +#ifdef ModuleDataModel + myDocModel = theModel; +#else + myDocModel = new XGUI_DataModel(this); +#endif + myTreeView->setModel(myDocModel); + QItemSelectionModel* aSelMod = myTreeView->selectionModel(); + connect(aSelMod, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&))); +} + +void XGUI_ObjectsBrowser::onSelectionChanged(const QItemSelection& theSelected, + const QItemSelection& theDeselected) +{ + emit selectionChanged(); +} + +QObjectPtrList XGUI_ObjectsBrowser::selectedObjects(QModelIndexList* theIndexes) const +{ + QObjectPtrList aList; + QModelIndexList aIndexes = selectedIndexes(); +#ifdef ModuleDataModel + ModuleBase_IDocumentDataModel* aModel = dataModel(); +#else + XGUI_DataModel* aModel = dataModel(); +#endif + QModelIndexList::const_iterator aIt; + for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) { + if ((*aIt).column() == 0) { + ObjectPtr aObject = aModel->object(*aIt); + if (aObject) { + aList.append(aObject); + if (theIndexes) + theIndexes->append(*aIt); + } } } + return aList; } \ No newline at end of file