refresh 080b1da3c594fb6ca84009c352cc5fb9cc294c43
[tagua/yd.git] / src / option.cpp
blobda669313387e7108c35b8e3478f7329423c85c01
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
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"
23 OptionWidget::OptionWidget(const OptList& options, QWidget* parent)
24 : QWidget(parent)
25 , m_dont_fire(false)
26 , m_options(options) {
27 setupOptionWidget(this, m_options);
30 void OptionWidget::notifyChange() {
31 if(m_dont_fire)
32 m_changed = true;
33 else {
34 dump_options_list(m_options);
35 changed(m_options);
39 void OptionWidget::setValues(OptList& newopts) {
40 m_changed = false;
41 m_dont_fire = true;
42 setOptionWidgetValues(this, newopts);
43 m_dont_fire = false;
44 if(m_changed)
45 notifyChange();
48 void OptionWidget::setupOptionWidget(QWidget* widget, OptList& options, bool indent) {
49 QGridLayout *layout = new QGridLayout(widget);
51 if(indent)
52 layout->setMargin(0);
54 int left = indent ? 1 : 0;
55 int right = indent ? 2 : 1;
56 int lpos = 0;
57 for(int i=0;i<options.size();i++) {
58 OptPtr _o = options[i];
59 if(BoolOptPtr o =
60 boost::dynamic_pointer_cast<BoolOpt,BaseOpt>(_o)) {
61 OptCheckBox *cb = new OptCheckBox(o, this, widget);
62 cb->setObjectName(qPrintf("%02d_check",i));
63 layout->addWidget(cb, lpos++, left, 1, 2);
64 if(o->m_sub_options.size()) {
65 QWidget *w = new QWidget(widget);
66 w->setObjectName(qPrintf("%02d_check_sub",i));
67 setupOptionWidget(w, o->m_sub_options, true);
68 w->setEnabled(o->value());
69 QObject::connect(cb, SIGNAL(toggled(bool)), w, SLOT(setEnabled(bool)));
70 layout->addWidget(w, lpos++, left, 1, 2);
73 else if(SelectOptPtr o =
74 boost::dynamic_pointer_cast<SelectOpt,BaseOpt>(_o)) {
75 QGroupBox *gb = new QGroupBox(o->label(), widget);
76 gb->setObjectName(qPrintf("%02d_group",i));
77 QVBoxLayout *vbox = new QVBoxLayout(gb);
78 //vbox->setMargin(0);
79 for(int j=0;j<o->m_options.size();j++) {
80 BoolOptPtr so = o->m_options[j];
81 OptRadioButton *rb = new OptRadioButton(o, j, this, gb);
82 rb->setObjectName(qPrintf("%02d_radio_%02d",i,j));
83 vbox->addWidget(rb);
84 if(so->m_sub_options.size()) {
85 QWidget *w = new QWidget(widget);
86 w->setObjectName(qPrintf("%02d_radio_%02d_sub",i,j));
87 setupOptionWidget(w, so->m_sub_options, true);
88 w->setEnabled(so->value());
89 QObject::connect(rb, SIGNAL(toggled(bool)), w, SLOT(setEnabled(bool)));
90 vbox->addWidget(w);
93 layout->addWidget(gb, lpos++, left, 1, 2);
95 else if (IntOptPtr o =
96 boost::dynamic_pointer_cast<IntOpt,BaseOpt>(_o)) {
97 layout->addWidget(new QLabel(o->label()), lpos, left);
98 switch (o->visualization()) {
99 case IntOpt::SpinBox:
101 OptSpinBox *sb = new OptSpinBox(o, this, widget);
102 sb->setObjectName(qPrintf("%02d_spin",i));
103 layout->addWidget(sb, lpos++, right);
104 break;
106 case IntOpt::Slider:
108 OptSlider *sl = new OptSlider(o, this, widget);
109 sl->setObjectName(qPrintf("%02d_slid",i));
110 layout->addWidget(sl, lpos++, right);
111 break;
115 else if(StringOptPtr o =
116 boost::dynamic_pointer_cast<StringOpt,BaseOpt>(_o)) {
117 layout->addWidget(new QLabel(o->label()), lpos, left);
118 OptLineEdit *ow = new OptLineEdit(o, this, widget);
119 ow->setObjectName(qPrintf("%02d_line",i));
120 layout->addWidget(ow, lpos++, right);
122 else if(UrlOptPtr o =
123 boost::dynamic_pointer_cast<UrlOpt,BaseOpt>(_o)) {
124 layout->addWidget(new QLabel(o->label()), lpos, left);
125 OptUrlRequester *ow = new OptUrlRequester(o, this, widget);
126 ow->setObjectName(qPrintf("%02d_url",i));
127 layout->addWidget(ow, lpos++, right);
129 else if(ComboOptPtr o =
130 boost::dynamic_pointer_cast<ComboOpt,BaseOpt>(_o)) {
131 layout->addWidget(new QLabel(o->label()), lpos, left);
132 OptComboBox *ow = new OptComboBox(o, this, widget);
133 ow->setObjectName(qPrintf("%02d_combo",i));
134 layout->addWidget(ow, lpos++, right);
136 else if(ColorOptPtr o =
137 boost::dynamic_pointer_cast<ColorOpt,BaseOpt>(_o)) {
138 layout->addWidget(new QLabel(o->label()), lpos, left);
139 OptColorButton *ow = new OptColorButton(o, this, widget);
140 ow->setObjectName(qPrintf("%02d_color",i));
141 layout->addWidget(ow, lpos++, right);
143 else if(FontOptPtr o =
144 boost::dynamic_pointer_cast<FontOpt,BaseOpt>(_o)) {
145 layout->addWidget(new QLabel(o->label()), lpos, left);
146 OptFontRequester *ow = new OptFontRequester(o,this, widget);
147 ow->setObjectName(qPrintf("%02d_font",i));
148 layout->addWidget(ow, lpos++, right);
150 else
151 ERROR("Unknown option of type " << prettyTypeName(typeid(*_o).name()));
154 if(indent)
155 layout->addItem(new QSpacerItem(25, 1, QSizePolicy::Minimum, QSizePolicy::Minimum),
156 0, 0, lpos, 1);
159 void OptionWidget::setOptionWidgetValues(QWidget* widget, OptList& newopts) {
160 for(int i=0;i<newopts.size();i++) {
161 OptPtr _o = newopts[i];
162 if(BoolOptPtr o =
163 boost::dynamic_pointer_cast<BoolOpt,BaseOpt>(_o)) {
164 OptCheckBox *cb = widget->findChild<OptCheckBox*>(qPrintf("%02d_check",i));
165 if(!cb) goto fail;
166 cb->setChecked(o->value());
168 if(o->m_sub_options.size()) {
169 QWidget *w = widget->findChild<QWidget*>(qPrintf("%02d_check_sub",i));
170 if(!w) goto fail;
171 setOptionWidgetValues(w, o->m_sub_options);
174 else if(SelectOptPtr o =
175 boost::dynamic_pointer_cast<SelectOpt,BaseOpt>(_o)) {
176 QGroupBox *gb = widget->findChild<QGroupBox*>(qPrintf("%02d_group",i));
177 if(!gb) goto fail;
179 for(int j=0;j<o->m_options.size();j++) {
180 BoolOptPtr so = o->m_options[j];
181 OptRadioButton *rb = gb->findChild<OptRadioButton*>(qPrintf("%02d_radio_%02d",i,j));
182 if(!rb) goto fail;
183 rb->setChecked(so->value());
185 if(so->m_sub_options.size()) {
186 QWidget *w = widget->findChild<QWidget*>(qPrintf("%02d_radio_%02d_sub",i,j));
187 if(!w) goto fail;
188 setOptionWidgetValues(w, so->m_sub_options);
192 else if(IntOptPtr o =
193 boost::dynamic_pointer_cast<IntOpt,BaseOpt>(_o)) {
194 switch (o->visualization()) {
195 case IntOpt::SpinBox:
197 OptSpinBox *sb = widget->findChild<OptSpinBox*>(qPrintf("%02d_spin",i));
198 if(!sb) goto fail;
199 sb->setValue(o->value());
200 break;
202 case IntOpt::Slider:
204 OptSlider *sl = widget->findChild<OptSlider*>(qPrintf("%02d_slid",i));
205 if(!sl) goto fail;
206 sl->setValue(o->value());
207 break;
211 else if(StringOptPtr o =
212 boost::dynamic_pointer_cast<StringOpt,BaseOpt>(_o)) {
213 OptLineEdit *ow = widget->findChild<OptLineEdit*>(qPrintf("%02d_line",i));
214 if(!ow) goto fail;
215 ow->setText(o->value());
217 else if(UrlOptPtr o =
218 boost::dynamic_pointer_cast<UrlOpt,BaseOpt>(_o)) {
219 OptUrlRequester *ow = widget->findChild<OptUrlRequester*>(qPrintf("%02d_url",i));
220 if(!ow) goto fail;
221 ow->setUrl(o->value());
223 else if(ComboOptPtr o =
224 boost::dynamic_pointer_cast<ComboOpt,BaseOpt>(_o)) {
225 OptComboBox *ow = widget->findChild<OptComboBox*>(qPrintf("%02d_combo",i));
226 if(!ow) goto fail;
227 ow->setCurrentIndex(o->selected());
229 else if(ColorOptPtr o =
230 boost::dynamic_pointer_cast<ColorOpt,BaseOpt>(_o)) {
231 OptColorButton *ow = widget->findChild<OptColorButton*>(qPrintf("%02d_color",i));
232 if(!ow) goto fail;
233 ow->setColor(o->value());
235 else if(FontOptPtr o =
236 boost::dynamic_pointer_cast<FontOpt,BaseOpt>(_o)) {
237 OptFontRequester *ow = widget->findChild<OptFontRequester*>(qPrintf("%02d_font",i));
238 if(!ow) goto fail;
239 ow->setFont(o->value());
241 else
242 ERROR("Unknown option of type " << prettyTypeName(typeid(*_o).name()));
244 return;
245 fail:
246 ERROR("Options/Widget mismatch!");
249 void dump_options_list(const OptList& options, int indent) {
250 if(!indent)std::cout << "---- begin dump ----" << std::endl;
251 for(int i=0;i<options.size();i++) {
252 OptPtr _o = options[i];
253 if(BoolOptPtr o =
254 boost::dynamic_pointer_cast<BoolOpt,BaseOpt>(_o)) {
255 for(int j=0;j<indent;j++)std::cout << " ";
256 std::cout << (o->value()?"[X]":"[ ]") << " " << o->label() << std::endl;
257 dump_options_list(o->subOptions(), indent+1);
259 else if(IntOptPtr o =
260 boost::dynamic_pointer_cast<IntOpt,BaseOpt>(_o)) {
261 for(int j=0;j<indent;j++)std::cout << " ";
262 std::cout << o->label() << " |" << o->value() << "|" << std::endl;
264 else if(StringOptPtr o =
265 boost::dynamic_pointer_cast<StringOpt,BaseOpt>(_o)) {
266 for(int j=0;j<indent;j++)std::cout << " ";
267 std::cout << o->label() << " [" << o->value() << "]" << std::endl;
269 else if(UrlOptPtr o =
270 boost::dynamic_pointer_cast<UrlOpt,BaseOpt>(_o)) {
271 for(int j=0;j<indent;j++)std::cout << " ";
272 std::cout << o->label() << " {" << o->value() << "}" << std::endl;
274 else if(ColorOptPtr o =
275 boost::dynamic_pointer_cast<ColorOpt,BaseOpt>(_o)) {
276 for(int j=0;j<indent;j++)std::cout << " ";
277 std::cout << o->label() << " {" << o->value().name() << "}" << std::endl;
279 else if(FontOptPtr o =
280 boost::dynamic_pointer_cast<FontOpt,BaseOpt>(_o)) {
281 for(int j=0;j<indent;j++)std::cout << " ";
282 std::cout << o->label() << " {" << o->value().toString() << "}" << std::endl;
284 else if(ComboOptPtr o =
285 boost::dynamic_pointer_cast<ComboOpt,BaseOpt>(_o)) {
286 for(int j=0;j<indent;j++)std::cout << " ";
287 std::cout << "[combo] " << o->label() << std::endl;
288 for(int k=0;k<o->values().size();k++) {
289 for(int j=0;j<indent+1;j++)std::cout << " ";
290 if(k==o->selected())
291 std::cout << " *<" << o->values()[k] << ">*" << std::endl;
292 else
293 std::cout << " <" << o->values()[k] << ">" << std::endl;
296 else if(SelectOptPtr o =
297 boost::dynamic_pointer_cast<SelectOpt,BaseOpt>(_o)) {
298 for(int j=0;j<indent;j++)std::cout << " ";
299 std::cout << "[group] " << o->label() << std::endl;
300 for(int j=0;j<o->options().size();j++) {
301 BoolOptPtr so = o->options()[j];
302 for(int j=0;j<indent+1;j++)std::cout << " ";
303 std::cout << (so->value()?"(*)":"( )") << " " << so->label() << std::endl;
304 if(so->subOptions().size())
305 dump_options_list(so->subOptions(), indent+2);
308 else {
309 std::cout << "dump_options_list: Error, unknown option of type "
310 << prettyTypeName(typeid(*_o).name()) << std::endl;
313 if(!indent)std::cout << "---- end dump ----" << std::endl;
316 bool options_list_load_from_settings(OptList& options, const Settings& s) {
317 bool retv = false;
318 for(int i=0;i<options.size();i++) {
319 OptPtr _o = options[i];
320 if(BoolOptPtr o =
321 boost::dynamic_pointer_cast<BoolOpt,BaseOpt>(_o)) {
322 Settings bool_group = s.group(o->name());
323 retv |= options_list_load_from_settings(o->m_sub_options, bool_group);
324 bool newval = bool_group.flag("value", o->value());
325 retv |= (newval != o->value());
326 o->setValue( newval );
328 else if(IntOptPtr o =
329 boost::dynamic_pointer_cast<IntOpt,BaseOpt>(_o)) {
330 int newval = s[o->name()] | o->value();
331 retv |= (newval != o->value());
332 o->setValue( newval );
334 else if(StringOptPtr o =
335 boost::dynamic_pointer_cast<StringOpt,BaseOpt>(_o)) {
336 QString newval = s[o->name()] | o->value();
337 retv |= (newval != o->value());
338 o->setValue( newval );
340 else if(UrlOptPtr o =
341 boost::dynamic_pointer_cast<UrlOpt,BaseOpt>(_o)) {
342 QString newval = s[o->name()] | o->value();
343 retv |= (newval != o->value());
344 o->setValue( newval );
346 else if(ColorOptPtr o =
347 boost::dynamic_pointer_cast<ColorOpt,BaseOpt>(_o)) {
348 QColor newval = s[o->name()] | o->value();
349 retv |= (newval != o->value());
350 o->setValue( newval );
352 else if(FontOptPtr o =
353 boost::dynamic_pointer_cast<FontOpt,BaseOpt>(_o)) {
354 QFont newval = s[o->name()] | o->value();
355 retv |= (newval != o->value());
356 o->setValue( newval );
358 else if(ComboOptPtr o =
359 boost::dynamic_pointer_cast<ComboOpt,BaseOpt>(_o)) {
360 int newval = s[o->name()] | o->selected();
361 retv |= (newval != o->selected());
362 o->setSelected( newval );
364 else if(SelectOptPtr o =
365 boost::dynamic_pointer_cast<SelectOpt,BaseOpt>(_o)) {
366 OptList l;
367 for(int i=0;i<o->m_options.size();i++)
368 l << o->m_options[i];
369 Settings sel_group = s.group(o->name());
370 retv |= options_list_load_from_settings(l, sel_group.group("sel-options"));
371 int newval = sel_group["value"] | o->selected();
372 retv |= (newval != o->selected());
373 o->setSelected( newval );
375 else
376 ERROR("option of type " << prettyTypeName(typeid(*_o).name()) );
378 return retv;
381 void options_list_save_to_settings(const OptList& options, Settings s) {
382 for(int i=0;i<options.size();i++) {
383 OptPtr _o = options[i];
384 if(BoolOptPtr o =
385 boost::dynamic_pointer_cast<BoolOpt,BaseOpt>(_o)) {
386 Settings bool_group = s.group(o->name());
387 options_list_save_to_settings(o->subOptions(), bool_group);
388 bool_group.setFlag("value", o->value());
390 else if(IntOptPtr o =
391 boost::dynamic_pointer_cast<IntOpt,BaseOpt>(_o)) {
392 s[o->name()] = o->value();
394 else if(StringOptPtr o =
395 boost::dynamic_pointer_cast<StringOpt,BaseOpt>(_o)) {
396 s[o->name()] = o->value();
398 else if(UrlOptPtr o =
399 boost::dynamic_pointer_cast<UrlOpt,BaseOpt>(_o)) {
400 s[o->name()] = o->value();
402 else if(ColorOptPtr o =
403 boost::dynamic_pointer_cast<ColorOpt,BaseOpt>(_o)) {
404 s[o->name()] = o->value();
406 else if(FontOptPtr o =
407 boost::dynamic_pointer_cast<FontOpt,BaseOpt>(_o)) {
408 s[o->name()] = o->value();
410 else if(ComboOptPtr o =
411 boost::dynamic_pointer_cast<ComboOpt,BaseOpt>(_o)) {
412 s[o->name()] = o->value();
414 else if(SelectOptPtr o =
415 boost::dynamic_pointer_cast<SelectOpt,BaseOpt>(_o)) {
416 OptList l;
417 for(int i=0;i<o->options().size();i++)
418 l << o->options()[i];
419 Settings sel_group = s.group(o->name());
420 options_list_save_to_settings(l, sel_group.group("sel-options"));
421 sel_group["value"] = o->value();
423 else
424 ERROR("option of type " << prettyTypeName(typeid(*_o).name()) );