Salome HOME
352fa4ba8dd1fdf9f0da2b0fdec87c83a2cd8e37
[modules/shaper.git] / src / XGUI / XGUI_ObjectsBrowser.cpp
1 #include "XGUI_ObjectsBrowser.h"
2 #include "XGUI_DocumentDataModel.h"
3
4 #include <ModelAPI_Data.h>
5 #include <ModelAPI_PluginManager.h>
6 #include <ModelAPI_Document.h>
7
8 #include <QLayout>
9 #include <QLabel>
10 #include <QLineEdit>
11 #include <QPixmap>
12 #include <QEvent>
13 #include <QMouseEvent>
14 #include <QAction>
15
16
17
18 XGUI_DataTree::XGUI_DataTree(QWidget* theParent)
19   : QTreeView(theParent)
20 {
21   setHeaderHidden(true);
22   setModel(new XGUI_DocumentDataModel(this));
23   setEditTriggers(QAbstractItemView::NoEditTriggers);
24
25   connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), 
26           this, SLOT(onSelectionChanged(const QItemSelection&, const QItemSelection&)));
27 }
28
29 XGUI_DataTree::~XGUI_DataTree()
30 {
31 }
32
33 XGUI_DocumentDataModel* XGUI_DataTree::dataModel() const 
34
35   return static_cast<XGUI_DocumentDataModel*>(model()); 
36 }
37
38
39 void XGUI_DataTree::onSelectionChanged(const QItemSelection& theSelected, 
40                                              const QItemSelection& theDeselected)
41 {
42   mySelectedData.clear();
43   QModelIndexList aIndexes = selectionModel()->selectedIndexes();
44   XGUI_DocumentDataModel* aModel = dataModel();
45   QModelIndexList::const_iterator aIt;
46   for (aIt = aIndexes.constBegin(); aIt != aIndexes.constEnd(); ++aIt) {
47     FeaturePtr aFeature = aModel->feature(*aIt);
48     if (aFeature)
49       mySelectedData.append(aFeature);
50   }
51   emit selectionChanged();
52 }
53
54 void XGUI_DataTree::mouseDoubleClickEvent(QMouseEvent* theEvent)
55 {
56   if (theEvent->button() == Qt::LeftButton) {
57     QModelIndex aIndex = currentIndex();
58     XGUI_DocumentDataModel* aModel = dataModel();
59
60     if ((aModel->activePartIndex() != aIndex) && aModel->activePartIndex().isValid()) {
61       setExpanded(aModel->activePartIndex(), false);
62     }
63     bool isChanged = aModel->activatedIndex(aIndex);
64     QTreeView::mouseDoubleClickEvent(theEvent);
65     if (isChanged) {
66       if (aModel->activePartIndex().isValid())
67         setExpanded(aIndex, true);
68       emit activePartChanged(aModel->activePart());
69     }
70   } else 
71     QTreeView::mouseDoubleClickEvent(theEvent);
72 }
73
74 void XGUI_DataTree::contextMenuEvent(QContextMenuEvent* theEvent)
75 {
76   emit contextMenuRequested(theEvent);
77 }
78
79 void XGUI_DataTree::commitData(QWidget* theEditor)
80 {
81   QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
82   if (aEditor) {
83     QString aRes = aEditor->text();
84     FeaturePtr aFeature = mySelectedData.first();
85     aFeature->data()->setName(qPrintable(aRes));
86   }
87 }
88
89 //********************************************************************
90 //********************************************************************
91 //********************************************************************
92 XGUI_ObjectsBrowser::XGUI_ObjectsBrowser(QWidget* theParent)
93   : QWidget(theParent)
94 {
95   QVBoxLayout* aLayout = new QVBoxLayout(this);
96   aLayout->setContentsMargins(0, 0, 0, 0);
97   aLayout->setSpacing(0);
98
99   QFrame* aLabelWgt = new QFrame(this);
100   aLabelWgt->setAutoFillBackground(true);
101   QPalette aPalet = aLabelWgt->palette();
102   aPalet.setColor(QPalette::Window, Qt::white);
103   aLabelWgt->setPalette(aPalet);
104
105   aLayout->addWidget(aLabelWgt);
106   QHBoxLayout* aLabelLay = new QHBoxLayout(aLabelWgt);
107   aLabelLay->setContentsMargins(0, 0, 0, 0);
108   aLabelLay->setSpacing(0);
109
110   QLabel* aLbl = new QLabel(aLabelWgt);
111   aLbl->setPixmap(QPixmap(":pictures/assembly.png"));
112   aLbl->setMargin(2);
113
114   aLbl->setAutoFillBackground(true);
115
116   aLabelLay->addWidget(aLbl);
117
118   PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
119   DocumentPtr aDoc = aMgr->rootDocument();
120   // TODO: Find a name of the root document
121
122   myActiveDocLbl = new QLineEdit(tr("Part set"), aLabelWgt);
123   myActiveDocLbl->setReadOnly(true);
124   myActiveDocLbl->setFrame(false);
125   //myActiveDocLbl->setMargin(2);
126   myActiveDocLbl->setContextMenuPolicy(Qt::CustomContextMenu);
127
128   myActiveDocLbl->installEventFilter(this);
129
130   aLabelLay->addWidget(myActiveDocLbl);
131   aLabelLay->setStretch(1,1);
132
133   myTreeView = new XGUI_DataTree(this);
134   aLayout->addWidget(myTreeView);
135
136   myDocModel = myTreeView->dataModel();
137
138   aLabelWgt->setFrameShape(myTreeView->frameShape());
139   aLabelWgt->setFrameShadow(myTreeView->frameShadow());
140
141   connect(myTreeView, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
142   connect(myTreeView, SIGNAL(activePartChanged(FeaturePtr)), this, SLOT(onActivePartChanged(FeaturePtr)));
143   connect(myTreeView, SIGNAL(activePartChanged(FeaturePtr)), this, SIGNAL(activePartChanged(FeaturePtr)));
144
145   connect(myActiveDocLbl, SIGNAL(customContextMenuRequested(const QPoint&)), 
146           this, SLOT(onLabelContextMenuRequested(const QPoint&)));
147   connect(myTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*)), 
148           this, SLOT(onContextMenuRequested(QContextMenuEvent*)));
149   
150   onActivePartChanged(FeaturePtr());
151
152   // Create internal actions
153   QAction* aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
154   aAction->setData("RENAME_CMD");
155   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onEditItem()));
156   addAction(aAction);
157 }
158
159 //***************************************************
160 XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser()
161 {
162 }
163
164 //***************************************************
165 void XGUI_ObjectsBrowser::onActivePartChanged(FeaturePtr thePart)
166 {
167   QPalette aPalet = myActiveDocLbl->palette();
168   if (thePart) {
169     aPalet.setColor(QPalette::Text, Qt::black);
170   }  else {
171     aPalet.setColor(QPalette::Text, QColor(0, 72, 140));
172   }
173   myActiveDocLbl->setPalette(aPalet);
174 }
175
176 //***************************************************
177 bool XGUI_ObjectsBrowser::eventFilter(QObject* obj, QEvent* theEvent)
178 {
179   if (obj == myActiveDocLbl) {
180     if (myActiveDocLbl->isReadOnly()) {
181       if (theEvent->type() == QEvent::MouseButtonDblClick) {
182         if (myDocModel->activePartIndex().isValid()) {
183           myTreeView->setExpanded(myDocModel->activePartIndex(), false);
184         }
185         myDocModel->deactivatePart();
186         onActivePartChanged(FeaturePtr());
187         emit activePartChanged(FeaturePtr());
188       }
189     } else {
190       // End of editing by mouse click
191       if (theEvent->type() == QEvent::MouseButtonRelease) {
192         QMouseEvent* aEvent = (QMouseEvent*) theEvent;
193         QPoint aPnt = mapFromGlobal(aEvent->globalPos());
194         if (childAt(aPnt) != myActiveDocLbl) {
195           closeDocNameEditing(true);
196         }
197       } else if (theEvent->type() == QEvent::KeyRelease) {
198         QKeyEvent* aEvent = (QKeyEvent*) theEvent;
199         switch (aEvent->key()) {
200         case Qt::Key_Return: // 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     PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
223     DocumentPtr aDoc = aMgr->rootDocument();
224   } else {
225     myActiveDocLbl->setText(myActiveDocLbl->property("OldText").toString());
226   }
227 }
228
229 //***************************************************
230 void XGUI_ObjectsBrowser::activatePart(const FeaturePtr& thePart)
231 {
232   if (thePart) {
233     QModelIndex aIndex = myDocModel->partIndex(thePart);
234
235     if ((myDocModel->activePartIndex() != aIndex) && myDocModel->activePartIndex().isValid()) {
236       myTreeView->setExpanded(myDocModel->activePartIndex(), false);
237     }
238     bool isChanged = myDocModel->activatedIndex(aIndex);
239     if (isChanged) {
240       if (myDocModel->activePartIndex().isValid()) {
241         myTreeView->setExpanded(aIndex.parent(), true);
242         myTreeView->setExpanded(aIndex, true);
243         onActivePartChanged(myDocModel->feature(aIndex));
244       } else {
245         onActivePartChanged(FeaturePtr());
246       }
247     }
248   } else {
249     QModelIndex aIndex = myDocModel->activePartIndex();
250     if (aIndex.isValid()) {
251       myDocModel->activatedIndex(aIndex);
252       myTreeView->setExpanded(aIndex, false);
253       onActivePartChanged(FeaturePtr());
254     }
255   }
256 }
257
258 //***************************************************
259 void XGUI_ObjectsBrowser::onContextMenuRequested(QContextMenuEvent* theEvent) 
260 {
261   myFeaturesList = myTreeView->selectedFeatures();
262   bool toEnable = myFeaturesList.size() > 0;
263   foreach(QAction* aCmd, actions()) {
264     aCmd->setEnabled(toEnable);
265   }
266   emit contextMenuRequested(theEvent);
267 }
268
269 //***************************************************
270 void XGUI_ObjectsBrowser::onLabelContextMenuRequested(const QPoint& thePnt)
271 {
272   myFeaturesList.clear();
273   //Empty feature pointer means that selected root document
274   myFeaturesList.append(FeaturePtr()); 
275
276   foreach(QAction* aCmd, actions()) {
277     aCmd->setEnabled(true);
278   }
279   QContextMenuEvent aEvent( QContextMenuEvent::Mouse, thePnt, myActiveDocLbl->mapToGlobal(thePnt) );
280   emit contextMenuRequested(&aEvent);
281 }
282
283 //***************************************************
284 void XGUI_ObjectsBrowser::onEditItem()
285 {
286   if (myFeaturesList.size() > 0) {
287     FeaturePtr aFeature = myFeaturesList.first();
288     if (aFeature) { // Selection happens in TreeView
289       // Find index which corresponds the feature
290       QModelIndex aIndex;
291       foreach(QModelIndex aIdx, selectedIndexes()) {
292         if (dataModel()->feature(aIdx) == aFeature) {
293           aIndex = aIdx;
294           break;
295         }
296       }
297       if (aIndex.isValid()) {
298         myTreeView->setCurrentIndex(aIndex);
299         myTreeView->edit(aIndex);
300       }
301     } else { //Selection happens in Upper label
302       myActiveDocLbl->setReadOnly(false);
303       myActiveDocLbl->setFocus();
304       myActiveDocLbl->selectAll();
305       myActiveDocLbl->grabMouse();
306       myActiveDocLbl->setProperty("OldText", myActiveDocLbl->text());
307     }
308   }
309 }