00001
00002 #include <QDateTime>
00003 #include <QCoreApplication>
00004 #include <QStringList>
00005 #include <QRegExp>
00006 #include <QKeyEvent>
00007 #include <QEvent>
00008
00009
00010 #include "mythdb.h"
00011 #include "mythdbcon.h"
00012 #include "mythdirs.h"
00013 #include "mythcorecontext.h"
00014 #include "recordinginfo.h"
00015 #include "tv.h"
00016
00017
00018 #include "mythuitext.h"
00019 #include "mythuibuttonlist.h"
00020 #include "mythuibutton.h"
00021 #include "mythuihelper.h"
00022 #include "mythscreenstack.h"
00023 #include "mythmainwindow.h"
00024
00025
00026 #include "guidegrid.h"
00027 #include "customedit.h"
00028 #include "progfind.h"
00029
00030 #define LOC QString("ProgFinder: ")
00031 #define LOC_ERR QString("ProgFinder, Error: ")
00032 #define LOC_WARN QString("ProgFinder, Warning: ")
00033
00034 void RunProgramFinder(TV *player, bool embedVideo, bool allowEPG)
00035 {
00036
00037 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00038 ProgFinder *programFind = NULL;
00039 if (gCoreContext->GetLanguage() == "ja")
00040 programFind = new JaProgFinder(mainStack, allowEPG, player, embedVideo);
00041 else if (gCoreContext->GetLanguage() == "he")
00042 programFind = new HeProgFinder(mainStack, allowEPG, player, embedVideo);
00043 else if (gCoreContext->GetLanguage() == "ru")
00044 programFind = new RuProgFinder(mainStack, allowEPG, player, embedVideo);
00045 else
00046 programFind = new ProgFinder(mainStack, allowEPG, player, embedVideo);
00047
00048 if (programFind->Create())
00049 mainStack->AddScreen(programFind, (player == NULL));
00050 else
00051 delete programFind;
00052 }
00053
00054 ProgFinder::ProgFinder(MythScreenStack *parentStack, bool allowEPG,
00055 TV *player, bool embedVideo)
00056 : ScheduleCommon(parentStack, "ProgFinder"),
00057 m_currentLetter(""),
00058 m_player(player), m_embedVideo(embedVideo),
00059 m_allowEPG(allowEPG), m_allowKeypress(true),
00060 m_alphabetList(NULL), m_showList(NULL),
00061 m_timesList(NULL), m_searchText(NULL),
00062 m_help1Text(NULL), m_help2Text(NULL)
00063 {
00064 }
00065
00066 bool ProgFinder::Create()
00067 {
00068 if (!LoadWindowFromXML("schedule-ui.xml", "programfind", this))
00069 return false;
00070
00071 bool err = false;
00072 UIUtilE::Assign(this, m_alphabetList, "alphabet", &err);
00073 UIUtilE::Assign(this, m_showList, "shows", &err);
00074 UIUtilE::Assign(this, m_timesList, "times", &err);
00075
00076 UIUtilW::Assign(this, m_help1Text, "help1text");
00077 UIUtilW::Assign(this, m_help2Text, "help2text");
00078 UIUtilW::Assign(this, m_searchText, "search");
00079
00080 if (err)
00081 {
00082 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'programfind'");
00083 return false;
00084 }
00085
00086 m_alphabetList->SetLCDTitles(tr("Starts With"), "");
00087 m_showList->SetLCDTitles(tr("Programs"), "");
00088 m_timesList->SetLCDTitles(tr("Times"), "buttontext");
00089
00090 BuildFocusList();
00091 LoadInBackground();
00092
00093 if (m_player)
00094 m_player->StartEmbedding(QRect());
00095
00096 return true;
00097 }
00098
00099 void ProgFinder::Init(void)
00100 {
00101 m_allowKeypress = true;
00102
00103 initAlphabetList();
00104
00105 gCoreContext->addListener(this);
00106
00107 connect(m_timesList, SIGNAL(itemSelected(MythUIButtonListItem*)),
00108 SLOT(updateInfo()));
00109 connect(m_timesList, SIGNAL(itemClicked(MythUIButtonListItem*)),
00110 SLOT(select()));
00111 connect(m_timesList, SIGNAL(LosingFocus()), SLOT(timesListLosingFocus()));
00112 connect(m_timesList, SIGNAL(TakingFocus()), SLOT(timesListTakeFocus()));
00113
00114 connect(m_alphabetList, SIGNAL(itemSelected(MythUIButtonListItem*)),
00115 SLOT(alphabetListItemSelected(MythUIButtonListItem*)));
00116 connect(m_alphabetList, SIGNAL(itemClicked(MythUIButtonListItem*)),
00117 SLOT(select()));
00118
00119 connect(m_showList, SIGNAL(TakingFocus()), SLOT(showListTakeFocus()));
00120 connect(m_showList, SIGNAL(itemClicked(MythUIButtonListItem*)),
00121 SLOT(select()));
00122
00123 m_alphabetList->MoveToNamedPosition("A");
00124 }
00125
00126 ProgFinder::~ProgFinder()
00127 {
00128 gCoreContext->removeListener(this);
00129
00130
00131
00132 if (m_player && m_allowEPG)
00133 {
00134 QString message = QString("PROGFINDER_EXITING");
00135 qApp->postEvent(m_player, new MythEvent(message));
00136 }
00137 }
00138
00139 void ProgFinder::alphabetListItemSelected(MythUIButtonListItem *item)
00140 {
00141 if (!item || (m_currentLetter == item->GetText()))
00142 return;
00143
00144 m_currentLetter = item->GetText();
00145
00146 updateShowList();
00147 updateInfo();
00148 }
00149
00150 void ProgFinder::timesListLosingFocus(void)
00151 {
00152 m_timesList->Reset();
00153 }
00154
00155 void ProgFinder::showListTakeFocus(void)
00156 {
00157 updateInfo();
00158 }
00159
00160 void ProgFinder::timesListTakeFocus(void)
00161 {
00162 selectShowData("", 0);
00163 updateInfo();
00164 }
00165
00166 bool ProgFinder::keyPressEvent(QKeyEvent *event)
00167 {
00168 if (!m_allowKeypress)
00169 return true;
00170
00171 m_allowKeypress = false;
00172
00173 if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
00174 {
00175 m_allowKeypress = true;
00176 return true;
00177 }
00178
00179 bool handled = false;
00180
00181 QStringList actions;
00182 handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", event, actions);
00183
00184 for (int i = 0; i < actions.size() && !handled; ++i)
00185 {
00186 QString action = actions[i];
00187 handled = true;
00188
00189 if (action == "EDIT")
00190 edit();
00191 else if (action == "CUSTOMEDIT")
00192 customEdit();
00193 else if (action == "UPCOMING")
00194 upcoming();
00195 else if (action == "DETAILS" || action == "INFO")
00196 details();
00197 else if (action == "TOGGLERECORD")
00198 quickRecord();
00199 else if (action == "GUIDE" || action == "4")
00200 showGuide();
00201 else if (action == "ESCAPE")
00202 {
00203
00204 if (m_player && m_allowEPG)
00205 GetScreenStack()->PopScreen(this, false);
00206 else
00207 GetScreenStack()->PopScreen(this, true);
00208 }
00209 else
00210 handled = false;
00211 }
00212
00213 if (!handled && MythScreenType::keyPressEvent(event))
00214 handled = true;
00215
00216 m_allowKeypress = true;
00217
00218 return handled;
00219 }
00220
00221 void ProgFinder::ShowMenu(void)
00222 {
00223 QString label = tr("Options");
00224
00225 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00226 MythDialogBox *menuPopup = new MythDialogBox(label, popupStack, "menuPopup");
00227
00228 if (menuPopup->Create())
00229 {
00230 menuPopup->SetReturnEvent(this, "menu");
00231
00232 if (!m_searchStr.isEmpty())
00233 menuPopup->AddButton(tr("Clear Search"));
00234 menuPopup->AddButton(tr("Edit Search"));
00235 if (GetFocusWidget() == m_timesList && m_timesList->GetCount() > 0)
00236 {
00237 menuPopup->AddButton(tr("Toggle Record"));
00238 menuPopup->AddButton(tr("Program Details"));
00239 menuPopup->AddButton(tr("Upcoming"));
00240 menuPopup->AddButton(tr("Custom Edit"));
00241 menuPopup->AddButton(tr("Program Guide"));
00242 }
00243
00244 popupStack->AddScreen(menuPopup);
00245 }
00246 else
00247 {
00248 delete menuPopup;
00249 }
00250 }
00251
00252 void ProgFinder::customEvent(QEvent *event)
00253 {
00254 if ((MythEvent::Type)(event->type()) == MythEvent::MythEventMessage)
00255 {
00256 MythEvent *me = (MythEvent *)event;
00257 QString message = me->Message();
00258
00259 if (message == "SCHEDULE_CHANGE")
00260 {
00261 if (GetFocusWidget() == m_timesList)
00262 {
00263 ProgramInfo *curPick = m_showData[m_timesList->GetCurrentPos()];
00264 if (curPick)
00265 selectShowData(curPick->GetTitle(),
00266 m_timesList->GetCurrentPos());
00267 }
00268 }
00269 }
00270 else if (event->type() == DialogCompletionEvent::kEventType)
00271 {
00272 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00273
00274 QString resultid = dce->GetId();
00275 QString resulttext = dce->GetResultText();
00276
00277 if (resultid == "menu")
00278 {
00279 if (resulttext == tr("Clear Search"))
00280 {
00281 m_searchStr.clear();
00282 if (m_searchText)
00283 m_searchText->SetText(m_searchStr);
00284 updateShowList();
00285 SetFocusWidget(m_showList);
00286 }
00287 else if (resulttext == tr("Edit Search"))
00288 {
00289 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00290 SearchInputDialog *textInput =
00291 new SearchInputDialog(popupStack, m_searchStr);
00292
00293 if (textInput->Create())
00294 {
00295 textInput->SetReturnEvent(this, "searchtext");
00296 popupStack->AddScreen(textInput);
00297 }
00298 }
00299 else if (resulttext == tr("Toggle Record"))
00300 {
00301 quickRecord();
00302 }
00303 else if (resulttext == tr("Program Details"))
00304 {
00305 details();
00306 }
00307 else if (resulttext == tr("Upcoming"))
00308 {
00309 upcoming();
00310 }
00311 else if (resulttext == tr("Custom Edit"))
00312 {
00313 customEdit();
00314 }
00315 else if (resulttext == tr("Program Guide"))
00316 {
00317 showGuide();
00318 }
00319 }
00320 else if (resultid == "searchtext")
00321 {
00322 m_searchStr = resulttext;
00323 if (m_searchText)
00324 m_searchText->SetText(m_searchStr);
00325 updateShowList();
00326 SetFocusWidget(m_showList);
00327 }
00328 else
00329 ScheduleCommon::customEvent(event);
00330 }
00331 }
00332
00333 void ProgFinder::updateInfo(void)
00334 {
00335 if (m_help1Text)
00336 m_help1Text->Reset();
00337 if (m_help2Text)
00338 m_help2Text->Reset();
00339
00340 if (GetFocusWidget() == m_alphabetList)
00341 {
00342 QString title;
00343 QString description;
00344
00345 if (m_showList->GetCount() == 0)
00346 {
00347 if (m_help1Text)
00348 m_help1Text->SetText(tr("No Programs"));
00349 if (m_help2Text)
00350 m_help2Text->SetText(tr("There are no available programs under this search. "
00351 "Please select another search."));
00352 }
00353 else
00354 {
00355 if (m_help1Text)
00356 m_help1Text->SetText(tr("Select a letter..."));
00357 if (m_help2Text)
00358 m_help2Text->SetText(tr("Pick the first letter of the program name, "
00359 "then press SELECT or the right arrow."));
00360 }
00361
00362 ResetMap(m_infoMap);
00363 }
00364 else if (GetFocusWidget() == m_showList)
00365 {
00366 if (m_help1Text)
00367 m_help1Text->SetText(tr("Select a program..."));
00368 if (m_help2Text)
00369 m_help2Text->SetText(tr("Select the title of the program you wish to find. "
00370 "When finished return with the left arrow key. "
00371 "Press SELECT to schedule a recording."));
00372
00373 ResetMap(m_infoMap);
00374 }
00375 else if (GetFocusWidget() == m_timesList)
00376 {
00377 if (m_showData.size() == 0)
00378 {
00379 ResetMap(m_infoMap);
00380 if (m_help1Text)
00381 m_help1Text->SetText(tr("No Programs"));
00382 if (m_help2Text)
00383 m_help2Text->SetText(tr("There are no available programs under "
00384 "this search. Please select another "
00385 "search."));
00386 }
00387 else
00388 {
00389 InfoMap infoMap;
00390 m_showData[m_timesList->GetCurrentPos()]->ToMap(infoMap);
00391 SetTextFromMap(infoMap);
00392 m_infoMap = infoMap;
00393 }
00394 }
00395 }
00396
00397 void ProgFinder::showGuide()
00398 {
00399 if (m_allowEPG)
00400 {
00401 QString startchannel = gCoreContext->GetSetting("DefaultTVChannel");
00402 if (startchannel.isEmpty())
00403 startchannel = '3';
00404 uint startchanid = 0;
00405 GuideGrid::RunProgramGuide(startchanid, startchannel, m_player, m_embedVideo, false, -2);
00406 }
00407 }
00408
00409 void ProgFinder::getInfo(bool toggle)
00410 {
00411 if (GetFocusWidget() == m_timesList)
00412 {
00413 ProgramInfo *curPick = m_showData[m_timesList->GetCurrentPos()];
00414
00415 if (curPick)
00416 {
00417 if (toggle)
00418 {
00419 RecordingInfo ri(*curPick);
00420 ri.ToggleRecord();
00421 *curPick = ri;
00422 }
00423 else
00424 EditRecording(curPick);
00425 }
00426 else
00427 return;
00428
00429
00430 selectShowData(curPick->GetTitle(), m_timesList->GetCurrentPos());
00431 }
00432 }
00433
00434 void ProgFinder::edit()
00435 {
00436 if (GetFocusWidget() == m_timesList)
00437 {
00438 ProgramInfo *curPick = m_showData[m_timesList->GetCurrentPos()];
00439
00440 if (curPick)
00441 {
00442 EditScheduled(curPick);
00443
00444 selectShowData(curPick->GetTitle(), m_timesList->GetCurrentPos());
00445 }
00446 }
00447 }
00448
00449 void ProgFinder::select()
00450 {
00451 if (GetFocusWidget() == m_timesList)
00452 getInfo();
00453 else if (GetFocusWidget() == m_alphabetList && m_showList->GetCount())
00454 SetFocusWidget(m_showList);
00455 else if (GetFocusWidget() == m_showList)
00456 SetFocusWidget(m_timesList);
00457 }
00458
00459 void ProgFinder::customEdit()
00460 {
00461 if (GetFocusWidget() == m_timesList)
00462 {
00463 ProgramInfo *pginfo = m_showData[m_timesList->GetCurrentPos()];
00464 EditCustom(pginfo);
00465 }
00466 }
00467
00468 void ProgFinder::upcoming()
00469 {
00470 if (GetFocusWidget() == m_timesList)
00471 {
00472 ProgramInfo *pginfo = m_showData[m_timesList->GetCurrentPos()];
00473 ShowUpcoming(pginfo);
00474 }
00475 }
00476
00477 void ProgFinder::details()
00478 {
00479 if (GetFocusWidget() != m_timesList)
00480 return;
00481
00482 ProgramInfo *curPick = m_showData[m_timesList->GetCurrentPos()];
00483 ShowDetails(curPick);
00484 }
00485
00486 void ProgFinder::quickRecord()
00487 {
00488 getInfo(true);
00489 }
00490
00491 void ProgFinder::updateTimesList()
00492 {
00493 InfoMap infoMap;
00494
00495 m_timesList->Reset();
00496
00497 if (m_showData.size() > 0)
00498 {
00499 QString itemText;
00500 QDateTime starttime;
00501 for (uint i = 0; i < m_showData.size(); ++i)
00502 {
00503 starttime = m_showData[i]->GetScheduledStartTime();
00504 itemText = MythDateTimeToString(starttime,
00505 kDateTimeFull | kSimplify);
00506
00507 MythUIButtonListItem *item =
00508 new MythUIButtonListItem(m_timesList, "");
00509
00510 m_showData[i]->ToMap(infoMap);
00511 item->SetTextFromMap(infoMap);
00512
00513 QString state = toUIState(m_showData[i]->GetRecordingStatus());
00514 item->SetText(itemText, "buttontext", state);
00515 item->DisplayState(state, "status");
00516 }
00517 }
00518 }
00519
00520 void ProgFinder::getShowNames()
00521 {
00522 m_showNames.clear();
00523
00524 QString thequery;
00525 MSqlBindings bindings;
00526
00527 MSqlQuery query(MSqlQuery::InitCon());
00528 whereClauseGetSearchData(thequery, bindings);
00529
00530 query.prepare(thequery);
00531 query.bindValues(bindings);
00532 if (!query.exec())
00533 {
00534 MythDB::DBError("getShowNames", query);
00535 return;
00536 }
00537
00538 QString data;
00539 while (query.next())
00540 {
00541 data = query.value(0).toString();
00542
00543 if (formatSelectedData(data))
00544 m_showNames[data.toLower()] = data;
00545 }
00546 }
00547
00548 void ProgFinder::updateShowList()
00549 {
00550 m_showList->Reset();
00551
00552 if (m_showNames.isEmpty())
00553 getShowNames();
00554
00555 ShowName::Iterator it;
00556 for (it = m_showNames.begin(); it != m_showNames.end(); ++it)
00557 {
00558 QString tmpProgData = *it;
00559 restoreSelectedData(tmpProgData);
00560 new MythUIButtonListItem(m_showList, tmpProgData);
00561 }
00562
00563 m_showNames.clear();
00564 }
00565
00566 void ProgFinder::selectShowData(QString progTitle, int newCurShow)
00567 {
00568 progTitle = m_showList->GetValue();
00569
00570 QDateTime progStart = QDateTime::currentDateTime();
00571
00572 MSqlBindings bindings;
00573 QString querystr = "WHERE program.title = :TITLE "
00574 " AND program.endtime > :ENDTIME "
00575 " AND channel.visible = 1 ";
00576 bindings[":TITLE"] = progTitle;
00577 bindings[":ENDTIME"] = progStart.addSecs(50 - progStart.time().second());
00578
00579 LoadFromScheduler(m_schedList);
00580 LoadFromProgram(m_showData, querystr, bindings, m_schedList);
00581
00582 updateTimesList();
00583
00584 m_timesList->SetItemCurrent(newCurShow);
00585 }
00586
00587 void ProgFinder::initAlphabetList(void)
00588 {
00589 for (int charNum = 48; charNum < 91; ++charNum)
00590 {
00591 if (charNum == 58)
00592 charNum = 65;
00593
00594 new MythUIButtonListItem(m_alphabetList, QString((char)charNum));
00595 }
00596
00597 new MythUIButtonListItem(m_alphabetList, QString('@'));
00598 }
00599
00600 void ProgFinder::whereClauseGetSearchData(QString &where, MSqlBindings &bindings)
00601 {
00602 QDateTime progStart = QDateTime::currentDateTime();
00603 QString searchChar = m_alphabetList->GetValue();
00604
00605 if (searchChar.isEmpty())
00606 searchChar = "A";
00607
00608 if (searchChar.contains('@'))
00609 {
00610 where = "SELECT DISTINCT title FROM program "
00611 "LEFT JOIN channel ON program.chanid = channel.chanid "
00612 "WHERE channel.visible = 1 AND "
00613 "( title NOT REGEXP '^[A-Z0-9]' AND "
00614 " title NOT REGEXP '^The [A-Z0-9]' AND "
00615 " title NOT REGEXP '^A [A-Z0-9]' AND "
00616 " title NOT REGEXP '^An [A-Z0-9]' AND "
00617 " starttime > :STARTTIME ) ";
00618 if (!m_searchStr.isEmpty())
00619 {
00620 where += "AND title LIKE :SEARCH ";
00621 bindings[":SEARCH"] = '%' + m_searchStr + '%';
00622 }
00623
00624 where += "ORDER BY title;";
00625
00626 bindings[":STARTTIME"] =
00627 progStart.addSecs(50 - progStart.time().second());
00628 }
00629 else
00630 {
00631 QString one = searchChar + '%';
00632 QString two = QString("The ") + one;
00633 QString three = QString("A ") + one;
00634 QString four = QString("An ") + one;
00635
00636 where = "SELECT DISTINCT title FROM program "
00637 "LEFT JOIN channel ON program.chanid = channel.chanid "
00638 "WHERE channel.visible = 1 "
00639 "AND ( title LIKE :ONE OR title LIKE :TWO "
00640 " OR title LIKE :THREE "
00641 " OR title LIKE :FOUR ) "
00642 "AND starttime > :STARTTIME ";
00643 if (!m_searchStr.isEmpty())
00644 where += "AND title LIKE :SEARCH ";
00645
00646 where += "ORDER BY title;";
00647
00648 bindings[":ONE"] = one;
00649 bindings[":TWO"] = two;
00650 bindings[":THREE"] = three;
00651 bindings[":FOUR"] = four;
00652 bindings[":STARTTIME"] =
00653 progStart.addSecs(50 - progStart.time().second());
00654
00655 if (!m_searchStr.isEmpty())
00656 bindings[":SEARCH"] = '%' + m_searchStr + '%';
00657 }
00658 }
00659
00660 bool ProgFinder::formatSelectedData(QString& data)
00661 {
00662 bool retval = true;
00663 QString searchChar = m_alphabetList->GetValue();
00664
00665 if (searchChar == "T")
00666 {
00667 if (data.left(4) != "The " && data.left(2) != "A ")
00668 {
00669
00670 }
00671 else if (data.left(5) == "The T")
00672 data = data.mid(4) + ", The";
00673 else if (data.left(3) == "A T")
00674 data = data.mid(2) + ", A";
00675 else
00676 {
00677
00678 retval = false;
00679 }
00680 }
00681 else if (searchChar == "A")
00682 {
00683 if (data.left(4) != "The " && data.left(2) != "A ")
00684 {
00685
00686 }
00687 else if (data.left(5) == "The A")
00688 data = data.mid(4) + ", The";
00689 else if (data.left(3) == "A A")
00690 data = data.mid(2) + ", A";
00691 else if (data.left(4) == "An A")
00692 data = data.mid(3) + ", An";
00693 else
00694 {
00695
00696 retval = false;
00697 }
00698 }
00699 else
00700 {
00701 if (data.left(4) == "The ")
00702 data = data.mid(4) + ", The";
00703 else if (data.left(2) == "A ")
00704 data = data.mid(2) + ", A";
00705 else if (data.left(3) == "An ")
00706 data = data.mid(3) + ", An";
00707 }
00708
00709 return retval;
00710 }
00711
00712 bool ProgFinder::formatSelectedData(QString& data, int charNum)
00713 {
00714 bool retval = true;
00715
00716 if (charNum == 29 || charNum == 10)
00717 {
00718 if (data.left(5) == "The T" && charNum == 29)
00719 data = data.mid(4) + ", The";
00720 else if (data.left(5) == "The A" && charNum == 10)
00721 data = data.mid(4) + ", The";
00722 else if (data.left(3) == "A T" && charNum == 29)
00723 data = data.mid(2) + ", A";
00724 else if (data.left(3) == "A A" && charNum == 10)
00725 data = data.mid(2) + ", A";
00726 else if (data.left(4) == "An A" && charNum == 10)
00727 data = data.mid(3) + ", An";
00728 else if (data.left(4) != "The " && data.left(2) != "A ")
00729 {
00730
00731 }
00732 else
00733 {
00734
00735 retval = false;
00736 }
00737 }
00738 else
00739 {
00740 if (data.left(4) == "The ")
00741 data = data.mid(4) + ", The";
00742 if (data.left(2) == "A ")
00743 data = data.mid(2) + ", A";
00744 if (data.left(3) == "An ")
00745 data = data.mid(3) + ", An";
00746 }
00747
00748 return retval;
00749 }
00750
00751 void ProgFinder::restoreSelectedData(QString &data)
00752 {
00753 if (data.right(5) == ", The")
00754 data = "The " + data.left(data.length() - 5);
00755 if (data.right(3) == ", A")
00756 data = "A " + data.left(data.length() - 3);
00757 }
00758
00760
00761
00762
00763 const char* JaProgFinder::searchChars[] = {
00764 "あ", "か", "さ", "た", "な", "は", "ま", "や", "ら", "わ",
00765 "英", "数",
00766 0,
00767 };
00768
00769 JaProgFinder::JaProgFinder(MythScreenStack *parentStack, bool gg,
00770 TV *player, bool embedVideo)
00771 : ProgFinder(parentStack, gg, player, embedVideo)
00772 {
00773 for (numberOfSearchChars = 0; searchChars[numberOfSearchChars];
00774 ++numberOfSearchChars)
00775 ;
00776 }
00777
00778 void JaProgFinder::initAlphabetList()
00779 {
00780 for (int charNum = 0; charNum < numberOfSearchChars; ++charNum)
00781 {
00782 new MythUIButtonListItem(m_alphabetList, QString(searchChars[charNum]));
00783 }
00784 }
00785
00786
00787
00788
00789
00790 void JaProgFinder::whereClauseGetSearchData(QString &where, MSqlBindings &bindings)
00791 {
00792 QDateTime progStart = QDateTime::currentDateTime();
00793 int charNum = m_alphabetList->GetCurrentPos();
00794
00795 where = "SELECT DISTINCT title FROM program "
00796 "LEFT JOIN channel ON program.chanid = channel.chanid "
00797 "WHERE channel.visible = 1 ";
00798
00799 switch (charNum) {
00800 case 0:
00801 where += "AND ( title_pronounce >= 'あ' AND title_pronounce <= 'お') ";
00802 break;
00803 case 1:
00804 where += "AND ( title_pronounce >= 'か' AND title_pronounce <= 'ご') ";
00805 break;
00806 case 2:
00807 where += "AND ( title_pronounce >= 'さ' AND title_pronounce <= 'そ') ";
00808 break;
00809 case 3:
00810 where += "AND ( title_pronounce >= 'た' AND title_pronounce <= 'ど') ";
00811 break;
00812 case 4:
00813 where += "AND ( title_pronounce >= 'な' AND title_pronounce <= 'の') ";
00814 break;
00815 case 5:
00816 where += "AND ( title_pronounce >= 'は' AND title_pronounce <= 'ぽ') ";
00817 break;
00818 case 6:
00819 where += "AND ( title_pronounce >= 'ま' AND title_pronounce <= 'も') ";
00820 break;
00821 case 7:
00822 where += "AND ( title_pronounce >= 'や' AND title_pronounce <= 'よ') ";
00823 break;
00824 case 8:
00825 where += "AND ( title_pronounce >= 'ら' AND title_pronounce <= 'ろ') ";
00826 break;
00827 case 9:
00828 where += "AND ( title_pronounce >= 'わ' AND title_pronounce <= 'ん') ";
00829 break;
00830 case 10:
00831 where += "AND ( title_pronounce >= 'A' AND title_pronounce <= 'z') ";
00832 break;
00833 case 11:
00834 where += "AND ( title_pronounce >= '0' AND title_pronounce <= '9') ";
00835 break;
00836 }
00837
00838 where += "AND starttime > :STARTTIME ";
00839
00840 if (!m_searchStr.isEmpty())
00841 {
00842 where += "AND title_pronounce LIKE :SEARCH ";
00843 bindings[":SEARCH"] = '%' + m_searchStr + '%';
00844 }
00845
00846 where += "ORDER BY title_pronounce;";
00847
00848 bindings[":STARTTIME"] = progStart.addSecs(50 - progStart.time().second());
00849 }
00850
00851
00852 bool JaProgFinder::formatSelectedData(QString& data)
00853 {
00854 (void)data;
00855 return true;
00856 }
00857
00858 bool JaProgFinder::formatSelectedData(QString& data, int charNum)
00859 {
00860 (void)data;
00861 (void)charNum;
00862 return true;
00863 }
00864
00865 void JaProgFinder::restoreSelectedData(QString& data)
00866 {
00867 (void)data;
00868 }
00869
00870
00871
00872
00873 const char* HeProgFinder::searchChars[] = {
00874 "\u05d0", "\u05d1", "\u05d2", "\u05d3", "\u05d4", "\u05d5", "\u05d6", "\u05d7", "\u05d8",
00875 "\u05d9", "\u05db", "\u05dc", "\u05de", "\u05e0", "\u05e1", "\u05e2", "\u05e4", "\u05e6",
00876 "\u05e7", "\u05e8", "\u05e9", "\u05ea", "E", "#", 0 };
00877
00878 HeProgFinder::HeProgFinder(MythScreenStack *parentStack, bool gg,
00879 TV *player, bool embedVideo)
00880 : ProgFinder(parentStack, gg, player, embedVideo)
00881 {
00882 for (numberOfSearchChars = 0; searchChars[numberOfSearchChars];
00883 ++numberOfSearchChars)
00884 ;
00885 }
00886
00887 void HeProgFinder::initAlphabetList()
00888 {
00889 for (int charNum = 0; charNum < numberOfSearchChars; ++charNum)
00890 {
00891 new MythUIButtonListItem(m_alphabetList, QString::fromUtf8(searchChars[charNum]));
00892 }
00893 }
00894
00895
00896
00897 void HeProgFinder::whereClauseGetSearchData(QString &where, MSqlBindings &bindings)
00898 {
00899 QDateTime progStart = QDateTime::currentDateTime();
00900 QString searchChar = m_alphabetList->GetValue();
00901
00902 if (searchChar.isEmpty())
00903 searchChar = searchChars[0];
00904
00905 where = "SELECT DISTINCT title FROM program "
00906 "LEFT JOIN channel ON program.chanid = channel.chanid "
00907 "WHERE channel.visible = 1 ";
00908
00909 if (searchChar.contains('E'))
00910 {
00911 where += "AND ( title REGEXP '^[A-Z]') ";
00912 }
00913 else if (searchChar.contains('#'))
00914 {
00915 where += "AND ( title REGEXP '^[0-9]') ";
00916 }
00917 else
00918 {
00919 QString one = searchChar + '%';
00920 bindings[":ONE"] = one;
00921 where += "AND ( title LIKE :ONE ) ";
00922 }
00923
00924 where += "AND starttime > :STARTTIME ";
00925
00926 if (!m_searchStr.isEmpty())
00927 {
00928 where += "AND title LIKE :SEARCH ";
00929 bindings[":SEARCH"] = '%' + m_searchStr + '%';
00930 }
00931
00932 where += "ORDER BY title;";
00933
00934 bindings[":STARTTIME"] = progStart.addSecs(50 - progStart.time().second());
00935 }
00936
00937 bool HeProgFinder::formatSelectedData(QString& data)
00938 {
00939 (void)data;
00940 return true;
00941 }
00942
00943 bool HeProgFinder::formatSelectedData(QString& data, int charNum)
00944 {
00945 (void)data;
00946 (void)charNum;
00947 return true;
00948 }
00949
00950 void HeProgFinder::restoreSelectedData(QString& data)
00951 {
00952 (void)data;
00953 }
00954
00956
00957
00958
00959 const char* RuProgFinder::searchChars[] = {
00960 "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "И",
00961 "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т",
00962 "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "ь",
00963 "Э", "Ю", "Я", "0", "1", "2", "3", "4", "5", "6",
00964 "7", "8", "9", "@", "A", "B", "C", "D", "E", "F",
00965 "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
00966 "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", 0 };
00967
00968 RuProgFinder::RuProgFinder(MythScreenStack *parentStack, bool gg,
00969 TV *player, bool embedVideo)
00970 : ProgFinder(parentStack, gg, player, embedVideo)
00971 {
00972 for (numberOfSearchChars = 0; searchChars[numberOfSearchChars];
00973 ++numberOfSearchChars)
00974 ;
00975 }
00976
00977 void RuProgFinder::initAlphabetList()
00978 {
00979 for (int charNum = 0; charNum < numberOfSearchChars; ++charNum)
00980 {
00981 new MythUIButtonListItem(m_alphabetList, QString::fromUtf8(searchChars[charNum]));
00982 }
00983 }
00984
00985
00986
00987 void RuProgFinder::whereClauseGetSearchData(QString &where, MSqlBindings
00988 &bindings)
00989 {
00990 QDateTime progStart = QDateTime::currentDateTime();
00991 QString searchChar = m_alphabetList->GetValue();
00992
00993 if (searchChar.isEmpty())
00994 searchChar = searchChars[0];
00995
00996
00997 if (searchChar.contains('@'))
00998 {
00999 where = "SELECT DISTINCT title FROM program "
01000 "LEFT JOIN channel ON program.chanid = channel.chanid "
01001 "WHERE channel.visible = 1 AND "
01002 "( "
01003 "title NOT REGEXP '^[A-Z0-9]' AND "
01004 "title NOT REGEXP '^The [A-Z0-9]' AND "
01005 "title NOT REGEXP '^A [A-Z0-9]' AND "
01006 "title NOT REGEXP '^[0-9]' AND "
01007 "starttime > :STARTTIME ) ";
01008 if (!m_searchStr.isEmpty())
01009 {
01010 where += "AND title LIKE :SEARCH ";
01011 bindings[":SEARCH"] = '%' + m_searchStr + '%';
01012 }
01013
01014 where += "ORDER BY title;";
01015
01016 bindings[":STARTTIME"] =
01017 progStart.addSecs(50 - progStart.time().second());
01018 }
01019 else
01020 {
01021 QString one = searchChar + '%';
01022 QString two = QString("The ") + one;
01023 QString three = QString("A ") + one;
01024 QString four = QString("An ") + one;
01025 QString five = QString("\"") + one;
01026
01027 where = "SELECT DISTINCT title FROM program "
01028 "LEFT JOIN channel ON program.chanid = channel.chanid "
01029 "WHERE channel.visible = 1 "
01030 "AND ( title LIKE :ONE OR title LIKE :TWO "
01031 " OR title LIKE :THREE "
01032 " OR title LIKE :FOUR "
01033 " OR title LIKE :FIVE )"
01034 "AND starttime > :STARTTIME ";
01035 if (!m_searchStr.isEmpty())
01036 where += "AND title LIKE :SEARCH ";
01037
01038 where += "ORDER BY title;";
01039
01040 bindings[":ONE"] = one;
01041 bindings[":TWO"] = two;
01042 bindings[":THREE"] = three;
01043 bindings[":FOUR"] = four;
01044 bindings[":FIVE"] = five;
01045 bindings[":STARTTIME"] =
01046 progStart.addSecs(50 - progStart.time().second());
01047
01048 if (!m_searchStr.isEmpty())
01049 bindings[":SEARCH"] = '%' + m_searchStr + '%';
01050 }
01051 }
01052
01053 bool RuProgFinder::formatSelectedData(QString& data)
01054 {
01055 (void)data;
01056 return true;
01057 }
01058
01059 bool RuProgFinder::formatSelectedData(QString& data, int charNum)
01060 {
01061 (void)data;
01062 (void)charNum;
01063 return true;
01064 }
01065
01066 void RuProgFinder::restoreSelectedData(QString& data)
01067 {
01068 (void)data;
01069 }
01071
01072 SearchInputDialog::SearchInputDialog(MythScreenStack *parent,
01073 const QString &defaultValue)
01074 : MythTextInputDialog(parent, "", FilterNone,
01075 false, defaultValue)
01076 {
01077 }
01078
01079 bool SearchInputDialog::Create(void)
01080 {
01081 if (!LoadWindowFromXML("schedule-ui.xml", "searchpopup", this))
01082 return false;
01083
01084 MythUIText *messageText = NULL;
01085 MythUIButton *okButton = NULL;
01086 MythUIButton *cancelButton = NULL;
01087
01088 bool err = false;
01089 UIUtilE::Assign(this, m_textEdit, "input", &err);
01090 UIUtilE::Assign(this, messageText, "message", &err);
01091 UIUtilE::Assign(this, okButton, "ok", &err);
01092 UIUtilW::Assign(this, cancelButton, "cancel");
01093
01094 if (err)
01095 {
01096 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'searchpopup'");
01097 return false;
01098 }
01099
01100 if (cancelButton)
01101 connect(cancelButton, SIGNAL(Clicked()), SLOT(Close()));
01102 connect(okButton, SIGNAL(Clicked()), SLOT(sendResult()));
01103
01104 m_textEdit->SetFilter(m_filter);
01105 m_textEdit->SetText(m_defaultValue);
01106 m_textEdit->SetPassword(m_isPassword);
01107 connect(m_textEdit, SIGNAL(valueChanged()), SLOT(editChanged()));
01108
01109 BuildFocusList();
01110
01111 return true;
01112 }
01113
01114 void SearchInputDialog::editChanged(void)
01115 {
01116 QString inputString = m_textEdit->GetText();
01117 emit valueChanged(inputString);
01118
01119 if (m_retObject)
01120 {
01121
01122 DialogCompletionEvent *dce =
01123 new DialogCompletionEvent(m_id, 0, inputString, "");
01124 QCoreApplication::postEvent(m_retObject, dce);
01125 }
01126 }
01127
01128