]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_PropertyPanel.cpp
Salome HOME
Merge tag 'V_1.3.1' into HEAD
[modules/shaper.git] / src / XGUI / XGUI_PropertyPanel.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 /*
4  * XGUI_PropertyPanel.cpp
5  *
6  *  Created on: Apr 29, 2014
7  *      Author: sbh
8  */
9
10 #include <XGUI_PropertyPanel.h>
11 #include <XGUI_ActionsMgr.h>
12 //#include <AppElements_Constants.h>
13 #include <ModuleBase_WidgetMultiSelector.h>
14 #include <ModuleBase_Tools.h>
15 #include <ModuleBase_PageBase.h>
16 #include <ModuleBase_PageWidget.h>
17
18 #include <QEvent>
19 #include <QFrame>
20 #include <QIcon>
21 #include <QKeyEvent>
22 #include <QLayoutItem>
23 #include <QToolButton>
24 #include <QVBoxLayout>
25 #include <QGridLayout>
26 #include <QWidget>
27 #include <QToolButton>
28 #include <QAction>
29
30 #ifdef _DEBUG
31 #include <iostream>
32 #endif
33
34 XGUI_PropertyPanel::XGUI_PropertyPanel(QWidget* theParent)
35     : ModuleBase_IPropertyPanel(theParent), 
36     myActiveWidget(NULL),
37     myPreselectionWidget(NULL),
38     myPanelPage(NULL)
39 {
40   this->setWindowTitle(tr("Property Panel"));
41   QAction* aViewAct = this->toggleViewAction();
42   this->setObjectName(PROP_PANEL);
43   setStyleSheet("::title { position: relative; padding-left: 5px; text-align: left center }");
44
45   QWidget* aContent = new QWidget(this);
46   QGridLayout* aMainLayout = new QGridLayout(aContent);
47   const int kPanelColumn = 0;
48   int aPanelRow = 0;
49   aMainLayout->setContentsMargins(3, 3, 3, 3);
50   this->setWidget(aContent);
51
52   QFrame* aFrm = new QFrame(aContent);
53   aFrm->setFrameStyle(QFrame::Raised);
54   aFrm->setFrameShape(QFrame::Panel);
55   QHBoxLayout* aBtnLay = new QHBoxLayout(aFrm);
56   ModuleBase_Tools::zeroMargins(aBtnLay);
57   aMainLayout->addWidget(aFrm, aPanelRow++, kPanelColumn);
58
59   QStringList aBtnNames;
60   aBtnNames << QString(PROP_PANEL_HELP)
61             << QString(PROP_PANEL_OK)
62             << QString(PROP_PANEL_CANCEL);
63   foreach(QString eachBtnName, aBtnNames) {
64     QToolButton* aBtn = new QToolButton(aFrm);
65     aBtn->setObjectName(eachBtnName);
66     aBtn->setAutoRaise(true);
67     aBtnLay->addWidget(aBtn);
68   }
69   aBtnLay->insertStretch(1, 1);
70
71   myPanelPage = new ModuleBase_PageWidget(aContent);
72   myPanelPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
73   aMainLayout->addWidget(myPanelPage, aPanelRow, kPanelColumn);
74 }
75
76 XGUI_PropertyPanel::~XGUI_PropertyPanel()
77 {
78 }
79
80 void XGUI_PropertyPanel::cleanContent()
81 {
82   if (myActiveWidget)
83     myActiveWidget->deactivate();
84   myWidgets.clear();
85   myPanelPage->clearPage();
86   myActiveWidget = NULL;
87   setWindowTitle(tr("Property Panel"));
88 }
89
90 void XGUI_PropertyPanel::setModelWidgets(const QList<ModuleBase_ModelWidget*>& theWidgets)
91 {
92   myWidgets = theWidgets;
93   if (theWidgets.empty()) return;
94   foreach (ModuleBase_ModelWidget* aWidget, theWidgets) {
95     connect(aWidget, SIGNAL(focusInWidget(ModuleBase_ModelWidget*)),
96             this,    SLOT(activateWidget(ModuleBase_ModelWidget*)));
97     connect(aWidget, SIGNAL(focusOutWidget(ModuleBase_ModelWidget*)),
98             this,    SLOT(activateNextWidget(ModuleBase_ModelWidget*)));
99     connect(aWidget, SIGNAL(keyReleased(QKeyEvent*)),
100             this,    SIGNAL(keyReleased(QKeyEvent*)));
101   }
102   ModuleBase_ModelWidget* aLastWidget = theWidgets.last();
103   if (aLastWidget) {
104     QList<QWidget*> aControls = aLastWidget->getControls();
105     if (!aControls.empty()) {
106       QWidget* aLastControl = aControls.last();
107
108       QToolButton* anOkBtn = findChild<QToolButton*>(PROP_PANEL_OK);
109       QToolButton* aCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
110
111       setTabOrder(aLastControl, anOkBtn);
112       setTabOrder(anOkBtn, aCancelBtn);
113     }
114   }
115 }
116
117 const QList<ModuleBase_ModelWidget*>& XGUI_PropertyPanel::modelWidgets() const
118 {
119   return myWidgets;
120 }
121
122 ModuleBase_PageBase* XGUI_PropertyPanel::contentWidget()
123 {
124
125   return static_cast<ModuleBase_PageBase*>(myPanelPage);
126 }
127
128 void XGUI_PropertyPanel::updateContentWidget(FeaturePtr theFeature)
129 {
130   // Invalid feature case on abort of the operation
131   if (theFeature.get() == NULL)
132     return;
133   if (theFeature->isAction() || !theFeature->data())
134     return;
135   foreach(ModuleBase_ModelWidget* eachWidget, myWidgets) {
136     if (!eachWidget->feature().get())
137       eachWidget->setFeature(theFeature);
138     eachWidget->restoreValue();
139   }
140   // the repaint is used here to immediately react in GUI to the values change.
141   repaint();
142 }
143
144 void XGUI_PropertyPanel::activateNextWidget(ModuleBase_ModelWidget* theWidget)
145 {
146   // TO CHECK: Editing operation does not have automatical activation of widgets
147   if (isEditingMode()) {
148     activateWidget(NULL);
149     return;
150   }
151   ModuleBase_ModelWidget* aNextWidget = 0;
152   QList<ModuleBase_ModelWidget*>::const_iterator anIt = myWidgets.begin(), aLast = myWidgets.end();
153   bool isFoundWidget = false;
154   for (; anIt != aLast && !aNextWidget; anIt++) {
155     if (isFoundWidget || !theWidget) {
156       if ((*anIt)->focusTo()) {
157         aNextWidget = *anIt;
158       }
159     }
160     isFoundWidget = (*anIt) == theWidget;
161   }
162   // Normaly focusTo is enough to activate widget
163   // here is a special case on mouse click in the viewer
164   if(aNextWidget == NULL) {
165     activateWidget(aNextWidget);
166   }
167 }
168
169 void XGUI_PropertyPanel::activateNextWidget()
170 {
171   activateNextWidget(myActiveWidget);
172 }
173
174 void XGUI_PropertyPanel::activateWidget(ModuleBase_ModelWidget* theWidget)
175 {
176   // Avoid activation of already actve widget. It could happen on focusIn event many times
177   if (theWidget == myActiveWidget) {
178     return;
179   }
180   if(myActiveWidget) {
181     myActiveWidget->deactivate();
182     myActiveWidget->setHighlighted(false);
183   }
184   if(theWidget) {
185     emit beforeWidgetActivated(theWidget);
186     theWidget->setHighlighted(true);
187     theWidget->activate();
188   }
189   myActiveWidget = theWidget;
190   if (myActiveWidget) {
191     emit widgetActivated(theWidget);
192   } else if (!isEditingMode()) {
193     emit noMoreWidgets();
194   }
195 }
196
197 void XGUI_PropertyPanel::setCancelEnabled(bool theEnabled)
198 {
199   QToolButton* anCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
200   anCancelBtn->setEnabled(theEnabled);
201 }
202
203 bool XGUI_PropertyPanel::isCancelEnabled() const
204 {
205   QToolButton* anCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
206   return anCancelBtn->isEnabled();
207 }
208
209 void XGUI_PropertyPanel::setEditingMode(bool isEditing)
210 {
211   ModuleBase_IPropertyPanel::setEditingMode(isEditing);
212   foreach(ModuleBase_ModelWidget* aWgt, myWidgets) {
213     aWgt->setEditingMode(isEditing);
214   }
215 }
216
217 void XGUI_PropertyPanel::setupActions(XGUI_ActionsMgr* theMgr)
218 {
219   QStringList aButtonNames;
220   aButtonNames << PROP_PANEL_OK << PROP_PANEL_CANCEL << PROP_PANEL_HELP;
221   QList<XGUI_ActionsMgr::OperationStateActionId> aActionIds;
222   aActionIds << XGUI_ActionsMgr::Accept << XGUI_ActionsMgr::Abort << XGUI_ActionsMgr::Help;
223   for (int i = 0; i < aButtonNames.size(); ++i) {
224     QToolButton* aBtn = findChild<QToolButton*>(aButtonNames.at(i));
225     QAction* anAct = theMgr->operationStateAction(aActionIds.at(i));
226     aBtn->setDefaultAction(anAct);
227   }
228 }
229
230 ModuleBase_ModelWidget* XGUI_PropertyPanel::preselectionWidget() const
231 {
232   return myPreselectionWidget;
233 }
234
235 void XGUI_PropertyPanel::setPreselectionWidget(ModuleBase_ModelWidget* theWidget)
236 {
237   myPreselectionWidget = theWidget;
238 }