removed clock pref widget. clock prefs are definitively part of the lua theme.
[kboard.git] / src / option.cpp
blobea8dce153bd9ce6a0d8d451a901ffa8ca9d05001
1 /*
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.
9 */
11 #include <iostream>
12 #include <QGridLayout>
13 #include <QGroupBox>
14 #include <QHBoxLayout>
15 #include <QLabel>
16 #include <QVBoxLayout>
17 #include "settings.h"
18 #include "common.h"
19 #include "option.h"
20 #include "option_p.h"
22 OptCheckBox::OptCheckBox(boost::shared_ptr<BoolOpt> opt, OptionWidget *owner, QWidget *parent)
23 : QCheckBox(opt->label(), parent)
24 , m_owner(owner)
25 , m_opt(opt) {
26 setChecked(m_opt->value());
27 connect(this, SIGNAL(toggled(bool)), this, SLOT(setOpt(bool)));
30 void OptCheckBox::setOpt(bool b) {
31 m_opt->setValue(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)
37 , m_owner(owner)
38 , m_opt(opt)
39 , m_index(i) {
40 setChecked(m_opt->m_options[i]->value());
41 connect(this, SIGNAL(toggled(bool)), this, SLOT(setOpt(bool)));
44 void OptRadioButton::setOpt(bool b) {
45 if(b) {
46 m_opt->setSelected(m_index);
47 m_owner->notifyChange();
51 OptSpinBox::OptSpinBox(boost::shared_ptr<IntOpt> opt, OptionWidget *owner, QWidget *parent)
52 : QSpinBox(parent)
53 , m_owner(owner)
54 , m_opt(opt) {
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) {
62 m_opt->setValue(i);
63 m_owner->notifyChange();
66 OptLineEdit::OptLineEdit(boost::shared_ptr<StringOpt> opt, OptionWidget *owner, QWidget *parent)
67 : QLineEdit(parent)
68 , m_owner(owner)
69 , m_opt(opt) {
70 setText(m_opt->value());
71 connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(setOpt(const QString&)));
74 void OptLineEdit::setOpt(const QString& s) {
75 m_opt->setValue(s);
76 m_owner->notifyChange();
79 OptUrlRequester::OptUrlRequester(boost::shared_ptr<UrlOpt> opt, OptionWidget *owner, QWidget *parent)
80 : KUrlRequester(parent)
81 , m_owner(owner)
82 , m_opt(opt) {
83 setUrl(m_opt->value());
84 connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(setOpt(const QString&)));
87 void OptUrlRequester::setOpt(const QString& s) {
88 m_opt->setValue(s);
89 m_owner->notifyChange();
92 OptComboBox::OptComboBox(boost::shared_ptr<ComboOpt> opt, OptionWidget *owner, QWidget *parent)
93 : QComboBox(parent)
94 , m_owner(owner)
95 , m_opt(opt) {
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)
108 , m_owner(owner)
109 , m_opt(opt) {
110 setColor(m_opt->value());
111 connect(this, SIGNAL(changed(const QColor&)), this, SLOT(setOpt(const QColor&)));
114 void OptColorButton::setOpt(const QColor& c) {
115 m_opt->setValue(c);
116 m_owner->notifyChange();
119 OptFontRequester::OptFontRequester(boost::shared_ptr<FontOpt> opt, OptionWidget *owner, QWidget *parent)
120 : KFontRequester(parent)
121 , m_owner(owner)
122 , m_opt(opt) {
123 setFont(m_opt->value());
124 connect(this, SIGNAL(fontSelected(const QFont&)), this, SLOT(setOpt(const QFont&)));
127 void OptFontRequester::setOpt(const QFont& f) {
128 m_opt->setValue(f);
129 m_owner->notifyChange();
132 OptionWidget::OptionWidget(const OptList& options, QWidget* parent)
133 : QWidget(parent)
134 , m_dont_fire(false)
135 , m_options(options) {
136 setupOptionWidget(this, m_options);
139 void OptionWidget::notifyChange() {
140 if(m_dont_fire)
141 m_changed = true;
142 else {
143 dump_options_list(m_options);
144 emit changed(m_options);
148 void OptionWidget::setValues(OptList& newopts) {
149 m_changed = false;
150 m_dont_fire = true;
151 setOptionWidgetValues(this, newopts);
152 m_dont_fire = false;
153 if(m_changed)
154 notifyChange();
157 void OptionWidget::setupOptionWidget(QWidget* widget, OptList& options, bool indent) {
158 QGridLayout *layout = new QGridLayout(widget);
160 if(indent)
161 layout->setMargin(0);
163 int left = indent ? 1 : 0;
164 int right = indent ? 2 : 1;
165 int lpos = 0;
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));
192 vbox->addWidget(rb);
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)));
199 vbox->addWidget(w);
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);
246 else
247 ERROR("Unknown option of type " << prettyTypeName(typeid(*_o).name()));
250 if(indent)
251 layout->addItem(new QSpacerItem(25, 1, QSizePolicy::Minimum, QSizePolicy::Minimum),
252 0, 0, lpos, 1);
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));
261 if(!cb) goto fail;
262 cb->setChecked(o->value());
264 if(o->m_sub_options.size()) {
265 QWidget *w = widget->findChild<QWidget*>(qPrintf("%02d_check_sub",i));
266 if(!w) goto fail;
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));
273 if(!gb) goto fail;
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));
278 if(!rb) goto fail;
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));
283 if(!w) goto fail;
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));
291 if(!sb) goto fail;
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));
297 if(!ow) goto fail;
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));
303 if(!ow) goto fail;
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));
309 if(!ow) goto fail;
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));
315 if(!ow) goto fail;
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));
321 if(!ow) goto fail;
322 ow->setFont(o->value());
324 else
325 ERROR("Unknown option of type " << prettyTypeName(typeid(*_o).name()));
327 return;
328 fail:
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 << " ";
373 if(k==o->selected())
374 std::cout << " *<" << o->m_values[k] << ">*" << std::endl;
375 else
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);
391 else {
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) {
400 bool retv = false;
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)) {
449 OptList l;
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 );
458 else
459 ERROR("option of type " << prettyTypeName(typeid(*_o).name()) );
461 return retv;
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)) {
499 OptList l;
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();
506 else
507 ERROR("option of type " << prettyTypeName(typeid(*_o).name()) );