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>
12 #include <ModuleBase_Tools.h>
19 #include <QMouseEvent>
22 XGUI_DataTree::XGUI_DataTree(QWidget* theParent)
23 : QTreeView(theParent)
25 setHeaderHidden(true);
26 setModel(new XGUI_DocumentDataModel(this));
27 setEditTriggers(QAbstractItemView::NoEditTriggers);
28 setSelectionBehavior(QAbstractItemView::SelectRows);
29 setSelectionMode(QAbstractItemView::ExtendedSelection);
31 connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
32 this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
35 XGUI_DataTree::~XGUI_DataTree()
39 XGUI_DocumentDataModel* XGUI_DataTree::dataModel() const
41 return static_cast<XGUI_DocumentDataModel*>(model());
44 void XGUI_DataTree::onSelectionChanged(const QItemSelection& theSelected,
45 const QItemSelection& theDeselected)
47 mySelectedData.clear();
48 QModelIndexList aIndexes = selectionModel()->selectedIndexes();
49 XGUI_DocumentDataModel* aModel = dataModel();
50 QModelIndexList::const_iterator aIt;
51 for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
52 ObjectPtr aObject = aModel->object(*aIt);
54 mySelectedData.append(aObject);
56 emit selectionChanged();
59 void XGUI_DataTree::mouseDoubleClickEvent(QMouseEvent* theEvent)
61 if (theEvent->button() == Qt::LeftButton) {
62 QModelIndex aIndex = currentIndex();
63 XGUI_DocumentDataModel* aModel = dataModel();
64 ObjectPtr aObject = aModel->object(aIndex);
65 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
70 QTreeView::mouseDoubleClickEvent(theEvent);
73 void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent)
75 emit contextMenuRequested(theEvent);
78 void XGUI_DataTree::commitData(QWidget* theEditor)
80 QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
82 QString aRes = aEditor->text();
83 ObjectPtr aFeature = mySelectedData.first();
84 SessionPtr aMgr = ModelAPI_Session::get();
85 aMgr->startOperation("Rename");
86 aFeature->data()->setName(qPrintable(aRes));
87 aMgr->finishOperation();
91 void XGUI_DataTree::clear()
93 mySelectedData.clear();
94 XGUI_DocumentDataModel* aModel = dataModel();
99 //********************************************************************
100 //********************************************************************
101 //********************************************************************
102 XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent)
105 QVBoxLayout* aLayout = new QVBoxLayout(this);
106 ModuleBase_Tools::zeroMargins(aLayout);
107 aLayout->setSpacing(0);
109 QFrame* aLabelWgt = new QFrame(this);
110 aLabelWgt->setAutoFillBackground(true);
111 QPalette aPalet = aLabelWgt->palette();
112 aPalet.setColor(QPalette::Window, Qt::white);
113 aLabelWgt->setPalette(aPalet);
115 aLayout->addWidget(aLabelWgt);
116 QHBoxLayout* aLabelLay = new QHBoxLayout(aLabelWgt);
117 ModuleBase_Tools::zeroMargins(aLabelLay);
118 aLabelLay->setSpacing(0);
120 QLabel* aLbl = new QLabel(aLabelWgt);
121 aLbl->setPixmap(QPixmap(":pictures/assembly.png"));
124 aLbl->setAutoFillBackground(true);
126 aLabelLay->addWidget(aLbl);
128 SessionPtr aMgr = ModelAPI_Session::get();
129 DocumentPtr aDoc = aMgr->moduleDocument();
130 // TODO: Find a name of the root document
132 myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt);
133 myActiveDocLbl->setReadOnly(true);
134 myActiveDocLbl->setFrame(false);
135 //myActiveDocLbl->setMargin(2);
136 myActiveDocLbl->setContextMenuPolicy(Qt::CustomContextMenu);
138 myActiveDocLbl->installEventFilter(this);
140 aLabelLay->addWidget(myActiveDocLbl);
141 aLabelLay->setStretch(1, 1);
143 myTreeView = new XGUI_DataTree(this);
144 aLayout->addWidget(myTreeView);
146 myDocModel = myTreeView->dataModel();
148 aLabelWgt->setFrameShape(myTreeView->frameShape());
149 aLabelWgt->setFrameShadow(myTreeView->frameShadow());
151 connect(myTreeView, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
152 connect(myTreeView, SIGNAL(activePartChanged(ObjectPtr)), this,
153 SLOT(onActivePartChanged(ObjectPtr)));
154 connect(myTreeView, SIGNAL(activePartChanged(ObjectPtr)), this,
155 SIGNAL(activePartChanged(ObjectPtr)));
157 connect(myActiveDocLbl, SIGNAL(customContextMenuRequested(const QPoint&)), this,
158 SLOT(onLabelContextMenuRequested(const QPoint&)));
159 connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
160 SLOT(onContextMenuRequested(QContextMenuEvent*)));
162 onActivePartChanged(ObjectPtr());
164 // Create internal actions
165 QAction* aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
166 aAction->setData("RENAME_CMD");
167 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem()));
171 //***************************************************
172 XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser()
176 //***************************************************
177 void XGUI_ObjectsBrowser::onActivePartChanged(ObjectPtr thePart)
179 QPalette aPalet = myActiveDocLbl->palette();
181 aPalet.setColor(QPalette::Text, Qt::black);
183 aPalet.setColor(QPalette::Text, QColor(0, 72, 140));
185 myActiveDocLbl->setPalette(aPalet);
188 //***************************************************
189 bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent)
191 if (obj == myActiveDocLbl) {
192 if (myActiveDocLbl->isReadOnly()) {
193 if (theEvent->type() == QEvent::MouseButtonDblClick) {
194 if (myDocModel->activePartIndex().isValid()) {
195 myTreeView->setExpanded(myDocModel->activePartIndex(), false);
197 myDocModel->deactivatePart();
198 onActivePartChanged(ObjectPtr());
199 emit activePartChanged(ObjectPtr());
202 // End of editing by mouse click
203 if (theEvent->type() == QEvent::MouseButtonRelease) {
204 QMouseEvent* aEvent = (QMouseEvent*) theEvent;
205 QPoint aPnt = mapFromGlobal(aEvent->globalPos());
206 if (childAt(aPnt) != myActiveDocLbl) {
207 closeDocNameEditing(true);
209 } else if (theEvent->type() == QEvent::KeyRelease) {
210 QKeyEvent* aEvent = (QKeyEvent*) theEvent;
211 switch (aEvent->key()) {
213 case Qt::Key_Enter: // Accept current input
214 closeDocNameEditing(true);
216 case Qt::Key_Escape: // Cancel the input
217 closeDocNameEditing(false);
223 return QWidget::eventFilter(obj, theEvent);
226 //***************************************************
227 void XGUI_ObjectsBrowser::closeDocNameEditing(bool toSave)
229 myActiveDocLbl->deselect();
230 myActiveDocLbl->clearFocus();
231 myActiveDocLbl->releaseMouse();
232 myActiveDocLbl->setReadOnly(true);
234 // TODO: Save the name of root document
235 SessionPtr aMgr = ModelAPI_Session::get();
236 DocumentPtr aDoc = aMgr->moduleDocument();
238 myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString());
242 //***************************************************
243 void XGUI_ObjectsBrowser::activatePart(const ResultPartPtr& thePart)
246 QModelIndex aIndex = myDocModel->partIndex(thePart);
248 if ((myDocModel->activePartIndex() != aIndex) && myDocModel->activePartIndex().isValid()) {
249 myTreeView->setExpanded(myDocModel->activePartIndex(), false);
251 bool isChanged = myDocModel->activatedIndex(aIndex);
253 if (myDocModel->activePartIndex().isValid()) {
254 myTreeView->setExpanded(aIndex.parent(), true);
255 myTreeView->setExpanded(aIndex, true);
256 onActivePartChanged(myDocModel->object(aIndex));
258 onActivePartChanged(ObjectPtr());
262 QModelIndex aIndex = myDocModel->activePartIndex();
263 if (aIndex.isValid()) {
264 myDocModel->activatedIndex(aIndex);
265 myTreeView->setExpanded(aIndex, false);
266 onActivePartChanged(ObjectPtr());
271 //***************************************************
272 void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent)
274 myObjectsList = myTreeView->selectedObjects();
275 bool toEnable = myObjectsList.size() == 1;
276 foreach(QAction* aCmd, actions())
278 aCmd->setEnabled(toEnable);
280 emit contextMenuRequested(theEvent);
283 //***************************************************
284 void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt)
286 myObjectsList.clear();
287 //Empty feature pointer means that selected root document
288 myObjectsList.append(ObjectPtr());
290 foreach(QAction* aCmd, actions())
292 aCmd->setEnabled(true);
294 QContextMenuEvent aEvent(QContextMenuEvent::Mouse, thePnt, myActiveDocLbl->mapToGlobal(thePnt));
295 emit contextMenuRequested(&aEvent);
298 //***************************************************
299 void XGUI_ObjectsBrowser::onEditItem()
301 if (myObjectsList.size() > 0) {
302 ObjectPtr aFeature = myObjectsList.first();
303 if (aFeature) { // Selection happens in TreeView
304 // Find index which corresponds the feature
306 foreach(QModelIndex aIdx, selectedIndexes())
308 ObjectPtr aFea = dataModel()->object(aIdx);
309 if (dataModel()->object(aIdx)->isSame(aFeature)) {
314 if (aIndex.isValid()) {
315 myTreeView->setCurrentIndex(aIndex);
316 myTreeView->edit(aIndex);
318 } else { //Selection happens in Upper label
319 myActiveDocLbl->setReadOnly(false);
320 myActiveDocLbl->setFocus();
321 myActiveDocLbl->selectAll();
322 myActiveDocLbl->grabMouse();
323 myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text());
328 //***************************************************
329 void XGUI_ObjectsBrowser::onSelectionChanged()
331 myObjectsList = myTreeView->selectedObjects();
332 emit selectionChanged();
335 //***************************************************
336 void XGUI_ObjectsBrowser::rebuildDataTree()
338 myDocModel->rebuildDataTree();
342 //***************************************************
343 void XGUI_ObjectsBrowser::setObjectsSelected(const QObjectPtrList& theObjects)
345 QList<QModelIndex> theIndexes;
346 QItemSelectionModel* aSelectModel = myTreeView->selectionModel();
347 aSelectModel->clear();
349 foreach(ObjectPtr aFeature, theObjects)
351 QModelIndex aIndex = myDocModel->objectIndex(aFeature);
352 if (aIndex.isValid()) {
353 aSelectModel->select(aIndex, QItemSelectionModel::Select);
358 //***************************************************
359 void XGUI_ObjectsBrowser::processEvent(const std::shared_ptr<Events_Message>& theMessage)
361 myDocModel->processEvent(theMessage);
365 //***************************************************
366 void XGUI_ObjectsBrowser::clearContent()
368 myObjectsList.clear();