Salome HOME
Merge branch 'master' into cgt/devCEA
[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
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 {
47   myToolTip = theData->widgetTooltip();
48   myGroupTitle = theData->getProperty(CONTAINER_PAGE_NAME);
49
50   bool isChecked = theData->getBooleanAttribute(ATTR_DEFAULT, false);
51   setDefaultValue(isChecked ? "true" : "false");
52
53   myMainLayout = new QVBoxLayout(this);
54   ModuleBase_Tools::adjustMargins(myMainLayout);
55 }
56
57 ModuleBase_WidgetOptionalBox::~ModuleBase_WidgetOptionalBox()
58 {
59 }
60
61 QWidget* ModuleBase_WidgetOptionalBox::pageWidget()
62 {
63   return myOptionType == GroupBox ? myGroupBox : (QWidget*)myCheckBoxFrame;
64 }
65
66 QList<QWidget*> ModuleBase_WidgetOptionalBox::getControls() const
67 {
68   QList<QWidget*> aControls;
69   if (myOptionType == GroupBox)
70     aControls.append(myGroupBox);
71   else
72     aControls.append(myCheckBoxFrame);
73
74   return aControls;
75 }
76
77 void ModuleBase_WidgetOptionalBox::onPageClicked()
78 {
79   storeValue();
80   updateControlsVisibility();
81
82   if (!isEditingMode())
83     emit focusOutWidget(this);
84 }
85
86 void ModuleBase_WidgetOptionalBox::addPageStretch()
87 {
88 }
89
90 void ModuleBase_WidgetOptionalBox::placeModelWidget(ModuleBase_ModelWidget* theWidget)
91 {
92   if(!isCheckBoxFilled() && myOptionType == CheckBox) {
93     createControl(CheckBox);
94     setOptionType(CheckBox);
95
96     myCheckBoxWidget = theWidget; /// check box frame becomes filled
97     myCheckBoxLayout->addWidget(theWidget);
98   }
99   else {
100     createControl(GroupBox);
101     setOptionType(GroupBox);
102
103     ModuleBase_ModelWidget* aCheckBoxWidget = myCheckBoxWidget;
104     myCheckBoxWidget = 0;
105     if (aCheckBoxWidget) // move the model widget from check box frame to group box frame
106       placeModelWidget(aCheckBoxWidget);
107
108     const int kCol = 0;
109     const int kRow = myGroupBoxLayout->count();
110     // it seems, that the align on left is not necessary here, but leads to widgets, which are
111     // not extended on full width of the parent page. The case is grouped widgets in
112     // the sketch translation operation
113     myGroupBoxLayout->addWidget(theWidget, kRow, kCol, Qt::AlignTop);// | Qt::AlignLeft);
114     myGroupBoxLayout->setRowStretch(kRow, 0);
115   }
116 }
117
118 void ModuleBase_WidgetOptionalBox::placeWidget(QWidget* theWidget)
119 {
120   createControl(GroupBox);
121   setOptionType(GroupBox);
122   if (isCheckBoxFilled())
123     placeModelWidget(myCheckBoxWidget);
124
125
126   if (!theWidget) {
127 #ifdef _DEBUG
128     std::cout << "ModuleBase_PageGroupBox::placePageWidget: can not cast page" << std::endl;
129 #endif
130     return;
131   }
132   const int kCol = 0;
133   const int kRow = myGroupBoxLayout->count();
134   myGroupBoxLayout->addWidget(theWidget, kRow, kCol);
135   myGroupBoxLayout->setRowStretch(kRow, 0);
136 }
137
138 QLayout* ModuleBase_WidgetOptionalBox::pageLayout()
139 {
140   return myOptionType == GroupBox ? myGroupBoxLayout : (QLayout*)myCheckBoxLayout;
141 }
142
143 void ModuleBase_WidgetOptionalBox::createControl(const OptionType& theType)
144 {
145   if (theType == GroupBox && !myGroupBox) {
146     // group box: more than one model widget is inside
147     myGroupBox = new QGroupBox(this);
148     myGroupBox->setTitle(translate(myGroupTitle));
149     myGroupBox->setVisible(false);
150     myGroupBox->setCheckable(true);
151     myGroupBox->setChecked(getDefaultValue() == "true");
152     myGroupBox->setToolTip(translate(myToolTip));
153
154     myGroupBoxLayout = new QGridLayout(myGroupBox);
155     ModuleBase_Tools::zeroMargins(myGroupBoxLayout);
156     myGroupBox->setLayout(myGroupBoxLayout);
157
158     // default vertical size policy is preferred
159     myMainLayout->addWidget(myGroupBox);
160     connect(myGroupBox, SIGNAL(clicked(bool)), this, SLOT(onPageClicked()));
161   }
162   else if (theType == CheckBox && !myCheckBoxFrame) {
163     myCheckBoxFrame = new QFrame(this);
164     myMainLayout->addWidget(myCheckBoxFrame);
165
166     myCheckBoxLayout = new QHBoxLayout(myCheckBoxFrame);
167     ModuleBase_Tools::adjustMargins(myCheckBoxLayout);
168     myCheckBox = new QCheckBox(myCheckBoxFrame);
169     myCheckBox->setChecked(getDefaultValue() == "true");
170     myCheckBoxLayout->addWidget(myCheckBox);
171
172     connect(myCheckBox, SIGNAL(clicked(bool)), this, SLOT(onPageClicked()));
173   }
174 }
175
176 bool ModuleBase_WidgetOptionalBox::storeValueCustom()
177 {
178   DataPtr aData = myFeature->data();
179   AttributeStringPtr aStringAttr = aData->string(attributeID());
180   aStringAttr->setValue(getCurrentValue() ? attributeID() : "");
181
182   updateObject(myFeature);
183
184   return true;
185 }
186
187 bool ModuleBase_WidgetOptionalBox::restoreValueCustom()
188 {
189   DataPtr aData = myFeature->data();
190   AttributeStringPtr aStringAttr = aData->string(attributeID());
191   setCurrentValue(!aStringAttr->value().empty());
192
193   return true;
194 }
195
196 void ModuleBase_WidgetOptionalBox::setOptionType(
197                          const ModuleBase_WidgetOptionalBox::OptionType& theType)
198 {
199   myOptionType = theType;
200
201   bool isGroupBox = myOptionType == GroupBox;
202   if (myCheckBoxFrame)
203     myCheckBoxFrame->setVisible(!isGroupBox);
204   if (myGroupBox)
205     myGroupBox->setVisible(isGroupBox);
206 }
207
208 bool ModuleBase_WidgetOptionalBox::isCheckBoxFilled() const
209 {
210   return myCheckBoxWidget != 0;
211 }
212
213 bool ModuleBase_WidgetOptionalBox::getCurrentValue() const
214 {
215   bool isGroupBox = myOptionType == GroupBox;
216   return isGroupBox ? myGroupBox->isChecked() : myCheckBox->isChecked();
217 }
218
219 void ModuleBase_WidgetOptionalBox::setCurrentValue(const bool& theValue)
220 {
221   bool isGroupBox = myOptionType == GroupBox;
222   if (isGroupBox) {
223     bool isBlocked = myGroupBox->blockSignals(true);
224     myGroupBox->setChecked(theValue);
225     myGroupBox->blockSignals(isBlocked);
226   }
227   else {
228     bool isBlocked = myCheckBox->blockSignals(true);
229     myCheckBox->setChecked(theValue);
230     myCheckBox->blockSignals(isBlocked);
231   }
232   updateControlsVisibility();
233 }
234
235 void ModuleBase_WidgetOptionalBox::updateControlsVisibility()
236 {
237   if (myOptionType == GroupBox) {
238     bool aChecked = myGroupBox->isChecked();
239     ModuleBase_Tools::adjustMargins(myGroupBoxLayout);
240
241     int aNbSubControls = myGroupBoxLayout->count();
242     for (int i = 0; i < aNbSubControls; i++) {
243       QWidget* aWidget = myGroupBoxLayout->itemAt(i)->widget();
244       if (aWidget)
245         aWidget->setEnabled(aChecked);
246     }
247   }
248   else {
249     bool aChecked = myCheckBox->isChecked();
250     myCheckBoxWidget->setEnabled(aChecked);
251   }
252 }