]> SALOME platform Git repositories - modules/shaper.git/blob - src/ModuleBase/ModuleBase_WidgetOptionalBox.cpp
Salome HOME
Merge branch 'V9_5_BR'
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetOptionalBox.cpp
1 // Copyright (C) 2014-2020  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 email : webmaster.salome@opencascade.com
18 //
19
20 #include <ModuleBase_WidgetOptionalBox.h>
21 #include <ModelAPI_AttributeString.h>
22 #include <ModelAPI_AttributeBoolean.h>
23
24 #include <Config_WidgetAPI.h>
25 #include <Config_Keywords.h>
26
27 #include <QWidget>
28 #include <QGroupBox>
29 #include <QCheckBox>
30 #include <QGridLayout>
31 #include <QVBoxLayout>
32
33 #include <QList>
34
35 ModuleBase_WidgetOptionalBox::ModuleBase_WidgetOptionalBox(QWidget* theParent,
36                                                                const Config_WidgetAPI* theData)
37 : ModuleBase_ModelWidget(theParent, theData),
38   ModuleBase_PageBase(),
39   myOptionType(CheckBox),
40   myCheckBoxFrame(0),
41   myCheckBox(0),
42   myCheckBoxLayout(0),
43   myCheckBoxWidget(0),
44   myGroupBox(0),
45   myGroupBoxLayout(0),
46   myCheckGroup(0),
47   myCheckGroupBtn(0),
48   myCheckContent(0),
49   myCheckGroupLayout(0),
50   myEnableOnCheck(true)
51 {
52   myToolTip = theData->widgetTooltip();
53   myGroupTitle = theData->getProperty(CONTAINER_PAGE_NAME);
54
55   myHaveFrame = theData->getBooleanAttribute("has_frame", true);
56   myEnableOnCheck = theData->getBooleanAttribute("enable_on_check", true);
57   myAlwaysShowTitle = theData->getBooleanAttribute("show_title", false);
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     if (myAlwaysShowTitle)
206       myCheckBox = new QCheckBox(translate(myGroupTitle), myCheckBoxFrame);
207     else
208       myCheckBox = new QCheckBox(myCheckBoxFrame);
209     myCheckBox->setChecked(getDefaultValue() == "true");
210     myCheckBoxLayout->addWidget(myCheckBox);
211
212     connect(myCheckBox, SIGNAL(clicked(bool)), this, SLOT(onPageClicked()));
213   }
214 }
215
216 bool ModuleBase_WidgetOptionalBox::storeValueCustom()
217 {
218   DataPtr aData = myFeature->data();
219   AttributeStringPtr aStringAttr = aData->string(attributeID());
220   if (aStringAttr.get())
221     aStringAttr->setValue(getCurrentValue() ? attributeID() : "");
222   else {
223     AttributeBooleanPtr aBoolAtr = aData->boolean(attributeID());
224     aBoolAtr->setValue(getCurrentValue());
225   }
226
227   updateObject(myFeature);
228
229   return true;
230 }
231
232 bool ModuleBase_WidgetOptionalBox::restoreValueCustom()
233 {
234   DataPtr aData = myFeature->data();
235   AttributeStringPtr aStringAttr = aData->string(attributeID());
236   if (aStringAttr.get())
237     setCurrentValue(!aStringAttr->value().empty());
238   else {
239     AttributeBooleanPtr aBoolAtr = aData->boolean(attributeID());
240     setCurrentValue(aBoolAtr->value());
241   }
242   return true;
243 }
244
245 void ModuleBase_WidgetOptionalBox::setOptionType(
246                          const ModuleBase_WidgetOptionalBox::OptionType& theType)
247 {
248   myOptionType = theType;
249
250   bool isGroupBox = myOptionType == GroupBox;
251   if (myCheckBoxFrame)
252     myCheckBoxFrame->setVisible(!isGroupBox);
253   if (myGroupBox)
254     myGroupBox->setVisible(isGroupBox);
255   else if (myCheckContent)
256     myCheckGroup->setVisible(isGroupBox);
257 }
258
259 bool ModuleBase_WidgetOptionalBox::isCheckBoxFilled() const
260 {
261   return myCheckBoxWidget != 0;
262 }
263
264 bool ModuleBase_WidgetOptionalBox::getCurrentValue() const
265 {
266   bool isGroupBox = myOptionType == GroupBox;
267   return isGroupBox ? (myGroupBox? myGroupBox->isChecked() : myCheckGroupBtn->isChecked()) :
268     myCheckBox->isChecked();
269 }
270
271 void ModuleBase_WidgetOptionalBox::setCurrentValue(const bool& theValue)
272 {
273   bool isGroupBox = myOptionType == GroupBox;
274   if (isGroupBox) {
275     if (myGroupBox) {
276       bool isBlocked = myGroupBox->blockSignals(true);
277       myGroupBox->setChecked(theValue);
278       myGroupBox->blockSignals(isBlocked);
279     }
280     else {
281       bool isBlocked = myCheckGroupBtn->blockSignals(true);
282       myCheckGroupBtn->setChecked(theValue);
283       myCheckGroupBtn->blockSignals(isBlocked);
284     }
285   }
286   else {
287     bool isBlocked = myCheckBox->blockSignals(true);
288     myCheckBox->setChecked(theValue);
289     myCheckBox->blockSignals(isBlocked);
290   }
291   updateControlsVisibility();
292 }
293
294 void ModuleBase_WidgetOptionalBox::updateControlsVisibility()
295 {
296   if (myOptionType == GroupBox) {
297     bool aChecked = toEnableWidgets();
298     ModuleBase_Tools::adjustMargins(myGroupBoxLayout);
299
300     QLayout* aLayout = myGroupBoxLayout ? myGroupBoxLayout : (QLayout*)myCheckGroupLayout;
301
302     int aNbSubControls = aLayout->count();
303     for (int i = 0; i < aNbSubControls; i++) {
304       QWidget* aWidget = aLayout->itemAt(i)->widget();
305       if (aWidget)
306         aWidget->setEnabled(aChecked);
307     }
308   }
309   else {
310     myCheckBoxWidget->setEnabled(toEnableWidgets());
311   }
312 }
313
314 bool ModuleBase_WidgetOptionalBox::toEnableWidgets() const
315 {
316   bool aChecked;
317   if (myOptionType == GroupBox)
318     aChecked = myGroupBox ? myGroupBox->isChecked() : myCheckGroupBtn->isChecked();
319   else
320     aChecked = myCheckBox->isChecked();
321
322   if (myEnableOnCheck)
323     return aChecked;
324   else
325     return !aChecked;
326 }