00001 #include <qcursor.h>
00002 #include <qdialog.h>
00003 #include <qdir.h>
00004 #include <qvbox.h>
00005 #include <qapplication.h>
00006 #include <qlayout.h>
00007 #include <qdir.h>
00008 #include <qregexp.h>
00009 #include <qaccel.h>
00010 #include <qfocusdata.h>
00011 #include <qdict.h>
00012 #include <qsqldatabase.h>
00013 #include <qobjectlist.h>
00014 #include <qeventloop.h>
00015 #include <qdeepcopy.h>
00016
00017 #ifdef QWS
00018 #include <qwindowsystem_qws.h>
00019 #endif
00020
00021 #include <iostream>
00022 #include <pthread.h>
00023 using namespace std;
00024
00025 #ifdef USE_LIRC
00026 #include "lirc.h"
00027 #include "lircevent.h"
00028 #endif
00029
00030 #ifdef USE_JOYSTICK_MENU
00031 #include "jsmenu.h"
00032 #include "jsmenuevent.h"
00033 #endif
00034
00035 #include "uitypes.h"
00036 #include "uilistbtntype.h"
00037 #include "xmlparse.h"
00038 #include "mythdialogs.h"
00039 #include "lcddevice.h"
00040 #include "mythmediamonitor.h"
00041 #include "screensaver.h"
00042 #include "mythdbcon.h"
00043
00044 #ifdef USING_MINGW
00045 #undef LoadImage
00046 #endif
00047
00052 MythDialog::MythDialog(MythMainWindow *parent, const char *name, bool setsize)
00053 : QFrame(parent, name), rescode(kDialogCodeAccepted)
00054 {
00055 if (!parent)
00056 {
00057 cerr << "Trying to create a dialog without a parent.\n";
00058 return;
00059 }
00060
00061 in_loop = false;
00062
00063 gContext->GetScreenSettings(xbase, screenwidth, wmult,
00064 ybase, screenheight, hmult);
00065
00066 defaultBigFont = gContext->GetBigFont();
00067 defaultMediumFont = gContext->GetMediumFont();
00068 defaultSmallFont = gContext->GetSmallFont();
00069
00070 setFont(defaultMediumFont);
00071
00072 if (setsize)
00073 {
00074 move(0, 0);
00075 setFixedSize(QSize(screenwidth, screenheight));
00076 gContext->ThemeWidget(this);
00077 }
00078
00079 parent->attach(this);
00080 m_parent = parent;
00081 }
00082
00083 MythDialog::~MythDialog()
00084 {
00085 TeardownAll();
00086 }
00087
00088 void MythDialog::deleteLater(void)
00089 {
00090 hide();
00091 TeardownAll();
00092 QFrame::deleteLater();
00093 }
00094
00095 void MythDialog::TeardownAll(void)
00096 {
00097 if (m_parent)
00098 {
00099 m_parent->detach(this);
00100 m_parent = NULL;
00101 }
00102 }
00103
00104 void MythDialog::setNoErase(void)
00105 {
00106 WFlags flags = getWFlags();
00107 flags |= WRepaintNoErase;
00108 #ifdef QWS
00109 flags |= WResizeNoErase;
00110 #endif
00111 setWFlags(flags);
00112 }
00113
00114 bool MythDialog::onMediaEvent(MythMediaDevice*)
00115 {
00116 return false;
00117 }
00118
00119
00120
00121 void MythDialog::Show(void)
00122 {
00123 show();
00124 }
00125
00126 void MythDialog::setResult(DialogCode r)
00127 {
00128 if ((r < kDialogCodeRejected) ||
00129 ((kDialogCodeAccepted < r) && (r < kDialogCodeListStart)))
00130 {
00131 VERBOSE(VB_IMPORTANT, "Programmer Error: MythDialog::setResult("
00132 <<r<<") called with invalid DialogCode");
00133 }
00134
00135 rescode = r;
00136 }
00137
00138 void MythDialog::done(int r)
00139 {
00140 hide();
00141 setResult((DialogCode) r);
00142 close();
00143 }
00144
00145 void MythDialog::AcceptItem(int i)
00146 {
00147 if (i < 0)
00148 {
00149 VERBOSE(VB_IMPORTANT, "Programmer Error: MythDialog::AcceptItem("
00150 <<i<<") called with negative index");
00151 reject();
00152 return;
00153 }
00154
00155 done((DialogCode)((int)kDialogCodeListStart + (int)i));
00156 }
00157
00158 int MythDialog::CalcItemIndex(DialogCode code)
00159 {
00160 return (int)code - (int)kDialogCodeListStart;
00161 }
00162
00163 void MythDialog::accept()
00164 {
00165 done(Accepted);
00166 }
00167
00168 void MythDialog::reject()
00169 {
00170 done(Rejected);
00171 }
00172
00173 DialogCode MythDialog::exec(void)
00174 {
00175 if (in_loop)
00176 {
00177 qWarning("MythDialog::exec: Recursive call detected.");
00178 return kDialogCodeRejected;
00179 }
00180
00181 setResult(kDialogCodeRejected);
00182
00183 Show();
00184
00185 in_loop = TRUE;
00186
00187 QEventLoop *qteloop = QApplication::eventLoop();
00188 if (!qteloop)
00189 return kDialogCodeRejected;
00190
00191 qteloop->enterLoop();
00192
00193 DialogCode res = result();
00194
00195 return res;
00196 }
00197
00198 void MythDialog::hide(void)
00199 {
00200 if (isHidden())
00201 return;
00202
00203
00204 QWidget::hide();
00205 QEventLoop *qteloop = QApplication::eventLoop();
00206 if (in_loop && qteloop)
00207 {
00208 in_loop = FALSE;
00209 qteloop->exitLoop();
00210 }
00211 }
00212
00213 void MythDialog::keyPressEvent( QKeyEvent *e )
00214 {
00215 bool handled = false;
00216 QStringList actions;
00217
00218 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
00219 {
00220 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00221 {
00222 QString action = actions[i];
00223 handled = true;
00224
00225 if (action == "ESCAPE")
00226 reject();
00227 else if (action == "UP" || action == "LEFT")
00228 {
00229 if (focusWidget() &&
00230 (focusWidget()->focusPolicy() == QWidget::StrongFocus ||
00231 focusWidget()->focusPolicy() == QWidget::WheelFocus))
00232 {
00233 }
00234 else
00235 focusNextPrevChild(false);
00236 }
00237 else if (action == "DOWN" || action == "RIGHT")
00238 {
00239 if (focusWidget() &&
00240 (focusWidget()->focusPolicy() == QWidget::StrongFocus ||
00241 focusWidget()->focusPolicy() == QWidget::WheelFocus))
00242 {
00243 }
00244 else
00245 focusNextPrevChild(true);
00246 }
00247 else if (action == "MENU")
00248 emit menuButtonPressed();
00249 else
00250 handled = false;
00251 }
00252 }
00253 }
00254
00269 MythPopupBox::MythPopupBox(MythMainWindow *parent, const char *name)
00270 : MythDialog(parent, name, false)
00271 {
00272 float wmult, hmult;
00273
00274 if (gContext->GetNumSetting("UseArrowAccels", 1))
00275 arrowAccel = true;
00276 else
00277 arrowAccel = false;
00278
00279 gContext->GetScreenSettings(wmult, hmult);
00280
00281 setLineWidth(3);
00282 setMidLineWidth(3);
00283 setFrameShape(QFrame::Panel);
00284 setFrameShadow(QFrame::Raised);
00285 setPalette(parent->palette());
00286 popupForegroundColor = foregroundColor ();
00287 setFont(parent->font());
00288
00289 hpadding = gContext->GetNumSetting("PopupHeightPadding", 120);
00290 wpadding = gContext->GetNumSetting("PopupWidthPadding", 80);
00291
00292 vbox = new QVBoxLayout(this, (int)(10 * hmult));
00293 }
00294
00295 MythPopupBox::MythPopupBox(MythMainWindow *parent, bool graphicPopup,
00296 QColor popupForeground, QColor popupBackground,
00297 QColor popupHighlight, const char *name)
00298 : MythDialog(parent, name, false)
00299 {
00300 float wmult, hmult;
00301
00302 if (gContext->GetNumSetting("UseArrowAccels", 1))
00303 arrowAccel = true;
00304 else
00305 arrowAccel = false;
00306
00307 gContext->GetScreenSettings(wmult, hmult);
00308
00309 setLineWidth(3);
00310 setMidLineWidth(3);
00311 setFrameShape(QFrame::Panel);
00312 setFrameShadow(QFrame::Raised);
00313 setFrameStyle(QFrame::Box | QFrame::Plain);
00314 setPalette(parent->palette());
00315 setFont(parent->font());
00316
00317 hpadding = gContext->GetNumSetting("PopupHeightPadding", 120);
00318 wpadding = gContext->GetNumSetting("PopupWidthPadding", 80);
00319
00320 vbox = new QVBoxLayout(this, (int)(10 * hmult));
00321
00322 if (!graphicPopup)
00323 setPaletteBackgroundColor(popupBackground);
00324 else
00325 gContext->ThemeWidget(this);
00326 setPaletteForegroundColor(popupHighlight);
00327
00328 popupForegroundColor = popupForeground;
00329 }
00330
00331 bool MythPopupBox::focusNextPrevChild(bool next)
00332 {
00333 QFocusData *focusList = focusData();
00334 QObjectList *objList = queryList(NULL,NULL,false,true);
00335
00336 QWidget *startingPoint = focusList->home();
00337 QWidget *candidate = NULL;
00338
00339 QWidget *w = (next) ? focusList->prev() : focusList->next();
00340
00341 int countdown = focusList->count();
00342
00343 do
00344 {
00345 if (w && w != startingPoint && !w->focusProxy() &&
00346 w->isVisibleTo(this) && w->isEnabled() &&
00347 (objList->find((QObject *)w) != -1))
00348 {
00349 candidate = w;
00350 }
00351
00352 w = (next) ? focusList->prev() : focusList->next();
00353 }
00354 while (w && !(candidate && w == startingPoint) && (countdown-- > 0));
00355
00356 if (!candidate)
00357 return false;
00358
00359 candidate->setFocus();
00360 return true;
00361 }
00362
00363 void MythPopupBox::addWidget(QWidget *widget, bool setAppearance)
00364 {
00365 if (setAppearance == true)
00366 {
00367 widget->setPalette(palette());
00368 widget->setFont(font());
00369 }
00370
00371 if (widget->isA("QLabel"))
00372 {
00373 widget->setBackgroundOrigin(ParentOrigin);
00374 widget->setPaletteForegroundColor(popupForegroundColor);
00375 }
00376
00377 vbox->addWidget(widget);
00378 }
00379
00380 QLabel *MythPopupBox::addLabel(QString caption, LabelSize size, bool wrap)
00381 {
00382 QLabel *label = new QLabel(caption, this);
00383 switch (size)
00384 {
00385 case Large: label->setFont(defaultBigFont); break;
00386 case Medium: label->setFont(defaultMediumFont); break;
00387 case Small: label->setFont(defaultSmallFont); break;
00388 }
00389
00390 label->setMaximumWidth((int)m_parent->width() / 2);
00391 if (wrap)
00392 {
00393 QChar::Direction text_dir = QChar::DirL;
00394
00395 if (caption.length())
00396 text_dir = caption[0].direction();
00397 int align = (QChar::DirAL == text_dir) ?
00398 Qt::WordBreak | Qt::AlignRight : Qt::WordBreak | Qt::AlignLeft;
00399 label->setAlignment(align);
00400 }
00401
00402 addWidget(label, false);
00403 return label;
00404 }
00405
00406 QButton *MythPopupBox::addButton(QString caption, QObject *target,
00407 const char *slot)
00408 {
00409 if (!target)
00410 {
00411 target = this;
00412 slot = SLOT(defaultButtonPressedHandler());
00413 }
00414
00415 MythPushButton *button = new MythPushButton(caption, this, arrowAccel);
00416 m_parent->connect(button, SIGNAL(pressed()), target, slot);
00417 addWidget(button, false);
00418 return button;
00419 }
00420
00421 void MythPopupBox::addLayout(QLayout *layout, int stretch)
00422 {
00423 vbox->addLayout(layout, stretch);
00424 }
00425
00426 void MythPopupBox::ShowPopup(QObject *target, const char *slot)
00427 {
00428 ShowPopupAtXY(-1, -1, target, slot);
00429 }
00430
00431 void MythPopupBox::ShowPopupAtXY(int destx, int desty,
00432 QObject *target, const char *slot)
00433 {
00434 const QObjectList *objlist = children();
00435 QObjectListIt it(*objlist);
00436 QObject *objs;
00437
00438 while ((objs = it.current()) != 0)
00439 {
00440 ++it;
00441 if (objs->isWidgetType())
00442 {
00443 QWidget *widget = (QWidget *)objs;
00444 widget->adjustSize();
00445 }
00446 }
00447
00448 polish();
00449
00450 int x = 0, y = 0, maxw = 0, poph = 0;
00451
00452 it = QObjectListIt(*objlist);
00453 while ((objs = it.current()) != 0)
00454 {
00455 ++it;
00456 if (objs->isWidgetType())
00457 {
00458 QString objname = objs->name();
00459 if (objname != "nopopsize")
00460 {
00461
00462 if (objs->isA("MythListBox"))
00463 poph += (int)(25 * hmult);
00464
00465 QWidget *widget = (QWidget *)objs;
00466 poph += widget->height();
00467 if (widget->width() > maxw)
00468 maxw = widget->width();
00469 }
00470 }
00471 }
00472
00473 poph += (int)(hpadding * hmult);
00474 setMinimumHeight(poph);
00475
00476 maxw += (int)(wpadding * wmult);
00477
00478 int width = (int)(800 * wmult);
00479 int height = (int)(600 * hmult);
00480
00481 if (parentWidget())
00482 {
00483 width = parentWidget()->width();
00484 height = parentWidget()->height();
00485 }
00486
00487 if (destx == -1)
00488 x = (int)(width / 2) - (int)(maxw / 2);
00489 else
00490 x = destx;
00491
00492 if (desty == -1)
00493 y = (int)(height / 2) - (int)(poph / 2);
00494 else
00495 y = desty;
00496
00497 if (poph + y > height)
00498 y = height - poph - (int)(8 * hmult);
00499
00500 setFixedSize(maxw, poph);
00501 setGeometry(x, y, maxw, poph);
00502
00503 if (target && slot)
00504 connect(this, SIGNAL(popupDone(int)), target, slot);
00505
00506 Show();
00507 }
00508
00509 void MythPopupBox::keyPressEvent(QKeyEvent *e)
00510 {
00511 bool handled = false;
00512 QStringList actions;
00513 gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions);
00514 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00515 {
00516 QString action = actions[i];
00517
00518 if ((action == "ESCAPE") || (arrowAccel && action == "LEFT"))
00519 {
00520 reject();
00521 handled = true;
00522 }
00523 }
00524
00525 if (!handled)
00526 MythDialog::keyPressEvent(e);
00527 }
00528
00529 void MythPopupBox::AcceptItem(int i)
00530 {
00531 MythDialog::AcceptItem(i);
00532 emit popupDone(rescode);
00533 }
00534
00535 void MythPopupBox::accept(void)
00536 {
00537 MythDialog::done(MythDialog::Accepted);
00538 emit popupDone(MythDialog::Accepted);
00539 }
00540
00541 void MythPopupBox::reject(void)
00542 {
00543 MythDialog::done(MythDialog::Rejected);
00544 emit popupDone(MythDialog::Rejected);
00545 }
00546
00547 DialogCode MythPopupBox::ExecPopup(QObject *target, const char *slot)
00548 {
00549 if (!target)
00550 ShowPopup(this, SLOT(done(int)));
00551 else
00552 ShowPopup(target, slot);
00553
00554 return exec();
00555 }
00556
00557 DialogCode MythPopupBox::ExecPopupAtXY(int destx, int desty,
00558 QObject *target, const char *slot)
00559 {
00560 if (!target)
00561 ShowPopupAtXY(destx, desty, this, SLOT(done(int)));
00562 else
00563 ShowPopupAtXY(destx, desty, target, slot);
00564
00565 return exec();
00566 }
00567
00568 void MythPopupBox::defaultButtonPressedHandler(void)
00569 {
00570 const QObjectList *objlist = children();
00571 QObjectListIt itf(*objlist);
00572 QObject *objs;
00573 int i = 0;
00574 bool foundbutton = false;
00575
00576
00577 while ((objs = itf.current()) != 0)
00578 {
00579 ++itf;
00580 if (objs->isWidgetType())
00581 {
00582 QWidget *widget = (QWidget *)objs;
00583 if (widget->isA("MythPushButton"))
00584 {
00585 if (widget->hasFocus())
00586 {
00587 foundbutton = true;
00588 break;
00589 }
00590 i++;
00591 }
00592 }
00593 }
00594 if (foundbutton)
00595 {
00596 AcceptItem(i);
00597 return;
00598 }
00599
00600
00601 QObjectListIt itd(*objlist);
00602 i = 0;
00603 while ((objs = itd.current()) != 0)
00604 {
00605 ++itd;
00606 if (objs->isWidgetType())
00607 {
00608 QWidget *widget = (QWidget *)objs;
00609 if (widget->isA("MythPushButton"))
00610 {
00611 MythPushButton *button = dynamic_cast<MythPushButton*>(widget);
00612 if (button && button->isDown())
00613 {
00614 foundbutton = true;
00615 break;
00616 }
00617 i++;
00618 }
00619 }
00620 }
00621 if (foundbutton)
00622 {
00623 AcceptItem(i);
00624 return;
00625 }
00626
00627 VERBOSE(VB_IMPORTANT, "MythPopupBox::defaultButtonPressedHandler(void)"
00628 "\n\t\t\tWe should never get here!");
00629 done(kDialogCodeRejected);
00630 }
00631
00632 bool MythPopupBox::showOkPopup(
00633 MythMainWindow *parent,
00634 const QString &title,
00635 const QString &message,
00636 QString button_msg)
00637 {
00638 if (button_msg.isEmpty())
00639 button_msg = QObject::tr("OK");
00640
00641 MythPopupBox *popup = new MythPopupBox(parent, title);
00642
00643 popup->addLabel(message, MythPopupBox::Medium, true);
00644 QButton *okButton = popup->addButton(button_msg, popup, SLOT(accept()));
00645 okButton->setFocus();
00646 bool ret = (kDialogCodeAccepted == popup->ExecPopup());
00647
00648 popup->hide();
00649 popup->deleteLater();
00650
00651 return ret;
00652 }
00653
00654 bool MythPopupBox::showOkCancelPopup(MythMainWindow *parent, QString title,
00655 QString message, bool focusOk)
00656 {
00657 MythPopupBox *popup = new MythPopupBox(parent, title);
00658
00659 popup->addLabel(message, Medium, true);
00660 QButton *okButton = NULL, *cancelButton = NULL;
00661 okButton = popup->addButton(tr("OK"), popup, SLOT(accept()));
00662 cancelButton = popup->addButton(tr("Cancel"), popup, SLOT(reject()));
00663
00664 if (focusOk)
00665 okButton->setFocus();
00666 else
00667 cancelButton->setFocus();
00668
00669 bool ok = (Accepted == popup->ExecPopup());
00670
00671 popup->hide();
00672 popup->deleteLater();
00673
00674 return ok;
00675 }
00676
00677 bool MythPopupBox::showGetTextPopup(MythMainWindow *parent, QString title,
00678 QString message, QString& text)
00679 {
00680 MythPopupBox *popup = new MythPopupBox(parent, title);
00681
00682 popup->addLabel(message, Medium, true);
00683
00684 MythRemoteLineEdit *textEdit =
00685 new MythRemoteLineEdit(popup, "chooseEdit");
00686
00687 textEdit->setText(text);
00688 popup->addWidget(textEdit);
00689
00690 popup->addButton(tr("OK"), popup, SLOT(accept()));
00691 popup->addButton(tr("Cancel"), popup, SLOT(reject()));
00692
00693 textEdit->setFocus();
00694
00695 bool ok = (Accepted == popup->ExecPopup());
00696 if (ok)
00697 text = QDeepCopy<QString>(textEdit->text());
00698
00699 popup->hide();
00700 popup->deleteLater();
00701
00702 return ok;
00703 }
00704
00711 QString MythPopupBox::showPasswordPopup(MythMainWindow *parent,
00712 QString title,
00713 QString message)
00714 {
00715 MythPopupBox *popup = new MythPopupBox(parent, title);
00716
00717 popup->addLabel(message, Medium, true);
00718
00719 MythLineEdit *entry = new MythLineEdit(popup, "passwordEntry");
00720 entry->setEchoMode(QLineEdit::Password);
00721
00722 popup->addWidget(entry);
00723
00724 popup->addButton(tr("OK"), popup, SLOT(accept()));
00725 popup->addButton(tr("Cancel"),popup, SLOT(reject()));
00726
00727
00728 popup->m_parent->connect(entry, SIGNAL(returnPressed()),
00729 popup, SLOT(accept()));
00730 entry->setFocus();
00731
00732 QString password = QString::null;
00733 if (popup->ExecPopup() == Accepted)
00734 password = QDeepCopy<QString>(entry->text());
00735
00736 popup->hide();
00737 popup->deleteLater();
00738
00739 return password;
00740 }
00741
00742
00743 DialogCode MythPopupBox::ShowButtonPopup(
00744 MythMainWindow *parent,
00745 const QString &title,
00746 const QString &message,
00747 const QStringList &buttonmsgs,
00748 DialogCode default_button)
00749 {
00750 MythPopupBox *popup = new MythPopupBox(parent, title);
00751
00752 popup->addLabel(message, Medium, true);
00753 popup->addLabel("");
00754
00755 const uint def = CalcItemIndex(default_button);
00756 for (unsigned int i = 0; i < buttonmsgs.size(); i++ )
00757 {
00758 QButton *but = popup->addButton(buttonmsgs[i]);
00759 if (def == i)
00760 but->setFocus();
00761 }
00762
00763 DialogCode ret = popup->ExecPopup();
00764
00765 popup->hide();
00766 popup->deleteLater();
00767
00768 return ret;
00769 }
00770
00771 MythProgressDialog::MythProgressDialog(const QString &message, int totalSteps,
00772 bool cancelButton, const QObject *target, const char *slot)
00773 : MythDialog(gContext->GetMainWindow(), "progress", false)
00774 {
00775 int screenwidth, screenheight;
00776 float wmult, hmult;
00777
00778 gContext->GetScreenSettings(screenwidth, wmult, screenheight, hmult);
00779
00780 setFont(gContext->GetMediumFont());
00781
00782 gContext->ThemeWidget(this);
00783
00784 int yoff = screenheight / 3;
00785 int xoff = screenwidth / 10;
00786 setGeometry(xoff, yoff, screenwidth - xoff * 2, yoff);
00787 setFixedSize(QSize(screenwidth - xoff * 2, yoff));
00788
00789 QVBoxLayout *lay = new QVBoxLayout(this, 0);
00790
00791 QVBox *vbox = new QVBox(this);
00792 lay->addWidget(vbox);
00793
00794 vbox->setLineWidth(3);
00795 vbox->setMidLineWidth(3);
00796 vbox->setFrameShape(QFrame::Panel);
00797 vbox->setFrameShadow(QFrame::Raised);
00798 vbox->setMargin((int)(15 * wmult));
00799
00800 msglabel = new QLabel(vbox);
00801 msglabel->setBackgroundOrigin(ParentOrigin);
00802 msglabel->setText(message);
00803 vbox->setStretchFactor(msglabel, 5);
00804
00805 QHBox *hbox = new QHBox(vbox);
00806 hbox->setSpacing(5);
00807
00808 progress = new QProgressBar(totalSteps, hbox);
00809 progress->setBackgroundOrigin(ParentOrigin);
00810
00811 if (cancelButton && slot && target)
00812 {
00813 MythPushButton *button = new MythPushButton("Cancel", hbox, 0);
00814 button->setFocus();
00815 connect(button, SIGNAL(pressed()), target, slot);
00816 }
00817
00818 setTotalSteps(totalSteps);
00819
00820 if (class LCD * lcddev = LCD::Get())
00821 {
00822 textItems = new QPtrList<LCDTextItem>;
00823 textItems->setAutoDelete(true);
00824
00825 textItems->clear();
00826 textItems->append(new LCDTextItem(1, ALIGN_CENTERED, message, "Generic",
00827 false));
00828 lcddev->switchToGeneric(textItems);
00829 }
00830 else
00831 textItems = NULL;
00832
00833 show();
00834
00835 qApp->processEvents();
00836 }
00837
00838 MythProgressDialog::~MythProgressDialog()
00839 {
00840 Teardown();
00841 }
00842
00843 void MythProgressDialog::deleteLater(void)
00844 {
00845 hide();
00846 Teardown();
00847 MythDialog::deleteLater();
00848 }
00849
00850 void MythProgressDialog::Teardown(void)
00851 {
00852 if (textItems)
00853 {
00854 delete textItems;
00855 textItems = NULL;
00856 }
00857 }
00858
00859 void MythProgressDialog::Close(void)
00860 {
00861 accept();
00862
00863 LCD *lcddev = LCD::Get();
00864 if (lcddev)
00865 {
00866 lcddev->switchToNothing();
00867 lcddev->switchToTime();
00868 }
00869 }
00870
00871 void MythProgressDialog::setProgress(int curprogress)
00872 {
00873 progress->setProgress(curprogress);
00874 if (curprogress % steps == 0)
00875 {
00876 qApp->processEvents();
00877 if (LCD * lcddev = LCD::Get())
00878 {
00879 float fProgress = (float)curprogress / m_totalSteps;
00880 lcddev->setGenericProgress(fProgress);
00881 }
00882 }
00883 }
00884
00885 void MythProgressDialog::setLabel(QString newlabel)
00886 {
00887 msglabel->setText(newlabel);
00888 }
00889
00890 void MythProgressDialog::keyPressEvent(QKeyEvent *e)
00891 {
00892 bool handled = false;
00893 QStringList actions;
00894 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
00895 {
00896 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00897 {
00898 QString action = actions[i];
00899 if (action == "ESCAPE")
00900 handled = true;
00901 }
00902 }
00903
00904 if (!handled)
00905 MythDialog::keyPressEvent(e);
00906 }
00907
00908 void MythProgressDialog::setTotalSteps(int totalSteps)
00909 {
00910 m_totalSteps = totalSteps;
00911 progress->setTotalSteps(totalSteps);
00912 steps = totalSteps / 1000;
00913 if (steps == 0)
00914 steps = 1;
00915 }
00916
00917 MythBusyDialog::MythBusyDialog(const QString &title,
00918 bool cancelButton, const QObject *target, const char *slot)
00919 : MythProgressDialog(title, 0,
00920 cancelButton, target, slot),
00921 timer(NULL)
00922 {
00923 }
00924
00925 MythBusyDialog::~MythBusyDialog()
00926 {
00927 Teardown();
00928 }
00929
00930 void MythBusyDialog::deleteLater(void)
00931 {
00932 Teardown();
00933 MythProgressDialog::deleteLater();
00934 }
00935
00936 void MythBusyDialog::Teardown(void)
00937 {
00938 if (timer)
00939 {
00940 timer->disconnect();
00941 timer->deleteLater();
00942 timer = NULL;
00943 }
00944 }
00945
00946 void MythBusyDialog::start(int interval)
00947 {
00948 if (!timer)
00949 timer = new QTimer (this);
00950
00951 connect(timer, SIGNAL(timeout()),
00952 this, SLOT (timeout()));
00953
00954 timer->start(interval);
00955 }
00956
00957 void MythBusyDialog::Close(void)
00958 {
00959 if (timer)
00960 {
00961 timer->disconnect();
00962 timer->deleteLater();
00963 timer = NULL;
00964 }
00965
00966 MythProgressDialog::Close();
00967 }
00968
00969 void MythBusyDialog::setProgress(void)
00970 {
00971 progress->setProgress(progress->progress () + 10);
00972 qApp->processEvents();
00973 if (LCD *lcddev = LCD::Get())
00974 lcddev->setGenericBusy();
00975 }
00976
00977 void MythBusyDialog::timeout(void)
00978 {
00979 setProgress();
00980 }
00981
00982 MythThemedDialog::MythThemedDialog(MythMainWindow *parent, QString window_name,
00983 QString theme_filename, const char* name,
00984 bool setsize)
00985 : MythDialog(parent, name, setsize)
00986 {
00987 setNoErase();
00988
00989 theme = NULL;
00990
00991 if (!loadThemedWindow(window_name, theme_filename))
00992 {
00993 QString msg =
00994 QString(tr("Could not locate '%1' in theme '%2'."
00995 "\n\nReturning to the previous menu."))
00996 .arg(window_name).arg(theme_filename);
00997 MythPopupBox::showOkPopup(gContext->GetMainWindow(),
00998 tr("Missing UI Element"), msg);
00999 reject();
01000 return;
01001 }
01002 }
01003
01004 MythThemedDialog::MythThemedDialog(MythMainWindow *parent, const char* name,
01005 bool setsize)
01006 : MythDialog(parent, name, setsize)
01007 {
01008 setNoErase();
01009 theme = NULL;
01010 }
01011
01012 bool MythThemedDialog::loadThemedWindow(QString window_name, QString theme_filename)
01013 {
01014
01015 if (theme)
01016 delete theme;
01017
01018 context = -1;
01019 my_containers.clear();
01020 widget_with_current_focus = NULL;
01021
01022 redrawRect = QRect(0, 0, 0, 0);
01023
01024 theme = new XMLParse();
01025 theme->SetWMult(wmult);
01026 theme->SetHMult(hmult);
01027 if (!theme->LoadTheme(xmldata, window_name, theme_filename))
01028 {
01029 return false;
01030 }
01031
01032 loadWindow(xmldata);
01033
01034
01035
01036
01037
01038
01039 QPtrListIterator<LayerSet> an_it(my_containers);
01040 LayerSet *looper;
01041 while ((looper = an_it.current()) != 0)
01042 {
01043
01044 vector<UIType *> *all_ui_type_objects = looper->getAllTypes();
01045 vector<UIType *>::iterator i = all_ui_type_objects->begin();
01046 for (; i != all_ui_type_objects->end(); i++)
01047 {
01048 UIType *type = (*i);
01049 connect(type, SIGNAL(requestUpdate()), this,
01050 SLOT(updateForeground()));
01051 connect(type, SIGNAL(requestUpdate(const QRect &)), this,
01052 SLOT(updateForeground(const QRect &)));
01053 connect(type, SIGNAL(requestRegionUpdate(const QRect &)), this,
01054 SLOT(updateForegroundRegion(const QRect &)));
01055 }
01056 ++an_it;
01057 }
01058
01059 buildFocusList();
01060
01061 updateBackground();
01062 initForeground();
01063
01064 return true;
01065 }
01066
01067 bool MythThemedDialog::buildFocusList()
01068 {
01069
01070
01071
01072
01073 focus_taking_widgets.clear();
01074
01075
01076
01077 LayerSet *looper;
01078 QPtrListIterator<LayerSet> another_it(my_containers);
01079 while ((looper = another_it.current()) != 0)
01080 {
01081
01082 vector<UIType *> *all_ui_type_objects = looper->getAllTypes();
01083 vector<UIType *>::iterator i = all_ui_type_objects->begin();
01084 for (; i != all_ui_type_objects->end(); i++)
01085 {
01086 UIType *type = (*i);
01087 if (type->canTakeFocus() && !type->isHidden())
01088 {
01089 if (context == -1 || type->GetContext() == -1 ||
01090 context == type->GetContext())
01091 focus_taking_widgets.append(type);
01092 }
01093 }
01094 ++another_it;
01095 }
01096 if (focus_taking_widgets.count() > 0)
01097 {
01098 return true;
01099 }
01100 return false;
01101 }
01102
01103 MythThemedDialog::~MythThemedDialog()
01104 {
01105 if (theme)
01106 {
01107 delete theme;
01108 theme = NULL;
01109 }
01110 }
01111
01112 void MythThemedDialog::deleteLater(void)
01113 {
01114 if (theme)
01115 {
01116 delete theme;
01117 theme = NULL;
01118 }
01119 MythDialog::deleteLater();
01120 }
01121
01122 void MythThemedDialog::loadWindow(QDomElement &element)
01123 {
01124
01125
01126
01127
01128 for (QDomNode child = element.firstChild(); !child.isNull();
01129 child = child.nextSibling())
01130 {
01131 QDomElement e = child.toElement();
01132 if (!e.isNull())
01133 {
01134 if (e.tagName() == "font")
01135 {
01136 theme->parseFont(e);
01137 }
01138 else if (e.tagName() == "container")
01139 {
01140 parseContainer(e);
01141 }
01142 else if (e.tagName() == "popup")
01143 {
01144 parsePopup(e);
01145 }
01146 else
01147 {
01148 VERBOSE(VB_IMPORTANT,
01149 QString("MythThemedDialog::loadWindow(): Do not "
01150 "understand DOM Element: '%1'. Ignoring.")
01151 .arg(e.tagName()));
01152 }
01153 }
01154 }
01155 }
01156
01157 void MythThemedDialog::parseContainer(QDomElement &element)
01158 {
01159
01160
01161
01162
01163
01164
01165 QRect area;
01166 QString name;
01167 int a_context;
01168 theme->parseContainer(element, name, a_context, area);
01169 if (name.length() < 1)
01170 {
01171 VERBOSE(VB_IMPORTANT, "Failed to parse a container. Ignoring.");
01172 return;
01173 }
01174
01175 LayerSet *container_reference = theme->GetSet(name);
01176 my_containers.append(container_reference);
01177 }
01178
01179 void MythThemedDialog::parseFont(QDomElement &element)
01180 {
01181
01182
01183
01184
01185
01186 theme->parseFont(element);
01187 }
01188
01189 void MythThemedDialog::parsePopup(QDomElement &element)
01190 {
01191
01192
01193
01194 element = element;
01195 cerr << "I don't know how to handle popops yet (I'm going to try and "
01196 "just ignore it)\n";
01197 }
01198
01199 void MythThemedDialog::initForeground()
01200 {
01201 my_foreground = my_background;
01202 updateForeground();
01203 }
01204
01205 void MythThemedDialog::updateBackground()
01206 {
01207
01208
01209
01210
01211 QPixmap bground(size());
01212 bground.fill(this, 0, 0);
01213
01214 QPainter tmp(&bground);
01215
01216
01217
01218
01219
01220
01221
01222 LayerSet *container = theme->GetSet("background");
01223
01224
01225
01226
01227 if (container)
01228 {
01229 container->Draw(&tmp, 0, context);
01230 tmp.end();
01231 }
01232
01233
01234
01235
01236
01237
01238 my_background = bground;
01239 setPaletteBackgroundPixmap(my_background);
01240 }
01241
01242 void MythThemedDialog::updateForeground()
01243 {
01244 QRect r = this->geometry();
01245 updateForeground(r);
01246 }
01247
01248 void MythThemedDialog::updateForeground(const QRect &r)
01249 {
01250 QRect rect_to_update = r;
01251 if (r.width() == 0 || r.height() == 0)
01252 {
01253 cerr << "MythThemedDialog.o: something is requesting a screen update of zero size. "
01254 << "A widget probably has not done a calculateScreeArea(). Will redraw "
01255 << "the whole screen (inefficient!)."
01256 << endl;
01257
01258 rect_to_update = this->geometry();
01259 }
01260
01261 redrawRect = redrawRect.unite(r);
01262
01263 update(redrawRect);
01264 }
01265
01266 void MythThemedDialog::ReallyUpdateForeground(const QRect &r)
01267 {
01268 QRect rect_to_update = r;
01269 if (r.width() == 0 || r.height() == 0)
01270 {
01271 cerr << "MythThemedDialog.o: something is requesting a screen update of zero size. "
01272 << "A widget probably has not done a calculateScreeArea(). Will redraw "
01273 << "the whole screen (inefficient!)."
01274 << endl;
01275
01276 rect_to_update = this->geometry();
01277 }
01278
01279 UpdateForegroundRect(rect_to_update);
01280
01281 redrawRect = QRect(0, 0, 0, 0);
01282 }
01283
01284 void MythThemedDialog::updateForegroundRegion(const QRect &r)
01285 {
01286
01287
01288
01289 UpdateForegroundRect(r);
01290
01291 update(r);
01292 }
01293
01294 void MythThemedDialog::UpdateForegroundRect(const QRect &inv_rect)
01295 {
01296 QPainter whole_dialog_painter(&my_foreground);
01297
01298
01299
01300
01301
01302 whole_dialog_painter.drawPixmap(inv_rect.topLeft(), my_background,
01303 inv_rect);
01304
01305 QPtrListIterator<LayerSet> an_it(my_containers);
01306 LayerSet *looper;
01307
01308 while ((looper = an_it.current()) != 0)
01309 {
01310 QRect container_area = looper->GetAreaRect();
01311
01312
01313
01314
01315
01316
01317
01318 const QRect intersect = inv_rect.intersect(container_area);
01319 int looper_context = looper->GetContext();
01320 if (container_area.isValid() &&
01321 (looper_context == context || looper_context == -1) &&
01322 intersect.isValid() &&
01323 looper->GetName().lower() != "background")
01324 {
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344 whole_dialog_painter.save();
01345
01346 whole_dialog_painter.setClipRect(intersect);
01347 whole_dialog_painter.translate(container_area.left(),
01348 container_area.top());
01349
01350 for (int i = 0; i <= looper->getLayers(); ++i)
01351 {
01352 looper->Draw(&whole_dialog_painter, i, context);
01353 }
01354
01355 whole_dialog_painter.restore();
01356 }
01357 ++an_it;
01358 }
01359 }
01360
01361 void MythThemedDialog::paintEvent(QPaintEvent *e)
01362 {
01363 if (redrawRect.width() > 0 && redrawRect.height() > 0)
01364 ReallyUpdateForeground(redrawRect);
01365
01366 bitBlt(this, e->rect().left(), e->rect().top(),
01367 &my_foreground, e->rect().left(), e->rect().top(),
01368 e->rect().width(), e->rect().height());
01369
01370 MythDialog::paintEvent(e);
01371 }
01372
01373 bool MythThemedDialog::assignFirstFocus()
01374 {
01375 if (widget_with_current_focus)
01376 {
01377 widget_with_current_focus->looseFocus();
01378 }
01379
01380 QPtrListIterator<UIType> an_it(focus_taking_widgets);
01381 UIType *looper;
01382
01383 while ((looper = an_it.current()) != 0)
01384 {
01385 if (looper->canTakeFocus())
01386 {
01387 widget_with_current_focus = looper;
01388 widget_with_current_focus->takeFocus();
01389 return true;
01390 }
01391 ++an_it;
01392 }
01393
01394 return false;
01395 }
01396
01397 bool MythThemedDialog::nextPrevWidgetFocus(bool up_or_down)
01398 {
01399 if (up_or_down)
01400 {
01401 bool reached_current = false;
01402 QPtrListIterator<UIType> an_it(focus_taking_widgets);
01403 UIType *looper;
01404
01405 while ((looper = an_it.current()) != 0)
01406 {
01407 if (reached_current && looper->canTakeFocus())
01408 {
01409 widget_with_current_focus->looseFocus();
01410 widget_with_current_focus = looper;
01411 widget_with_current_focus->takeFocus();
01412 return true;
01413 }
01414
01415 if (looper == widget_with_current_focus)
01416 {
01417 reached_current= true;
01418 }
01419 ++an_it;
01420 }
01421
01422 if (assignFirstFocus())
01423 {
01424 return true;
01425 }
01426 return false;
01427 }
01428 else
01429 {
01430 bool reached_current = false;
01431 QPtrListIterator<UIType> an_it(focus_taking_widgets);
01432 an_it.toLast();
01433 UIType *looper;
01434
01435 while ((looper = an_it.current()) != 0)
01436 {
01437 if (reached_current && looper->canTakeFocus())
01438 {
01439 widget_with_current_focus->looseFocus();
01440 widget_with_current_focus = looper;
01441 widget_with_current_focus->takeFocus();
01442 return true;
01443 }
01444
01445 if (looper == widget_with_current_focus)
01446 {
01447 reached_current= true;
01448 }
01449 --an_it;
01450 }
01451
01452 if (reached_current)
01453 {
01454 an_it.toLast();
01455 while ((looper = an_it.current()) != 0)
01456 {
01457 if (looper->canTakeFocus())
01458 {
01459 widget_with_current_focus->looseFocus();
01460 widget_with_current_focus = looper;
01461 widget_with_current_focus->takeFocus();
01462 return true;
01463 }
01464 --an_it;
01465 }
01466 }
01467 return false;
01468 }
01469 return false;
01470 }
01471
01472 void MythThemedDialog::activateCurrent()
01473 {
01474 if (widget_with_current_focus)
01475 {
01476 widget_with_current_focus->activate();
01477 }
01478 else
01479 {
01480 cerr << "dialogbox.o: Something asked me activate the current widget, "
01481 "but there is no current widget\n";
01482 }
01483 }
01484
01485 namespace
01486 {
01487 template <typename T>
01488 T *GetUIType(MythThemedDialog *dialog, const QString &name)
01489 {
01490 UIType *sf = dialog->getUIObject(name);
01491 if (sf)
01492 {
01493 T *ret = dynamic_cast<T *>(sf);
01494 if (ret)
01495 return ret;
01496 }
01497 return 0;
01498 }
01499 };
01500
01501 UIType* MythThemedDialog::getUIObject(const QString &name)
01502 {
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512 QPtrListIterator<LayerSet> an_it(my_containers);
01513 LayerSet *looper;
01514
01515 while ((looper = an_it.current()) != 0)
01516 {
01517 UIType *hunter = looper->GetType(name);
01518 if (hunter)
01519 return hunter;
01520 ++an_it;
01521 }
01522
01523 return NULL;
01524 }
01525
01526 UIType* MythThemedDialog::getCurrentFocusWidget()
01527 {
01528 if (widget_with_current_focus)
01529 {
01530 return widget_with_current_focus;
01531 }
01532 return NULL;
01533 }
01534
01535 void MythThemedDialog::setCurrentFocusWidget(UIType* widget)
01536 {
01537
01538 if (focus_taking_widgets.find(widget) == -1)
01539 return;
01540
01541 if (widget_with_current_focus)
01542 widget_with_current_focus->looseFocus();
01543
01544 widget_with_current_focus = widget;
01545 widget_with_current_focus->takeFocus();
01546 }
01547
01548 UIManagedTreeListType* MythThemedDialog::getUIManagedTreeListType(const QString &name)
01549 {
01550 return GetUIType<UIManagedTreeListType>(this, name);
01551 }
01552
01553 UITextType* MythThemedDialog::getUITextType(const QString &name)
01554 {
01555 return GetUIType<UITextType>(this, name);
01556 }
01557
01558 UIRichTextType* MythThemedDialog::getUIRichTextType(const QString &name)
01559 {
01560 return GetUIType<UIRichTextType>(this, name);
01561 }
01562
01563 UIRemoteEditType* MythThemedDialog::getUIRemoteEditType(const QString &name)
01564 {
01565 return GetUIType<UIRemoteEditType>(this, name);
01566 }
01567
01568 UIMultiTextType* MythThemedDialog::getUIMultiTextType(const QString &name)
01569 {
01570 return GetUIType<UIMultiTextType>(this, name);
01571 }
01572
01573 UIPushButtonType* MythThemedDialog::getUIPushButtonType(const QString &name)
01574 {
01575 return GetUIType<UIPushButtonType>(this, name);
01576 }
01577
01578 UITextButtonType* MythThemedDialog::getUITextButtonType(const QString &name)
01579 {
01580 return GetUIType<UITextButtonType>(this, name);
01581 }
01582
01583 UIRepeatedImageType* MythThemedDialog::getUIRepeatedImageType(const QString &name)
01584 {
01585 return GetUIType<UIRepeatedImageType>(this, name);
01586 }
01587
01588 UICheckBoxType* MythThemedDialog::getUICheckBoxType(const QString &name)
01589 {
01590 return GetUIType<UICheckBoxType>(this, name);
01591 }
01592
01593 UISelectorType* MythThemedDialog::getUISelectorType(const QString &name)
01594 {
01595 return GetUIType<UISelectorType>(this, name);
01596 }
01597
01598 UIBlackHoleType* MythThemedDialog::getUIBlackHoleType(const QString &name)
01599 {
01600 return GetUIType<UIBlackHoleType>(this, name);
01601 }
01602
01603 UIImageType* MythThemedDialog::getUIImageType(const QString &name)
01604 {
01605 return GetUIType<UIImageType>(this, name);
01606 }
01607
01608 UIStatusBarType* MythThemedDialog::getUIStatusBarType(const QString &name)
01609 {
01610 return GetUIType<UIStatusBarType>(this, name);
01611 }
01612
01613 UIListBtnType* MythThemedDialog::getUIListBtnType(const QString &name)
01614 {
01615 return GetUIType<UIListBtnType>(this, name);
01616 }
01617
01618 UIListTreeType* MythThemedDialog::getUIListTreeType(const QString &name)
01619 {
01620 return GetUIType<UIListTreeType>(this, name);
01621 }
01622
01623 UIKeyboardType *MythThemedDialog::getUIKeyboardType(const QString &name)
01624 {
01625 return GetUIType<UIKeyboardType>(this, name);
01626 }
01627
01628 UIImageGridType* MythThemedDialog::getUIImageGridType(const QString &name)
01629 {
01630 return GetUIType<UIImageGridType>(this, name);
01631 }
01632
01633 LayerSet* MythThemedDialog::getContainer(const QString& name)
01634 {
01635 QPtrListIterator<LayerSet> an_it(my_containers);
01636 LayerSet *looper;
01637
01638 while( (looper = an_it.current()) != 0)
01639 {
01640 if (looper->GetName() == name)
01641 return looper;
01642
01643 ++an_it;
01644 }
01645
01646 return NULL;
01647 }
01648
01649 fontProp* MythThemedDialog::getFont(const QString &name)
01650 {
01651 fontProp* font = NULL;
01652 if (theme)
01653 font = theme->GetFont(name, true);
01654
01655 return font;
01656 }
01657
01670 MythPasswordDialog::MythPasswordDialog(QString message,
01671 bool *success,
01672 QString target,
01673 MythMainWindow *parent,
01674 const char *name,
01675 bool)
01676 :MythDialog(parent, name, false)
01677 {
01678 int textWidth = fontMetrics().width(message);
01679 int totalWidth = textWidth + 175;
01680
01681 success_flag = success;
01682 target_text = target;
01683
01684 gContext->GetScreenSettings(screenwidth, wmult, screenheight, hmult);
01685 this->setGeometry((screenwidth - 250 ) / 2,
01686 (screenheight - 50 ) / 2,
01687 totalWidth,50);
01688 QFrame *outside_border = new QFrame(this);
01689 outside_border->setGeometry(0,0,totalWidth,50);
01690 outside_border->setFrameStyle(QFrame::Panel | QFrame::Raised );
01691 outside_border->setLineWidth(4);
01692 QLabel *message_label = new QLabel(message, this);
01693 message_label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
01694 message_label->setGeometry(15,10,textWidth,30);
01695 message_label->setBackgroundOrigin(ParentOrigin);
01696 password_editor = new MythLineEdit(this);
01697 password_editor->setEchoMode(QLineEdit::Password);
01698 password_editor->setGeometry(textWidth + 20,10,135,30);
01699 password_editor->setBackgroundOrigin(ParentOrigin);
01700 password_editor->setAllowVirtualKeyboard(false);
01701 connect(password_editor, SIGNAL(textChanged(const QString &)),
01702 this, SLOT(checkPassword(const QString &)));
01703
01704 this->setActiveWindow();
01705 password_editor->setFocus();
01706 }
01707
01708 void MythPasswordDialog::keyPressEvent(QKeyEvent *e)
01709 {
01710 bool handled = false;
01711 QStringList actions;
01712 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
01713 {
01714 for (unsigned int i = 0; i < actions.size() && !handled; i++)
01715 {
01716 QString action = actions[i];
01717 if (action == "ESCAPE")
01718 {
01719 handled = true;
01720 MythDialog::keyPressEvent(e);
01721 }
01722 }
01723 }
01724 }
01725
01726
01727 void MythPasswordDialog::checkPassword(const QString &the_text)
01728 {
01729 if (the_text == target_text)
01730 {
01731 *success_flag = true;
01732 accept();
01733 }
01734 else
01735 {
01736
01737 }
01738 }
01739
01740 MythPasswordDialog::~MythPasswordDialog()
01741 {
01742 }
01743
01744
01745
01746
01747
01748 MythSearchDialog::MythSearchDialog(MythMainWindow *parent, const char *name)
01749 :MythPopupBox(parent, name)
01750 {
01751
01752 caption = addLabel(QString(""));
01753
01754 editor = new MythRemoteLineEdit(this);
01755 connect(editor, SIGNAL(textChanged()), this, SLOT(searchTextChanged()));
01756 addWidget(editor);
01757 editor->setFocus();
01758 editor->setPopupPosition(VK_POSBOTTOMDIALOG);
01759
01760 listbox = new MythListBox(this);
01761 listbox->setScrollBar(false);
01762 listbox->setBottomScrollBar(false);
01763 connect(listbox, SIGNAL(accepted(int)), this, SLOT(AcceptItem(int)));
01764 addWidget(listbox);
01765
01766 ok_button = addButton(tr("OK"), this, SLOT(accept()));
01767 cancel_button = addButton(tr("Cancel"), this, SLOT(reject()));
01768 }
01769
01770 void MythSearchDialog::keyPressEvent(QKeyEvent *e)
01771 {
01772 bool handled = false;
01773 QStringList actions;
01774 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
01775 {
01776 for (unsigned int i = 0; i < actions.size() && !handled; i++)
01777 {
01778 QString action = actions[i];
01779 if (action == "ESCAPE")
01780 {
01781 handled = true;
01782 reject();
01783 }
01784 if (action == "LEFT")
01785 {
01786 handled = true;
01787 focusNextPrevChild(false);
01788 }
01789 if (action == "RIGHT")
01790 {
01791 handled = true;
01792 focusNextPrevChild(true);
01793 }
01794 if (action == "SELECT")
01795 {
01796 handled = true;
01797 accept();
01798 }
01799 }
01800 }
01801 if (!handled)
01802 MythPopupBox::keyPressEvent(e);
01803 }
01804
01805 void MythSearchDialog::setCaption(QString text)
01806 {
01807 if (caption)
01808 caption->setText(text);
01809 }
01810
01811 void MythSearchDialog::setSearchText(QString text)
01812 {
01813 if (editor)
01814 {
01815 editor->setText(text);
01816 editor->setCursorPosition(0, editor->text().length());
01817 }
01818 }
01819
01820 void MythSearchDialog::searchTextChanged(void)
01821 {
01822 if (listbox && editor)
01823 {
01824 listbox->setCurrentItem(editor->text(), false, true);
01825 listbox->setTopItem(listbox->currentItem());
01826 }
01827 }
01828
01829 QString MythSearchDialog::getResult(void)
01830 {
01831 if (listbox)
01832 return listbox->currentText();
01833
01834
01835
01836 return "";
01837 }
01838
01839 void MythSearchDialog::setItems(QStringList items)
01840 {
01841 if (listbox)
01842 {
01843 listbox->insertStringList(items);
01844 searchTextChanged();
01845 }
01846 }
01847
01848 MythSearchDialog::~MythSearchDialog()
01849 {
01850 Teardown();
01851 }
01852
01853 void MythSearchDialog::deleteLater(void)
01854 {
01855 Teardown();
01856 MythPopupBox::deleteLater();
01857 }
01858
01859 void MythSearchDialog::Teardown(void)
01860 {
01861 caption = NULL;
01862
01863 if (editor)
01864 {
01865 editor->disconnect();
01866 editor = NULL;
01867 }
01868
01869 if (listbox)
01870 {
01871 listbox->disconnect();
01872 listbox = NULL;
01873 }
01874
01875 ok_button = NULL;
01876 cancel_button = NULL;
01877 }
01878
01879
01880
01881
01882
01893 MythImageFileDialog::MythImageFileDialog(QString *result,
01894 QString top_directory,
01895 MythMainWindow *parent,
01896 QString window_name,
01897 QString theme_filename,
01898 const char *name,
01899 bool setsize)
01900 :MythThemedDialog(parent,
01901 window_name,
01902 theme_filename,
01903 name,
01904 setsize)
01905 {
01906 selected_file = result;
01907 initial_node = NULL;
01908
01909 UIImageType *file_browser_background = getUIImageType("file_browser_background");
01910 if (file_browser_background)
01911 {
01912 QPixmap background = file_browser_background->GetImage();
01913
01914 this->setFixedSize(QSize(background.width(), background.height()));
01915 this->move((screenwidth - background.width()) / 2,
01916 (screenheight - background.height()) / 2);
01917 }
01918 else
01919 {
01920 QString msg =
01921 QString(tr("The theme you are using is missing the "
01922 "'file_browser_background' "
01923 "element. \n\nReturning to the previous menu."));
01924 MythPopupBox::showOkPopup(gContext->GetMainWindow(),
01925 tr("Missing UI Element"), msg);
01926 reject();
01927 return;
01928 }
01929
01930
01931
01932
01933
01934 this->setFrameStyle(QFrame::Panel | QFrame::Raised );
01935 this->setLineWidth(4);
01936
01937
01938
01939
01940
01941
01942
01943 file_browser = getUIManagedTreeListType("file_browser");
01944 if (file_browser)
01945 {
01946 file_browser->calculateScreenArea();
01947 file_browser->showWholeTree(true);
01948 connect(file_browser, SIGNAL(nodeSelected(int, IntVector*)),
01949 this, SLOT(handleTreeListSelection(int, IntVector*)));
01950 connect(file_browser, SIGNAL(nodeEntered(int, IntVector*)),
01951 this, SLOT(handleTreeListEntered(int, IntVector*)));
01952 }
01953 else
01954 {
01955 QString msg =
01956 QString(tr("The theme you are using is missing the "
01957 "'file_browser' element. "
01958 "\n\nReturning to the previous menu."));
01959 MythPopupBox::showOkPopup(gContext->GetMainWindow(),
01960 tr("Missing UI Element"), msg);
01961 reject();
01962 return;
01963 }
01964
01965
01966
01967
01968
01969
01970 image_box = getUIImageType("image_box");
01971 if (image_box)
01972 {
01973 image_box->calculateScreenArea();
01974 }
01975 initialDir = top_directory;
01976
01977 image_files.clear();
01978 buildTree(top_directory);
01979
01980 file_browser->assignTreeData(root_parent);
01981 if (initial_node)
01982 {
01983 file_browser->setCurrentNode(initial_node);
01984 }
01985 file_browser->enter();
01986 file_browser->refresh();
01987
01988 }
01989
01990 void MythImageFileDialog::keyPressEvent(QKeyEvent *e)
01991 {
01992 bool handled = false;
01993 QStringList actions;
01994 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
01995 {
01996 for (unsigned int i = 0; i < actions.size() && !handled; i++)
01997 {
01998 QString action = actions[i];
01999 handled = true;
02000
02001 if (action == "UP")
02002 file_browser->moveUp();
02003 else if (action == "DOWN")
02004 file_browser->moveDown();
02005 else if (action == "LEFT")
02006 file_browser->popUp();
02007 else if (action == "RIGHT")
02008 file_browser->pushDown();
02009 else if (action == "PAGEUP")
02010 file_browser->pageUp();
02011 else if (action == "PAGEDOWN")
02012 file_browser->pageDown();
02013 else if (action == "SELECT")
02014 file_browser->select();
02015 else
02016 handled = false;
02017 }
02018 }
02019
02020 if (!handled)
02021 MythThemedDialog::keyPressEvent(e);
02022 }
02023
02024 void MythImageFileDialog::buildTree(QString starting_where)
02025 {
02026 buildFileList(starting_where);
02027
02028 root_parent = new GenericTree("Image Files root", -1, false);
02029 file_root = root_parent->addNode("Image Files", -1, false);
02030
02031
02032
02033
02034 for(uint i = 0; i < image_files.count(); ++i)
02035 {
02036 bool make_active = false;
02037 QString file_string = *(image_files.at(i));
02038 if (file_string == *selected_file)
02039 {
02040 make_active = true;
02041 }
02042 QString prefix = initialDir;
02043
02044 if (prefix.length() < 1)
02045 {
02046 cerr << "mythdialogs.o: Seems unlikely that this is going to work" << endl;
02047 }
02048 file_string.remove(0, prefix.length());
02049 QStringList list(QStringList::split("/", file_string));
02050 GenericTree *where_to_add;
02051 where_to_add = file_root;
02052 int a_counter = 0;
02053 QStringList::Iterator an_it = list.begin();
02054 for( ; an_it != list.end(); ++an_it)
02055 {
02056 if (a_counter + 1 >= (int) list.count())
02057 {
02058 QString title = (*an_it);
02059 GenericTree *added_node = where_to_add->addNode(title.section(".",0,0), i, true);
02060 if (make_active)
02061 {
02062 initial_node = added_node;
02063 }
02064 }
02065 else
02066 {
02067 QString dirname = *an_it + "/";
02068 GenericTree *sub_node;
02069 sub_node = where_to_add->getChildByName(dirname);
02070 if (!sub_node)
02071 {
02072 sub_node = where_to_add->addNode(dirname, -1, false);
02073 }
02074 where_to_add = sub_node;
02075 }
02076 ++a_counter;
02077 }
02078 }
02079 if (file_root->childCount() < 1)
02080 {
02081
02082
02083
02084 file_root->addNode("No files found", -1, false);
02085 }
02086 }
02087
02088 void MythImageFileDialog::buildFileList(QString directory)
02089 {
02090 QStringList imageExtensions = QImage::inputFormatList();
02091
02092
02093
02094
02095 if (imageExtensions.contains("jpeg") || imageExtensions.contains("JPEG"))
02096 imageExtensions += "jpg";
02097
02098 QDir d(directory);
02099
02100 if (!d.exists())
02101 return;
02102
02103 const QFileInfoList *list = d.entryInfoList();
02104
02105 if (!list)
02106 return;
02107
02108 QFileInfoListIterator it(*list);
02109 QFileInfo *fi;
02110 QRegExp r;
02111 while ((fi = it.current()) != 0)
02112 {
02113 ++it;
02114 if (fi->fileName() == "." ||
02115 fi->fileName() == ".." )
02116 {
02117 continue;
02118 }
02119
02120 if (fi->isDir())
02121 {
02122 buildFileList(fi->absFilePath());
02123 }
02124 else
02125 {
02126 r.setPattern("^" + fi->extension() + "$");
02127 r.setCaseSensitive(false);
02128 QStringList result = imageExtensions.grep(r);
02129 if (!result.isEmpty())
02130 {
02131 image_files.append(fi->absFilePath());
02132 }
02133 else
02134 {
02135 r.setPattern("^" + fi->extension());
02136 r.setCaseSensitive(false);
02137 QStringList other_result = imageExtensions.grep(r);
02138 if (!result.isEmpty())
02139 {
02140 image_files.append(fi->absFilePath());
02141 }
02142 }
02143 }
02144 }
02145 }
02146
02147 void MythImageFileDialog::handleTreeListEntered(int type, IntVector*)
02148 {
02149 if (image_box)
02150 {
02151 if (type > -1)
02152 {
02153 image_box->SetImage(image_files[type]);
02154 }
02155 else
02156 {
02157 image_box->SetImage("");
02158 }
02159 image_box->LoadImage();
02160 }
02161 }
02162
02163 void MythImageFileDialog::handleTreeListSelection(int type, IntVector*)
02164 {
02165 if (type > -1)
02166 {
02167 *selected_file = image_files[type];
02168 accept();
02169 }
02170 }
02171
02172 MythImageFileDialog::~MythImageFileDialog()
02173 {
02174 if (root_parent)
02175 {
02176 root_parent->deleteAllChildren();
02177 delete root_parent;
02178 root_parent = NULL;
02179 }
02180 }
02181
02182
02183
02184 MythScrollDialog::MythScrollDialog(MythMainWindow *parent,
02185 MythScrollDialog::ScrollMode mode,
02186 const char *name)
02187 : QScrollView(parent, name)
02188 {
02189 if (!parent)
02190 {
02191 VERBOSE(VB_IMPORTANT,
02192 "MythScrollDialog: Programmer error, trying to create "
02193 "a dialog without a parent.");
02194 done(kDialogCodeRejected);
02195 return;
02196 }
02197
02198 m_parent = parent;
02199 m_scrollMode = mode;
02200
02201 m_resCode = kDialogCodeRejected;
02202 m_inLoop = false;
02203
02204 gContext->GetScreenSettings(m_xbase, m_screenWidth, m_wmult,
02205 m_ybase, m_screenHeight, m_hmult);
02206
02207 m_defaultBigFont = gContext->GetBigFont();
02208 m_defaultMediumFont = gContext->GetMediumFont();
02209 m_defaultSmallFont = gContext->GetSmallFont();
02210
02211 setFont(m_defaultMediumFont);
02212 setCursor(QCursor(Qt::ArrowCursor));
02213
02214 setFrameShape(QFrame::NoFrame);
02215 setHScrollBarMode(QScrollView::AlwaysOff);
02216 setVScrollBarMode(QScrollView::AlwaysOff);
02217 setFixedSize(QSize(m_screenWidth, m_screenHeight));
02218
02219 gContext->ThemeWidget(viewport());
02220 if (viewport()->paletteBackgroundPixmap())
02221 m_bgPixmap = new QPixmap(*(viewport()->paletteBackgroundPixmap()));
02222 else {
02223 m_bgPixmap = new QPixmap(m_screenWidth, m_screenHeight);
02224 m_bgPixmap->fill(viewport()->colorGroup().base());
02225 }
02226 viewport()->setBackgroundMode(Qt::NoBackground);
02227
02228 m_upArrowPix = gContext->LoadScalePixmap("scrollarrow-up.png");
02229 m_dnArrowPix = gContext->LoadScalePixmap("scrollarrow-dn.png");
02230 m_ltArrowPix = gContext->LoadScalePixmap("scrollarrow-left.png");
02231 m_rtArrowPix = gContext->LoadScalePixmap("scrollarrow-right.png");
02232
02233 int wmargin = (int)(20*m_wmult);
02234 int hmargin = (int)(20*m_hmult);
02235
02236 if (m_upArrowPix)
02237 m_upArrowRect = QRect(m_screenWidth - m_upArrowPix->width() - wmargin,
02238 hmargin,
02239 m_upArrowPix->width(), m_upArrowPix->height());
02240 if (m_dnArrowPix)
02241 m_dnArrowRect = QRect(m_screenWidth - m_dnArrowPix->width() - wmargin,
02242 m_screenHeight - m_dnArrowPix->height() - hmargin,
02243 m_dnArrowPix->width(), m_dnArrowPix->height());
02244 if (m_rtArrowPix)
02245 m_rtArrowRect = QRect(m_screenWidth - m_rtArrowPix->width() - wmargin,
02246 m_screenHeight - m_rtArrowPix->height() - hmargin,
02247 m_rtArrowPix->width(), m_rtArrowPix->height());
02248 if (m_ltArrowPix)
02249 m_ltArrowRect = QRect(wmargin,
02250 m_screenHeight - m_ltArrowPix->height() - hmargin,
02251 m_ltArrowPix->width(), m_ltArrowPix->height());
02252
02253 m_showUpArrow = true;
02254 m_showDnArrow = true;
02255 m_showRtArrow = false;
02256 m_showLtArrow = false;
02257
02258 m_parent->attach(this);
02259 }
02260
02261 MythScrollDialog::~MythScrollDialog()
02262 {
02263 m_parent->detach(this);
02264 delete m_bgPixmap;
02265
02266 if (m_upArrowPix)
02267 delete m_upArrowPix;
02268 if (m_dnArrowPix)
02269 delete m_dnArrowPix;
02270 if (m_ltArrowPix)
02271 delete m_ltArrowPix;
02272 if (m_rtArrowPix)
02273 delete m_rtArrowPix;
02274 }
02275
02276 void MythScrollDialog::setArea(int w, int h)
02277 {
02278 resizeContents(w, h);
02279 }
02280
02281 void MythScrollDialog::setAreaMultiplied(int areaWTimes, int areaHTimes)
02282 {
02283 if (areaWTimes < 1 || areaHTimes < 1) {
02284 VERBOSE(VB_IMPORTANT,
02285 QString("MythScrollDialog::setAreaMultiplied(%1,%2): "
02286 "Warning, Invalid areaWTimes or areaHTimes. "
02287 "Setting to 1.")
02288 .arg(areaWTimes).arg(areaHTimes));
02289 areaWTimes = areaHTimes = 1;
02290 }
02291
02292 resizeContents(m_screenWidth*areaWTimes,
02293 m_screenHeight*areaHTimes);
02294 }
02295
02296 DialogCode MythScrollDialog::result(void) const
02297 {
02298 return m_resCode;
02299 }
02300
02301 void MythScrollDialog::show()
02302 {
02303 QScrollView::show();
02304 }
02305
02306 void MythScrollDialog::hide()
02307 {
02308 if (isHidden())
02309 return;
02310
02311
02312 QWidget::hide();
02313 QEventLoop *qteloop = QApplication::eventLoop();
02314 if (m_inLoop && qteloop)
02315 {
02316 m_inLoop = false;
02317 qteloop->exitLoop();
02318 }
02319 }
02320
02321 DialogCode MythScrollDialog::exec(void)
02322 {
02323 if (m_inLoop)
02324 {
02325 std::cerr << "MythScrollDialog::exec: Recursive call detected."
02326 << std::endl;
02327 return kDialogCodeRejected;
02328 }
02329
02330 setResult(kDialogCodeRejected);
02331
02332 show();
02333
02334 m_inLoop = true;
02335
02336 QEventLoop *qteloop = QApplication::eventLoop();
02337 if (!qteloop)
02338 return kDialogCodeRejected;
02339
02340 qteloop->enterLoop();
02341
02342 DialogCode res = result();
02343
02344 return res;
02345 }
02346
02347 void MythScrollDialog::done(int r)
02348 {
02349 hide();
02350 setResult((DialogCode)r);
02351 close();
02352 }
02353
02354 void MythScrollDialog::accept()
02355 {
02356 done(kDialogCodeAccepted);
02357 }
02358
02359 void MythScrollDialog::reject()
02360 {
02361 done(kDialogCodeRejected);
02362 }
02363
02364 void MythScrollDialog::setResult(DialogCode r)
02365 {
02366 m_resCode = r;
02367 }
02368
02369 void MythScrollDialog::keyPressEvent(QKeyEvent *e)
02370 {
02371 bool handled = false;
02372 QStringList actions;
02373
02374 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
02375 {
02376 for (unsigned int i = 0; i < actions.size() && !handled; i++)
02377 {
02378 QString action = actions[i];
02379 handled = true;
02380
02381 if (action == "ESCAPE")
02382 reject();
02383 else if (action == "UP" || action == "LEFT")
02384 {
02385 if (focusWidget() &&
02386 (focusWidget()->focusPolicy() == QWidget::StrongFocus ||
02387 focusWidget()->focusPolicy() == QWidget::WheelFocus))
02388 {
02389 }
02390 else
02391 focusNextPrevChild(false);
02392 }
02393 else if (action == "DOWN" || action == "RIGHT")
02394 {
02395 if (focusWidget() &&
02396 (focusWidget()->focusPolicy() == QWidget::StrongFocus ||
02397 focusWidget()->focusPolicy() == QWidget::WheelFocus))
02398 {
02399 }
02400 else
02401 focusNextPrevChild(true);
02402 }
02403 else
02404 handled = false;
02405 }
02406 }
02407 }
02408
02409 void MythScrollDialog::viewportPaintEvent(QPaintEvent *pe)
02410 {
02411 if (!pe)
02412 return;
02413
02414 QRect er(pe->rect());
02415 QRegion reg(er);
02416
02417 paintEvent(reg, er.x()+contentsX(), er.y()+contentsY(),
02418 er.width(), er.height());
02419
02420 if (m_scrollMode == HScroll) {
02421 if (m_ltArrowPix && m_showLtArrow) {
02422 QPixmap pix(m_ltArrowRect.size());
02423 bitBlt(&pix, 0, 0, m_bgPixmap, m_ltArrowRect.x(), m_ltArrowRect.y());
02424 bitBlt(&pix, 0, 0, m_ltArrowPix);
02425 bitBlt(viewport(), m_ltArrowRect.x(), m_ltArrowRect.y(), &pix);
02426 reg -= m_ltArrowRect;
02427 }
02428 if (m_rtArrowPix && m_showRtArrow) {
02429 QPixmap pix(m_rtArrowRect.size());
02430 bitBlt(&pix, 0, 0, m_bgPixmap, m_rtArrowRect.x(), m_rtArrowRect.y());
02431 bitBlt(&pix, 0, 0, m_rtArrowPix);
02432 bitBlt(viewport(), m_rtArrowRect.x(), m_rtArrowRect.y(), &pix);
02433 reg -= m_rtArrowRect;
02434 }
02435 }
02436 else {
02437 if (m_upArrowPix && m_showUpArrow) {
02438 QPixmap pix(m_upArrowRect.size());
02439 bitBlt(&pix, 0, 0, m_bgPixmap, m_upArrowRect.x(), m_upArrowRect.y());
02440 bitBlt(&pix, 0, 0, m_upArrowPix);
02441 bitBlt(viewport(), m_upArrowRect.x(), m_upArrowRect.y(), &pix);
02442 reg -= m_upArrowRect;
02443 }
02444 if (m_dnArrowPix && m_showDnArrow) {
02445 QPixmap pix(m_dnArrowRect.size());
02446 bitBlt(&pix, 0, 0, m_bgPixmap, m_dnArrowRect.x(), m_dnArrowRect.y());
02447 bitBlt(&pix, 0, 0, m_dnArrowPix);
02448 bitBlt(viewport(), m_dnArrowRect.x(), m_dnArrowRect.y(), &pix);
02449 reg -= m_dnArrowRect;
02450 }
02451 }
02452
02453 QPainter p(viewport());
02454 p.setClipRegion(reg);
02455 p.drawPixmap(0, 0, *m_bgPixmap, 0, 0, viewport()->width(),
02456 viewport()->height());
02457 p.end();
02458 }
02459
02460 void MythScrollDialog::paintEvent(QRegion&, int , int , int , int )
02461 {
02462 }
02463
02464 void MythScrollDialog::setContentsPos(int x, int y)
02465 {
02466 viewport()->setUpdatesEnabled(false);
02467 QScrollView::setContentsPos(x,y);
02468 viewport()->setUpdatesEnabled(true);
02469 updateContents();
02470 }
02471
02472