00001 #include <unistd.h>
00002 #include <fcntl.h>
00003 #include <signal.h>
00004 #include <cerrno>
00005
00006 #include <iostream>
00007 using namespace std;
00008
00009 #include <QFile>
00010 #include <QFileInfo>
00011 #include <QMap>
00012 #include <QKeyEvent>
00013 #include <QEvent>
00014 #include <QDir>
00015 #include <QTextCodec>
00016 #include <QWidget>
00017 #include <QApplication>
00018 #include <QTimer>
00019
00020 #include "previewgeneratorqueue.h"
00021 #include "mythconfig.h"
00022 #include "tv.h"
00023 #include "proglist.h"
00024 #include "progfind.h"
00025 #include "scheduleeditor.h"
00026 #include "manualschedule.h"
00027 #include "playbackbox.h"
00028 #include "themechooser.h"
00029 #include "setupwizard_general.h"
00030 #include "customedit.h"
00031 #include "viewscheduled.h"
00032 #include "programrecpriority.h"
00033 #include "channelrecpriority.h"
00034 #include "custompriority.h"
00035 #include "audiooutput.h"
00036 #include "globalsettings.h"
00037 #include "audiogeneralsettings.h"
00038 #include "grabbersettings.h"
00039 #include "playgroup.h"
00040 #include "networkcontrol.h"
00041 #include "scheduledrecording.h"
00042 #include "mythsystemevent.h"
00043 #include "hardwareprofile.h"
00044
00045 #include "compat.h"
00046 #include "exitcodes.h"
00047 #include "exitprompt.h"
00048 #include "programinfo.h"
00049 #include "mythcontext.h"
00050 #include "mythdbcon.h"
00051 #include "guidegrid.h"
00052 #include "mythplugin.h"
00053 #include "remoteutil.h"
00054 #include "dbcheck.h"
00055 #include "mythmediamonitor.h"
00056 #include "statusbox.h"
00057 #include "idlescreen.h"
00058 #include "lcddevice.h"
00059 #include "langsettings.h"
00060 #include "mythtranslation.h"
00061 #include "commandlineparser.h"
00062 #include "channelgroupsettings.h"
00063
00064 #include "myththemedmenu.h"
00065 #include "mediarenderer.h"
00066 #include "mythmainwindow.h"
00067 #include "screenwizard.h"
00068 #include "mythcontrols.h"
00069 #include "mythuihelper.h"
00070 #include "mythdirs.h"
00071 #include "mythdb.h"
00072 #include "backendconnectionmanager.h"
00073 #include "themechooser.h"
00074 #include "mythversion.h"
00075 #include "taskqueue.h"
00076
00077
00078 #include "cleanup.h"
00079 #include "globals.h"
00080 #include "videodlg.h"
00081 #include "videoglobalsettings.h"
00082 #include "videofileassoc.h"
00083 #include "videoplayersettings.h"
00084 #include "videometadatasettings.h"
00085 #include "videolist.h"
00086
00087
00088 #include "DVD/dvdringbuffer.h"
00089
00090
00091 #ifdef USING_RAOP
00092 #include "AirPlay/mythraopdevice.h"
00093 #endif
00094
00095 #ifdef USING_LIBDNS_SD
00096 #include <QScopedPointer>
00097 #include "bonjourregister.h"
00098 #include "AirPlay/mythairplayserver.h"
00099 #endif
00100
00101 static ExitPrompter *exitPopup = NULL;
00102 static MythThemedMenu *menu;
00103
00104 static QString logfile;
00105 static MediaRenderer *g_pUPnp = NULL;
00106 static MythPluginManager *pmanager = NULL;
00107
00108 static void handleExit(bool prompt);
00109 static void resetAllKeys(void);
00110
00111 namespace
00112 {
00113 class RunSettingsCompletion : public QObject
00114 {
00115 Q_OBJECT
00116
00117 public:
00118 static void Create(bool check)
00119 {
00120 new RunSettingsCompletion(check);
00121 }
00122
00123 private:
00124 RunSettingsCompletion(bool check)
00125 {
00126 if (check)
00127 {
00128 connect(&m_plcc,
00129 SIGNAL(SigResultReady(bool, ParentalLevel::Level)),
00130 SLOT(OnPasswordResultReady(bool,
00131 ParentalLevel::Level)));
00132 m_plcc.Check(ParentalLevel::plMedium, ParentalLevel::plHigh);
00133 }
00134 else
00135 {
00136 OnPasswordResultReady(true, ParentalLevel::plHigh);
00137 }
00138 }
00139
00140 ~RunSettingsCompletion() {}
00141
00142 private slots:
00143 void OnPasswordResultReady(bool passwordValid,
00144 ParentalLevel::Level newLevel)
00145 {
00146 (void) newLevel;
00147
00148 if (passwordValid)
00149 {
00150 VideoGeneralSettings settings;
00151 settings.exec();
00152 }
00153 else
00154 {
00155 LOG(VB_GENERAL, LOG_WARNING,
00156 QObject::tr("Aggressive Parental Controls Warning: "
00157 "invalid password. An attempt to enter a "
00158 "MythVideo settings screen was prevented."));
00159 }
00160
00161 deleteLater();
00162 }
00163
00164 public:
00165 ParentalLevelChangeChecker m_plcc;
00166 };
00167
00168 class BookmarkDialog : MythScreenType
00169 {
00170 public:
00171 BookmarkDialog(ProgramInfo *pginfo, MythScreenStack *parent) :
00172 MythScreenType(parent, "bookmarkdialog"),
00173 pgi(pginfo)
00174 {
00175 }
00176
00177 bool Create()
00178 {
00179 QString msg = QObject::tr("DVD/Video contains a bookmark");
00180 QString btn0msg = QObject::tr("Play from bookmark");
00181 QString btn1msg = QObject::tr("Play from beginning");
00182
00183 MythDialogBox *popup = new MythDialogBox(msg, GetScreenStack(), "bookmarkdialog");
00184 if (!popup->Create())
00185 {
00186 delete popup;
00187 return false;
00188 }
00189
00190 GetScreenStack()->AddScreen(popup);
00191
00192 popup->SetReturnEvent(this, "bookmarkdialog");
00193 popup->AddButton(btn0msg);
00194 popup->AddButton(btn1msg);
00195 return true;
00196 }
00197
00198 void customEvent(QEvent *event)
00199 {
00200 if (event->type() == DialogCompletionEvent::kEventType)
00201 {
00202 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00203 int buttonnum = dce->GetResult();
00204
00205 if (dce->GetId() == "bookmarkdialog")
00206 {
00207 uint flags = kStartTVNoFlags;
00208 if (buttonnum == 1)
00209 {
00210 flags |= kStartTVIgnoreBookmark;
00211 }
00212 else if (buttonnum != 0)
00213 {
00214 delete pgi;
00215 return;
00216 }
00217
00218 TV::StartTV(pgi, flags);
00219
00220 delete pgi;
00221 }
00222 }
00223 }
00224
00225 private:
00226 ProgramInfo* pgi;
00227 };
00228
00229 void cleanup()
00230 {
00231 #ifdef USING_RAOP
00232 MythRAOPDevice::Cleanup();
00233 #endif
00234
00235 #ifdef USING_LIBDNS_SD
00236 MythAirplayServer::Cleanup();
00237 #endif
00238
00239 delete exitPopup;
00240 exitPopup = NULL;
00241
00242 AudioOutput::Cleanup();
00243
00244 if (g_pUPnp)
00245 {
00246
00247 LOG(VB_GENERAL, LOG_INFO, "Deleting UPnP client...");
00248 delete g_pUPnp;
00249 g_pUPnp = NULL;
00250 }
00251
00252 if (pmanager)
00253 {
00254 delete pmanager;
00255 pmanager = NULL;
00256 }
00257
00258 DestroyMythMainWindow();
00259
00260 delete gContext;
00261 gContext = NULL;
00262
00263 delete qApp;
00264
00265 #ifndef _MSC_VER
00266 signal(SIGUSR1, SIG_DFL);
00267 #endif
00268 }
00269
00270 class CleanupGuard
00271 {
00272 public:
00273 typedef void (*CleanupFunc)();
00274
00275 public:
00276 CleanupGuard(CleanupFunc cleanFunction) :
00277 m_cleanFunction(cleanFunction) {}
00278
00279 ~CleanupGuard()
00280 {
00281 m_cleanFunction();
00282 }
00283
00284 private:
00285 CleanupFunc m_cleanFunction;
00286 };
00287 }
00288
00289 static void startAppearWiz(void)
00290 {
00291 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00292
00293 ScreenWizard *screenwizard = new ScreenWizard(mainStack,
00294 "screenwizard");
00295
00296 if (screenwizard->Create())
00297 mainStack->AddScreen(screenwizard);
00298 else
00299 delete screenwizard;
00300 }
00301
00302
00303 static void startKeysSetup()
00304 {
00305 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00306
00307 MythControls *mythcontrols = new MythControls(mainStack, "mythcontrols");
00308
00309 if (mythcontrols->Create())
00310 mainStack->AddScreen(mythcontrols);
00311 else
00312 delete mythcontrols;
00313 }
00314
00315 static void startGuide(void)
00316 {
00317 uint chanid = 0;
00318 QString channum = gCoreContext->GetSetting("DefaultTVChannel");
00319 channum = (channum.isEmpty()) ? "3" : channum;
00320 GuideGrid::RunProgramGuide(chanid, channum, NULL, false, true, -2);
00321 }
00322
00323 static void startFinder(void)
00324 {
00325 RunProgramFinder();
00326 }
00327
00328 static void startSearchTitle(void)
00329 {
00330 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00331 ProgLister *pl = new ProgLister(mainStack, plTitleSearch, "", "");
00332 if (pl->Create())
00333 mainStack->AddScreen(pl);
00334 else
00335 delete pl;
00336 }
00337
00338 static void startSearchKeyword(void)
00339 {
00340 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00341 ProgLister *pl = new ProgLister(mainStack, plKeywordSearch, "", "");
00342 if (pl->Create())
00343 mainStack->AddScreen(pl);
00344 else
00345 delete pl;
00346 }
00347
00348 static void startSearchPeople(void)
00349 {
00350 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00351 ProgLister *pl = new ProgLister(mainStack, plPeopleSearch, "", "");
00352 if (pl->Create())
00353 mainStack->AddScreen(pl);
00354 else
00355 delete pl;
00356 }
00357
00358 static void startSearchPower(void)
00359 {
00360 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00361 ProgLister *pl = new ProgLister(mainStack, plPowerSearch, "", "");
00362 if (pl->Create())
00363 mainStack->AddScreen(pl);
00364 else
00365 delete pl;
00366 }
00367
00368 static void startSearchStored(void)
00369 {
00370 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00371 ProgLister *pl = new ProgLister(mainStack, plStoredSearch, "", "");
00372 if (pl->Create())
00373 mainStack->AddScreen(pl);
00374 else
00375 delete pl;
00376 }
00377
00378 static void startSearchChannel(void)
00379 {
00380 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00381 ProgLister *pl = new ProgLister(mainStack, plChannel, "", "");
00382 if (pl->Create())
00383 mainStack->AddScreen(pl);
00384 else
00385 delete pl;
00386 }
00387
00388 static void startSearchCategory(void)
00389 {
00390 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00391 ProgLister *pl = new ProgLister(mainStack, plCategory, "", "");
00392 if (pl->Create())
00393 mainStack->AddScreen(pl);
00394 else
00395 delete pl;
00396 }
00397
00398 static void startSearchMovie(void)
00399 {
00400 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00401 ProgLister *pl = new ProgLister(mainStack, plMovies, "", "");
00402 if (pl->Create())
00403 mainStack->AddScreen(pl);
00404 else
00405 delete pl;
00406 }
00407
00408 static void startSearchNew(void)
00409 {
00410 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00411 ProgLister *pl = new ProgLister(mainStack, plNewListings, "", "");
00412 if (pl->Create())
00413 mainStack->AddScreen(pl);
00414 else
00415 delete pl;
00416 }
00417
00418 static void startSearchTime(void)
00419 {
00420 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00421 ProgLister *pl = new ProgLister(mainStack, plTime, "", "");
00422 if (pl->Create())
00423 mainStack->AddScreen(pl);
00424 else
00425 delete pl;
00426 }
00427
00428 static void startManaged(void)
00429 {
00430 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00431
00432 ViewScheduled *viewsched = new ViewScheduled(mainStack);
00433
00434 if (viewsched->Create())
00435 mainStack->AddScreen(viewsched);
00436 else
00437 delete viewsched;
00438 }
00439
00440 static void startProgramRecPriorities(void)
00441 {
00442 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00443
00444 ProgramRecPriority *progRecPrior = new ProgramRecPriority(mainStack,
00445 "ProgramRecPriority");
00446
00447 if (progRecPrior->Create())
00448 mainStack->AddScreen(progRecPrior);
00449 else
00450 delete progRecPrior;
00451 }
00452
00453 static void startManageRecordingRules(void)
00454 {
00455 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00456
00457 ProgramRecPriority *progRecPrior = new ProgramRecPriority(mainStack,
00458 "ManageRecRules");
00459
00460 if (progRecPrior->Create())
00461 mainStack->AddScreen(progRecPrior);
00462 else
00463 delete progRecPrior;
00464 }
00465
00466 static void startChannelRecPriorities(void)
00467 {
00468 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00469
00470 ChannelRecPriority *chanRecPrior = new ChannelRecPriority(mainStack);
00471
00472 if (chanRecPrior->Create())
00473 mainStack->AddScreen(chanRecPrior);
00474 else
00475 delete chanRecPrior;
00476 }
00477
00478 static void startCustomPriority(void)
00479 {
00480 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00481
00482 CustomPriority *custom = new CustomPriority(mainStack);
00483
00484 if (custom->Create())
00485 mainStack->AddScreen(custom);
00486 else
00487 delete custom;
00488 }
00489
00490 static void startPlaybackWithGroup(QString recGroup = "")
00491 {
00492 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00493
00494 PlaybackBox *pbb = new PlaybackBox(
00495 mainStack, "playbackbox", PlaybackBox::kPlayBox);
00496
00497 if (pbb->Create())
00498 {
00499 if (!recGroup.isEmpty())
00500 pbb->setInitialRecGroup(recGroup);
00501
00502 mainStack->AddScreen(pbb);
00503 }
00504 else
00505 delete pbb;
00506 }
00507
00508 static void startPlayback(void)
00509 {
00510 startPlaybackWithGroup();
00511 }
00512
00513 static void startDelete(void)
00514 {
00515 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00516
00517 PlaybackBox *pbb = new PlaybackBox(
00518 mainStack, "deletebox", PlaybackBox::kDeleteBox);
00519
00520 if (pbb->Create())
00521 mainStack->AddScreen(pbb);
00522 else
00523 delete pbb;
00524 }
00525
00526 static void startPrevious(void)
00527 {
00528 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00529 ProgLister *pl = new ProgLister(mainStack);
00530 if (pl->Create())
00531 mainStack->AddScreen(pl);
00532 else
00533 delete pl;
00534 }
00535
00536 static void startCustomEdit(void)
00537 {
00538 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00539 CustomEdit *custom = new CustomEdit(mainStack);
00540
00541 if (custom->Create())
00542 mainStack->AddScreen(custom);
00543 else
00544 delete custom;
00545 }
00546
00547 static void startManualSchedule(void)
00548 {
00549 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00550
00551 ManualSchedule *mansched= new ManualSchedule(mainStack);
00552
00553 if (mansched->Create())
00554 mainStack->AddScreen(mansched);
00555 else
00556 delete mansched;
00557 }
00558
00559 static bool isLiveTVAvailable(void)
00560 {
00561 if (RemoteGetFreeRecorderCount() > 0)
00562 return true;
00563
00564 QString msg = QObject::tr("All tuners are currently busy.");
00565 if (TV::ConfiguredTunerCards() < 1)
00566 msg = QObject::tr("There are no configured tuners.");
00567
00568 ShowOkPopup(msg);
00569 return false;
00570 }
00571
00572 static void startTVInGuide(void)
00573 {
00574 if (isLiveTVAvailable())
00575 TV::StartTV(NULL, kStartTVInGuide);
00576 }
00577
00578 static void startTVNormal(void)
00579 {
00580 if (isLiveTVAvailable())
00581 TV::StartTV(NULL, kStartTVNoFlags);
00582 }
00583
00584 static void showStatus(void)
00585 {
00586 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00587
00588 StatusBox *statusbox = new StatusBox(mainStack);
00589
00590 if (statusbox->Create())
00591 mainStack->AddScreen(statusbox);
00592 else
00593 delete statusbox;
00594 }
00595
00596
00597 static void standbyScreen(void)
00598 {
00599 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00600
00601 IdleScreen *idlescreen = new IdleScreen(mainStack);
00602
00603 if (idlescreen->Create())
00604 mainStack->AddScreen(idlescreen);
00605 else
00606 delete idlescreen;
00607 }
00608
00609 static void RunVideoScreen(VideoDialog::DialogType type, bool fromJump = false)
00610 {
00611 QString message = QObject::tr("Loading videos ...");
00612
00613 MythScreenStack *popupStack =
00614 GetMythMainWindow()->GetStack("popup stack");
00615
00616 MythUIBusyDialog *busyPopup = new MythUIBusyDialog(message,
00617 popupStack, "mythvideobusydialog");
00618
00619 if (busyPopup->Create())
00620 popupStack->AddScreen(busyPopup, false);
00621
00622 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00623
00624 VideoDialog::VideoListPtr video_list;
00625 if (fromJump)
00626 {
00627 VideoDialog::VideoListDeathDelayPtr &saved =
00628 VideoDialog::GetSavedVideoList();
00629 if (!saved.isNull())
00630 {
00631 video_list = saved->GetSaved();
00632 }
00633 }
00634
00635 VideoDialog::BrowseType browse = static_cast<VideoDialog::BrowseType>(
00636 gCoreContext->GetNumSetting("mythvideo.db_group_type",
00637 VideoDialog::BRS_FOLDER));
00638
00639 if (!video_list)
00640 video_list = new VideoList;
00641
00642 VideoDialog *mythvideo =
00643 new VideoDialog(mainStack, "mythvideo", video_list, type, browse);
00644
00645 if (mythvideo->Create())
00646 {
00647 busyPopup->Close();
00648 mainStack->AddScreen(mythvideo);
00649 }
00650 else
00651 busyPopup->Close();
00652 }
00653
00654 static void jumpScreenVideoManager() { RunVideoScreen(VideoDialog::DLG_MANAGER, true); }
00655 static void jumpScreenVideoBrowser() { RunVideoScreen(VideoDialog::DLG_BROWSER, true); }
00656 static void jumpScreenVideoTree() { RunVideoScreen(VideoDialog::DLG_TREE, true); }
00657 static void jumpScreenVideoGallery() { RunVideoScreen(VideoDialog::DLG_GALLERY, true); }
00658 static void jumpScreenVideoDefault() { RunVideoScreen(VideoDialog::DLG_DEFAULT, true); }
00659
00660 QString gDVDdevice;
00661
00662 static void playDisc()
00663 {
00664
00665
00666
00667
00668 bool isBD = false;
00669
00670 QString command_string =
00671 gCoreContext->GetSetting("mythdvd.DVDPlayerCommand");
00672 QString bluray_mountpoint =
00673 gCoreContext->GetSetting("BluRayMountpoint", "/media/cdrom");
00674 QDir bdtest(bluray_mountpoint + "/BDMV");
00675
00676 if (bdtest.exists())
00677 isBD = true;
00678
00679 if (isBD)
00680 {
00681 GetMythUI()->AddCurrentLocation("playdisc");
00682
00683 QString filename = QString("bd:/%1").arg(bluray_mountpoint);
00684
00685 GetMythMainWindow()->HandleMedia("Internal", filename, "", "", "", "",
00686 0, 0, "", 0, "", "", true);
00687
00688 GetMythUI()->RemoveCurrentLocation();
00689 }
00690 else
00691 {
00692 QString dvd_device = gDVDdevice;
00693
00694 if (dvd_device.isEmpty())
00695 dvd_device = MediaMonitor::defaultDVDdevice();
00696
00697 if (dvd_device.isEmpty())
00698 return;
00699
00700 GetMythUI()->AddCurrentLocation("playdisc");
00701
00702 if ((command_string.indexOf("internal", 0, Qt::CaseInsensitive) > -1) ||
00703 (command_string.length() < 1))
00704 {
00705 #ifdef Q_OS_MAC
00706
00707 QString filename = "dvd://dev/r";
00708 #elif USING_MINGW
00709 QString filename = "dvd:";
00710 #else
00711 QString filename = "dvd:/";
00712 #endif
00713 filename += dvd_device;
00714
00715 command_string = "Internal";
00716 GetMythMainWindow()->HandleMedia(command_string, filename, "", "",
00717 "", "", 0, 0, "", 0, "", "", true);
00718 GetMythUI()->RemoveCurrentLocation();
00719
00720 return;
00721 }
00722 else
00723 {
00724 if (command_string.contains("%d"))
00725 {
00726
00727
00728
00729 command_string =
00730 command_string.replace(QRegExp("%d"), dvd_device);
00731 }
00732 sendPlaybackStart();
00733 GetMythMainWindow()->PauseIdleTimer(true);
00734 myth_system(command_string);
00735 sendPlaybackEnd();
00736 GetMythMainWindow()->PauseIdleTimer(false);
00737 if (GetMythMainWindow())
00738 {
00739 GetMythMainWindow()->raise();
00740 GetMythMainWindow()->activateWindow();
00741 if (GetMythMainWindow()->currentWidget())
00742 GetMythMainWindow()->currentWidget()->setFocus();
00743 }
00744 }
00745 GetMythUI()->RemoveCurrentLocation();
00746 }
00747 }
00748
00752 static void handleDVDMedia(MythMediaDevice *dvd)
00753 {
00754 if (!dvd)
00755 return;
00756
00757 QString newDevice = dvd->getDevicePath();
00758
00759
00760 if (dvd->isUsable())
00761 if (gDVDdevice.length() && gDVDdevice != newDevice)
00762 {
00763
00764
00765
00766 LOG(VB_MEDIA, LOG_INFO,
00767 "MythVideo: Multiple DVD drives? Forgetting " + gDVDdevice);
00768 gDVDdevice.clear();
00769 }
00770 else
00771 {
00772 gDVDdevice = newDevice;
00773 LOG(VB_MEDIA, LOG_INFO,
00774 "MythVideo: Storing DVD device " + gDVDdevice);
00775 }
00776 else
00777 {
00778
00779
00780 if (gDVDdevice.length() && gDVDdevice == newDevice)
00781 {
00782 LOG(VB_MEDIA, LOG_INFO,
00783 "MythVideo: Forgetting existing DVD " + gDVDdevice);
00784 gDVDdevice.clear();
00785 }
00786
00787 return;
00788 }
00789
00790 switch (gCoreContext->GetNumSetting("DVDOnInsertDVD", 1))
00791 {
00792 case 0 :
00793 break;
00794 case 1 :
00795 GetMythMainWindow()->JumpTo("Main Menu");
00796 break;
00797 case 2 :
00798 GetMythMainWindow()->JumpTo("Main Menu");
00799 playDisc();
00800 break;
00801 default:
00802 LOG(VB_GENERAL, LOG_ERR,
00803 "mythdvd main.o: handleMedia() does not know what to do");
00804 }
00805 }
00806
00807 static void TVMenuCallback(void *data, QString &selection)
00808 {
00809 (void)data;
00810 QString sel = selection.toLower();
00811
00812 if (sel.left(9) == "settings ")
00813 {
00814 GetMythUI()->AddCurrentLocation("Setup");
00815 gCoreContext->ActivateSettingsCache(false);
00816 GetMythMainWindow()->HidePainterWindow();
00817 }
00818
00819 if (sel == "tv_watch_live")
00820 startTVNormal();
00821 else if (sel == "tv_watch_live_epg")
00822 startTVInGuide();
00823 else if (sel.left(18) == "tv_watch_recording")
00824 {
00825
00826 if ((selection.length() > 19) && (selection.mid(18, 1) == " "))
00827 startPlaybackWithGroup(selection.mid(19));
00828 else
00829 startPlayback();
00830 }
00831 else if (sel == "tv_schedule")
00832 startGuide();
00833 else if (sel == "tv_delete")
00834 startDelete();
00835 else if (sel == "tv_manualschedule")
00836 startManualSchedule();
00837 else if (sel == "tv_custom_record")
00838 startCustomEdit();
00839 else if (sel == "tv_fix_conflicts")
00840 startManaged();
00841 else if (sel == "tv_set_recpriorities")
00842 startProgramRecPriorities();
00843 else if (sel == "tv_manage_recording_rules")
00844 startManageRecordingRules();
00845 else if (sel == "tv_progfind")
00846 startFinder();
00847 else if (sel == "tv_search_title")
00848 startSearchTitle();
00849 else if (sel == "tv_search_keyword")
00850 startSearchKeyword();
00851 else if (sel == "tv_search_people")
00852 startSearchPeople();
00853 else if (sel == "tv_search_power")
00854 startSearchPower();
00855 else if (sel == "tv_search_stored")
00856 startSearchStored();
00857 else if (sel == "tv_search_channel")
00858 startSearchChannel();
00859 else if (sel == "tv_search_category")
00860 startSearchCategory();
00861 else if (sel == "tv_search_movie")
00862 startSearchMovie();
00863 else if (sel == "tv_search_new")
00864 startSearchNew();
00865 else if (sel == "tv_search_time")
00866 startSearchTime();
00867 else if (sel == "tv_previous")
00868 startPrevious();
00869 else if (sel == "settings appearance")
00870 {
00871 AppearanceSettings *settings = new AppearanceSettings();
00872 DialogCode res = settings->exec();
00873 delete settings;
00874
00875 if (kDialogCodeRejected != res)
00876 {
00877 qApp->processEvents();
00878 GetMythMainWindow()->JumpTo("Reload Theme");
00879 }
00880 }
00881 else if (sel == "settings themechooser")
00882 {
00883 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00884 ThemeChooser *tp = new ThemeChooser(mainStack);
00885
00886 if (tp->Create())
00887 mainStack->AddScreen(tp);
00888 else
00889 delete tp;
00890 }
00891 else if (sel == "settings setupwizard")
00892 {
00893 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00894 GeneralSetupWizard *sw = new GeneralSetupWizard(mainStack, "setupwizard");
00895
00896 if (sw->Create())
00897 mainStack->AddScreen(sw);
00898 else
00899 delete sw;
00900 }
00901 else if (sel == "settings grabbers")
00902 {
00903 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00904 GrabberSettings *gs = new GrabberSettings(mainStack, "grabbersettings");
00905
00906 if (gs->Create())
00907 mainStack->AddScreen(gs);
00908 else
00909 delete gs;
00910 }
00911 else if (sel == "screensetupwizard")
00912 {
00913 startAppearWiz();
00914 }
00915 else if (sel == "setup_keys")
00916 {
00917 startKeysSetup();
00918 }
00919 else if (sel == "settings playgroup")
00920 {
00921 PlayGroupEditor editor;
00922 editor.exec();
00923 }
00924 else if (sel == "settings general")
00925 {
00926 GeneralSettings settings;
00927 settings.exec();
00928 }
00929 else if (sel == "settings audiogeneral")
00930 {
00931 AudioGeneralSettings audiosettings;
00932 audiosettings.exec();
00933 }
00934 else if (sel == "settings maingeneral")
00935 {
00936 MainGeneralSettings mainsettings;
00937 mainsettings.exec();
00938 QStringList strlist( QString("REFRESH_BACKEND") );
00939 gCoreContext->SendReceiveStringList(strlist);
00940 }
00941 else if (sel == "settings playback")
00942 {
00943 PlaybackSettings settings;
00944 settings.exec();
00945 }
00946 else if (sel == "settings osd")
00947 {
00948 OSDSettings settings;
00949 settings.exec();
00950 }
00951 else if (sel == "settings epg")
00952 {
00953 EPGSettings settings;
00954 settings.exec();
00955 }
00956 else if (sel == "settings channelgroups")
00957 {
00958 ChannelGroupEditor editor;
00959 editor.exec();
00960 }
00961 else if (sel == "settings generalrecpriorities")
00962 {
00963 GeneralRecPrioritiesSettings settings;
00964 settings.exec();
00965 }
00966 else if (sel == "settings channelrecpriorities")
00967 {
00968 startChannelRecPriorities();
00969 }
00970 else if (sel == "settings custompriority")
00971 {
00972 startCustomPriority();
00973 }
00974 else if (sel == "system_events")
00975 {
00976 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00977
00978 MythSystemEventEditor *msee = new MythSystemEventEditor(
00979 mainStack, "System Event Editor");
00980
00981 if (msee->Create())
00982 mainStack->AddScreen(msee);
00983 else
00984 delete msee;
00985 }
00986 else if (sel == "video_settings_general")
00987 {
00988 RunSettingsCompletion::Create(gCoreContext->
00989 GetNumSetting("VideoAggressivePC", 0));
00990 }
00991 else if (sel == "video_settings_player")
00992 {
00993 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00994
00995 PlayerSettings *ps = new PlayerSettings(mainStack, "player settings");
00996
00997 if (ps->Create())
00998 mainStack->AddScreen(ps);
00999 }
01000 else if (sel == "video_settings_metadata")
01001 {
01002 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
01003
01004 MetadataSettings *ms = new MetadataSettings(mainStack, "metadata settings");
01005
01006 if (ms->Create())
01007 mainStack->AddScreen(ms);
01008 }
01009 else if (sel == "video_settings_associations")
01010 {
01011 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
01012
01013 FileAssocDialog *fa = new FileAssocDialog(mainStack, "fa dialog");
01014
01015 if (fa->Create())
01016 mainStack->AddScreen(fa);
01017 }
01018 else if (sel == "manager")
01019 RunVideoScreen(VideoDialog::DLG_MANAGER);
01020 else if (sel == "browser")
01021 RunVideoScreen(VideoDialog::DLG_BROWSER);
01022 else if (sel == "listing")
01023 RunVideoScreen(VideoDialog::DLG_TREE);
01024 else if (sel == "gallery")
01025 RunVideoScreen(VideoDialog::DLG_GALLERY);
01026 else if (sel == "disc_play")
01027 {
01028 playDisc();
01029 }
01030 else if (sel == "tv_status")
01031 showStatus();
01032 else if (sel == "exiting_app_prompt")
01033 handleExit(true);
01034 else if (sel == "exiting_app")
01035 handleExit(false);
01036 else if (sel == "standby_mode")
01037 standbyScreen();
01038 else
01039 LOG(VB_GENERAL, LOG_ERR, "Unknown menu action: " + selection);
01040
01041 if (sel.left(9) == "settings " || sel == "video_settings_general")
01042 {
01043 GetMythUI()->RemoveCurrentLocation();
01044
01045 gCoreContext->ActivateSettingsCache(true);
01046 gCoreContext->SendMessage("CLEAR_SETTINGS_CACHE");
01047
01048 if (sel == "settings general" ||
01049 sel == "settings generalrecpriorities")
01050 ScheduledRecording::ReschedulePlace("TVMenuCallback");
01051 GetMythMainWindow()->ShowPainterWindow();
01052 }
01053 }
01054
01055 static void handleExit(bool prompt)
01056 {
01057 if (prompt)
01058 {
01059 if (!exitPopup)
01060 exitPopup = new ExitPrompter();
01061
01062 exitPopup->handleExit();
01063 }
01064 else
01065 qApp->quit();
01066 }
01067
01068 static bool RunMenu(QString themedir, QString themename)
01069 {
01070 QByteArray tmp = themedir.toLocal8Bit();
01071 menu = new MythThemedMenu(QString(tmp.constData()), "mainmenu.xml",
01072 GetMythMainWindow()->GetMainStack(), "mainmenu");
01073
01074 if (menu->foundTheme())
01075 {
01076 LOG(VB_GENERAL, LOG_NOTICE, QString("Found mainmenu.xml for theme '%1'")
01077 .arg(themename));
01078 menu->setCallback(TVMenuCallback, gContext);
01079 GetMythMainWindow()->GetMainStack()->AddScreen(menu);
01080 return true;
01081 }
01082
01083 LOG(VB_GENERAL, LOG_ERR,
01084 QString("Couldn't find mainmenu.xml for theme '%1'") .arg(themename));
01085 delete menu;
01086 menu = NULL;
01087
01088 return false;
01089 }
01090
01091
01092
01093 static void WriteDefaults()
01094 {
01095 PlaybackSettings ps;
01096 ps.Load();
01097 ps.Save();
01098 OSDSettings os;
01099 os.Load();
01100 os.Save();
01101 GeneralSettings gs;
01102 gs.Load();
01103 gs.Save();
01104 EPGSettings es;
01105 es.Load();
01106 es.Save();
01107 AppearanceSettings as;
01108 as.Load();
01109 as.Save();
01110 MainGeneralSettings mgs;
01111 mgs.Load();
01112 mgs.Save();
01113 GeneralRecPrioritiesSettings grs;
01114 grs.Load();
01115 grs.Save();
01116 VideoGeneralSettings vgs;
01117 vgs.Load();
01118 vgs.Save();
01119 }
01120
01121 static int internal_play_media(const QString &mrl, const QString &plot,
01122 const QString &title, const QString &subtitle,
01123 const QString &director, int season, int episode,
01124 const QString &inetref, int lenMins, const QString &year,
01125 const QString &id, const bool useBookmark)
01126 {
01127 int res = -1;
01128
01129 QFile checkFile(mrl);
01130 if ((!checkFile.exists() && !mrl.startsWith("dvd:")
01131 && !mrl.startsWith("bd:")
01132 && !mrl.startsWith("myth:")
01133 && !mrl.startsWith("http://")))
01134 {
01135 QString errorText = QObject::tr("Failed to open \n '%1' in %2 \n"
01136 "Check if the video exists")
01137 .arg(mrl.section('/', -1))
01138 .arg(mrl.section('/', 0, -2));
01139 ShowOkPopup(errorText);
01140 return res;
01141 }
01142
01143 ProgramInfo *pginfo = new ProgramInfo(
01144 mrl, plot, title, subtitle, director, season, episode,
01145 inetref, lenMins, (year.toUInt()) ? year.toUInt() : 1900,
01146 id);
01147
01148 pginfo->SetProgramInfoType(pginfo->DiscoverProgramInfoType());
01149
01150 int64_t pos = 0;
01151
01152 if (pginfo->IsVideoDVD())
01153 {
01154 DVDInfo *dvd = new DVDInfo(pginfo->GetPlaybackURL());
01155 if (dvd && dvd->IsValid())
01156 {
01157 QString name;
01158 QString serialid;
01159 if (dvd->GetNameAndSerialNum(name, serialid))
01160 {
01161 QStringList fields = pginfo->QueryDVDBookmark(serialid);
01162 if (!fields.empty())
01163 {
01164 QStringList::Iterator it = fields.begin();
01165 pos = (int64_t)((*++it).toLongLong() & 0xffffffffLL);
01166 }
01167 }
01168 }
01169 else
01170 {
01171 if (dvd)
01172 delete dvd;
01173 delete pginfo;
01174 return res;
01175 }
01176 delete dvd;
01177 }
01178 else if (pginfo->IsVideo())
01179 pos = pginfo->QueryBookmark();
01180
01181 if (useBookmark && pos > 0)
01182 {
01183 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
01184 BookmarkDialog *bookmarkdialog = new BookmarkDialog(pginfo, mainStack);
01185 if (!bookmarkdialog->Create())
01186 {
01187 delete bookmarkdialog;
01188 delete pginfo;
01189 return res;
01190 }
01191 }
01192 else
01193 {
01194 TV::StartTV(pginfo, kStartTVNoFlags | kStartTVIgnoreBookmark);
01195
01196 res = 0;
01197
01198 delete pginfo;
01199 }
01200
01201 return res;
01202 }
01203
01204 static void gotoMainMenu(void)
01205 {
01206
01207 MythThemedMenuState *menu = dynamic_cast<MythThemedMenuState *>
01208 (GetMythMainWindow()->GetMainStack()->GetTopScreen());
01209 if (menu)
01210 menu->m_buttonList->SetItemCurrent(0);
01211 }
01212
01213
01214
01215 static bool resetTheme(QString themedir, const QString badtheme)
01216 {
01217 QString themename = DEFAULT_UI_THEME;
01218
01219 if (badtheme == DEFAULT_UI_THEME)
01220 themename = FALLBACK_UI_THEME;
01221
01222 LOG(VB_GENERAL, LOG_WARNING,
01223 QString("Overriding broken theme '%1' with '%2'")
01224 .arg(badtheme).arg(themename));
01225
01226 gCoreContext->OverrideSettingForSession("Theme", themename);
01227 themedir = GetMythUI()->FindThemeDir(themename);
01228
01229 MythTranslation::reload();
01230 gCoreContext->ReInitLocale();
01231 GetMythUI()->LoadQtConfig();
01232 GetMythMainWindow()->Init();
01233
01234 GetMythMainWindow()->ReinitDone();
01235
01236 return RunMenu(themedir, themename);
01237 }
01238
01239 static int reloadTheme(void)
01240 {
01241 QString themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME);
01242 QString themedir = GetMythUI()->FindThemeDir(themename);
01243 if (themedir.isEmpty())
01244 {
01245 LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find theme '%1'")
01246 .arg(themename));
01247 return GENERIC_EXIT_NO_THEME;
01248 }
01249
01250 gCoreContext->ReInitLocale();
01251 MythTranslation::reload();
01252
01253 GetMythMainWindow()->SetEffectsEnabled(false);
01254
01255 GetMythUI()->LoadQtConfig();
01256
01257 if (menu)
01258 {
01259 menu->Close();
01260 }
01261 GetMythMainWindow()->Init();
01262
01263 GetMythMainWindow()->ReinitDone();
01264
01265 GetMythMainWindow()->SetEffectsEnabled(true);
01266
01267 if (!RunMenu(themedir, themename) && !resetTheme(themedir, themename))
01268 return GENERIC_EXIT_NO_THEME;
01269
01270 LCD::SetupLCD();
01271 if (LCD *lcd = LCD::Get())
01272 {
01273 lcd->setupLEDs(RemoteGetRecordingMask);
01274 lcd->resetServer();
01275 }
01276
01277 return 0;
01278 }
01279
01280 static void reloadTheme_void(void)
01281 {
01282 int err = reloadTheme();
01283 if (err)
01284 exit(err);
01285 }
01286
01287 static void setDebugShowBorders(void)
01288 {
01289 MythPainter *p = GetMythPainter();
01290 p->SetDebugMode(!p->ShowBorders(), p->ShowTypeNames());
01291
01292 if (GetMythMainWindow()->GetMainStack()->GetTopScreen())
01293 GetMythMainWindow()->GetMainStack()->GetTopScreen()->SetRedraw();
01294 }
01295
01296 static void setDebugShowNames(void)
01297 {
01298 MythPainter *p = GetMythPainter();
01299 p->SetDebugMode(p->ShowBorders(), !p->ShowTypeNames());
01300
01301 if (GetMythMainWindow()->GetMainStack()->GetTopScreen())
01302 GetMythMainWindow()->GetMainStack()->GetTopScreen()->SetRedraw();
01303 }
01304
01305 static void InitJumpPoints(void)
01306 {
01307 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Reload Theme"),
01308 "", "", reloadTheme_void);
01309 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Main Menu"),
01310 "", "", gotoMainMenu);
01311 REG_JUMPLOC(QT_TRANSLATE_NOOP("MythControls", "Program Guide"),
01312 "", "", startGuide, "GUIDE");
01313 REG_JUMPLOC(QT_TRANSLATE_NOOP("MythControls", "Program Finder"),
01314 "", "", startFinder, "FINDER");
01315
01316
01317 REG_JUMPLOC(QT_TRANSLATE_NOOP("MythControls", "Manage Recordings / "
01318 "Fix Conflicts"), "", "", startManaged, "VIEWSCHEDULED");
01319 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Program Recording "
01320 "Priorities"), "", "", startProgramRecPriorities);
01321 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Manage Recording Rules"),
01322 "", "", startManageRecordingRules);
01323 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Channel Recording "
01324 "Priorities"), "", "", startChannelRecPriorities);
01325 REG_JUMPLOC(QT_TRANSLATE_NOOP("MythControls", "TV Recording Playback"),
01326 "", "", startPlayback, "JUMPREC");
01327 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "TV Recording Deletion"),
01328 "", "", startDelete);
01329 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Live TV"),
01330 "", "", startTVNormal);
01331 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Live TV In Guide"),
01332 "", "", startTVInGuide);
01333 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Status Screen"),
01334 "", "", showStatus);
01335 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Previously Recorded"),
01336 "", "", startPrevious);
01337
01338 REG_JUMP(QT_TRANSLATE_NOOP("MythControls", "Standby Mode"),
01339 "", "", standbyScreen);
01340
01341
01342
01343 REG_JUMP(JUMP_VIDEO_DEFAULT, QT_TRANSLATE_NOOP("MythControls",
01344 "The Video Default View"), "", jumpScreenVideoDefault);
01345 REG_JUMP(JUMP_VIDEO_MANAGER, QT_TRANSLATE_NOOP("MythControls",
01346 "The Video Manager"), "", jumpScreenVideoManager);
01347 REG_JUMP(JUMP_VIDEO_BROWSER, QT_TRANSLATE_NOOP("MythControls",
01348 "The Video Browser"), "", jumpScreenVideoBrowser);
01349 REG_JUMP(JUMP_VIDEO_TREE, QT_TRANSLATE_NOOP("MythControls",
01350 "The Video Listings"), "", jumpScreenVideoTree);
01351 REG_JUMP(JUMP_VIDEO_GALLERY, QT_TRANSLATE_NOOP("MythControls",
01352 "The Video Gallery"), "", jumpScreenVideoGallery);
01353 REG_JUMP("Play Disc", QT_TRANSLATE_NOOP("MythControls",
01354 "Play an Optical Disc"), "", playDisc);
01355
01356 REG_JUMPEX(QT_TRANSLATE_NOOP("MythControls", "Toggle Show Widget Borders"),
01357 "", "", setDebugShowBorders, false);
01358 REG_JUMPEX(QT_TRANSLATE_NOOP("MythControls", "Toggle Show Widget Names"),
01359 "", "", setDebugShowNames, false);
01360 REG_JUMPEX(QT_TRANSLATE_NOOP("MythControls", "Reset All Keys"),
01361 QT_TRANSLATE_NOOP("MythControls", "Reset all keys to defaults"),
01362 "", resetAllKeys, false);
01363 }
01364
01365 static void ReloadJumpPoints(void)
01366 {
01367 MythMainWindow *mainWindow = GetMythMainWindow();
01368 mainWindow->ClearAllJumps();
01369 InitJumpPoints();
01370 }
01371
01372 static void InitKeys(void)
01373 {
01374 REG_KEY("Video","PLAYALT", QT_TRANSLATE_NOOP("MythControls",
01375 "Play selected item in alternate player"), "ALT+P");
01376 REG_KEY("Video","FILTER", QT_TRANSLATE_NOOP("MythControls",
01377 "Open video filter dialog"), "F");
01378 REG_KEY("Video","BROWSE", QT_TRANSLATE_NOOP("MythControls",
01379 "Change browsable in video manager"), "B");
01380 REG_KEY("Video","INCPARENT", QT_TRANSLATE_NOOP("MythControls",
01381 "Increase Parental Level"), "],},F11");
01382 REG_KEY("Video","DECPARENT", QT_TRANSLATE_NOOP("MythControls",
01383 "Decrease Parental Level"), "[,{,F10");
01384 REG_KEY("Video","INCSEARCH", QT_TRANSLATE_NOOP("MythControls",
01385 "Show Incremental Search Dialog"), "Ctrl+S");
01386 REG_KEY("Video","DOWNLOADDATA", QT_TRANSLATE_NOOP("MythControls",
01387 "Download metadata for current item"), "W");
01388 REG_KEY("Video","ITEMDETAIL", QT_TRANSLATE_NOOP("MythControls",
01389 "Display Item Detail Popup"), "");
01390 REG_KEY("Video","HOME", QT_TRANSLATE_NOOP("MythControls",
01391 "Go to the first video"), "Home");
01392 REG_KEY("Video","END", QT_TRANSLATE_NOOP("MythControls",
01393 "Go to the last video"), "End");
01394 }
01395
01396 static void ReloadKeys(void)
01397 {
01398 GetMythMainWindow()->ClearKeyContext("Video");
01399 InitKeys();
01400
01401 TV::ReloadKeys();
01402 }
01403
01404 static void SetFuncPtrs(void)
01405 {
01406 TV::SetFuncPtr("playbackbox", (void *)PlaybackBox::RunPlaybackBox);
01407 TV::SetFuncPtr("viewscheduled", (void *)ViewScheduled::RunViewScheduled);
01408 TV::SetFuncPtr("programguide", (void *)GuideGrid::RunProgramGuide);
01409 TV::SetFuncPtr("programfinder", (void *)RunProgramFinder);
01410 TV::SetFuncPtr("scheduleeditor", (void *)ScheduleEditor::RunScheduleEditor);
01411 }
01412
01416 static void clearAllKeys(void)
01417 {
01418 MSqlQuery query(MSqlQuery::InitCon());
01419
01420 query.prepare("DELETE FROM keybindings "
01421 "WHERE hostname = :HOSTNAME;");
01422 query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
01423 if (!query.exec())
01424 MythDB::DBError("Deleting keybindings", query);
01425 query.prepare("DELETE FROM jumppoints "
01426 "WHERE hostname = :HOSTNAME;");
01427 query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
01428 if (!query.exec())
01429 MythDB::DBError("Deleting jumppoints", query);
01430 }
01431
01435 static void resetAllKeys(void)
01436 {
01437 clearAllKeys();
01438
01439 GetMythMainWindow()->ReloadKeys();
01440
01441 ReloadJumpPoints();
01442
01443 ReloadKeys();
01444 }
01445
01446
01447 static void signal_USR1_handler(int){
01448 LOG(VB_GENERAL, LOG_NOTICE, "SIGUSR1 received, reloading theme");
01449 gCoreContext->SendMessage("CLEAR_SETTINGS_CACHE");
01450 gCoreContext->ActivateSettingsCache(false);
01451 GetMythMainWindow()->JumpTo("Reload Theme");
01452 gCoreContext->ActivateSettingsCache(true);
01453 }
01454
01455 static void signal_USR2_handler(int)
01456 {
01457 LOG(VB_GENERAL, LOG_NOTICE, "SIGUSR2 received, restart LIRC handler");
01458 GetMythMainWindow()->StartLIRC();
01459 }
01460
01461
01462 static int internal_media_init()
01463 {
01464 REG_MEDIAPLAYER("Internal", QT_TRANSLATE_NOOP("MythControls",
01465 "MythTV's native media player."), internal_play_media);
01466 REG_MEDIA_HANDLER(QT_TRANSLATE_NOOP("MythControls",
01467 "MythDVD DVD Media Handler"), "", "", handleDVDMedia,
01468 MEDIATYPE_DVD, QString::null);
01469 return 0;
01470 }
01471
01472 static void CleanupMyOldInUsePrograms(void)
01473 {
01474 MSqlQuery query(MSqlQuery::InitCon());
01475
01476 query.prepare("DELETE FROM inuseprograms "
01477 "WHERE hostname = :HOSTNAME and recusage = 'player' ;");
01478 query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
01479 if (!query.exec())
01480 MythDB::DBError("CleanupMyOldInUsePrograms", query);
01481 }
01482
01483 int main(int argc, char **argv)
01484 {
01485 bool bPromptForBackend = false;
01486 bool bBypassAutoDiscovery = false;
01487
01488 MythFrontendCommandLineParser cmdline;
01489 if (!cmdline.Parse(argc, argv))
01490 {
01491 cmdline.PrintHelp();
01492 return GENERIC_EXIT_INVALID_CMDLINE;
01493 }
01494
01495 if (cmdline.toBool("showhelp"))
01496 {
01497 cmdline.PrintHelp();
01498 return GENERIC_EXIT_OK;
01499 }
01500
01501 if (cmdline.toBool("showversion"))
01502 {
01503 cmdline.PrintVersion();
01504 return GENERIC_EXIT_OK;
01505 }
01506
01507 CleanupGuard callCleanup(cleanup);
01508
01509 #ifdef Q_WS_MACX
01510
01511
01512 QApplication::setDesktopSettingsAware(false);
01513 #endif
01514 new QApplication(argc, argv);
01515 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHFRONTEND);
01516
01517 int retval;
01518 if ((retval = cmdline.ConfigureLogging()) != GENERIC_EXIT_OK)
01519 return retval;
01520
01521 bool ResetSettings = false;
01522
01523 if (cmdline.toBool("prompt"))
01524 bPromptForBackend = true;
01525 if (cmdline.toBool("noautodiscovery"))
01526 bBypassAutoDiscovery = true;
01527
01528 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
01529 cerr << "Unable to ignore SIGPIPE\n";
01530
01531 if (!cmdline.toString("display").isEmpty())
01532 {
01533 MythUIHelper::SetX11Display(cmdline.toString("display"));
01534 }
01535
01536 if (!cmdline.toString("geometry").isEmpty())
01537 {
01538 MythUIHelper::ParseGeometryOverride(cmdline.toString("geometry"));
01539 }
01540
01541 gContext = new MythContext(MYTH_BINARY_VERSION);
01542
01543 if (!gContext->Init(true, bPromptForBackend, bBypassAutoDiscovery))
01544 {
01545 LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext, exiting.");
01546 return GENERIC_EXIT_NO_MYTHCONTEXT;
01547 }
01548
01549 cmdline.ApplySettingsOverride();
01550
01551 if (!GetMythDB()->HaveSchema())
01552 {
01553 if (!InitializeMythSchema())
01554 return GENERIC_EXIT_DB_ERROR;
01555 }
01556
01557 if (cmdline.toBool("reset"))
01558 ResetSettings = true;
01559
01560 if (!cmdline.toBool("noupnp"))
01561 {
01562 g_pUPnp = new MediaRenderer();
01563 if (!g_pUPnp->initialized())
01564 {
01565 delete g_pUPnp;
01566 g_pUPnp = NULL;
01567 }
01568 }
01569
01570 QString fileprefix = GetConfDir();
01571
01572 QDir dir(fileprefix);
01573 if (!dir.exists())
01574 dir.mkdir(fileprefix);
01575
01576 if (ResetSettings)
01577 {
01578 AppearanceSettings as;
01579 as.Save();
01580
01581 gCoreContext->SaveSetting("Theme", DEFAULT_UI_THEME);
01582 gCoreContext->SaveSetting("Language", "");
01583 gCoreContext->SaveSetting("Country", "");
01584
01585 return GENERIC_EXIT_OK;
01586 }
01587
01588 setuid(getuid());
01589
01590 #ifdef USING_LIBDNS_SD
01591
01592
01593 QScopedPointer<BonjourRegister> bonjour(new BonjourRegister());
01594 if (bonjour.data())
01595 {
01596 QByteArray dummy;
01597 int port = gCoreContext->GetNumSetting("UPnP/MythFrontend/ServicePort", 6547);
01598 QByteArray name("Mythfrontend on ");
01599 name.append(gCoreContext->GetHostName());
01600 bonjour->Register(port, "_mythfrontend._tcp",
01601 name, dummy);
01602 }
01603
01604 if (getenv("MYTHTV_AIRPLAY"))
01605 MythAirplayServer::Create();
01606 #endif
01607
01608 #ifdef USING_RAOP
01609 MythRAOPDevice::Create();
01610 #endif
01611
01612 LCD::SetupLCD();
01613 if (LCD *lcd = LCD::Get())
01614 lcd->setupLEDs(RemoteGetRecordingMask);
01615
01616 MythTranslation::load("mythfrontend");
01617
01618 QString themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME);
01619
01620 QString themedir = GetMythUI()->FindThemeDir(themename);
01621 if (themedir.isEmpty())
01622 {
01623 LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find theme '%1'")
01624 .arg(themename));
01625 return GENERIC_EXIT_NO_THEME;
01626 }
01627
01628 GetMythUI()->LoadQtConfig();
01629
01630 themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME);
01631 themedir = GetMythUI()->FindThemeDir(themename);
01632 if (themedir.isEmpty())
01633 {
01634 LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find theme '%1'")
01635 .arg(themename));
01636 return GENERIC_EXIT_NO_THEME;
01637 }
01638
01639 MythMainWindow *mainWindow = GetMythMainWindow();
01640 mainWindow->Init();
01641 mainWindow->setWindowTitle(QObject::tr("MythTV Frontend"));
01642
01643
01644
01645
01646 if (LanguageSelection::prompt())
01647 {
01648 if (!reloadTheme())
01649 return GENERIC_EXIT_NO_THEME;
01650 }
01651
01652 if (!UpgradeTVDatabaseSchema(false))
01653 {
01654 LOG(VB_GENERAL, LOG_ERR,
01655 "Couldn't upgrade database to new schema, exiting.");
01656 return GENERIC_EXIT_DB_OUTOFDATE;
01657 }
01658
01659 WriteDefaults();
01660
01661
01662
01663 mainWindow->ReloadKeys();
01664
01665 InitJumpPoints();
01666 InitKeys();
01667 TV::InitKeys();
01668 SetFuncPtrs();
01669
01670 internal_media_init();
01671
01672 CleanupMyOldInUsePrograms();
01673
01674 setHttpProxy();
01675
01676 pmanager = new MythPluginManager();
01677 gContext->SetPluginManager(pmanager);
01678
01679 MediaMonitor *mon = MediaMonitor::GetMediaMonitor();
01680 if (mon)
01681 {
01682 mon->StartMonitoring();
01683 mainWindow->installEventFilter(mon);
01684 }
01685
01686 NetworkControl *networkControl = NULL;
01687 if (gCoreContext->GetNumSetting("NetworkControlEnabled", 0))
01688 {
01689 int port = gCoreContext->GetNumSetting("NetworkControlPort", 6546);
01690 networkControl = new NetworkControl();
01691 if (!networkControl->listen(port))
01692 LOG(VB_GENERAL, LOG_ERR,
01693 QString("NetworkControl failed to bind to port %1.")
01694 .arg(port));
01695 }
01696
01697 #ifdef __linux__
01698 #ifdef CONFIG_BINDINGS_PYTHON
01699 HardwareProfile *profile = new HardwareProfile();
01700 if (profile && profile->NeedsUpdate())
01701 profile->SubmitProfile();
01702 delete profile;
01703 #endif
01704 #endif
01705
01706 if (!RunMenu(themedir, themename) && !resetTheme(themedir, themename))
01707 {
01708 return GENERIC_EXIT_NO_THEME;
01709 }
01710
01711 #ifndef _MSC_VER
01712
01713 signal(SIGUSR1, &signal_USR1_handler);
01714
01715 signal(SIGUSR2, &signal_USR2_handler);
01716 #endif
01717 ThemeUpdateChecker *themeUpdateChecker = NULL;
01718 if (gCoreContext->GetNumSetting("ThemeUpdateNofications", 1))
01719 themeUpdateChecker = new ThemeUpdateChecker();
01720
01721 MythSystemEventHandler *sysEventHandler = new MythSystemEventHandler();
01722
01723 BackendConnectionManager bcm;
01724
01725 PreviewGeneratorQueue::CreatePreviewGeneratorQueue(
01726 PreviewGenerator::kRemote, 50, 60);
01727
01728 if (cmdline.toBool("runplugin"))
01729 {
01730 QStringList plugins = pmanager->EnumeratePlugins();
01731
01732 if (plugins.contains(cmdline.toString("runplugin")))
01733 pmanager->run_plugin(cmdline.toString("runplugin"));
01734 else if (plugins.contains("myth" + cmdline.toString("runplugin")))
01735 pmanager->run_plugin("myth" + cmdline.toString("runplugin"));
01736 else
01737 {
01738 LOG(VB_GENERAL, LOG_ERR,
01739 QString("Invalid plugin name supplied on command line: '%1'")
01740 .arg(cmdline.toString("runplugin")));
01741 LOG(VB_GENERAL, LOG_ERR,
01742 QString("Available plugins: %1")
01743 .arg(plugins.join(", ")));
01744 return GENERIC_EXIT_INVALID_CMDLINE;
01745 }
01746 }
01747 else if (cmdline.toBool("jumppoint"))
01748 {
01749 MythMainWindow *mmw = GetMythMainWindow();
01750
01751 if (mmw->DestinationExists(cmdline.toString("jumppoint")))
01752 mmw->JumpTo(cmdline.toString("jumppoint"));
01753 else
01754 {
01755 LOG(VB_GENERAL, LOG_ERR,
01756 QString("Invalid jump point supplied on the command line: %1")
01757 .arg(cmdline.toString("jumppoint")));
01758 LOG(VB_GENERAL, LOG_ERR,
01759 QString("Available jump points: %2")
01760 .arg(mmw->EnumerateDestinations().join(", ")));
01761 return GENERIC_EXIT_INVALID_CMDLINE;
01762 }
01763 }
01764
01765 int ret = qApp->exec();
01766
01767 PreviewGeneratorQueue::TeardownPreviewGeneratorQueue();
01768
01769 if (themeUpdateChecker)
01770 delete themeUpdateChecker;
01771
01772 delete sysEventHandler;
01773
01774 pmanager->DestroyAllPlugins();
01775
01776 if (mon)
01777 mon->deleteLater();
01778
01779 delete networkControl;
01780
01781 return ret;
01782
01783 }
01784
01785 #include "main.moc"
01786