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>
23 class XGUI_TreeViewItemDelegate: public QStyledItemDelegate
26 XGUI_TreeViewItemDelegate(XGUI_DataTree* theParent):QStyledItemDelegate(theParent), myTreedView(theParent) {}
28 virtual void setEditorData ( QWidget* editor, const QModelIndex& index ) const
30 QLineEdit* aEditor = dynamic_cast<QLineEdit*>(editor);
32 XGUI_DocumentDataModel* aModel = myTreedView->dataModel();
33 ObjectPtr aObj = aModel->object(index);
34 if (aObj.get() != NULL) {
35 aEditor->setText(aObj->data()->name().c_str());
39 QStyledItemDelegate::setEditorData(editor, index);
43 XGUI_DataTree* myTreedView;
47 XGUI_DataTree::XGUI_DataTree(QWidget* theParent)
48 : QTreeView(theParent)
50 setHeaderHidden(true);
51 setModel(new XGUI_DocumentDataModel(this));
52 setEditTriggers(QAbstractItemView::NoEditTriggers);
53 setSelectionBehavior(QAbstractItemView::SelectRows);
54 setSelectionMode(QAbstractItemView::ExtendedSelection);
56 setItemDelegateForColumn(0, new XGUI_TreeViewItemDelegate(this));
58 connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
59 this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
62 XGUI_DataTree::~XGUI_DataTree()
66 XGUI_DocumentDataModel* XGUI_DataTree::dataModel() const
68 return static_cast<XGUI_DocumentDataModel*>(model());
71 void XGUI_DataTree::onSelectionChanged(const QItemSelection& theSelected,
72 const QItemSelection& theDeselected)
74 mySelectedData.clear();
75 QModelIndexList aIndexes = selectionModel()->selectedIndexes();
76 XGUI_DocumentDataModel* aModel = dataModel();
77 QModelIndexList::const_iterator aIt;
78 for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
79 ObjectPtr aObject = aModel->object(*aIt);
81 mySelectedData.append(aObject);
83 emit selectionChanged();
86 void XGUI_DataTree::mouseDoubleClickEvent(QMouseEvent* theEvent)
88 if (theEvent->button() == Qt::LeftButton) {
89 QModelIndex aIndex = currentIndex();
90 XGUI_DocumentDataModel* aModel = dataModel();
91 ObjectPtr aObject = aModel->object(aIndex);
92 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
97 QTreeView::mouseDoubleClickEvent(theEvent);
100 void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent)
102 emit contextMenuRequested(theEvent);
105 void XGUI_DataTree::commitData(QWidget* theEditor)
107 QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
109 QString aRes = aEditor->text();
110 ObjectPtr aFeature = mySelectedData.first();
111 SessionPtr aMgr = ModelAPI_Session::get();
112 aMgr->startOperation("Rename");
113 aFeature->data()->setName(qPrintable(aRes));
114 aMgr->finishOperation();
118 void XGUI_DataTree::clear()
120 mySelectedData.clear();
121 XGUI_DocumentDataModel* aModel = dataModel();
126 //********************************************************************
127 //********************************************************************
128 //********************************************************************
129 XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent)
132 QVBoxLayout* aLayout = new QVBoxLayout(this);
133 ModuleBase_Tools::zeroMargins(aLayout);
134 aLayout->setSpacing(0);
136 QFrame* aLabelWgt = new QFrame(this);
137 aLabelWgt->setAutoFillBackground(true);
138 QPalette aPalet = aLabelWgt->palette();
139 aPalet.setColor(QPalette::Window, Qt::white);
140 aLabelWgt->setPalette(aPalet);
142 aLayout->addWidget(aLabelWgt);
143 QHBoxLayout* aLabelLay = new QHBoxLayout(aLabelWgt);
144 ModuleBase_Tools::zeroMargins(aLabelLay);
145 aLabelLay->setSpacing(0);
147 QLabel* aLbl = new QLabel(aLabelWgt);
148 aLbl->setPixmap(QPixmap(":pictures/assembly.png"));
151 aLbl->setAutoFillBackground(true);
153 aLabelLay->addWidget(aLbl);
155 SessionPtr aMgr = ModelAPI_Session::get();
156 DocumentPtr aDoc = aMgr->moduleDocument();
157 // TODO: Find a name of the root document
159 myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt);
160 myActiveDocLbl->setReadOnly(true);
161 myActiveDocLbl->setFrame(false);
162 //myActiveDocLbl->setMargin(2);
163 myActiveDocLbl->setContextMenuPolicy(Qt::CustomContextMenu);
165 myActiveDocLbl->installEventFilter(this);
167 aLabelLay->addWidget(myActiveDocLbl);
168 aLabelLay->setStretch(1, 1);
170 myTreeView = new XGUI_DataTree(this);
171 aLayout->addWidget(myTreeView);
173 myDocModel = myTreeView->dataModel();
175 aLabelWgt->setFrameShape(myTreeView->frameShape());
176 aLabelWgt->setFrameShadow(myTreeView->frameShadow());
178 connect(myTreeView, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
179 connect(myTreeView, SIGNAL(activePartChanged(ObjectPtr)), this,
180 SLOT(onActivePartChanged(ObjectPtr)));
181 connect(myTreeView, SIGNAL(activePartChanged(ObjectPtr)), this,
182 SIGNAL(activePartChanged(ObjectPtr)));
184 connect(myActiveDocLbl, SIGNAL(customContextMenuRequested(const QPoint&)), this,
185 SLOT(onLabelContextMenuRequested(const QPoint&)));
186 connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
187 SLOT(onContextMenuRequested(QContextMenuEvent*)));
189 onActivePartChanged(ObjectPtr());
191 // Create internal actions
192 QAction* aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
193 aAction->setData("RENAME_CMD");
194 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem()));
198 //***************************************************
199 XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser()
203 //***************************************************
204 void XGUI_ObjectsBrowser::onActivePartChanged(ObjectPtr thePart)
206 QPalette aPalet = myActiveDocLbl->palette();
208 aPalet.setColor(QPalette::Text, Qt::black);
210 aPalet.setColor(QPalette::Text, QColor(0, 72, 140));
212 myActiveDocLbl->setPalette(aPalet);
215 //***************************************************
216 bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent)
218 if (obj == myActiveDocLbl) {
219 if (myActiveDocLbl->isReadOnly()) {
220 if (theEvent->type() == QEvent::MouseButtonDblClick) {
221 if (myDocModel->activePartIndex().isValid()) {
222 myTreeView->setExpanded(myDocModel->activePartIndex(), false);
224 myDocModel->deactivatePart();
225 onActivePartChanged(ObjectPtr());
226 emit activePartChanged(ObjectPtr());
229 // End of editing by mouse click
230 if (theEvent->type() == QEvent::MouseButtonRelease) {
231 QMouseEvent* aEvent = (QMouseEvent*) theEvent;
232 QPoint aPnt = mapFromGlobal(aEvent->globalPos());
233 if (childAt(aPnt) != myActiveDocLbl) {
234 closeDocNameEditing(true);
236 } else if (theEvent->type() == QEvent::KeyRelease) {
237 QKeyEvent* aEvent = (QKeyEvent*) theEvent;
238 switch (aEvent->key()) {
240 case Qt::Key_Enter: // Accept current input
241 closeDocNameEditing(true);
243 case Qt::Key_Escape: // Cancel the input
244 closeDocNameEditing(false);
250 return QWidget::eventFilter(obj, theEvent);
253 //***************************************************
254 void XGUI_ObjectsBrowser::closeDocNameEditing(bool toSave)
256 myActiveDocLbl->deselect();
257 myActiveDocLbl->clearFocus();
258 myActiveDocLbl->releaseMouse();
259 myActiveDocLbl->setReadOnly(true);
261 // TODO: Save the name of root document
262 SessionPtr aMgr = ModelAPI_Session::get();
263 DocumentPtr aDoc = aMgr->moduleDocument();
265 myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString());
269 //***************************************************
270 void XGUI_ObjectsBrowser::activatePart(const ResultPartPtr& thePart)
273 QModelIndex aIndex = myDocModel->partIndex(thePart);
275 if ((myDocModel->activePartIndex() != aIndex) && myDocModel->activePartIndex().isValid()) {
276 myTreeView->setExpanded(myDocModel->activePartIndex(), false);
278 bool isChanged = myDocModel->activatedIndex(aIndex);
280 if (myDocModel->activePartIndex().isValid()) {
281 myTreeView->setExpanded(aIndex.parent(), true);
282 myTreeView->setExpanded(aIndex, true);
283 onActivePartChanged(myDocModel->object(aIndex));
285 onActivePartChanged(ObjectPtr());
289 QModelIndex aIndex = myDocModel->activePartIndex();
290 if (aIndex.isValid()) {
291 myDocModel->activatedIndex(aIndex);
292 myTreeView->setExpanded(aIndex, false);
293 onActivePartChanged(ObjectPtr());
298 //***************************************************
299 void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent)
301 myObjectsList = myTreeView->selectedObjects();
302 bool toEnable = myObjectsList.size() == 1;
303 foreach(QAction* aCmd, actions())
305 aCmd->setEnabled(toEnable);
307 emit contextMenuRequested(theEvent);
310 //***************************************************
311 void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt)
313 myObjectsList.clear();
314 //Empty feature pointer means that selected root document
315 myObjectsList.append(ObjectPtr());
317 foreach(QAction* aCmd, actions())
319 aCmd->setEnabled(true);
321 QContextMenuEvent aEvent(QContextMenuEvent::Mouse, thePnt, myActiveDocLbl->mapToGlobal(thePnt));
322 emit contextMenuRequested(&aEvent);
325 //***************************************************
326 void XGUI_ObjectsBrowser::onEditItem()
328 if (myObjectsList.size() > 0) {
329 ObjectPtr aFeature = myObjectsList.first();
330 if (aFeature) { // Selection happens in TreeView
331 // Find index which corresponds the feature
333 foreach(QModelIndex aIdx, selectedIndexes())
335 ObjectPtr aFea = dataModel()->object(aIdx);
336 if (dataModel()->object(aIdx)->isSame(aFeature)) {
341 if (aIndex.isValid()) {
342 myTreeView->setCurrentIndex(aIndex);
343 myTreeView->edit(aIndex);
345 } else { //Selection happens in Upper label
346 myActiveDocLbl->setReadOnly(false);
347 myActiveDocLbl->setFocus();
348 myActiveDocLbl->selectAll();
349 myActiveDocLbl->grabMouse();
350 myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text());
355 //***************************************************
356 void XGUI_ObjectsBrowser::onSelectionChanged()
358 myObjectsList = myTreeView->selectedObjects();
359 emit selectionChanged();
362 //***************************************************
363 void XGUI_ObjectsBrowser::rebuildDataTree()
365 myDocModel->rebuildDataTree();
369 //***************************************************
370 void XGUI_ObjectsBrowser::setObjectsSelected(const QObjectPtrList& theObjects)
372 QList<QModelIndex> theIndexes;
373 QItemSelectionModel* aSelectModel = myTreeView->selectionModel();
374 aSelectModel->clear();
376 foreach(ObjectPtr aFeature, theObjects)
378 QModelIndex aIndex = myDocModel->objectIndex(aFeature);
379 if (aIndex.isValid()) {
380 aSelectModel->select(aIndex, QItemSelectionModel::Select);
385 //***************************************************
386 void XGUI_ObjectsBrowser::processEvent(const std::shared_ptr<Events_Message>& theMessage)
388 myDocModel->processEvent(theMessage);
392 //***************************************************
393 void XGUI_ObjectsBrowser::clearContent()
395 myObjectsList.clear();