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