1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 #include "XGUI_ObjectsBrowser.h"
4 #include "XGUI_Tools.h"
6 #include <ModelAPI_Data.h>
7 #include <ModelAPI_Session.h>
8 #include <ModelAPI_Document.h>
9 #include <ModelAPI_Tools.h>
11 #include <ModuleBase_Tools.h>
12 #include <ModuleBase_IDocumentDataModel.h>
19 #include <QMouseEvent>
21 #include <QStyledItemDelegate>
22 #include <QMessageBox>
24 /// Width of second column (minimum acceptable = 27)
25 #define SECOND_COL_WIDTH 30
30 * Tree item delegate for definition of data in column items editor
32 class XGUI_TreeViewItemDelegate: public QStyledItemDelegate
36 /// \param theParent a parent of the delegate
37 XGUI_TreeViewItemDelegate(XGUI_DataTree* theParent):QStyledItemDelegate(theParent), myTreedView(theParent) {}
39 /// Set data for item editor (name of the item)
40 /// \param editor a widget of editor
41 /// \param index the tree item index
42 virtual void setEditorData ( QWidget* editor, const QModelIndex& index ) const
44 QLineEdit* aEditor = dynamic_cast<QLineEdit*>(editor);
46 ModuleBase_IDocumentDataModel* aModel = myTreedView->dataModel();
47 ObjectPtr aObj = aModel->object(index);
48 if (aObj.get() != NULL) {
49 aEditor->setText(aObj->data()->name().c_str());
53 QStyledItemDelegate::setEditorData(editor, index);
57 XGUI_DataTree* myTreedView;
61 XGUI_DataTree::XGUI_DataTree(QWidget* theParent)
62 : QTreeView(theParent)
64 setHeaderHidden(true);
65 setEditTriggers(QAbstractItemView::NoEditTriggers);
66 setSelectionBehavior(QAbstractItemView::SelectRows);
67 setSelectionMode(QAbstractItemView::ExtendedSelection);
69 setItemDelegateForColumn(0, new XGUI_TreeViewItemDelegate(this));
72 XGUI_DataTree::~XGUI_DataTree()
76 ModuleBase_IDocumentDataModel* XGUI_DataTree::dataModel() const
78 return static_cast<ModuleBase_IDocumentDataModel*>(model());
81 void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent)
83 emit contextMenuRequested(theEvent);
86 void XGUI_DataTree::commitData(QWidget* theEditor)
88 QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
90 QString aName = aEditor->text();
91 QModelIndexList aIndexList = selectionModel()->selectedIndexes();
92 ModuleBase_IDocumentDataModel* aModel = dataModel();
93 ObjectPtr aObj = aModel->object(aIndexList.first());
94 SessionPtr aMgr = ModelAPI_Session::get();
95 aMgr->startOperation("Rename");
97 if (!canRename(aObj, aName)) {
98 aMgr->abortOperation();
102 aObj->data()->setName(qPrintable(aName));
103 aMgr->finishOperation();
107 bool XGUI_DataTree::canRename(const ObjectPtr& theObject, const QString& theName)
110 ResultParameterPtr aParam;
112 bool isVariableFound = ModelAPI_Tools::findVariable(theObject->document(), qPrintable(theName), aValue, aParam);
115 QMessageBox::information(this, tr("Rename parameter"),
116 QString(tr("Selected parameter can not be renamed to: %1. \
117 There is a parameter with the same name. Its value is: %2.")).arg(qPrintable(theName)).arg(aValue));
119 return !isVariableFound;
122 void XGUI_DataTree::clear()
124 ModuleBase_IDocumentDataModel* aModel = dataModel();
129 void XGUI_DataTree::resizeEvent(QResizeEvent* theEvent)
131 QSize aSize = theEvent->size();
132 if (aSize.isValid()) {
133 setColumnWidth(0, aSize.width() - SECOND_COL_WIDTH);
134 setColumnWidth(1, SECOND_COL_WIDTH);
139 //********************************************************************
140 //********************************************************************
141 //********************************************************************
142 XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent)
143 : QWidget(theParent), myDocModel(0)
145 QVBoxLayout* aLayout = new QVBoxLayout(this);
146 ModuleBase_Tools::zeroMargins(aLayout);
147 aLayout->setSpacing(0);
149 QFrame* aLabelWgt = new QFrame(this);
150 aLabelWgt->setAutoFillBackground(true);
151 QPalette aPalet = aLabelWgt->palette();
152 aPalet.setColor(QPalette::Window, Qt::white);
153 aLabelWgt->setPalette(aPalet);
155 aLayout->addWidget(aLabelWgt);
156 QHBoxLayout* aLabelLay = new QHBoxLayout(aLabelWgt);
157 ModuleBase_Tools::zeroMargins(aLabelLay);
158 aLabelLay->setSpacing(0);
160 QLabel* aLbl = new QLabel(aLabelWgt);
161 aLbl->setPixmap(QPixmap(":pictures/assembly.png"));
164 aLbl->setAutoFillBackground(true);
166 aLabelLay->addWidget(aLbl);
168 SessionPtr aMgr = ModelAPI_Session::get();
169 DocumentPtr aDoc = aMgr->moduleDocument();
170 // TODO: Find a name of the root document
172 myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt);
173 myActiveDocLbl->setReadOnly(true);
174 myActiveDocLbl->setFrame(false);
175 //myActiveDocLbl->setMargin(2);
176 myActiveDocLbl->setContextMenuPolicy(Qt::CustomContextMenu);
178 myActiveDocLbl->installEventFilter(this);
180 aLabelLay->addWidget(myActiveDocLbl);
181 aLabelLay->setStretch(1, 1);
183 myTreeView = new XGUI_DataTree(this);
184 aLayout->addWidget(myTreeView);
186 aLabelWgt->setFrameShape(myTreeView->frameShape());
187 aLabelWgt->setFrameShadow(myTreeView->frameShadow());
189 connect(myActiveDocLbl, SIGNAL(customContextMenuRequested(const QPoint&)), this,
190 SLOT(onLabelContextMenuRequested(const QPoint&)));
191 connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
192 SLOT(onContextMenuRequested(QContextMenuEvent*)));
194 // Create internal actions
195 QAction* aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
196 aAction->setData("RENAME_CMD");
197 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem()));
201 //***************************************************
202 XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser()
206 //***************************************************
207 bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent)
209 if (obj == myActiveDocLbl) {
210 if (!myActiveDocLbl->isReadOnly()) {
211 // End of editing by mouse click
212 if (theEvent->type() == QEvent::MouseButtonRelease) {
213 QMouseEvent* aEvent = (QMouseEvent*) theEvent;
214 QPoint aPnt = mapFromGlobal(aEvent->globalPos());
215 if (childAt(aPnt) != myActiveDocLbl) {
216 closeDocNameEditing(true);
218 } else if (theEvent->type() == QEvent::KeyRelease) {
219 QKeyEvent* aEvent = (QKeyEvent*) theEvent;
220 switch (aEvent->key()) {
222 case Qt::Key_Enter: // Accept current input
223 closeDocNameEditing(true);
225 case Qt::Key_Escape: // Cancel the input
226 closeDocNameEditing(false);
231 if (theEvent->type() == QEvent::MouseButtonDblClick) {
232 emit headerMouseDblClicked(QModelIndex());
237 return QWidget::eventFilter(obj, theEvent);
240 //***************************************************
241 void XGUI_ObjectsBrowser::closeDocNameEditing(bool toSave)
243 myActiveDocLbl->deselect();
244 myActiveDocLbl->clearFocus();
245 myActiveDocLbl->releaseMouse();
246 myActiveDocLbl->setReadOnly(true);
248 // TODO: Save the name of root document
249 SessionPtr aMgr = ModelAPI_Session::get();
250 DocumentPtr aDoc = aMgr->moduleDocument();
252 myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString());
256 //***************************************************
257 void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent)
259 QModelIndexList aIndexes;
260 QObjectPtrList aSelectedData = selectedObjects(&aIndexes);
261 bool toEnable = false;
262 if (aSelectedData.size() == 1) {
263 Qt::ItemFlags aFlags = dataModel()->flags(aIndexes.first());
264 toEnable = ((aFlags & Qt::ItemIsEditable) != 0);
266 foreach(QAction* aCmd, actions()) {
267 aCmd->setEnabled(toEnable);
269 emit contextMenuRequested(theEvent);
272 //***************************************************
273 void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt)
275 myTreeView->selectionModel()->clearSelection();
276 //Empty feature pointer means that selected root document
277 foreach(QAction* aCmd, actions()) {
278 aCmd->setEnabled(true);
280 QContextMenuEvent aEvent(QContextMenuEvent::Mouse, thePnt, myActiveDocLbl->mapToGlobal(thePnt));
281 emit contextMenuRequested(&aEvent);
284 //***************************************************
285 void XGUI_ObjectsBrowser::onEditItem()
287 QObjectPtrList aSelectedData = selectedObjects();
288 if (aSelectedData.size() > 0) {
289 ObjectPtr aFeature = aSelectedData.first();
290 if (aFeature) { // Selection happens in TreeView
291 QObjectPtrList aList;
292 aList.append(aFeature);
293 // check whether the object can be deleted. There should not be parts which are not loaded
294 if (!XGUI_Tools::canRemoveOrRename((QWidget*)parent(), aList))
297 // Find index which corresponds the feature
299 foreach(QModelIndex aIdx, selectedIndexes()) {
300 ObjectPtr aFea = dataModel()->object(aIdx);
301 if (dataModel()->object(aIdx)->isSame(aFeature)) {
306 if (aIndex.isValid()) {
307 myTreeView->setCurrentIndex(aIndex);
308 myTreeView->edit(aIndex);
313 //Selection happens in Upper label
314 myActiveDocLbl->setReadOnly(false);
315 myActiveDocLbl->setFocus();
316 myActiveDocLbl->selectAll();
317 myActiveDocLbl->grabMouse();
318 myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text());
321 //***************************************************
322 void XGUI_ObjectsBrowser::rebuildDataTree()
324 myDocModel->rebuildDataTree();
328 //***************************************************
329 void XGUI_ObjectsBrowser::setObjectsSelected(const QObjectPtrList& theObjects)
331 QList<QModelIndex> theIndexes;
332 QItemSelectionModel* aSelectModel = myTreeView->selectionModel();
333 aSelectModel->clear();
335 foreach(ObjectPtr aFeature, theObjects)
337 QModelIndex aIndex = myDocModel->objectIndex(aFeature);
338 if (aIndex.isValid()) {
339 aSelectModel->select(aIndex, QItemSelectionModel::Select);
344 //***************************************************
345 void XGUI_ObjectsBrowser::clearContent()
350 void XGUI_ObjectsBrowser::setDataModel(ModuleBase_IDocumentDataModel* theModel)
352 myDocModel = theModel;
353 myTreeView->setModel(myDocModel);
354 QItemSelectionModel* aSelMod = myTreeView->selectionModel();
355 connect(aSelMod, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
356 this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
359 void XGUI_ObjectsBrowser::onSelectionChanged(const QItemSelection& theSelected,
360 const QItemSelection& theDeselected)
362 emit selectionChanged();
365 QObjectPtrList XGUI_ObjectsBrowser::selectedObjects(QModelIndexList* theIndexes) const
367 QObjectPtrList aList;
368 QModelIndexList aIndexes = selectedIndexes();
369 ModuleBase_IDocumentDataModel* aModel = dataModel();
370 QModelIndexList::const_iterator aIt;
371 for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
372 if ((*aIt).column() == 0) {
373 ObjectPtr aObject = aModel->object(*aIt);
375 aList.append(aObject);
377 theIndexes->append(*aIt);