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>
21 #include <QStyledItemDelegate>
25 * Tree item delegate for definition of data in column items editor
27 class XGUI_TreeViewItemDelegate: public QStyledItemDelegate
31 /// \param theParent a parent of the delegate
32 XGUI_TreeViewItemDelegate(XGUI_DataTree* theParent):QStyledItemDelegate(theParent), myTreedView(theParent) {}
34 /// Set data for item editor (name of the item)
35 /// \param editor a widget of editor
36 /// \param index the tree item index
37 virtual void setEditorData ( QWidget* editor, const QModelIndex& index ) const
39 QLineEdit* aEditor = dynamic_cast<QLineEdit*>(editor);
41 XGUI_DocumentDataModel* aModel = myTreedView->dataModel();
42 ObjectPtr aObj = aModel->object(index);
43 if (aObj.get() != NULL) {
44 aEditor->setText(aObj->data()->name().c_str());
48 QStyledItemDelegate::setEditorData(editor, index);
52 XGUI_DataTree* myTreedView;
56 XGUI_DataTree::XGUI_DataTree(QWidget* theParent)
57 : QTreeView(theParent)
59 setHeaderHidden(true);
60 setModel(new XGUI_DocumentDataModel(this));
61 setEditTriggers(QAbstractItemView::NoEditTriggers);
62 setSelectionBehavior(QAbstractItemView::SelectRows);
63 setSelectionMode(QAbstractItemView::ExtendedSelection);
65 setItemDelegateForColumn(0, new XGUI_TreeViewItemDelegate(this));
67 connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
68 this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
71 XGUI_DataTree::~XGUI_DataTree()
75 XGUI_DocumentDataModel* XGUI_DataTree::dataModel() const
77 return static_cast<XGUI_DocumentDataModel*>(model());
80 void XGUI_DataTree::onSelectionChanged(const QItemSelection& theSelected,
81 const QItemSelection& theDeselected)
83 mySelectedData.clear();
84 QModelIndexList aIndexes = selectionModel()->selectedIndexes();
85 XGUI_DocumentDataModel* aModel = dataModel();
86 QModelIndexList::const_iterator aIt;
87 for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
88 ObjectPtr aObject = aModel->object(*aIt);
90 mySelectedData.append(aObject);
92 emit selectionChanged();
95 void XGUI_DataTree::mouseDoubleClickEvent(QMouseEvent* theEvent)
97 if (theEvent->button() == Qt::LeftButton) {
98 QModelIndex aIndex = currentIndex();
99 XGUI_DocumentDataModel* aModel = dataModel();
100 ObjectPtr aObject = aModel->object(aIndex);
101 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
106 QTreeView::mouseDoubleClickEvent(theEvent);
109 void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent)
111 emit contextMenuRequested(theEvent);
114 void XGUI_DataTree::commitData(QWidget* theEditor)
116 QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
118 QString aRes = aEditor->text();
119 ObjectPtr aFeature = mySelectedData.first();
120 SessionPtr aMgr = ModelAPI_Session::get();
121 aMgr->startOperation("Rename");
122 aFeature->data()->setName(qPrintable(aRes));
123 aMgr->finishOperation();
127 void XGUI_DataTree::clear()
129 mySelectedData.clear();
130 XGUI_DocumentDataModel* aModel = dataModel();
135 //********************************************************************
136 //********************************************************************
137 //********************************************************************
138 XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent)
141 QVBoxLayout* aLayout = new QVBoxLayout(this);
142 ModuleBase_Tools::zeroMargins(aLayout);
143 aLayout->setSpacing(0);
145 QFrame* aLabelWgt = new QFrame(this);
146 aLabelWgt->setAutoFillBackground(true);
147 QPalette aPalet = aLabelWgt->palette();
148 aPalet.setColor(QPalette::Window, Qt::white);
149 aLabelWgt->setPalette(aPalet);
151 aLayout->addWidget(aLabelWgt);
152 QHBoxLayout* aLabelLay = new QHBoxLayout(aLabelWgt);
153 ModuleBase_Tools::zeroMargins(aLabelLay);
154 aLabelLay->setSpacing(0);
156 QLabel* aLbl = new QLabel(aLabelWgt);
157 aLbl->setPixmap(QPixmap(":pictures/assembly.png"));
160 aLbl->setAutoFillBackground(true);
162 aLabelLay->addWidget(aLbl);
164 SessionPtr aMgr = ModelAPI_Session::get();
165 DocumentPtr aDoc = aMgr->moduleDocument();
166 // TODO: Find a name of the root document
168 myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt);
169 myActiveDocLbl->setReadOnly(true);
170 myActiveDocLbl->setFrame(false);
171 //myActiveDocLbl->setMargin(2);
172 myActiveDocLbl->setContextMenuPolicy(Qt::CustomContextMenu);
174 myActiveDocLbl->installEventFilter(this);
176 aLabelLay->addWidget(myActiveDocLbl);
177 aLabelLay->setStretch(1, 1);
179 myTreeView = new XGUI_DataTree(this);
180 aLayout->addWidget(myTreeView);
182 myDocModel = myTreeView->dataModel();
184 aLabelWgt->setFrameShape(myTreeView->frameShape());
185 aLabelWgt->setFrameShadow(myTreeView->frameShadow());
187 connect(myTreeView, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
188 connect(myTreeView, SIGNAL(activePartChanged(ObjectPtr)), this,
189 SLOT(onActivePartChanged(ObjectPtr)));
190 connect(myTreeView, SIGNAL(activePartChanged(ObjectPtr)), this,
191 SIGNAL(activePartChanged(ObjectPtr)));
193 connect(myActiveDocLbl, SIGNAL(customContextMenuRequested(const QPoint&)), this,
194 SLOT(onLabelContextMenuRequested(const QPoint&)));
195 connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
196 SLOT(onContextMenuRequested(QContextMenuEvent*)));
198 onActivePartChanged(ObjectPtr());
200 // Create internal actions
201 QAction* aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
202 aAction->setData("RENAME_CMD");
203 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem()));
207 //***************************************************
208 XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser()
212 //***************************************************
213 void XGUI_ObjectsBrowser::onActivePartChanged(ObjectPtr thePart)
215 QPalette aPalet = myActiveDocLbl->palette();
217 aPalet.setColor(QPalette::Text, Qt::black);
219 aPalet.setColor(QPalette::Text, QColor(0, 72, 140));
221 myActiveDocLbl->setPalette(aPalet);
224 //***************************************************
225 bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent)
227 if (obj == myActiveDocLbl) {
228 if (myActiveDocLbl->isReadOnly()) {
229 if (theEvent->type() == QEvent::MouseButtonDblClick) {
230 if (myDocModel->activePartIndex().isValid()) {
231 myTreeView->setExpanded(myDocModel->activePartIndex(), false);
233 myDocModel->deactivatePart();
234 onActivePartChanged(ObjectPtr());
235 emit activePartChanged(ObjectPtr());
238 // End of editing by mouse click
239 if (theEvent->type() == QEvent::MouseButtonRelease) {
240 QMouseEvent* aEvent = (QMouseEvent*) theEvent;
241 QPoint aPnt = mapFromGlobal(aEvent->globalPos());
242 if (childAt(aPnt) != myActiveDocLbl) {
243 closeDocNameEditing(true);
245 } else if (theEvent->type() == QEvent::KeyRelease) {
246 QKeyEvent* aEvent = (QKeyEvent*) theEvent;
247 switch (aEvent->key()) {
249 case Qt::Key_Enter: // Accept current input
250 closeDocNameEditing(true);
252 case Qt::Key_Escape: // Cancel the input
253 closeDocNameEditing(false);
259 return QWidget::eventFilter(obj, theEvent);
262 //***************************************************
263 void XGUI_ObjectsBrowser::closeDocNameEditing(bool toSave)
265 myActiveDocLbl->deselect();
266 myActiveDocLbl->clearFocus();
267 myActiveDocLbl->releaseMouse();
268 myActiveDocLbl->setReadOnly(true);
270 // TODO: Save the name of root document
271 SessionPtr aMgr = ModelAPI_Session::get();
272 DocumentPtr aDoc = aMgr->moduleDocument();
274 myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString());
278 //***************************************************
279 void XGUI_ObjectsBrowser::activatePart(const ResultPartPtr& thePart)
282 QModelIndex aIndex = myDocModel->partIndex(thePart);
284 if ((myDocModel->activePartIndex() != aIndex) && myDocModel->activePartIndex().isValid()) {
285 myTreeView->setExpanded(myDocModel->activePartIndex(), false);
287 bool isChanged = myDocModel->activatedIndex(aIndex);
289 if (myDocModel->activePartIndex().isValid()) {
290 myTreeView->setExpanded(aIndex.parent(), true);
291 myTreeView->setExpanded(aIndex, true);
292 onActivePartChanged(myDocModel->object(aIndex));
294 onActivePartChanged(ObjectPtr());
298 QModelIndex aIndex = myDocModel->activePartIndex();
299 if (aIndex.isValid()) {
300 myDocModel->activatedIndex(aIndex);
301 myTreeView->setExpanded(aIndex, false);
302 onActivePartChanged(ObjectPtr());
307 //***************************************************
308 void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent)
310 myObjectsList = myTreeView->selectedObjects();
311 bool toEnable = myObjectsList.size() == 1;
312 foreach(QAction* aCmd, actions())
314 aCmd->setEnabled(toEnable);
316 emit contextMenuRequested(theEvent);
319 //***************************************************
320 void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt)
322 myObjectsList.clear();
323 //Empty feature pointer means that selected root document
324 myObjectsList.append(ObjectPtr());
326 foreach(QAction* aCmd, actions())
328 aCmd->setEnabled(true);
330 QContextMenuEvent aEvent(QContextMenuEvent::Mouse, thePnt, myActiveDocLbl->mapToGlobal(thePnt));
331 emit contextMenuRequested(&aEvent);
334 //***************************************************
335 void XGUI_ObjectsBrowser::onEditItem()
337 if (myObjectsList.size() > 0) {
338 ObjectPtr aFeature = myObjectsList.first();
339 if (aFeature) { // Selection happens in TreeView
340 // Find index which corresponds the feature
342 foreach(QModelIndex aIdx, selectedIndexes())
344 ObjectPtr aFea = dataModel()->object(aIdx);
345 if (dataModel()->object(aIdx)->isSame(aFeature)) {
350 if (aIndex.isValid()) {
351 myTreeView->setCurrentIndex(aIndex);
352 myTreeView->edit(aIndex);
354 } else { //Selection happens in Upper label
355 myActiveDocLbl->setReadOnly(false);
356 myActiveDocLbl->setFocus();
357 myActiveDocLbl->selectAll();
358 myActiveDocLbl->grabMouse();
359 myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text());
364 //***************************************************
365 void XGUI_ObjectsBrowser::onSelectionChanged()
367 myObjectsList = myTreeView->selectedObjects();
368 emit selectionChanged();
371 //***************************************************
372 void XGUI_ObjectsBrowser::rebuildDataTree()
374 myDocModel->rebuildDataTree();
378 //***************************************************
379 void XGUI_ObjectsBrowser::setObjectsSelected(const QObjectPtrList& theObjects)
381 QList<QModelIndex> theIndexes;
382 QItemSelectionModel* aSelectModel = myTreeView->selectionModel();
383 aSelectModel->clear();
385 foreach(ObjectPtr aFeature, theObjects)
387 QModelIndex aIndex = myDocModel->objectIndex(aFeature);
388 if (aIndex.isValid()) {
389 aSelectModel->select(aIndex, QItemSelectionModel::Select);
394 //***************************************************
395 void XGUI_ObjectsBrowser::processEvent(const std::shared_ptr<Events_Message>& theMessage)
397 myDocModel->processEvent(theMessage);
401 //***************************************************
402 void XGUI_ObjectsBrowser::clearContent()
404 myObjectsList.clear();