1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 #include "XGUI_ObjectsBrowser.h"
4 #include "XGUI_DocumentDataModel.h"
5 #include "XGUI_Tools.h"
7 #include <ModelAPI_Data.h>
8 #include <ModelAPI_Session.h>
9 #include <ModelAPI_Document.h>
10 #include <ModelAPI_Object.h>
17 #include <QMouseEvent>
20 XGUI_DataTree::XGUI_DataTree(QWidget* theParent)
21 : QTreeView(theParent)
23 setHeaderHidden(true);
24 setModel(new XGUI_DocumentDataModel(this));
25 setEditTriggers(QAbstractItemView::NoEditTriggers);
26 setSelectionBehavior(QAbstractItemView::SelectRows);
27 setSelectionMode(QAbstractItemView::ExtendedSelection);
29 connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
30 this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
33 XGUI_DataTree::~XGUI_DataTree()
37 XGUI_DocumentDataModel* XGUI_DataTree::dataModel() const
39 return static_cast<XGUI_DocumentDataModel*>(model());
42 void XGUI_DataTree::onSelectionChanged(const QItemSelection& theSelected,
43 const QItemSelection& theDeselected)
45 mySelectedData.clear();
46 QModelIndexList aIndexes = selectionModel()->selectedIndexes();
47 XGUI_DocumentDataModel* aModel = dataModel();
48 QModelIndexList::const_iterator aIt;
49 for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
50 ObjectPtr aObject = aModel->object(*aIt);
52 mySelectedData.append(aObject);
54 emit selectionChanged();
57 void XGUI_DataTree::mouseDoubleClickEvent(QMouseEvent* theEvent)
59 if (theEvent->button() == Qt::LeftButton) {
60 QModelIndex aIndex = currentIndex();
61 XGUI_DocumentDataModel* aModel = dataModel();
62 ObjectPtr aObject = aModel->object(aIndex);
63 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
68 QTreeView::mouseDoubleClickEvent(theEvent);
71 void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent)
73 emit contextMenuRequested(theEvent);
76 void XGUI_DataTree::commitData(QWidget* theEditor)
78 QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
80 QString aRes = aEditor->text();
81 ObjectPtr aFeature = mySelectedData.first();
82 SessionPtr aMgr = ModelAPI_Session::get();
83 aMgr->startOperation("RenameFeature");
84 aFeature->data()->setName(qPrintable(aRes));
85 aMgr->finishOperation();
89 void XGUI_DataTree::clear()
91 mySelectedData.clear();
92 XGUI_DocumentDataModel* aModel = dataModel();
97 //********************************************************************
98 //********************************************************************
99 //********************************************************************
100 XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent)
103 QVBoxLayout* aLayout = new QVBoxLayout(this);
104 aLayout->setContentsMargins(0, 0, 0, 0);
105 aLayout->setSpacing(0);
107 QFrame* aLabelWgt = new QFrame(this);
108 aLabelWgt->setAutoFillBackground(true);
109 QPalette aPalet = aLabelWgt->palette();
110 aPalet.setColor(QPalette::Window, Qt::white);
111 aLabelWgt->setPalette(aPalet);
113 aLayout->addWidget(aLabelWgt);
114 QHBoxLayout* aLabelLay = new QHBoxLayout(aLabelWgt);
115 aLabelLay->setContentsMargins(0, 0, 0, 0);
116 aLabelLay->setSpacing(0);
118 QLabel* aLbl = new QLabel(aLabelWgt);
119 aLbl->setPixmap(QPixmap(":pictures/assembly.png"));
122 aLbl->setAutoFillBackground(true);
124 aLabelLay->addWidget(aLbl);
126 SessionPtr aMgr = ModelAPI_Session::get();
127 DocumentPtr aDoc = aMgr->moduleDocument();
128 // TODO: Find a name of the root document
130 myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt);
131 myActiveDocLbl->setReadOnly(true);
132 myActiveDocLbl->setFrame(false);
133 //myActiveDocLbl->setMargin(2);
134 myActiveDocLbl->setContextMenuPolicy(Qt::CustomContextMenu);
136 myActiveDocLbl->installEventFilter(this);
138 aLabelLay->addWidget(myActiveDocLbl);
139 aLabelLay->setStretch(1, 1);
141 myTreeView = new XGUI_DataTree(this);
142 aLayout->addWidget(myTreeView);
144 myDocModel = myTreeView->dataModel();
146 aLabelWgt->setFrameShape(myTreeView->frameShape());
147 aLabelWgt->setFrameShadow(myTreeView->frameShadow());
149 connect(myTreeView, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
150 connect(myTreeView, SIGNAL(activePartChanged(ObjectPtr)), this,
151 SLOT(onActivePartChanged(ObjectPtr)));
152 connect(myTreeView, SIGNAL(activePartChanged(ObjectPtr)), this,
153 SIGNAL(activePartChanged(ObjectPtr)));
155 connect(myActiveDocLbl, SIGNAL(customContextMenuRequested(const QPoint&)), this,
156 SLOT(onLabelContextMenuRequested(const QPoint&)));
157 connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
158 SLOT(onContextMenuRequested(QContextMenuEvent*)));
160 onActivePartChanged(ObjectPtr());
162 // Create internal actions
163 QAction* aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
164 aAction->setData("RENAME_CMD");
165 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem()));
169 //***************************************************
170 XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser()
174 //***************************************************
175 void XGUI_ObjectsBrowser::onActivePartChanged(ObjectPtr thePart)
177 QPalette aPalet = myActiveDocLbl->palette();
179 aPalet.setColor(QPalette::Text, Qt::black);
181 aPalet.setColor(QPalette::Text, QColor(0, 72, 140));
183 myActiveDocLbl->setPalette(aPalet);
186 //***************************************************
187 bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent)
189 if (obj == myActiveDocLbl) {
190 if (myActiveDocLbl->isReadOnly()) {
191 if (theEvent->type() == QEvent::MouseButtonDblClick) {
192 if (myDocModel->activePartIndex().isValid()) {
193 myTreeView->setExpanded(myDocModel->activePartIndex(), false);
195 myDocModel->deactivatePart();
196 onActivePartChanged(ObjectPtr());
197 emit activePartChanged(ObjectPtr());
200 // End of editing by mouse click
201 if (theEvent->type() == QEvent::MouseButtonRelease) {
202 QMouseEvent* aEvent = (QMouseEvent*) theEvent;
203 QPoint aPnt = mapFromGlobal(aEvent->globalPos());
204 if (childAt(aPnt) != myActiveDocLbl) {
205 closeDocNameEditing(true);
207 } else if (theEvent->type() == QEvent::KeyRelease) {
208 QKeyEvent* aEvent = (QKeyEvent*) theEvent;
209 switch (aEvent->key()) {
211 case Qt::Key_Enter: // Accept current input
212 closeDocNameEditing(true);
214 case Qt::Key_Escape: // Cancel the input
215 closeDocNameEditing(false);
221 return QWidget::eventFilter(obj, theEvent);
224 //***************************************************
225 void XGUI_ObjectsBrowser::closeDocNameEditing(bool toSave)
227 myActiveDocLbl->deselect();
228 myActiveDocLbl->clearFocus();
229 myActiveDocLbl->releaseMouse();
230 myActiveDocLbl->setReadOnly(true);
232 // TODO: Save the name of root document
233 SessionPtr aMgr = ModelAPI_Session::get();
234 DocumentPtr aDoc = aMgr->moduleDocument();
236 myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString());
240 //***************************************************
241 void XGUI_ObjectsBrowser::activatePart(const ResultPartPtr& thePart)
244 QModelIndex aIndex = myDocModel->partIndex(thePart);
246 if ((myDocModel->activePartIndex() != aIndex) && myDocModel->activePartIndex().isValid()) {
247 myTreeView->setExpanded(myDocModel->activePartIndex(), false);
249 bool isChanged = myDocModel->activatedIndex(aIndex);
251 if (myDocModel->activePartIndex().isValid()) {
252 myTreeView->setExpanded(aIndex.parent(), true);
253 myTreeView->setExpanded(aIndex, true);
254 onActivePartChanged(myDocModel->object(aIndex));
256 onActivePartChanged(ObjectPtr());
260 QModelIndex aIndex = myDocModel->activePartIndex();
261 if (aIndex.isValid()) {
262 myDocModel->activatedIndex(aIndex);
263 myTreeView->setExpanded(aIndex, false);
264 onActivePartChanged(ObjectPtr());
269 //***************************************************
270 void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent)
272 myObjectsList = myTreeView->selectedObjects();
273 bool toEnable = myObjectsList.size() == 1;
274 foreach(QAction* aCmd, actions())
276 aCmd->setEnabled(toEnable);
278 emit contextMenuRequested(theEvent);
281 //***************************************************
282 void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt)
284 myObjectsList.clear();
285 //Empty feature pointer means that selected root document
286 myObjectsList.append(ObjectPtr());
288 foreach(QAction* aCmd, actions())
290 aCmd->setEnabled(true);
292 QContextMenuEvent aEvent(QContextMenuEvent::Mouse, thePnt, myActiveDocLbl->mapToGlobal(thePnt));
293 emit contextMenuRequested(&aEvent);
296 //***************************************************
297 void XGUI_ObjectsBrowser::onEditItem()
299 if (myObjectsList.size() > 0) {
300 ObjectPtr aFeature = myObjectsList.first();
301 if (aFeature) { // Selection happens in TreeView
302 // Find index which corresponds the feature
304 foreach(QModelIndex aIdx, selectedIndexes())
306 ObjectPtr aFea = dataModel()->object(aIdx);
307 if (dataModel()->object(aIdx)->isSame(aFeature)) {
312 if (aIndex.isValid()) {
313 myTreeView->setCurrentIndex(aIndex);
314 myTreeView->edit(aIndex);
316 } else { //Selection happens in Upper label
317 myActiveDocLbl->setReadOnly(false);
318 myActiveDocLbl->setFocus();
319 myActiveDocLbl->selectAll();
320 myActiveDocLbl->grabMouse();
321 myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text());
326 //***************************************************
327 void XGUI_ObjectsBrowser::onSelectionChanged()
329 myObjectsList = myTreeView->selectedObjects();
330 emit selectionChanged();
333 //***************************************************
334 void XGUI_ObjectsBrowser::rebuildDataTree()
336 myDocModel->rebuildDataTree();
340 //***************************************************
341 void XGUI_ObjectsBrowser::setObjectsSelected(const QObjectPtrList& theObjects)
343 QList<QModelIndex> theIndexes;
344 QItemSelectionModel* aSelectModel = myTreeView->selectionModel();
345 aSelectModel->clear();
347 foreach(ObjectPtr aFeature, theObjects)
349 QModelIndex aIndex = myDocModel->objectIndex(aFeature);
350 if (aIndex.isValid()) {
351 aSelectModel->select(aIndex, QItemSelectionModel::Select);
356 //***************************************************
357 void XGUI_ObjectsBrowser::processEvent(const std::shared_ptr<Events_Message>& theMessage)
359 myDocModel->processEvent(theMessage);
363 //***************************************************
364 void XGUI_ObjectsBrowser::clearContent()
366 myObjectsList.clear();