Salome HOME
c035f02c760c7fa56bbf29c4c5d4a61f02fba723
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetOptionalBox.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include <ModuleBase_WidgetOptionalBox.h>
22 #include <ModelAPI_AttributeString.h>
23 #include <ModelAPI_AttributeBoolean.h>
24
25 #include <Config_WidgetAPI.h>
26 #include <Config_Keywords.h>
27
28 #include <QWidget>
29 #include <QGroupBox>
30 #include <QCheckBox>
31 #include <QGridLayout>
32 #include <QVBoxLayout>
33
34 #include <QList>
35
36 ModuleBase_WidgetOptionalBox::ModuleBase_WidgetOptionalBox(QWidget* theParent,
37                                                                const Config_WidgetAPI* theData)
38 : ModuleBase_ModelWidget(theParent, theData),
39   ModuleBase_PageBase(),
40   myOptionType(CheckBox),
41   myCheckBoxFrame(0),
42   myCheckBox(0),
43   myCheckBoxLayout(0),
44   myCheckBoxWidget(0),
45   myGroupBox(0),
46   myGroupBoxLayout(0),
47   myCheckGroup(0),
48   myCheckGroupLayout(0),
49   myCheckContent(0),
50   myCheckGroupBtn(0),
51   myEnableOnCheck(true)
52 {
53   myToolTip = theData->widgetTooltip();
54   myGroupTitle = theData->getProperty(CONTAINER_PAGE_NAME);
55
56   myHaveFrame = theData->getBooleanAttribute("has_frame", true);
57   myEnableOnCheck = theData->getBooleanAttribute("enable_on_check", true);
58
59   bool isChecked = theData->getBooleanAttribute(ATTR_DEFAULT, false);
60   setDefaultValue(isChecked ? "true" : "false");
61
62   myMainLayout = new QVBoxLayout(this);
63   ModuleBase_Tools::adjustMargins(myMainLayout);
64 }
65
66 ModuleBase_WidgetOptionalBox::~ModuleBase_WidgetOptionalBox()
67 {
68 }
69
70 QWidget* ModuleBase_WidgetOptionalBox::pageWidget()
71 {
72   return myOptionType == GroupBox ? (myGroupBox? myGroupBox : myCheckGroup) :
73     (QWidget*)myCheckBoxFrame;
74 }
75
76 QList<QWidget*> ModuleBase_WidgetOptionalBox::getControls() const
77 {
78   QList<QWidget*> aControls;
79   if (myOptionType == GroupBox) {
80     if (myGroupBox)
81       aControls.append(myGroupBox);
82     else
83       aControls.append(myCheckGroup);
84   }
85   else
86     aControls.append(myCheckBoxFrame);
87
88   return aControls;
89 }
90
91 void ModuleBase_WidgetOptionalBox::onPageClicked()
92 {
93   storeValue();
94   updateControlsVisibility();
95
96   if (!isEditingMode())
97     emit focusOutWidget(this);
98 }
99
100 void ModuleBase_WidgetOptionalBox::addPageStretch()
101 {
102 }
103
104 void ModuleBase_WidgetOptionalBox::placeModelWidget(ModuleBase_ModelWidget* theWidget)
105 {
106   if(!isCheckBoxFilled() && myOptionType == CheckBox) {
107     createControl(CheckBox);
108     setOptionType(CheckBox);
109
110     myCheckBoxWidget = theWidget; /// check box frame becomes filled
111     myCheckBoxLayout->addWidget(theWidget, 1);
112   }
113   else {
114     createControl(GroupBox);
115     setOptionType(GroupBox);
116
117     ModuleBase_ModelWidget* aCheckBoxWidget = myCheckBoxWidget;
118     myCheckBoxWidget = 0;
119     if (aCheckBoxWidget) // move the model widget from check box frame to group box frame
120       placeModelWidget(aCheckBoxWidget);
121
122     const int kCol = 0;
123     const int kRow = myGroupBoxLayout->count();
124     // it seems, that the align on left is not necessary here, but leads to widgets, which are
125     // not extended on full width of the parent page. The case is grouped widgets in
126     // the sketch translation operation
127     myGroupBoxLayout->addWidget(theWidget, kRow, kCol, Qt::AlignTop);// | Qt::AlignLeft);
128     myGroupBoxLayout->setRowStretch(kRow, 0);
129   }
130 }
131
132 void ModuleBase_WidgetOptionalBox::placeWidget(QWidget* theWidget)
133 {
134   createControl(GroupBox);
135   setOptionType(GroupBox);
136   if (isCheckBoxFilled())
137     placeModelWidget(myCheckBoxWidget);
138
139
140   if (!theWidget) {
141 #ifdef _DEBUG
142     std::cout << "ModuleBase_PageGroupBox::placePageWidget: can not cast page" << std::endl;
143 #endif
144     return;
145   }
146   if (myGroupBoxLayout) {
147     const int kCol = 0;
148     const int kRow = myGroupBoxLayout->count();
149     myGroupBoxLayout->addWidget(theWidget, kRow, kCol);
150     myGroupBoxLayout->setRowStretch(kRow, 0);
151   }
152   else {
153     myCheckGroupLayout->addWidget(theWidget);
154   }
155 }
156
157 QLayout* ModuleBase_WidgetOptionalBox::pageLayout()
158 {
159   return myOptionType == GroupBox ? myGroupBoxLayout : (QLayout*)myCheckBoxLayout;
160 }
161
162 void ModuleBase_WidgetOptionalBox::createControl(const OptionType& theType)
163 {
164   if (theType == GroupBox && !myGroupBox) {
165     // group box: more than one model widget is inside
166     if (myHaveFrame) {
167       myGroupBox = new QGroupBox(this);
168       myGroupBox->setTitle(translate(myGroupTitle));
169       myGroupBox->setVisible(false);
170       myGroupBox->setCheckable(true);
171       myGroupBox->setChecked(getDefaultValue() == "true");
172       myGroupBox->setToolTip(translate(myToolTip));
173
174       myGroupBoxLayout = new QGridLayout(myGroupBox);
175       ModuleBase_Tools::zeroMargins(myGroupBoxLayout);
176       myGroupBox->setLayout(myGroupBoxLayout);
177
178       // default vertical size policy is preferred
179       myMainLayout->addWidget(myGroupBox);
180       connect(myGroupBox, SIGNAL(clicked(bool)), this, SLOT(onPageClicked()));
181     }
182     else {
183       myCheckGroup = new QWidget(this);
184       QVBoxLayout* aLayout = new QVBoxLayout(myCheckGroup);
185       ModuleBase_Tools::zeroMargins(aLayout);
186
187       myCheckGroupBtn = new QCheckBox(translate(myGroupTitle), myCheckGroup);
188       aLayout->addWidget(myCheckGroupBtn);
189
190       myCheckContent = new QWidget(myCheckGroup);
191       myCheckGroupLayout = new QVBoxLayout(myCheckContent);
192       ModuleBase_Tools::zeroMargins(myCheckGroupLayout);
193       aLayout->addWidget(myCheckContent);
194
195       myMainLayout->addWidget(myCheckGroup);
196       connect(myCheckGroupBtn, SIGNAL(toggled(bool)), this, SLOT(onPageClicked()));
197     }
198   }
199   else if (theType == CheckBox && !myCheckBoxFrame) {
200     myCheckBoxFrame = new QFrame(this);
201     myMainLayout->addWidget(myCheckBoxFrame);
202
203     myCheckBoxLayout = new QHBoxLayout(myCheckBoxFrame);
204     ModuleBase_Tools::adjustMargins(myCheckBoxLayout);
205     myCheckBox = new QCheckBox(myCheckBoxFrame);
206     myCheckBox->setChecked(getDefaultValue() == "true");
207     myCheckBoxLayout->addWidget(myCheckBox);
208
209     connect(myCheckBox, SIGNAL(clicked(bool)), this, SLOT(onPageClicked()));
210   }
211 }
212
213 bool ModuleBase_WidgetOptionalBox::storeValueCustom()
214 {
215   DataPtr aData = myFeature->data();
216   AttributeStringPtr aStringAttr = aData->string(attributeID());
217   if (aStringAttr.get())
218     aStringAttr->setValue(getCurrentValue() ? attributeID() : "");
219   else {
220     AttributeBooleanPtr aBoolAtr = aData->boolean(attributeID());
221     aBoolAtr->setValue(getCurrentValue());
222   }
223
224   updateObject(myFeature);
225
226   return true;
227 }
228
229 bool ModuleBase_WidgetOptionalBox::restoreValueCustom()
230 {
231   DataPtr aData = myFeature->data();
232   AttributeStringPtr aStringAttr = aData->string(attributeID());
233   if (aStringAttr.get())
234     setCurrentValue(!aStringAttr->value().empty());
235   else {
236     AttributeBooleanPtr aBoolAtr = aData->boolean(attributeID());
237     setCurrentValue(aBoolAtr->value());
238   }
239   return true;
240 }
241
242 void ModuleBase_WidgetOptionalBox::setOptionType(
243                          const ModuleBase_WidgetOptionalBox::OptionType& theType)
244 {
245   myOptionType = theType;
246
247   bool isGroupBox = myOptionType == GroupBox;
248   if (myCheckBoxFrame)
249     myCheckBoxFrame->setVisible(!isGroupBox);
250   if (myGroupBox)
251     myGroupBox->setVisible(isGroupBox);
252   else if (myCheckContent)
253     myCheckGroup->setVisible(isGroupBox);
254 }
255
256 bool ModuleBase_WidgetOptionalBox::isCheckBoxFilled() const
257 {
258   return myCheckBoxWidget != 0;
259 }
260
261 bool ModuleBase_WidgetOptionalBox::getCurrentValue() const
262 {
263   bool isGroupBox = myOptionType == GroupBox;
264   return isGroupBox ? (myGroupBox? myGroupBox->isChecked() : myCheckGroupBtn->isChecked()) :
265     myCheckBox->isChecked();
266 }
267
268 void ModuleBase_WidgetOptionalBox::setCurrentValue(const bool& theValue)
269 {
270   bool isGroupBox = myOptionType == GroupBox;
271   if (isGroupBox) {
272     if (myGroupBox) {
273       bool isBlocked = myGroupBox->blockSignals(true);
274       myGroupBox->setChecked(theValue);
275       myGroupBox->blockSignals(isBlocked);
276     }
277     else {
278       bool isBlocked = myCheckGroupBtn->blockSignals(true);
279       myCheckGroupBtn->setChecked(theValue);
280       myCheckGroupBtn->blockSignals(isBlocked);
281     }
282   }
283   else {
284     bool isBlocked = myCheckBox->blockSignals(true);
285     myCheckBox->setChecked(theValue);
286     myCheckBox->blockSignals(isBlocked);
287   }
288   updateControlsVisibility();
289 }
290
291 void ModuleBase_WidgetOptionalBox::updateControlsVisibility()
292 {
293   if (myOptionType == GroupBox) {
294     bool aChecked = toEnableWidgets();
295     ModuleBase_Tools::adjustMargins(myGroupBoxLayout);
296
297     QLayout* aLayout = myGroupBoxLayout ? myGroupBoxLayout : (QLayout*)myCheckGroupLayout;
298
299     int aNbSubControls = aLayout->count();
300     for (int i = 0; i < aNbSubControls; i++) {
301       QWidget* aWidget = aLayout->itemAt(i)->widget();
302       if (aWidget)
303         aWidget->setEnabled(aChecked);
304     }
305   }
306   else {
307     myCheckBoxWidget->setEnabled(toEnableWidgets());
308   }
309 }
310
311 bool ModuleBase_WidgetOptionalBox::toEnableWidgets() const
312 {
313   bool aChecked;
314   if (myOptionType == GroupBox)
315     aChecked = myGroupBox ? myGroupBox->isChecked() : myCheckGroupBtn->isChecked();
316   else
317     aChecked = myCheckBox->isChecked();
318
319   if (myEnableOnCheck)
320     return aChecked;
321   else
322     return !aChecked;
323 }