]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_ObjectsBrowser.cpp
Salome HOME
3851b9fbee9fe2cbde17b715993c6bbeef8167ee
[modules/shaper.git] / src / XGUI / XGUI_ObjectsBrowser.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 #include "XGUI_ObjectsBrowser.h"
4 #include "XGUI_Tools.h"
5
6 #include <ModelAPI_Data.h>
7 #include <ModelAPI_Session.h>
8 #include <ModelAPI_Document.h>
9
10 #include <ModuleBase_Tools.h>
11 #include <ModuleBase_IDocumentDataModel.h>
12
13 #include <QLayout>
14 #include <QLabel>
15 #include <QLineEdit>
16 #include <QPixmap>
17 #include <QEvent>
18 #include <QMouseEvent>
19 #include <QAction>
20 #include <QStyledItemDelegate>
21
22
23 /// Width of second column (minimum acceptable = 27)
24 #define SECOND_COL_WIDTH 30
25
26
27 /**
28 * \ingroup GUI
29 * Tree item delegate for definition of data in column items editor
30 */
31 class XGUI_TreeViewItemDelegate: public QStyledItemDelegate
32 {
33 public:
34   /// Constructor
35   /// \param theParent a parent of the delegate
36   XGUI_TreeViewItemDelegate(XGUI_DataTree* theParent):QStyledItemDelegate(theParent), myTreedView(theParent) {}
37
38   /// Set data for item editor (name of the item)
39   /// \param editor a widget of editor
40   /// \param index the tree item index
41   virtual void  setEditorData ( QWidget* editor, const QModelIndex& index ) const
42   {
43     QLineEdit* aEditor = dynamic_cast<QLineEdit*>(editor);
44     if (aEditor) {
45       ModuleBase_IDocumentDataModel* aModel = myTreedView->dataModel();
46       ObjectPtr aObj = aModel->object(index);
47       if (aObj.get() != NULL) {
48         aEditor->setText(aObj->data()->name().c_str());
49         return;
50       }
51     }
52     QStyledItemDelegate::setEditorData(editor, index);
53   }
54
55 private:
56   XGUI_DataTree* myTreedView;
57 };
58
59
60 XGUI_DataTree::XGUI_DataTree(QWidget* theParent)
61     : QTreeView(theParent)
62 {
63   setHeaderHidden(true);
64   setEditTriggers(QAbstractItemView::NoEditTriggers);
65   setSelectionBehavior(QAbstractItemView::SelectRows);
66   setSelectionMode(QAbstractItemView::ExtendedSelection);
67
68   setItemDelegateForColumn(0, new XGUI_TreeViewItemDelegate(this));
69 }
70
71 XGUI_DataTree::~XGUI_DataTree()
72 {
73 }
74
75 ModuleBase_IDocumentDataModel* XGUI_DataTree::dataModel() const
76 {
77   return static_cast<ModuleBase_IDocumentDataModel*>(model());
78 }
79
80 void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent)
81 {
82   emit contextMenuRequested(theEvent);
83 }
84
85 void XGUI_DataTree::commitData(QWidget* theEditor)
86 {
87   QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
88   if (aEditor) {
89     QString aRes = aEditor->text();
90     QModelIndexList aIndexList = selectionModel()->selectedIndexes();
91     ModuleBase_IDocumentDataModel* aModel = dataModel();
92     ObjectPtr aObj = aModel->object(aIndexList.first());
93     SessionPtr aMgr = ModelAPI_Session::get();
94     aMgr->startOperation("Rename");
95     aObj->data()->setName(qPrintable(aRes));
96     aMgr->finishOperation();
97   }
98 }
99
100 void XGUI_DataTree::clear() 
101 {
102   ModuleBase_IDocumentDataModel* aModel = dataModel();
103   aModel->clear();
104   reset();
105 }
106
107 void XGUI_DataTree::resizeEvent(QResizeEvent* theEvent)
108 {
109   QSize aSize = theEvent->size();
110   if (aSize.isValid()) {
111     setColumnWidth(0, aSize.width() - SECOND_COL_WIDTH);
112     setColumnWidth(1, SECOND_COL_WIDTH);
113   }
114 }
115
116
117 //********************************************************************
118 //********************************************************************
119 //********************************************************************
120 XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent)
121     : QWidget(theParent), myDocModel(0)
122 {
123   QVBoxLayout* aLayout = new QVBoxLayout(this);
124   ModuleBase_Tools::zeroMargins(aLayout);
125   aLayout->setSpacing(0);
126
127   QFrame* aLabelWgt = new QFrame(this);
128   aLabelWgt->setAutoFillBackground(true);
129   QPalette aPalet = aLabelWgt->palette();
130   aPalet.setColor(QPalette::Window, Qt::white);
131   aLabelWgt->setPalette(aPalet);
132
133   aLayout->addWidget(aLabelWgt);
134   QHBoxLayout* aLabelLay = new QHBoxLayout(aLabelWgt);
135   ModuleBase_Tools::zeroMargins(aLabelLay);
136   aLabelLay->setSpacing(0);
137
138   QLabel* aLbl = new QLabel(aLabelWgt);
139   aLbl->setPixmap(QPixmap(":pictures/assembly.png"));
140   aLbl->setMargin(2);
141
142   aLbl->setAutoFillBackground(true);
143
144   aLabelLay->addWidget(aLbl);
145
146   SessionPtr aMgr = ModelAPI_Session::get();
147   DocumentPtr aDoc = aMgr->moduleDocument();
148   // TODO: Find a name of the root document
149
150   myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt);
151   myActiveDocLbl->setReadOnly(true);
152   myActiveDocLbl->setFrame(false);
153   //myActiveDocLbl->setMargin(2);
154   myActiveDocLbl->setContextMenuPolicy(Qt::CustomContextMenu);
155
156   myActiveDocLbl->installEventFilter(this);
157
158   aLabelLay->addWidget(myActiveDocLbl);
159   aLabelLay->setStretch(1, 1);
160
161   myTreeView = new XGUI_DataTree(this);
162   aLayout->addWidget(myTreeView);
163
164   aLabelWgt->setFrameShape(myTreeView->frameShape());
165   aLabelWgt->setFrameShadow(myTreeView->frameShadow());
166
167   connect(myActiveDocLbl, SIGNAL(customContextMenuRequested(const QPoint&)), this,
168           SLOT(onLabelContextMenuRequested(const QPoint&)));
169   connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
170           SLOT(onContextMenuRequested(QContextMenuEvent*)));
171
172   // Create internal actions
173   QAction* aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
174   aAction->setData("RENAME_CMD");
175   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem()));
176   addAction(aAction);
177 }
178
179 //***************************************************
180 XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser()
181 {
182 }
183
184 //***************************************************
185 bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent)
186 {
187   if (obj == myActiveDocLbl) {
188     if (!myActiveDocLbl->isReadOnly()) {
189       // End of editing by mouse click
190       if (theEvent->type() == QEvent::MouseButtonRelease) {
191         QMouseEvent* aEvent = (QMouseEvent*) theEvent;
192         QPoint aPnt = mapFromGlobal(aEvent->globalPos());
193         if (childAt(aPnt) != myActiveDocLbl) {
194           closeDocNameEditing(true);
195         }
196       } else if (theEvent->type() == QEvent::KeyRelease) {
197         QKeyEvent* aEvent = (QKeyEvent*) theEvent;
198         switch (aEvent->key()) {
199           case Qt::Key_Return:
200           case Qt::Key_Enter:  // Accept current input
201             closeDocNameEditing(true);
202             break;
203           case Qt::Key_Escape:  // Cancel the input
204             closeDocNameEditing(false);
205             break;
206         }
207       }
208     }
209   }
210   return QWidget::eventFilter(obj, theEvent);
211 }
212
213 //***************************************************
214 void XGUI_ObjectsBrowser::closeDocNameEditing(bool toSave)
215 {
216   myActiveDocLbl->deselect();
217   myActiveDocLbl->clearFocus();
218   myActiveDocLbl->releaseMouse();
219   myActiveDocLbl->setReadOnly(true);
220   if (toSave) {
221     // TODO: Save the name of root document
222     SessionPtr aMgr = ModelAPI_Session::get();
223     DocumentPtr aDoc = aMgr->moduleDocument();
224   } else {
225     myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString());
226   }
227 }
228
229 //***************************************************
230 void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent)
231 {
232   bool toEnable = mySelectedData.size() == 1;
233   foreach(QAction* aCmd, actions())
234   {
235     aCmd->setEnabled(toEnable);
236   }
237   emit contextMenuRequested(theEvent);
238 }
239
240 //***************************************************
241 void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt)
242 {
243   mySelectedData.clear();
244   //Empty feature pointer means that selected root document
245   mySelectedData.append(ObjectPtr());
246
247   foreach(QAction* aCmd, actions())
248   {
249     aCmd->setEnabled(true);
250   }
251   QContextMenuEvent aEvent(QContextMenuEvent::Mouse, thePnt, myActiveDocLbl->mapToGlobal(thePnt));
252   emit contextMenuRequested(&aEvent);
253 }
254
255 //***************************************************
256 void XGUI_ObjectsBrowser::onEditItem()
257 {
258   if (mySelectedData.size() > 0) {
259     ObjectPtr aFeature = mySelectedData.first();
260     if (aFeature) {  // Selection happens in TreeView
261       // Find index which corresponds the feature
262       QModelIndex aIndex;
263       foreach(QModelIndex aIdx, selectedIndexes())
264       {
265         ObjectPtr aFea = dataModel()->object(aIdx);
266         if (dataModel()->object(aIdx)->isSame(aFeature)) {
267           aIndex = aIdx;
268           break;
269         }
270       }
271       if (aIndex.isValid()) {
272         myTreeView->setCurrentIndex(aIndex);
273         myTreeView->edit(aIndex);
274       }
275     } else {  //Selection happens in Upper label
276       myActiveDocLbl->setReadOnly(false);
277       myActiveDocLbl->setFocus();
278       myActiveDocLbl->selectAll();
279       myActiveDocLbl->grabMouse();
280       myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text());
281     }
282   }
283 }
284
285 //***************************************************
286 void XGUI_ObjectsBrowser::rebuildDataTree()
287 {
288   myDocModel->rebuildDataTree();
289   update();
290 }
291
292 //***************************************************
293 void XGUI_ObjectsBrowser::setObjectsSelected(const QObjectPtrList& theObjects)
294 {
295   QList<QModelIndex> theIndexes;
296   QItemSelectionModel* aSelectModel = myTreeView->selectionModel();
297   aSelectModel->clear();
298
299   foreach(ObjectPtr aFeature, theObjects)
300   {
301     QModelIndex aIndex = myDocModel->objectIndex(aFeature);
302     if (aIndex.isValid()) {
303       aSelectModel->select(aIndex, QItemSelectionModel::Select);
304     }
305   }
306 }
307
308 //***************************************************
309 void XGUI_ObjectsBrowser::clearContent()  
310
311   mySelectedData.clear();
312   myTreeView->clear(); 
313 }
314
315 void XGUI_ObjectsBrowser::setDataModel(ModuleBase_IDocumentDataModel* theModel)
316 {
317   myDocModel = theModel;
318   myTreeView->setModel(myDocModel);
319   QItemSelectionModel* aSelMod = myTreeView->selectionModel();
320   connect(aSelMod, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
321           this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
322 }
323
324 void XGUI_ObjectsBrowser::onSelectionChanged(const QItemSelection& theSelected,
325                                        const QItemSelection& theDeselected)
326 {
327   mySelectedData.clear();
328   QModelIndexList aIndexes = myTreeView->selectionModel()->selectedIndexes();
329   ModuleBase_IDocumentDataModel* aModel = dataModel();
330   QModelIndexList::const_iterator aIt;
331   for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
332     if ((*aIt).column() == 0) {
333       ObjectPtr aObject = aModel->object(*aIt);
334       if (aObject)
335         mySelectedData.append(aObject);
336     }
337   }
338   emit selectionChanged();
339 }