00001 #include <algorithm>
00002
00003 #include <qwidgetstack.h>
00004 #include <qtabdialog.h>
00005
00006 #include "mythconfiggroups.h"
00007
00008 static void clear_widgets(vector<Configurable*> &children,
00009 vector<QWidget*> &childwidget)
00010 {
00011 for (uint i = 0; (i < childwidget.size()) && (i < children.size()); i++)
00012 {
00013 if (children[i] && childwidget[i])
00014 children[i]->widgetInvalid(childwidget[i]);
00015 }
00016 childwidget.clear();
00017 }
00018
00019 ConfigurationGroup::~ConfigurationGroup()
00020 {
00021 childList::iterator it = children.begin();
00022 for (; it != children.end() ; ++it)
00023 {
00024 if (*it)
00025 {
00026 (*it)->disconnect();
00027 (*it)->deleteLater();
00028 }
00029 }
00030 children.clear();
00031 }
00032
00033 void ConfigurationGroup::deleteLater(void)
00034 {
00035 childList::iterator it = children.begin();
00036 for (; it != children.end() ; ++it)
00037 {
00038 if (*it)
00039 (*it)->disconnect();
00040 }
00041 Setting::deleteLater();
00042 }
00043
00044 Setting *ConfigurationGroup::byName(const QString &name)
00045 {
00046 Setting *tmp = NULL;
00047
00048 childList::iterator it = children.begin();
00049 for (; !tmp && (it != children.end()); ++it)
00050 {
00051 if (*it)
00052 tmp = (*it)->byName(name);
00053 }
00054
00055 return tmp;
00056 }
00057
00058 void ConfigurationGroup::load(void)
00059 {
00060 childList::iterator it = children.begin();
00061 for (; it != children.end() ; ++it)
00062 if (*it && (*it)->GetStorage())
00063 (*it)->GetStorage()->load();
00064 }
00065
00066 void ConfigurationGroup::save(void)
00067 {
00068 childList::iterator it = children.begin();
00069 for (; it != children.end() ; ++it)
00070 if (*it && (*it)->GetStorage())
00071 (*it)->GetStorage()->save();
00072 }
00073
00074 void ConfigurationGroup::save(QString destination)
00075 {
00076 childList::iterator it = children.begin();
00077 for (; it != children.end() ; ++it)
00078 if (*it && (*it)->GetStorage())
00079 (*it)->GetStorage()->save(destination);
00080 }
00081
00082 QWidget* VerticalConfigurationGroup::configWidget(ConfigurationGroup *cg,
00083 QWidget* parent,
00084 const char* widgetName)
00085 {
00086 widget = new QGroupBox(parent, widgetName);
00087 connect(widget, SIGNAL(destroyed(QObject*)),
00088 this, SLOT(widgetDeleted(QObject*)));
00089
00090 widget->setBackgroundOrigin(QWidget::WindowOrigin);
00091
00092 if (!useframe)
00093 widget->setFrameShape(QFrame::NoFrame);
00094
00095 float wmult = 0, hmult = 0;
00096 gContext->GetScreenSettings(wmult, hmult);
00097
00098 int space = (zeroSpace) ? 4 : -1;
00099 int margin = (int) ((uselabel) ? (28 * hmult) : (10 * hmult));
00100 margin = (zeroMargin) ? 4 : margin;
00101
00102 layout = new QVBoxLayout(widget, margin, space);
00103
00104 if (uselabel)
00105 widget->setTitle(getLabel());
00106
00107 childwidget.resize(children.size());
00108 for (uint i = 0; i < children.size(); i++)
00109 {
00110 if (children[i] && children[i]->isVisible())
00111 {
00112 childwidget[i] = children[i]->configWidget(cg, widget, NULL);
00113 layout->add(childwidget[i]);
00114 children[i]->setEnabled(children[i]->isEnabled());
00115 }
00116 }
00117
00118 if (cg)
00119 {
00120 connect(this, SIGNAL(changeHelpText(QString)),
00121 cg, SIGNAL(changeHelpText(QString)));
00122 confgrp = cg;
00123 }
00124
00125 return widget;
00126 }
00127
00128 void VerticalConfigurationGroup::widgetInvalid(QObject *obj)
00129 {
00130 widget = (widget == obj) ? NULL : widget;
00131 }
00132
00133 void VerticalConfigurationGroup::deleteLater(void)
00134 {
00135 clear_widgets(children, childwidget);
00136 ConfigurationGroup::deleteLater();
00137 }
00138
00139 bool VerticalConfigurationGroup::replaceChild(
00140 Configurable *old_child, Configurable *new_child)
00141 {
00142 childList::iterator it = children.begin();
00143 for (uint i = 0; it != children.end(); ++it, ++i)
00144 {
00145 if (*it != old_child)
00146 continue;
00147
00148 *it = new_child;
00149
00150 if (!widget)
00151 {
00152 old_child->deleteLater();
00153 return true;
00154 }
00155
00156 if (childwidget[i])
00157 {
00158 old_child->widgetInvalid(childwidget[i]);
00159 layout->remove(childwidget[i]);
00160 childwidget[i]->deleteLater();
00161 childwidget[i] = NULL;
00162 }
00163
00164 bool was_visible = old_child->isVisible();
00165 bool was_enabled = old_child->isEnabled();
00166
00167 old_child->deleteLater();
00168
00169 if (was_visible)
00170 {
00171 childwidget[i] = new_child->configWidget(confgrp, widget, NULL);
00172 layout->add(childwidget[i]);
00173 new_child->setEnabled(was_enabled);
00174 childwidget[i]->resize(1,1);
00175 childwidget[i]->show();
00176 }
00177
00178 return true;
00179 }
00180
00181 return false;
00182 }
00183
00184 void VerticalConfigurationGroup::repaint(void)
00185 {
00186 if (widget)
00187 widget->repaint();
00188 }
00189
00190 QWidget* HorizontalConfigurationGroup::configWidget(ConfigurationGroup *cg,
00191 QWidget* parent,
00192 const char* widgetName)
00193 {
00194 QGroupBox* widget = new QGroupBox(parent, widgetName);
00195 widget->setBackgroundOrigin(QWidget::WindowOrigin);
00196
00197 if (!useframe)
00198 widget->setFrameShape(QFrame::NoFrame);
00199
00200 QHBoxLayout *layout = NULL;
00201
00202 float wmult = 0, hmult = 0;
00203
00204 gContext->GetScreenSettings(wmult, hmult);
00205
00206 if (uselabel)
00207 {
00208 int space = -1;
00209 int margin = (int)(28 * hmult);
00210 if (zeroSpace)
00211 space = 4;
00212 if (zeroMargin)
00213 margin = 4;
00214
00215 layout = new QHBoxLayout(widget, margin, space);
00216
00217
00218 widget->setTitle(getLabel());
00219 }
00220 else
00221 {
00222 int space = -1;
00223 int margin = (int)(10 * hmult);
00224 if (zeroSpace)
00225 space = 4;
00226 if (zeroMargin)
00227 margin = 4;
00228
00229 layout = new QHBoxLayout(widget, margin, space);
00230 }
00231
00232 for(unsigned i = 0 ; i < children.size() ; ++i)
00233 if (children[i]->isVisible())
00234 {
00235 QWidget *child = children[i]->configWidget(cg, widget, NULL);
00236 layout->add(child);
00237 children[i]->setEnabled(children[i]->isEnabled());
00238 }
00239
00240 if (cg)
00241 {
00242 connect(this, SIGNAL(changeHelpText(QString)), cg,
00243 SIGNAL(changeHelpText(QString)));
00244 }
00245
00246 return widget;
00247 }
00248
00249 QWidget* GridConfigurationGroup::configWidget(ConfigurationGroup *cg,
00250 QWidget* parent,
00251 const char* widgetName)
00252 {
00253 QGroupBox* widget = new QGroupBox(parent, widgetName);
00254 widget->setBackgroundOrigin(QWidget::WindowOrigin);
00255
00256 if (!useframe)
00257 widget->setFrameShape(QFrame::NoFrame);
00258
00259 QGridLayout *layout = NULL;
00260
00261 float wmult = 0, hmult = 0;
00262
00263 gContext->GetScreenSettings(wmult, hmult);
00264
00265 int rows = (children.size()+columns-1) / columns;
00266 if (uselabel)
00267 {
00268 int space = -1;
00269 int margin = (int)(28 * hmult);
00270 if (zeroSpace)
00271 space = 4;
00272 if (zeroMargin)
00273 margin = 4;
00274
00275 layout = new QGridLayout(widget, rows, columns, margin, space);
00276
00277
00278 widget->setTitle(getLabel());
00279 }
00280 else
00281 {
00282 int space = -1;
00283 int margin = (int)(10 * hmult);
00284 if (zeroSpace)
00285 space = 4;
00286 if (zeroMargin)
00287 margin = 4;
00288
00289 layout = new QGridLayout(widget, rows, columns, margin, space);
00290 }
00291
00292 for (unsigned i = 0 ; i < children.size() ; ++i)
00293 if (children[i]->isVisible())
00294 {
00295 QWidget *child = children[i]->configWidget(cg, widget, NULL);
00296 layout->addWidget(child, i / columns, i % columns);
00297 children[i]->setEnabled(children[i]->isEnabled());
00298 }
00299
00300 if (cg)
00301 {
00302 connect(this, SIGNAL(changeHelpText(QString)), cg,
00303 SIGNAL(changeHelpText(QString)));
00304 }
00305
00306 return widget;
00307 }
00308
00309 StackedConfigurationGroup::~StackedConfigurationGroup()
00310 {
00311 clear_widgets(children, childwidget);
00312 ConfigurationGroup::deleteLater();
00313 }
00314
00315 void StackedConfigurationGroup::deleteLater(void)
00316 {
00317 clear_widgets(children, childwidget);
00318 ConfigurationGroup::deleteLater();
00319 }
00320
00321 QWidget* StackedConfigurationGroup::configWidget(ConfigurationGroup *cg,
00322 QWidget* parent,
00323 const char* widgetName)
00324 {
00325 widget = new QWidgetStack(parent, widgetName);
00326 connect(widget, SIGNAL(destroyed(QObject*)),
00327 this, SLOT(widgetDeleted(QObject*)));
00328
00329 widget->setBackgroundOrigin(QWidget::WindowOrigin);
00330
00331 for (uint i = 0 ; i < children.size() ; ++i)
00332 {
00333 if (children[i]->isVisible())
00334 {
00335 childwidget[i] = children[i]->configWidget(cg, widget, NULL);
00336 widget->addWidget(childwidget[i], i);
00337 }
00338 }
00339
00340 widget->raiseWidget(top);
00341
00342 connect(this, SIGNAL(raiseWidget(int)),
00343 widget, SLOT(raiseWidget(int)));
00344
00345 if (cg)
00346 {
00347 connect(this, SIGNAL(changeHelpText(QString)), cg,
00348 SIGNAL(changeHelpText(QString)));
00349 }
00350 confgrp = cg;
00351
00352 return widget;
00353 }
00354
00355 void StackedConfigurationGroup::widgetInvalid(QObject *obj)
00356 {
00357 widget = (widget == obj) ? NULL : widget;
00358 }
00359
00360 void StackedConfigurationGroup::addChild(Configurable *child)
00361 {
00362 ConfigurationGroup::addChild(child);
00363 childwidget.resize(childwidget.size() + 1);
00364 if (!widget)
00365 return;
00366
00367 uint i = children.size() - 1;
00368 if ((i < children.size()) && children[i]->isVisible())
00369 {
00370 childwidget[i] = children[i]->configWidget(confgrp, widget, NULL);
00371 widget->addWidget(childwidget[i], i);
00372 childwidget[i]->resize(1,1);
00373 childwidget[i]->show();
00374 }
00375 }
00376
00377 void StackedConfigurationGroup::removeChild(Configurable *child)
00378 {
00379 childList::iterator it = find(children.begin(), children.end(), child);
00380 if (it == children.end())
00381 return;
00382
00383 uint i = it - children.begin();
00384 if ((i >= children.size()) || (i >= childwidget.size()))
00385 return;
00386
00387 children.erase(it);
00388
00389 vector<QWidget*>::iterator cit = childwidget.begin() + i;
00390 QWidget *cw = *cit;
00391 childwidget.erase(cit);
00392
00393 if (widget && cw)
00394 {
00395 child->widgetInvalid(cw);
00396 widget->removeWidget(cw);
00397 }
00398 }
00399
00400 void StackedConfigurationGroup::raise(Configurable* child)
00401 {
00402 for (uint i = 0 ; i < children.size() ; i++)
00403 {
00404 if (children[i] == child)
00405 {
00406 top = i;
00407 emit raiseWidget((int)i);
00408 return;
00409 }
00410 }
00411
00412 VERBOSE(VB_IMPORTANT, "BUG: StackedConfigurationGroup::raise(): "
00413 "unrecognized child " << child << " "
00414 <<QString("on setting %1/%2").arg(getName()).arg(getLabel()));
00415 }
00416
00417 void StackedConfigurationGroup::save(void)
00418 {
00419 if (saveAll)
00420 ConfigurationGroup::save();
00421 else if (top < children.size())
00422 children[top]->GetStorage()->save();
00423 }
00424
00425 void StackedConfigurationGroup::save(QString destination)
00426 {
00427 if (saveAll)
00428 ConfigurationGroup::save(destination);
00429 else if (top < children.size())
00430 children[top]->GetStorage()->save(destination);
00431 }
00432
00433 void TriggeredConfigurationGroup::addChild(Configurable* child)
00434 {
00435 VerifyLayout();
00436 configLayout->addChild(child);
00437 }
00438
00439 void TriggeredConfigurationGroup::addTarget(QString triggerValue,
00440 Configurable *target)
00441 {
00442 VerifyLayout();
00443 triggerMap[QDeepCopy<QString>(triggerValue)] = target;
00444
00445 if (!configStack)
00446 {
00447 configStack = new StackedConfigurationGroup(
00448 stackUseLabel, stackUseFrame, stackZeroMargin, stackZeroSpace);
00449 configStack->setSaveAll(isSaveAll);
00450 }
00451
00452 configStack->addChild(target);
00453 }
00454
00455 Setting *TriggeredConfigurationGroup::byName(const QString &settingName)
00456 {
00457 VerifyLayout();
00458 Setting *setting = ConfigurationGroup::byName(settingName);
00459
00460 if (!setting)
00461 setting = configLayout->byName(settingName);
00462
00463 if (!setting && !widget)
00464 setting = configStack->byName(settingName);
00465
00466 return setting;
00467 }
00468
00469 void TriggeredConfigurationGroup::load(void)
00470 {
00471 VerifyLayout();
00472
00473 configLayout->load();
00474
00475 if (!widget && configStack)
00476 configStack->load();
00477 }
00478
00479 void TriggeredConfigurationGroup::save(void)
00480 {
00481 VerifyLayout();
00482
00483 configLayout->save();
00484
00485 if (!widget)
00486 configStack->save();
00487 }
00488
00489 void TriggeredConfigurationGroup::save(QString destination)
00490 {
00491 VerifyLayout();
00492
00493 configLayout->save(destination);
00494
00495 if (!widget)
00496 configStack->save(destination);
00497 }
00498
00499 void TriggeredConfigurationGroup::repaint(void)
00500 {
00501 VerifyLayout();
00502
00503 if (widget)
00504 widget->repaint();
00505 }
00506
00507 void TriggeredConfigurationGroup::setTrigger(Configurable *_trigger)
00508 {
00509 if (trigger)
00510 {
00511 trigger->disconnect();
00512 }
00513
00514 trigger = _trigger;
00515
00516 if (trigger)
00517 {
00518 connect(trigger, SIGNAL(valueChanged( const QString&)),
00519 this, SLOT( triggerChanged(const QString&)));
00520 }
00521 }
00522
00529 void TriggeredConfigurationGroup::SetVertical(bool vert)
00530 {
00531 if (configLayout)
00532 {
00533 VERBOSE(VB_IMPORTANT, "TriggeredConfigurationGroup::setVertical(): "
00534 "Sorry, this must be called before any children are added "
00535 "to the group.");
00536 return;
00537 }
00538
00539 isVertical = vert;
00540 }
00541
00542 void TriggeredConfigurationGroup::removeTarget(QString triggerValue)
00543 {
00544 HostComboBox *combobox = dynamic_cast<HostComboBox*>(trigger);
00545 if (!combobox)
00546 return;
00547
00548 QMap<QString,Configurable*>::iterator cit = triggerMap.find(triggerValue);
00549 if (cit == triggerMap.end())
00550 return;
00551
00552
00553 combobox->removeSelection(triggerValue);
00554
00555
00556 configStack->removeChild(*cit);
00557 triggerMap.erase(cit);
00558 }
00559
00560 void TriggeredConfigurationGroup::VerifyLayout(void)
00561 {
00562 if (configLayout)
00563 return;
00564
00565 if (isVertical)
00566 {
00567 configLayout = new VerticalConfigurationGroup(
00568 uselabel, useframe, zeroMargin, zeroSpace);
00569 }
00570 else
00571 {
00572 configLayout = new HorizontalConfigurationGroup(
00573 uselabel, useframe, zeroMargin, zeroSpace);
00574 }
00575
00576 ConfigurationGroup::addChild(configLayout);
00577 }
00578
00579 QWidget *TriggeredConfigurationGroup::configWidget(
00580 ConfigurationGroup *cg, QWidget *parent, const char *widgetName)
00581 {
00582 VerifyLayout();
00583
00584 configLayout->addChild(configStack);
00585
00586 widget = configLayout->configWidget(cg, parent, widgetName);
00587 connect(widget, SIGNAL(destroyed(QObject*)),
00588 this, SLOT(widgetDeleted(QObject*)));
00589
00590 return widget;
00591 }
00592
00593 void TriggeredConfigurationGroup::widgetInvalid(QObject *obj)
00594 {
00595 widget = (widget == obj) ? NULL : widget;
00596 }
00597
00598 QWidget* TabbedConfigurationGroup::configWidget(ConfigurationGroup *cg,
00599 QWidget* parent,
00600 const char* widgetName)
00601 {
00602 QTabDialog* widget = new QTabDialog(parent, widgetName);
00603 widget->setBackgroundOrigin(QWidget::WindowOrigin);
00604
00605 for(unsigned i = 0 ; i < children.size() ; ++i)
00606 if (children[i]->isVisible())
00607 widget->addTab(children[i]->configWidget(cg, widget),
00608 children[i]->getLabel());
00609
00610 if (cg)
00611 {
00612 connect(this, SIGNAL(changeHelpText(QString)), cg,
00613 SIGNAL(changeHelpText(QString)));
00614 }
00615
00616 return widget;
00617 };
00618
00619 JumpPane::JumpPane(const QStringList &labels, const QStringList &helptext) :
00620 VerticalConfigurationGroup(true, false, true, true)
00621 {
00622
00623 for (uint i = 0; i < labels.size(); i++)
00624 {
00625 TransButtonSetting *button =
00626 new TransButtonSetting(QString::number(i));
00627 button->setLabel(labels[i]);
00628 button->setHelpText(helptext[i]);
00629 connect(button, SIGNAL(pressed(QString)),
00630 this, SIGNAL(pressed(QString)));
00631 addChild(button);
00632 }
00633 }