2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
12 #include <QGridLayout>
14 #include <QHBoxLayout>
16 #include <QVBoxLayout>
22 OptCheckBox::OptCheckBox(boost::shared_ptr
<BoolOpt
> opt
, OptionWidget
*owner
, QWidget
*parent
)
23 : QCheckBox(opt
->label(), parent
)
26 setChecked(m_opt
->value());
27 connect(this, SIGNAL(toggled(bool)), this, SLOT(setOpt(bool)));
30 void OptCheckBox::setOpt(bool b
) {
32 m_owner
->notifyChange();
35 OptRadioButton::OptRadioButton(boost::shared_ptr
<SelectOpt
> opt
, int i
, OptionWidget
*owner
, QWidget
*parent
)
36 : QRadioButton(opt
->m_options
[i
]->label(), parent
)
40 setChecked(m_opt
->m_options
[i
]->value());
41 connect(this, SIGNAL(toggled(bool)), this, SLOT(setOpt(bool)));
44 void OptRadioButton::setOpt(bool b
) {
46 m_opt
->setSelected(m_index
);
47 m_owner
->notifyChange();
51 OptSpinBox::OptSpinBox(boost::shared_ptr
<IntOpt
> opt
, OptionWidget
*owner
, QWidget
*parent
)
55 setValue(m_opt
->value());
56 setMinimum(m_opt
->min());
57 setMaximum(m_opt
->max());
58 connect(this, SIGNAL(valueChanged(int)), this, SLOT(setOpt(int)));
61 void OptSpinBox::setOpt(int i
) {
63 m_owner
->notifyChange();
66 OptLineEdit::OptLineEdit(boost::shared_ptr
<StringOpt
> opt
, OptionWidget
*owner
, QWidget
*parent
)
70 setText(m_opt
->value());
71 connect(this, SIGNAL(textChanged(const QString
&)), this, SLOT(setOpt(const QString
&)));
74 void OptLineEdit::setOpt(const QString
& s
) {
76 m_owner
->notifyChange();
79 OptUrlRequester::OptUrlRequester(boost::shared_ptr
<UrlOpt
> opt
, OptionWidget
*owner
, QWidget
*parent
)
80 : KUrlRequester(parent
)
83 setUrl(m_opt
->value());
84 connect(this, SIGNAL(textChanged(const QString
&)), this, SLOT(setOpt(const QString
&)));
87 void OptUrlRequester::setOpt(const QString
& s
) {
89 m_owner
->notifyChange();
92 OptComboBox::OptComboBox(boost::shared_ptr
<ComboOpt
> opt
, OptionWidget
*owner
, QWidget
*parent
)
96 addItems(m_opt
->m_values
);
97 setCurrentIndex(m_opt
->selected());
98 connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(setOpt(int)));
101 void OptComboBox::setOpt(int c
) {
102 m_opt
->setSelected(c
);
103 m_owner
->notifyChange();
106 OptColorButton::OptColorButton(boost::shared_ptr
<ColorOpt
> opt
, OptionWidget
*owner
, QWidget
*parent
)
107 : KColorButton(parent
)
110 setColor(m_opt
->value());
111 connect(this, SIGNAL(changed(const QColor
&)), this, SLOT(setOpt(const QColor
&)));
114 void OptColorButton::setOpt(const QColor
& c
) {
116 m_owner
->notifyChange();
119 OptFontRequester::OptFontRequester(boost::shared_ptr
<FontOpt
> opt
, OptionWidget
*owner
, QWidget
*parent
)
120 : KFontRequester(parent
)
123 setFont(m_opt
->value());
124 connect(this, SIGNAL(fontSelected(const QFont
&)), this, SLOT(setOpt(const QFont
&)));
127 void OptFontRequester::setOpt(const QFont
& f
) {
129 m_owner
->notifyChange();
132 OptionWidget::OptionWidget(const OptList
& options
, QWidget
* parent
)
135 , m_options(options
) {
136 setupOptionWidget(this, m_options
);
139 void OptionWidget::notifyChange() {
143 dump_options_list(m_options
);
144 emit
changed(m_options
);
148 void OptionWidget::setValues(OptList
& newopts
) {
151 setOptionWidgetValues(this, newopts
);
157 void OptionWidget::setupOptionWidget(QWidget
* widget
, OptList
& options
, bool indent
) {
158 QGridLayout
*layout
= new QGridLayout(widget
);
161 layout
->setMargin(0);
163 int left
= indent
? 1 : 0;
164 int right
= indent
? 2 : 1;
166 for(int i
=0;i
<options
.size();i
++) {
167 OptPtr _o
= options
[i
];
168 if(boost::shared_ptr
<BoolOpt
> o
=
169 boost::dynamic_pointer_cast
<BoolOpt
,BaseOpt
>(_o
)) {
170 OptCheckBox
*cb
= new OptCheckBox(o
, this, widget
);
171 cb
->setObjectName(qPrintf("%02d_check",i
));
172 layout
->addWidget(cb
, lpos
++, left
, 1, 2);
173 if(o
->m_sub_options
.size()) {
174 QWidget
*w
= new QWidget(widget
);
175 w
->setObjectName(qPrintf("%02d_check_sub",i
));
176 setupOptionWidget(w
, o
->m_sub_options
, true);
177 w
->setEnabled(o
->value());
178 QObject::connect(cb
, SIGNAL(toggled(bool)), w
, SLOT(setEnabled(bool)));
179 layout
->addWidget(w
, lpos
++, left
, 1, 2);
182 else if(boost::shared_ptr
<SelectOpt
> o
=
183 boost::dynamic_pointer_cast
<SelectOpt
,BaseOpt
>(_o
)) {
184 QGroupBox
*gb
= new QGroupBox(o
->label(), widget
);
185 gb
->setObjectName(qPrintf("%02d_group",i
));
186 QVBoxLayout
*vbox
= new QVBoxLayout(gb
);
187 //vbox->setMargin(0);
188 for(int j
=0;j
<o
->m_options
.size();j
++) {
189 BoolOptPtr so
= o
->m_options
[j
];
190 OptRadioButton
*rb
= new OptRadioButton(o
, j
, this, gb
);
191 rb
->setObjectName(qPrintf("%02d_radio_%02d",i
,j
));
193 if(so
->m_sub_options
.size()) {
194 QWidget
*w
= new QWidget(widget
);
195 w
->setObjectName(qPrintf("%02d_radio_%02d_sub",i
,j
));
196 setupOptionWidget(w
, so
->m_sub_options
, true);
197 w
->setEnabled(so
->value());
198 QObject::connect(rb
, SIGNAL(toggled(bool)), w
, SLOT(setEnabled(bool)));
202 layout
->addWidget(gb
, lpos
++, left
, 1, 2);
204 else if(boost::shared_ptr
<IntOpt
> o
=
205 boost::dynamic_pointer_cast
<IntOpt
,BaseOpt
>(_o
)) {
206 layout
->addWidget(new QLabel(o
->label()), lpos
, left
);
207 OptSpinBox
*sb
= new OptSpinBox(o
, this, widget
);
208 sb
->setObjectName(qPrintf("%02d_spin",i
));
209 layout
->addWidget(sb
, lpos
++, right
);
211 else if(boost::shared_ptr
<StringOpt
> o
=
212 boost::dynamic_pointer_cast
<StringOpt
,BaseOpt
>(_o
)) {
213 layout
->addWidget(new QLabel(o
->label()), lpos
, left
);
214 OptLineEdit
*ow
= new OptLineEdit(o
, this, widget
);
215 ow
->setObjectName(qPrintf("%02d_line",i
));
216 layout
->addWidget(ow
, lpos
++, right
);
218 else if(boost::shared_ptr
<UrlOpt
> o
=
219 boost::dynamic_pointer_cast
<UrlOpt
,BaseOpt
>(_o
)) {
220 layout
->addWidget(new QLabel(o
->label()), lpos
, left
);
221 OptUrlRequester
*ow
= new OptUrlRequester(o
, this, widget
);
222 ow
->setObjectName(qPrintf("%02d_url",i
));
223 layout
->addWidget(ow
, lpos
++, right
);
225 else if(boost::shared_ptr
<ComboOpt
> o
=
226 boost::dynamic_pointer_cast
<ComboOpt
,BaseOpt
>(_o
)) {
227 layout
->addWidget(new QLabel(o
->label()), lpos
, left
);
228 OptComboBox
*ow
= new OptComboBox(o
, this, widget
);
229 ow
->setObjectName(qPrintf("%02d_combo",i
));
230 layout
->addWidget(ow
, lpos
++, right
);
232 else if(boost::shared_ptr
<ColorOpt
> o
=
233 boost::dynamic_pointer_cast
<ColorOpt
,BaseOpt
>(_o
)) {
234 layout
->addWidget(new QLabel(o
->label()), lpos
, left
);
235 OptColorButton
*ow
= new OptColorButton(o
, this, widget
);
236 ow
->setObjectName(qPrintf("%02d_color",i
));
237 layout
->addWidget(ow
, lpos
++, right
);
239 else if(boost::shared_ptr
<FontOpt
> o
=
240 boost::dynamic_pointer_cast
<FontOpt
,BaseOpt
>(_o
)) {
241 layout
->addWidget(new QLabel(o
->label()), lpos
, left
);
242 OptFontRequester
*ow
= new OptFontRequester(o
,this, widget
);
243 ow
->setObjectName(qPrintf("%02d_font",i
));
244 layout
->addWidget(ow
, lpos
++, right
);
247 ERROR("Unknown option of type " << prettyTypeName(typeid(*_o
).name()));
251 layout
->addItem(new QSpacerItem(25, 1, QSizePolicy::Minimum
, QSizePolicy::Minimum
),
255 void OptionWidget::setOptionWidgetValues(QWidget
* widget
, OptList
& newopts
) {
256 for(int i
=0;i
<newopts
.size();i
++) {
257 OptPtr _o
= newopts
[i
];
258 if(boost::shared_ptr
<BoolOpt
> o
=
259 boost::dynamic_pointer_cast
<BoolOpt
,BaseOpt
>(_o
)) {
260 OptCheckBox
*cb
= widget
->findChild
<OptCheckBox
*>(qPrintf("%02d_check",i
));
262 cb
->setChecked(o
->value());
264 if(o
->m_sub_options
.size()) {
265 QWidget
*w
= widget
->findChild
<QWidget
*>(qPrintf("%02d_check_sub",i
));
267 setOptionWidgetValues(w
, o
->m_sub_options
);
270 else if(boost::shared_ptr
<SelectOpt
> o
=
271 boost::dynamic_pointer_cast
<SelectOpt
,BaseOpt
>(_o
)) {
272 QGroupBox
*gb
= widget
->findChild
<QGroupBox
*>(qPrintf("%02d_group",i
));
275 for(int j
=0;j
<o
->m_options
.size();j
++) {
276 BoolOptPtr so
= o
->m_options
[j
];
277 OptRadioButton
*rb
= gb
->findChild
<OptRadioButton
*>(qPrintf("%02d_radio_%02d",i
,j
));
279 rb
->setChecked(so
->value());
281 if(so
->m_sub_options
.size()) {
282 QWidget
*w
= widget
->findChild
<QWidget
*>(qPrintf("%02d_radio_%02d_sub",i
,j
));
284 setOptionWidgetValues(w
, so
->m_sub_options
);
288 else if(boost::shared_ptr
<IntOpt
> o
=
289 boost::dynamic_pointer_cast
<IntOpt
,BaseOpt
>(_o
)) {
290 OptSpinBox
*sb
= widget
->findChild
<OptSpinBox
*>(qPrintf("%02d_spin",i
));
292 sb
->setValue(o
->value());
294 else if(boost::shared_ptr
<StringOpt
> o
=
295 boost::dynamic_pointer_cast
<StringOpt
,BaseOpt
>(_o
)) {
296 OptLineEdit
*ow
= widget
->findChild
<OptLineEdit
*>(qPrintf("%02d_line",i
));
298 ow
->setText(o
->value());
300 else if(boost::shared_ptr
<UrlOpt
> o
=
301 boost::dynamic_pointer_cast
<UrlOpt
,BaseOpt
>(_o
)) {
302 OptUrlRequester
*ow
= widget
->findChild
<OptUrlRequester
*>(qPrintf("%02d_url",i
));
304 ow
->setUrl(o
->value());
306 else if(boost::shared_ptr
<ComboOpt
> o
=
307 boost::dynamic_pointer_cast
<ComboOpt
,BaseOpt
>(_o
)) {
308 OptComboBox
*ow
= widget
->findChild
<OptComboBox
*>(qPrintf("%02d_combo",i
));
310 ow
->setCurrentIndex(o
->m_selected
);
312 else if(boost::shared_ptr
<ColorOpt
> o
=
313 boost::dynamic_pointer_cast
<ColorOpt
,BaseOpt
>(_o
)) {
314 OptColorButton
*ow
= widget
->findChild
<OptColorButton
*>(qPrintf("%02d_color",i
));
316 ow
->setColor(o
->value());
318 else if(boost::shared_ptr
<FontOpt
> o
=
319 boost::dynamic_pointer_cast
<FontOpt
,BaseOpt
>(_o
)) {
320 OptFontRequester
*ow
= widget
->findChild
<OptFontRequester
*>(qPrintf("%02d_font",i
));
322 ow
->setFont(o
->value());
325 ERROR("Unknown option of type " << prettyTypeName(typeid(*_o
).name()));
329 ERROR("Options/Widget mismatch!");
332 void dump_options_list(OptList
& options
, int indent
) {
333 if(!indent
)std::cout
<< "---- begin dump ----" << std::endl
;
334 for(int i
=0;i
<options
.size();i
++) {
335 OptPtr _o
= options
[i
];
336 if(boost::shared_ptr
<BoolOpt
> o
=
337 boost::dynamic_pointer_cast
<BoolOpt
,BaseOpt
>(_o
)) {
338 for(int j
=0;j
<indent
;j
++)std::cout
<< " ";
339 std::cout
<< (o
->value()?"[X]":"[ ]") << " " << o
->label() << std::endl
;
340 dump_options_list(o
->m_sub_options
, indent
+1);
342 else if(boost::shared_ptr
<IntOpt
> o
=
343 boost::dynamic_pointer_cast
<IntOpt
,BaseOpt
>(_o
)) {
344 for(int j
=0;j
<indent
;j
++)std::cout
<< " ";
345 std::cout
<< o
->label() << " |" << o
->value() << "|" << std::endl
;
347 else if(boost::shared_ptr
<StringOpt
> o
=
348 boost::dynamic_pointer_cast
<StringOpt
,BaseOpt
>(_o
)) {
349 for(int j
=0;j
<indent
;j
++)std::cout
<< " ";
350 std::cout
<< o
->label() << " [" << o
->value() << "]" << std::endl
;
352 else if(boost::shared_ptr
<UrlOpt
> o
=
353 boost::dynamic_pointer_cast
<UrlOpt
,BaseOpt
>(_o
)) {
354 for(int j
=0;j
<indent
;j
++)std::cout
<< " ";
355 std::cout
<< o
->label() << " {" << o
->value() << "}" << std::endl
;
357 else if(boost::shared_ptr
<ColorOpt
> o
=
358 boost::dynamic_pointer_cast
<ColorOpt
,BaseOpt
>(_o
)) {
359 for(int j
=0;j
<indent
;j
++)std::cout
<< " ";
360 std::cout
<< o
->label() << " {" << o
->value().name() << "}" << std::endl
;
362 else if(boost::shared_ptr
<FontOpt
> o
=
363 boost::dynamic_pointer_cast
<FontOpt
,BaseOpt
>(_o
)) {
364 for(int j
=0;j
<indent
;j
++)std::cout
<< " ";
365 std::cout
<< o
->label() << " {" << o
->value().toString() << "}" << std::endl
;
367 else if(boost::shared_ptr
<ComboOpt
> o
=
368 boost::dynamic_pointer_cast
<ComboOpt
,BaseOpt
>(_o
)) {
369 for(int j
=0;j
<indent
;j
++)std::cout
<< " ";
370 std::cout
<< "[combo] " << o
->label() << std::endl
;
371 for(int k
=0;k
<o
->m_values
.size();k
++) {
372 for(int j
=0;j
<indent
+1;j
++)std::cout
<< " ";
374 std::cout
<< " *<" << o
->m_values
[k
] << ">*" << std::endl
;
376 std::cout
<< " <" << o
->m_values
[k
] << ">" << std::endl
;
379 else if(boost::shared_ptr
<SelectOpt
> o
=
380 boost::dynamic_pointer_cast
<SelectOpt
,BaseOpt
>(_o
)) {
381 for(int j
=0;j
<indent
;j
++)std::cout
<< " ";
382 std::cout
<< "[group] " << o
->label() << std::endl
;
383 for(int j
=0;j
<o
->m_options
.size();j
++) {
384 BoolOptPtr so
= o
->m_options
[j
];
385 for(int j
=0;j
<indent
+1;j
++)std::cout
<< " ";
386 std::cout
<< (so
->value()?"(*)":"( )") << " " << so
->label() << std::endl
;
387 if(so
->m_sub_options
.size())
388 dump_options_list(so
->m_sub_options
, indent
+2);
392 std::cout
<< "dump_options_list: Error, unknown option of type "
393 << prettyTypeName(typeid(*_o
).name()) << std::endl
;
396 if(!indent
)std::cout
<< "---- end dump ----" << std::endl
;
399 bool options_list_load_from_settings(OptList
& options
, const Settings
& s
) {
401 for(int i
=0;i
<options
.size();i
++) {
402 OptPtr _o
= options
[i
];
403 if(boost::shared_ptr
<BoolOpt
> o
=
404 boost::dynamic_pointer_cast
<BoolOpt
,BaseOpt
>(_o
)) {
405 Settings bool_group
= s
.group(o
->name());
406 retv
|= options_list_load_from_settings(o
->m_sub_options
, bool_group
);
407 bool newval
= bool_group
.flag("value", o
->value());
408 retv
|= (newval
!= o
->value());
409 o
->setValue( newval
);
411 else if(boost::shared_ptr
<IntOpt
> o
=
412 boost::dynamic_pointer_cast
<IntOpt
,BaseOpt
>(_o
)) {
413 int newval
= s
[o
->name()] | o
->value();
414 retv
|= (newval
!= o
->value());
415 o
->setValue( newval
);
417 else if(boost::shared_ptr
<StringOpt
> o
=
418 boost::dynamic_pointer_cast
<StringOpt
,BaseOpt
>(_o
)) {
419 QString newval
= s
[o
->name()] | o
->value();
420 retv
|= (newval
!= o
->value());
421 o
->setValue( newval
);
423 else if(boost::shared_ptr
<UrlOpt
> o
=
424 boost::dynamic_pointer_cast
<UrlOpt
,BaseOpt
>(_o
)) {
425 QString newval
= s
[o
->name()] | o
->value();
426 retv
|= (newval
!= o
->value());
427 o
->setValue( newval
);
429 else if(boost::shared_ptr
<ColorOpt
> o
=
430 boost::dynamic_pointer_cast
<ColorOpt
,BaseOpt
>(_o
)) {
431 QColor newval
= s
[o
->name()] | o
->value();
432 retv
|= (newval
!= o
->value());
433 o
->setValue( newval
);
435 else if(boost::shared_ptr
<FontOpt
> o
=
436 boost::dynamic_pointer_cast
<FontOpt
,BaseOpt
>(_o
)) {
437 QFont newval
= s
[o
->name()] | o
->value();
438 retv
|= (newval
!= o
->value());
439 o
->setValue( newval
);
441 else if(boost::shared_ptr
<ComboOpt
> o
=
442 boost::dynamic_pointer_cast
<ComboOpt
,BaseOpt
>(_o
)) {
443 int newval
= s
[o
->name()] | o
->selected();
444 retv
|= (newval
!= o
->selected());
445 o
->setSelected( newval
);
447 else if(boost::shared_ptr
<SelectOpt
> o
=
448 boost::dynamic_pointer_cast
<SelectOpt
,BaseOpt
>(_o
)) {
450 for(int i
=0;i
<o
->m_options
.size();i
++)
451 l
<< o
->m_options
[i
];
452 Settings sel_group
= s
.group(o
->name());
453 retv
|= options_list_load_from_settings(l
, sel_group
.group("sel-options"));
454 int newval
= sel_group
["value"] | o
->selected();
455 retv
|= (newval
!= o
->selected());
456 o
->setSelected( newval
);
459 ERROR("option of type " << prettyTypeName(typeid(*_o
).name()) );
464 void options_list_save_to_settings(const OptList
& options
, Settings s
) {
465 for(int i
=0;i
<options
.size();i
++) {
466 OptPtr _o
= options
[i
];
467 if(boost::shared_ptr
<BoolOpt
> o
=
468 boost::dynamic_pointer_cast
<BoolOpt
,BaseOpt
>(_o
)) {
469 Settings bool_group
= s
.group(o
->name());
470 options_list_save_to_settings(o
->m_sub_options
, bool_group
);
471 bool_group
.setFlag("value", o
->value());
473 else if(boost::shared_ptr
<IntOpt
> o
=
474 boost::dynamic_pointer_cast
<IntOpt
,BaseOpt
>(_o
)) {
475 s
[o
->name()] = o
->value();
477 else if(boost::shared_ptr
<StringOpt
> o
=
478 boost::dynamic_pointer_cast
<StringOpt
,BaseOpt
>(_o
)) {
479 s
[o
->name()] = o
->value();
481 else if(boost::shared_ptr
<UrlOpt
> o
=
482 boost::dynamic_pointer_cast
<UrlOpt
,BaseOpt
>(_o
)) {
483 s
[o
->name()] = o
->value();
485 else if(boost::shared_ptr
<ColorOpt
> o
=
486 boost::dynamic_pointer_cast
<ColorOpt
,BaseOpt
>(_o
)) {
487 s
[o
->name()] = o
->value();
489 else if(boost::shared_ptr
<FontOpt
> o
=
490 boost::dynamic_pointer_cast
<FontOpt
,BaseOpt
>(_o
)) {
491 s
[o
->name()] = o
->value();
493 else if(boost::shared_ptr
<ComboOpt
> o
=
494 boost::dynamic_pointer_cast
<ComboOpt
,BaseOpt
>(_o
)) {
495 s
[o
->name()] = o
->value();
497 else if(boost::shared_ptr
<SelectOpt
> o
=
498 boost::dynamic_pointer_cast
<SelectOpt
,BaseOpt
>(_o
)) {
500 for(int i
=0;i
<o
->m_options
.size();i
++)
501 l
<< o
->m_options
[i
];
502 Settings sel_group
= s
.group(o
->name());
503 options_list_save_to_settings(l
, sel_group
.group("sel-options"));
504 sel_group
["value"] = o
->value();
507 ERROR("option of type " << prettyTypeName(typeid(*_o
).name()) );