00001 #include <cstdlib>
00002 using namespace std;
00003
00004 #include "managedlist.h"
00005 #include "mythcontext.h"
00006 #include "xmlparse.h"
00008
00009
00010
00012 ManagedListItem::ManagedListItem(const QString& startingText, ManagedList* _parentList, QObject* _parent, const char* _name)
00013 : QObject(_parent, _name)
00014 {
00015 text = startingText;
00016 listIndex = 0;
00017 curState = MLS_NORMAL;
00018 enabled = true;
00019 parentList = _parentList;
00020 valueText = " ";
00021 }
00022
00023 void ManagedListItem::setParentList(ManagedList* _parentList)
00024 {
00025 parentList = _parentList;
00026 connect(this, SIGNAL(changed(ManagedListItem*)), parentList, SLOT(itemChanged(ManagedListItem*)));
00027 }
00028
00029
00030
00031
00033
00034
00035
00037
00038
00039 BoolManagedListItem::BoolManagedListItem(bool _initialValue, ManagedListGroup* pGroup,
00040 ManagedList* pList, QObject* _parent, const char* _name)
00041 : SelectManagedListItem("", pGroup, pList, _parent, _name)
00042 {
00043 initialValue = _initialValue;
00044 listBuilt = false;
00045 }
00046
00047 void BoolManagedListItem::setLabels(const QString& _trueLabel, const QString& _falseLabel)
00048 {
00049 trueLabel = _trueLabel;
00050 falseLabel = _falseLabel;
00051 setValue(initialValue);
00052 }
00053
00054 void BoolManagedListItem::generateList()
00055 {
00056 if (!listBuilt)
00057 {
00058 addSelection(trueLabel, "1", false);
00059 addSelection(falseLabel, "0", false);
00060 listBuilt = true;
00061 selectValue(valueText);
00062 }
00063 }
00064
00065
00067
00068
00069
00071 IntegerManagedListItem::IntegerManagedListItem(int _bigStep, int _step, ManagedList* pList, QObject* _parent, const char* _name)
00072 : ManagedListItem("", pList, _parent, _name)
00073 {
00074 step = _step;
00075 bigStep = _bigStep;
00076
00077 setTemplates("-%1","-%1", "%1", "%1", "%1");
00078 setShortTemplates("-%1","-%1", "%1", "%1", "%1");
00079
00080 ManagedListItem::setValue(QString("0"));
00081 }
00082
00083
00084 void IntegerManagedListItem::setTemplates(const QString& negStr, const QString& negOneStr, const QString& zeroStr,
00085 const QString& oneStr, const QString& posStr)
00086 {
00087 negTemplate = negStr;
00088 negOneTemplate = negOneStr;
00089 posTemplate = posStr;
00090 posOneTemplate = oneStr;
00091 zeroTemplate = zeroStr;
00092 syncTextToValue();
00093 }
00094
00095 void IntegerManagedListItem::setShortTemplates(const QString& negStr, const QString& negOneStr, const QString& zeroStr,
00096 const QString& oneStr, const QString& posStr)
00097 {
00098 shortNegTemplate = negStr;
00099 shortNegOneTemplate = negOneStr;
00100 shortPosTemplate = posStr;
00101 shortPosOneTemplate = oneStr;
00102 shortZeroTemplate = zeroStr;
00103 syncTextToValue();
00104 }
00105
00106 #define ASSIGN_TEMPLATE(x,y,z) \
00107 if (x.find("%1") != -1) \
00108 y = QString(x).arg(abs(z)); \
00109 else \
00110 y = x;
00111
00112
00113
00114 void IntegerManagedListItem::syncTextToValue()
00115 {
00116 int v = intValue();
00117 if (v == 0)
00118 {
00119 ASSIGN_TEMPLATE(zeroTemplate, text, v)
00120 ASSIGN_TEMPLATE(shortZeroTemplate, shortText, v)
00121 }
00122 else if (v == 1)
00123 {
00124 ASSIGN_TEMPLATE(posOneTemplate, text, v);
00125 ASSIGN_TEMPLATE(shortPosOneTemplate, shortText, v);
00126 }
00127 else if (v == -1)
00128 {
00129 ASSIGN_TEMPLATE(negOneTemplate, text, v);
00130 ASSIGN_TEMPLATE(shortNegOneTemplate, shortText, v);
00131 }
00132 else if (v > 0)
00133 {
00134 ASSIGN_TEMPLATE(posTemplate, text, v);
00135 ASSIGN_TEMPLATE(shortPosTemplate, shortText, v);
00136 }
00137 else
00138 {
00139 ASSIGN_TEMPLATE(negTemplate, text, v);
00140 ASSIGN_TEMPLATE(shortNegTemplate, shortText, v);
00141 }
00142
00143 ManagedListItem::syncTextToValue();
00144 }
00145
00146
00148
00149
00150
00152 BoundedIntegerManagedListItem::BoundedIntegerManagedListItem(int _minVal, int _maxVal, int _bigStep,
00153 int _step, ManagedListGroup* _group,
00154 ManagedList* _list,
00155 QObject* _parent, const char* _name,
00156 bool _invert)
00157 : SelectManagedListItem("", _group, _list, _parent, _name)
00158 {
00159 step = _step;
00160 bigStep = _bigStep;
00161 minVal = _minVal;
00162 maxVal = _maxVal;
00163 listBuilt = false;
00164 inverted = _invert;
00165
00166 }
00167
00168
00169 void BoundedIntegerManagedListItem::setTemplates(const QString& negStr, const QString& negOneStr,
00170 const QString& zeroStr,
00171 const QString& oneStr, const QString& posStr)
00172 {
00173 negTemplate = negStr;
00174 negOneTemplate = negOneStr;
00175 posTemplate = posStr;
00176 posOneTemplate = oneStr;
00177 zeroTemplate = zeroStr;
00178
00179 }
00180
00181 void BoundedIntegerManagedListItem::setValue(int val)
00182 {
00183 if (val > maxVal)
00184 val = maxVal;
00185 else if ( val < minVal)
00186 val = minVal;
00187
00188 SelectManagedListItem::setValue(QString::number(val));
00189 }
00190
00191 void BoundedIntegerManagedListItem::generateList()
00192 {
00193 if (!listBuilt)
00194 {
00195 for (int i = minVal; i <= maxVal; i++)
00196 {
00197 addSelection( numericToString(i), QString::number(i), false);
00198 }
00199
00200 listBuilt = true;
00201 selectValue(valueText);
00202 }
00203
00204 }
00205
00206
00207 QString BoundedIntegerManagedListItem::numericToString(int v)
00208 {
00209 QString str;
00210 if (v == 0)
00211 {
00212 ASSIGN_TEMPLATE(zeroTemplate, str, v)
00213 }
00214 else if (v == 1)
00215 {
00216 ASSIGN_TEMPLATE(posOneTemplate, str, v);
00217 }
00218 else if (v == -1)
00219 {
00220 ASSIGN_TEMPLATE(negOneTemplate, str, v);
00221 }
00222 else if (v > 0)
00223 {
00224 ASSIGN_TEMPLATE(posTemplate, str, v);
00225 }
00226 else
00227 {
00228 ASSIGN_TEMPLATE(negTemplate, str, v);
00229 }
00230
00231 return str;
00232 }
00233
00234
00236
00237
00238
00240 ManagedListGroup::ManagedListGroup(const QString& txt, ManagedListGroup* pGroup, ManagedList* pList,
00241 QObject* _parent, const char* _name)
00242 : ManagedListItem(txt, pList, _parent, _name)
00243 {
00244 parentGroup = pGroup;
00245 if (pGroup)
00246 {
00247 goBack = new ManagedListItem(QString("[ %1 ]").arg(QObject::tr("Go Back")), parentList, this, "goBack");
00248 goBack->setValue("__NO_VALUE__");
00249 goBack->setState(MLS_BOLD);
00250 goBack->setEnabled(true);
00251 addItem(goBack);
00252 connect(goBack, SIGNAL(selected(ManagedListItem*)), this, SLOT(doGoBack()));
00253 connect(goBack, SIGNAL(canceled(ManagedListItem*)), this, SLOT(doGoBack()));
00254 }
00255 else
00256 goBack = NULL;
00257 curItem = 0;
00258 itemCount = 0;
00259
00260 }
00261
00262 void ManagedListGroup::slotGuiActivate(ManagedListGroup* _group)
00263 {
00264 if (_group != this)
00265 return;
00266
00267 ManagedListItem* item = NULL;
00268 for (item = itemList.first(); item; item = itemList.next())
00269 {
00270 item->slotGuiActivate(_group);
00271 }
00272 }
00273
00274 void ManagedListGroup::setCurIndex(int newVal)
00275 {
00276 if (newVal < 0)
00277 newVal = 0;
00278 else if (newVal >= itemCount)
00279 newVal = itemCount - 1;
00280
00281 curItem = newVal;
00282 valueText = QString::number(curItem);
00283 getCurItem()->gotFocus();
00284
00285 changed();
00286 }
00287
00288
00289 bool ManagedListGroup::addItem(ManagedListItem* item, int where)
00290 {
00291 if (!item)
00292 return false;
00293
00294 if (QString(item->name()) == "unnamed")
00295 item->setName( QString( "ITEM-%1").arg(itemList.count()));
00296
00297 if (!child(item->name()) && !item->parent())
00298 insertChild(item);
00299
00300 int listSize = itemList.count();
00301
00302 if ((where == -2) || (listSize ==0))
00303 itemList.append(item);
00304 else if (where == -1)
00305 itemList.insert(itemList.count() - 1, item);
00306 else
00307 itemList.insert(where, item);
00308
00309 itemCount = itemList.count();
00310 if (parentList)
00311 connect(item, SIGNAL(changed(ManagedListItem*)), parentList, SLOT(itemChanged(ManagedListItem*)));
00312 return true;
00313 }
00314
00315 void ManagedListGroup::doGoBack()
00316 {
00317 emit goingBack();
00318 getParentList()->setCurGroup(parentGroup);
00319 emit wentBack();
00320 }
00321
00322 void ManagedListGroup::cursorRight(bool)
00323 {
00324 getParentList()->setCurGroup(this);
00325 }
00326
00327 void ManagedListGroup::select()
00328 {
00329 if (enabled)
00330 getParentList()->setCurGroup(this);
00331 }
00332
00333 void ManagedListGroup::clear()
00334 {
00335 ManagedListItem* tempItem = NULL;
00336 for(tempItem = itemList.first(); tempItem; tempItem = itemList.next() )
00337 {
00338 delete tempItem;
00339 }
00340
00341 itemList.clear();
00342
00343 if (parentGroup)
00344 {
00345 goBack = new ManagedListItem(QString("[ %1 ]").arg(QObject::tr("Go Back")), parentList, this, "goBack");
00346 goBack->setValue("__NO_VALUE__");
00347 addItem(goBack);
00348 connect(goBack, SIGNAL(selected(ManagedListItem*)), this, SLOT(doGoBack()));
00349 connect(goBack, SIGNAL(canceled(ManagedListItem*)), this, SLOT(doGoBack()));
00350 }
00351
00352 }
00353
00354
00355 void ManagedListGroup::setParentList(ManagedList* _parent)
00356 {
00357 ManagedListItem* tempItem = NULL;
00358 ManagedListItem::setParentList(_parent);
00359 for(tempItem = itemList.first(); tempItem; tempItem = itemList.next() )
00360 {
00361 tempItem->setParentList(_parent);
00362 }
00363 }
00364
00366
00367
00368
00370 SelectManagedListItem::SelectManagedListItem(const QString& baseTxt, ManagedListGroup* pGroup, ManagedList* pList,
00371 QObject* _parent, const char* _name)
00372 : ManagedListGroup(baseTxt, pGroup, pList, _parent, _name)
00373 {
00374 baseText = baseTxt;
00375 goBack->setText(QString("[ %1 ]").arg(QObject::tr("No Change")));
00376 }
00377
00378 ManagedListItem* SelectManagedListItem::addSelection(const QString& label, QString value, bool selectit)
00379 {
00380 ManagedListItem* ret = NULL;
00381
00382 if (value == QString::null)
00383 value = label;
00384
00385 bool found = false;
00386
00387 for(ManagedListItem* tempItem = itemList.first(); tempItem; tempItem = itemList.next() )
00388 {
00389 if ((tempItem->getText() == label) || (tempItem->getValue() == value))
00390 {
00391 found = true;
00392 tempItem->setValue(value);
00393 tempItem->setText(label);
00394 ret = tempItem;
00395 break;
00396 }
00397
00398 }
00399
00400 if (!found)
00401 {
00402 ManagedListItem* newItem = new ManagedListItem(label, parentList, this, label);
00403 newItem->setValue(value);
00404 addItem(newItem);
00405 ret = newItem;
00406 connect(newItem, SIGNAL(selected(ManagedListItem*)), this, SLOT(itemSelected(ManagedListItem* )));
00407 }
00408
00409
00410
00411
00412
00413 if (value == valueText)
00414 {
00415
00416 int index = getValueIndex(value);
00417
00418 if (index > 0)
00419 {
00420 curItem = index;
00421 text = getCurItemText();
00422 setValue(value);
00423 }
00424 }
00425 else if (selectit)
00426 selectValue(value);
00427
00428
00429 emit selectionAdded(label, value);
00430
00431 return ret;
00432 }
00433
00434 ManagedListItem* SelectManagedListItem::addButton(const QString& label, QString value, bool selectit)
00435 {
00436 ManagedListItem* newItem = new ManagedListItem(label, parentList, this, label);
00437 newItem->setValue(value);
00438 addItem(newItem);
00439
00440
00441 connect(newItem, SIGNAL(selected(ManagedListItem*)), this, SLOT(buttonSelected(ManagedListItem* )));
00442 if (selectit)
00443 selectValue(value);
00444 return newItem;
00445 }
00446
00447
00448 void SelectManagedListItem::clearSelections(void)
00449 {
00450 ManagedListGroup::clear();
00451 isSet = false;
00452
00453 text = baseText;
00454 emit selectionsCleared();
00455 changed();
00456 }
00457
00458
00459 void SelectManagedListItem::cursorRight(bool)
00460 {
00461 if (!enabled)
00462 return;
00463
00464 ++curItem;
00465 if (curItem >= (itemCount-1))
00466 curItem = 0;
00467
00468 text = getCurItemText();
00469 valueText = getCurItemValue();
00470
00471 changed();
00472 }
00473
00474 void SelectManagedListItem::cursorLeft(bool)
00475 {
00476 if (!enabled)
00477 return;
00478
00479 --curItem;
00480 if (curItem < 0)
00481 curItem = itemCount - 2;
00482
00483 text = getCurItemText();
00484 valueText = getCurItemValue();
00485 changed();
00486 }
00487
00488 void SelectManagedListItem::setValue(const QString& newValue)
00489 {
00490 int index = getValueIndex(newValue);
00491 if ((curItem != index) && (index != -1))
00492 {
00493 curItem = getValueIndex(newValue);
00494 }
00495 text = getCurItemText();
00496 ManagedListGroup::setValue(newValue);
00497 }
00498
00499
00500 void SelectManagedListItem::select(const QString& newValue, bool bValue)
00501 {
00502 int index = 1;
00503
00504 if (bValue)
00505 index = getValueIndex(newValue);
00506 else
00507 index = getTextIndex(newValue);
00508
00509
00510 if (index > -1)
00511 {
00512 curItem = index;
00513 text = getCurItemText();
00514 setValue(getCurItemValue());
00515 }
00516 }
00517
00518
00519 void SelectManagedListItem::select()
00520 {
00521 lastItem = curItem;
00522 ManagedListGroup::select();
00523 }
00524
00525 void SelectManagedListItem::doGoBack()
00526 {
00527 if (curItem == (itemCount - 1) )
00528 curItem = lastItem;
00529 else
00530 text = getCurItemText();
00531
00532 valueText = getCurItemValue();
00533 text = getCurItemText();
00534 changed();
00535
00536
00537 ManagedListGroup::doGoBack();
00538 }
00539
00540 void SelectManagedListItem::itemSelected(ManagedListItem*)
00541 {
00542 doGoBack();
00543 }
00544
00545 void SelectManagedListItem::buttonSelected(ManagedListItem* itm)
00546 {
00547 parentList->setLocked();
00548 emit(buttonPressed(this, itm));
00549 doGoBack();
00550 parentList->setLocked(false);
00551 }
00552
00553
00555
00556
00557
00559 ManagedList::ManagedList(MythDialog* parent, const char* name) : QObject(parent, name)
00560 {
00561 listRect = QRect(0, 0, 0, 0);
00562 theme = NULL;
00563 curGroup = NULL;
00564 locked = false;
00565 }
00566
00567
00568 void ManagedList::paintEvent(const QRect& r, QPainter *p, bool force)
00569 {
00570
00571 if (force || r.intersects(listRect))
00572 update(p);
00573 }
00574
00575
00576 void ManagedList::update(QPainter *p)
00577 {
00578
00579 LayerSet *container = theme->GetSet(containerName);
00580 if (container && curGroup)
00581 {
00582
00583 int itemCount = curGroup->getItemCount();
00584 int curItem = curGroup->getCurIndex();
00585
00586
00587 QRect pr = listRect;
00588 QPixmap pix(pr.size());
00589 pix.fill(getParent(), pr.topLeft());
00590 QPainter tmp(&pix);
00591
00592 QString tmptitle;
00593
00594
00595
00596 UIListType *ltype = (UIListType *)container->GetType(listName);
00597 if (ltype)
00598 {
00599 ltype->ResetList();
00600 ltype->SetActive(true);
00601 int skip;
00602 if (itemCount <= listSize || curItem <= listSize / 2)
00603 skip = 0;
00604 else if (curItem >= itemCount - listSize + listSize / 2)
00605 skip = itemCount - listSize;
00606 else
00607 skip = curItem - listSize / 2;
00608
00609 ltype->SetUpArrow(skip > 0);
00610 ltype->SetDownArrow(skip + listSize < itemCount);
00611
00612
00613 for (int i = 0; i < listSize; i++)
00614 {
00615 if (i + skip >= itemCount)
00616 break;
00617
00618 ManagedListItem *itm = curGroup->getItem(i+skip);
00619
00620 ltype->SetItemText(i, 1, itm->getText());
00621 int arrowsWanted = 0;
00622
00623 if (itm->hasLeft())
00624 {
00625 arrowsWanted = UIListType::ARROW_LEFT;
00626 }
00627
00628 if (itm->hasRight())
00629 {
00630 arrowsWanted |= UIListType::ARROW_RIGHT;
00631
00632 }
00633
00634 ltype->SetItemArrow(i, arrowsWanted);
00635 ltype->SetItemText(i, itm->getText());
00636
00637 int state = itm->getState();
00638 if (state == MLS_NORMAL)
00639 {
00640 if ( !itm->getEnabled())
00641 ltype->EnableForcedFont(i, "disabled");
00642
00643 }
00644 else
00645 {
00646 QString fntName;
00647 if (itm->getEnabled())
00648 fntName = QString("enabled_state_%1").arg(state - MLS_BOLD);
00649 else
00650 fntName = QString("disabled_state_%1").arg(state - MLS_BOLD);
00651
00652 ltype->EnableForcedFont(i, fntName);
00653 }
00654
00655 if (i + skip == curItem)
00656 ltype->SetItemCurrent(i);
00657
00658 }
00659
00660 }
00661
00662 container->Draw(&tmp, 0, 0);
00663 container->Draw(&tmp, 1, 0);
00664 container->Draw(&tmp, 2, 0);
00665 container->Draw(&tmp, 3, 0);
00666 container->Draw(&tmp, 4, 0);
00667 container->Draw(&tmp, 5, 0);
00668 container->Draw(&tmp, 6, 0);
00669 container->Draw(&tmp, 7, 0);
00670 container->Draw(&tmp, 8, 0);
00671
00672 tmp.end();
00673 p->drawPixmap(pr.topLeft(), pix);
00674 }
00675
00676 }
00677
00678
00679 void ManagedList::cursorDown(bool page)
00680 {
00681 if (curGroup)
00682 {
00683 int newIndex = curGroup->getCurIndex();
00684 int itemCount = curGroup->getItemCount();
00685
00686 newIndex += (page ? listSize : 1);
00687
00688 if (newIndex >= itemCount)
00689 newIndex = (page ? itemCount - 1 : newIndex - itemCount);
00690
00691 while(curGroup->getItem(newIndex)->getEnabled() == false)
00692 {
00693 ++newIndex;
00694 if (newIndex >= itemCount )
00695 newIndex = 0;
00696 }
00697
00698 curGroup->setCurIndex(newIndex);
00699 getParent()->update(listRect);
00700 }
00701 }
00702
00703
00704 void ManagedList::cursorUp(bool page)
00705 {
00706 if (curGroup)
00707 {
00708 int newIndex = curGroup->getCurIndex();
00709 int itemCount = curGroup->getItemCount();
00710
00711 newIndex -= (page ? listSize : 1);
00712 if (newIndex < 0)
00713 newIndex = (page ? 0 : itemCount + newIndex);
00714
00715 while(curGroup->getItem(newIndex)->getEnabled() == false)
00716 {
00717 --newIndex;
00718 if (newIndex < 0 )
00719 newIndex = itemCount - 1;
00720 }
00721
00722 curGroup->setCurIndex(newIndex);
00723 getParent()->update(listRect);
00724 }
00725 }
00726
00727
00728 void ManagedList::cursorLeft(bool page)
00729 {
00730 curGroup->getCurItem()->cursorLeft(page);
00731 }
00732
00733
00734 void ManagedList::cursorRight(bool page)
00735 {
00736 curGroup->getCurItem()->cursorRight(page);
00737 }
00738
00739
00740 void ManagedList::select()
00741 {
00742 curGroup->getCurItem()->select();
00743 }
00744
00745
00746 void ManagedList::itemChanged(ManagedListItem* itm)
00747 {
00748 if (itm)
00749 getParent()->update(listRect);
00750 }
00751
00752
00753 bool ManagedList::init(XMLParse *themeIn, const QString& containerNameIn, const QString& listNameIn, const QRect& r)
00754 {
00755 UIListType *ltype = NULL;
00756 LayerSet *container = NULL;
00757
00758
00759 if (!themeIn || containerNameIn.isEmpty() || listNameIn.isEmpty())
00760 {
00761 cerr << "sanity check failed" << endl;
00762 return false;
00763 }
00764
00765 theme = themeIn;
00766 containerName = containerNameIn;
00767
00768 container = theme->GetSet(containerName);
00769 if (!container)
00770 {
00771 cerr << "Failed to get container " << containerName << endl;
00772 return false;
00773 }
00774
00775 listName = listNameIn;
00776
00777 ltype = (UIListType *)container->GetType(listName);
00778 if (!ltype)
00779 {
00780 cerr << "Failed to get list " << listName << endl;
00781 return false;
00782 }
00783
00784 listSize = ltype->GetItems();
00785 listRect = r;
00786
00787 return true;
00788 }
00789
00790 void ManagedList::setCurGroup(ManagedListGroup* newGroup)
00791 {
00792 newGroup->slotGuiActivate(newGroup);
00793 curGroup = newGroup;
00794 getParent()->update(listRect);
00795 }
00796
00797 bool ManagedList::goBack()
00798 {
00799 if (curGroup && curGroup->getParentGroup())
00800 {
00801 curGroup->doGoBack();
00802 return true;
00803 }
00804
00805 return false;
00806 }
00807