int main(int argc, char **argv) { MythScreenWizardCommandLineParser cmdline; if (!cmdline.Parse(argc, argv)) { cmdline.PrintHelp(); return GENERIC_EXIT_INVALID_CMDLINE; } if (cmdline.toBool("showhelp")) { cmdline.PrintHelp(); return GENERIC_EXIT_OK; } if (cmdline.toBool("showversion")) { cmdline.PrintVersion(); return GENERIC_EXIT_OK; } #ifdef Q_OS_MAC // Without this, we can't set focus to any of the CheckBoxSetting, and most // of the MythPushButton widgets, and they don't use the themed background. QApplication::setDesktopSettingsAware(false); #endif new QApplication(argc, argv); QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHSCREENWIZARD); int retval; QString mask("general"); if ((retval = cmdline.ConfigureLogging(mask, false)) != GENERIC_EXIT_OK) return retval; CleanupGuard callCleanup(cleanup); #ifndef _WIN32 QList<int> signallist; signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE << SIGILL; #if ! CONFIG_DARWIN signallist << SIGRTMIN; #endif SignalHandler::Init(signallist); signal(SIGHUP, SIG_IGN); #endif if ((retval = cmdline.ConfigureLogging()) != GENERIC_EXIT_OK) return retval; if (!cmdline.toString("display").isEmpty()) { MythUIHelper::SetX11Display(cmdline.toString("display")); } gContext = new MythContext(MYTH_BINARY_VERSION); if (!gContext->Init(true, false, true)) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to init MythContext, exiting."); return GENERIC_EXIT_NO_MYTHCONTEXT; } if (gCoreContext->GetNumSetting("RunFrontendInWindow")) { LOG(VB_GENERAL, LOG_WARNING, LOC + "Refusing to run screen setup wizard in windowed mode."); return GENERIC_EXIT_NOT_OK; } int GuiOffsetX = gCoreContext->GetNumSetting("GuiOffsetX", 0); int GuiOffsetY = gCoreContext->GetNumSetting("GuiOffsetY", 0); int GuiWidth = gCoreContext->GetNumSetting("GuiWidth", 0); int GuiHeight = gCoreContext->GetNumSetting("GuiHeight", 0); gCoreContext->OverrideSettingForSession("GuiOffsetX", "0"); gCoreContext->OverrideSettingForSession("GuiOffsetY", "0"); gCoreContext->OverrideSettingForSession("GuiWidth", "0"); gCoreContext->OverrideSettingForSession("GuiHeight", "0"); cmdline.ApplySettingsOverride(); GetMythUI()->LoadQtConfig(); QString themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME); QString themedir = GetMythUI()->FindThemeDir(themename); if (themedir.isEmpty()) { LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find theme '%1'") .arg(themename)); return GENERIC_EXIT_NO_THEME; } MythMainWindow *mainWindow = GetMythMainWindow(); #if CONFIG_DARWIN mainWindow->Init(OPENGL2_PAINTER); #else mainWindow->Init(); #endif mainWindow->setWindowTitle(QObject::tr("MythTV Screen Setup Wizard")); // We must reload the translation after a language change and this // also means clearing the cached/loaded theme strings, so reload the // theme which also triggers a translation reload /* if (LanguageSelection::prompt()) { if (!reloadTheme()) return GENERIC_EXIT_NO_THEME; } */ /* I don't think we need to connect to the backend if (!gCoreContext->ConnectToMasterServer()) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to connect to master server"); return GENERIC_EXIT_CONNECT_ERROR; } MythSystemEventHandler *sysEventHandler = new MythSystemEventHandler(); */ startAppearWiz(GuiOffsetX, GuiOffsetY, GuiWidth, GuiHeight); int exitCode = qApp->exec(); /* if (sysEventHandler) delete sysEventHandler; */ return exitCode ? exitCode : GENERIC_EXIT_OK; }
int main(int argc, char **argv) { bool bPromptForBackend = false; bool bBypassAutoDiscovery = false; bool upgradeAllowed = false; bool cmdline_err; MythCommandLineParser cmdline( kCLPOverrideSettingsFile | kCLPOverrideSettings | kCLPWindowed | kCLPNoWindowed | kCLPGetSettings | kCLPQueryVersion | kCLPVerbose | kCLPNoUPnP | #ifdef USING_X11 kCLPDisplay | #endif // USING_X11 kCLPExtra | kCLPGeometry); // Handle --help before QApplication is created, so that // we can print help even if X11 is absent. for (int argpos = 1; argpos < argc; ++argpos) { QString arg(argv[argpos]); if (arg == "-h" || arg == "--help" || arg == "--usage") { ShowUsage(cmdline); return GENERIC_EXIT_OK; } } for (int argpos = 1; argpos < argc; ++argpos) { if (cmdline.PreParse(argc, argv, argpos, cmdline_err)) { if (cmdline_err) return GENERIC_EXIT_INVALID_CMDLINE; if (cmdline.WantsToExit()) return GENERIC_EXIT_OK; } } #ifdef Q_WS_MACX // Without this, we can't set focus to any of the CheckBoxSetting, and most // of the MythPushButton widgets, and they don't use the themed background. QApplication::setDesktopSettingsAware(false); #endif QApplication a(argc, argv); QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHFRONTEND); QString pluginname; QFileInfo finfo(a.argv()[0]); QString binname = finfo.baseName(); VERBOSE(VB_IMPORTANT, QString("%1 version: %2 [%3] www.mythtv.org") .arg(MYTH_APPNAME_MYTHFRONTEND) .arg(MYTH_SOURCE_PATH) .arg(MYTH_SOURCE_VERSION)); bool ResetSettings = false; if (binname.toLower() != "mythfrontend") pluginname = binname; for (int argpos = 1; argpos < a.argc(); ++argpos) { if (!strcmp(a.argv()[argpos],"--prompt") || !strcmp(a.argv()[argpos],"-p" )) { bPromptForBackend = true; } else if (!strcmp(a.argv()[argpos],"--disable-autodiscovery") || !strcmp(a.argv()[argpos],"-d" )) { bBypassAutoDiscovery = true; } else if (!strcmp(a.argv()[argpos],"-l") || !strcmp(a.argv()[argpos],"--logfile")) { if (a.argc()-1 > argpos) { logfile = a.argv()[argpos+1]; if (logfile.startsWith('-')) { cerr << "Invalid or missing argument" " to -l/--logfile option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } else { ++argpos; } } else { cerr << "Missing argument to -l/--logfile option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } } else if (cmdline.Parse(a.argc(), a.argv(), argpos, cmdline_err)) { if (cmdline_err) return GENERIC_EXIT_INVALID_CMDLINE; if (cmdline.WantsToExit()) return GENERIC_EXIT_OK; } } QMap<QString,QString> settingsOverride = cmdline.GetSettingsOverride(); if (logfile.size()) { if (log_rotate(1) < 0) cerr << "cannot open logfile; using stdout/stderr" << endl; else { VERBOSE(VB_IMPORTANT, QString("%1 version: %2 [%3] www.mythtv.org") .arg(MYTH_APPNAME_MYTHFRONTEND) .arg(MYTH_SOURCE_PATH) .arg(MYTH_SOURCE_VERSION)); signal(SIGHUP, &log_rotate_handler); } } if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) cerr << "Unable to ignore SIGPIPE\n"; if (!cmdline.GetDisplay().isEmpty()) { MythUIHelper::SetX11Display(cmdline.GetDisplay()); } if (!cmdline.GetGeometry().isEmpty()) { MythUIHelper::ParseGeometryOverride(cmdline.GetGeometry()); } CleanupGuard callCleanup(cleanup); gContext = new MythContext(MYTH_BINARY_VERSION); if (cmdline.IsUPnPEnabled()) { g_pUPnp = new MediaRenderer(); if (!g_pUPnp->initialized()) { delete g_pUPnp; g_pUPnp = NULL; } } // Override settings as early as possible to cover bootstrapped screens // such as the language prompt settingsOverride = cmdline.GetSettingsOverride(); if (settingsOverride.size()) { QMap<QString, QString>::iterator it; for (it = settingsOverride.begin(); it != settingsOverride.end(); ++it) { VERBOSE(VB_IMPORTANT, QString("Setting '%1' being forced to '%2'") .arg(it.key()).arg(*it)); gCoreContext->OverrideSettingForSession(it.key(), *it); } } if (!gContext->Init(true, bPromptForBackend, bBypassAutoDiscovery)) { VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); return GENERIC_EXIT_NO_MYTHCONTEXT; } if (!GetMythDB()->HaveSchema()) { if (!InitializeMythSchema()) return GENERIC_EXIT_DB_ERROR; } for(int argpos = 1; argpos < a.argc(); ++argpos) { if (!strcmp(a.argv()[argpos],"-l") || !strcmp(a.argv()[argpos],"--logfile")) { // Arg processing for logfile already done (before MythContext) ++argpos; } else if (!strcmp(a.argv()[argpos],"-v") || !strcmp(a.argv()[argpos],"--verbose")) { // Arg processing for verbose already done (before MythContext) ++argpos; } else if (!strcmp(a.argv()[argpos],"-r") || !strcmp(a.argv()[argpos],"--reset")) { ResetSettings = true; } else if (!strcmp(a.argv()[argpos],"--prompt") || !strcmp(a.argv()[argpos],"-p" )) { } else if (!strcmp(a.argv()[argpos],"--disable-autodiscovery") || !strcmp(a.argv()[argpos],"-d" )) { } else if (!strcmp(a.argv()[argpos],"--upgrade-schema") || !strcmp(a.argv()[argpos],"-u" )) { upgradeAllowed = true; } else if (cmdline.Parse(a.argc(), a.argv(), argpos, cmdline_err)) { if (cmdline_err) { return GENERIC_EXIT_INVALID_CMDLINE; } if (cmdline.WantsToExit()) { return GENERIC_EXIT_OK; } } else if ((argpos + 1 == a.argc()) && (!QString(a.argv()[argpos]).startsWith('-'))) { pluginname = a.argv()[argpos]; } else { cerr << "Invalid argument: " << a.argv()[argpos] << endl; ShowUsage(cmdline); return GENERIC_EXIT_INVALID_CMDLINE; } } QStringList settingsQuery = cmdline.GetSettingsQuery(); if (!settingsQuery.empty()) { QStringList::const_iterator it = settingsQuery.begin(); for (; it != settingsQuery.end(); ++it) { QString value = gCoreContext->GetSetting(*it); QString out = QString("\tSettings Value : %1 = %2") .arg(*it).arg(value); cout << out.toLocal8Bit().constData() << endl; } return GENERIC_EXIT_OK; } QString fileprefix = GetConfDir(); QDir dir(fileprefix); if (!dir.exists()) dir.mkdir(fileprefix); if (ResetSettings) { AppearanceSettings as; as.Save(); gCoreContext->SaveSetting("Theme", DEFAULT_UI_THEME); gCoreContext->SaveSetting("Language", ""); gCoreContext->SaveSetting("Country", ""); return GENERIC_EXIT_OK; } setuid(getuid()); VERBOSE(VB_IMPORTANT, QString("Enabled verbose msgs: %1").arg(verboseString)); LCD::SetupLCD(); if (LCD *lcd = LCD::Get()) lcd->setupLEDs(RemoteGetRecordingMask); MythTranslation::load("mythfrontend"); QString themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME); QString themedir = GetMythUI()->FindThemeDir(themename); if (themedir.isEmpty()) { VERBOSE(VB_IMPORTANT, QString("Couldn't find theme '%1'") .arg(themename)); return GENERIC_EXIT_NO_THEME; } GetMythUI()->LoadQtConfig(); themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME); themedir = GetMythUI()->FindThemeDir(themename); if (themedir.isEmpty()) { VERBOSE(VB_IMPORTANT, QString("Couldn't find theme '%1'") .arg(themename)); return GENERIC_EXIT_NO_THEME; } MythMainWindow *mainWindow = GetMythMainWindow(); mainWindow->Init(); mainWindow->setWindowTitle(QObject::tr("MythTV Frontend")); // We must reload the translation after a language change and this // also means clearing the cached/loaded theme strings, so reload the // theme which also triggers a translation reload if (LanguageSelection::prompt()) { if (!reloadTheme()) return GENERIC_EXIT_NO_THEME; } if (!UpgradeTVDatabaseSchema(upgradeAllowed)) { VERBOSE(VB_IMPORTANT, "Couldn't upgrade database to new schema, exiting."); return GENERIC_EXIT_DB_OUTOFDATE; } WriteDefaults(); // Refresh Global/Main Menu keys after DB update in case there was no DB // when they were written originally mainWindow->ResetKeys(); InitJumpPoints(); internal_media_init(); CleanupMyOldInUsePrograms(); pmanager = new MythPluginManager(); gContext->SetPluginManager(pmanager); if (pluginname.size()) { if (pmanager->run_plugin(pluginname) || pmanager->run_plugin("myth" + pluginname)) { qApp->exec(); return GENERIC_EXIT_OK; } else return GENERIC_EXIT_INVALID_CMDLINE; } MediaMonitor *mon = MediaMonitor::GetMediaMonitor(); if (mon) { mon->StartMonitoring(); mainWindow->installEventFilter(mon); } NetworkControl *networkControl = NULL; if (gCoreContext->GetNumSetting("NetworkControlEnabled", 0)) { int networkPort = gCoreContext->GetNumSetting("NetworkControlPort", 6545); networkControl = new NetworkControl(); if (!networkControl->listen(QHostAddress::Any,networkPort)) VERBOSE(VB_IMPORTANT, QString("NetworkControl failed to bind to port %1.") .arg(networkPort)); } #ifdef __linux__ #ifdef CONFIG_BINDINGS_PYTHON HardwareProfile *profile = new HardwareProfile(); if (profile && profile->NeedsUpdate()) profile->SubmitProfile(); delete profile; #endif #endif if (!RunMenu(themedir, themename) && !resetTheme(themedir, themename)) { return GENERIC_EXIT_NO_THEME; } #ifndef _MSC_VER // Setup handler for USR1 signals to reload theme signal(SIGUSR1, &signal_USR1_handler); // Setup handler for USR2 signals to restart LIRC signal(SIGUSR2, &signal_USR2_handler); #endif ThemeUpdateChecker *themeUpdateChecker = NULL; if (gCoreContext->GetNumSetting("ThemeUpdateNofications", 1)) themeUpdateChecker = new ThemeUpdateChecker(); MythSystemEventHandler *sysEventHandler = new MythSystemEventHandler(); GetMythMainWindow()->RegisterSystemEventHandler(sysEventHandler); BackendConnectionManager bcm; PreviewGeneratorQueue::CreatePreviewGeneratorQueue( PreviewGenerator::kRemote, 50, 60); int ret = qApp->exec(); PreviewGeneratorQueue::TeardownPreviewGeneratorQueue(); if (themeUpdateChecker) delete themeUpdateChecker; delete sysEventHandler; pmanager->DestroyAllPlugins(); if (mon) mon->deleteLater(); delete networkControl; DestroyMythMainWindow(); return ret; }
int main(int argc, char *argv[]) { QString geometry = QString::null; QString display = QString::null; bool doScan = false; bool doScanList = false; bool doScanSaveOnly = false; bool scanInteractive = true; bool expertMode = false; uint scanImport = 0; bool scanFTAOnly = false; ServiceRequirements scanServiceRequirements = kRequireAV; uint scanCardId = 0; QString scanTableName = "atsc-vsb8-us"; QString scanInputName = ""; MythTVSetupCommandLineParser cmdline; if (!cmdline.Parse(argc, argv)) { cmdline.PrintHelp(); return GENERIC_EXIT_INVALID_CMDLINE; } if (cmdline.toBool("showhelp")) { cmdline.PrintHelp(); return GENERIC_EXIT_OK; } if (cmdline.toBool("showversion")) { cmdline.PrintVersion(); return GENERIC_EXIT_OK; } bool quiet = false, use_display = true; if (cmdline.toBool("scan")) { quiet = true; use_display = false; } CleanupGuard callCleanup(cleanup); #ifdef Q_WS_MACX // Without this, we can't set focus to any of the CheckBoxSetting, and most // of the MythPushButton widgets, and they don't use the themed background. QApplication::setDesktopSettingsAware(FALSE); #endif new QApplication(argc, argv, use_display); QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHTV_SETUP); if (cmdline.toBool("display")) display = cmdline.toString("display"); if (cmdline.toBool("geometry")) geometry = cmdline.toString("geometry"); int retval; QString mask("general"); if ((retval = cmdline.ConfigureLogging(mask, quiet)) != GENERIC_EXIT_OK) return retval; if (cmdline.toBool("expert")) expertMode = true; if (cmdline.toBool("scanlist")) doScanList = true; if (cmdline.toBool("savescan")) doScanSaveOnly = true; if (cmdline.toBool("scannoninteractive")) scanInteractive = false; if (cmdline.toBool("importscan")) scanImport = cmdline.toUInt("importscan"); if (cmdline.toBool("ftaonly")) scanFTAOnly = true; if (cmdline.toBool("servicetype")) { scanServiceRequirements = kRequireNothing; if (cmdline.toString("servicetype").contains("radio")) scanServiceRequirements = kRequireAudio; if (cmdline.toString("servicetype").contains("tv")) scanServiceRequirements = kRequireAV; if (cmdline.toString("servicetype").contains("tv+radio") || cmdline.toString("servicetype").contains("radio+tv")) scanServiceRequirements = kRequireAudio; if (cmdline.toString("servicetype").contains("all")) scanServiceRequirements = kRequireNothing; } if (cmdline.toBool("scan")) { scanCardId = cmdline.toUInt("scan"); doScan = true; } if (cmdline.toBool("freqtable")) scanTableName = cmdline.toString("freqtable"); if (cmdline.toBool("inputname")) scanInputName = cmdline.toString("inputname"); if (!display.isEmpty()) { MythUIHelper::SetX11Display(display); } if (!geometry.isEmpty()) { MythUIHelper::ParseGeometryOverride(geometry); } gContext = new MythContext(MYTH_BINARY_VERSION); if (!gContext->Init(use_display)) // No Upnp, Prompt for db { LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext, exiting."); return GENERIC_EXIT_NO_MYTHCONTEXT; } cmdline.ApplySettingsOverride(); if (!GetMythDB()->HaveSchema()) { if (!InitializeMythSchema()) return GENERIC_EXIT_DB_ERROR; } if (use_display) { gCoreContext->SetSetting("Theme", DEFAULT_UI_THEME); GetMythUI()->LoadQtConfig(); QString fileprefix = GetConfDir(); QDir dir(fileprefix); if (!dir.exists()) dir.mkdir(fileprefix); } if (doScan) { bool okCardID = scanCardId; QStringList inputnames = CardUtil::GetInputNames(scanCardId); okCardID &= !inputnames.empty(); if (scanInputName.isEmpty()) scanInputName = CardUtil::GetStartInput(scanCardId); bool okInputName = inputnames.contains(scanInputName); doScan = (okCardID && okInputName); if (!okCardID) { cerr << "You must enter a valid cardid to scan." << endl; vector<uint> cardids = CardUtil::GetCardIDs(); if (cardids.empty()) { cerr << "But no cards have been defined on this host" << endl; return GENERIC_EXIT_INVALID_CMDLINE; } cerr << "Valid cards: " << endl; for (uint i = 0; i < cardids.size(); i++) { fprintf(stderr, "%5i: %s %s\n", cardids[i], CardUtil::GetRawCardType(cardids[i]) .toAscii().constData(), CardUtil::GetVideoDevice(cardids[i]) .toAscii().constData()); } return GENERIC_EXIT_INVALID_CMDLINE; } if (!okInputName) { cerr << "You must enter a valid input to scan this card." << endl; cerr << "Valid inputs: " << endl; for (int i = 0; i < inputnames.size(); i++) { cerr << inputnames[i].toAscii().constData() << endl; } return GENERIC_EXIT_INVALID_CMDLINE; } } if (doScan) { int ret = 0; int firstBreak = scanTableName.indexOf("-"); int secondBreak = scanTableName.lastIndexOf("-"); if (!firstBreak || !secondBreak || firstBreak == secondBreak) { cerr << "Failed to parse the frequence table parameter " << scanTableName.toLocal8Bit().constData() << endl << "Please make sure it is in the format freq_std-" "modulation-country." << endl; return GENERIC_EXIT_INVALID_CMDLINE; } QString freq_std = scanTableName.mid(0, firstBreak).toLower(); QString mod = scanTableName.mid( firstBreak+1, secondBreak-firstBreak-1).toLower(); QString tbl = scanTableName.mid(secondBreak+1).toLower(); uint inputid = CardUtil::GetInputID(scanCardId, scanInputName); uint sourceid = CardUtil::GetSourceID(inputid); QMap<QString,QString> startChan; { ChannelScannerCLI scanner(doScanSaveOnly, scanInteractive); scanner.Scan( (freq_std=="atsc") ? ScanTypeSetting::FullScan_ATSC : ((freq_std=="dvbt") ? ScanTypeSetting::FullScan_DVBT : ScanTypeSetting::FullScan_ATSC), /* cardid */ scanCardId, /* inputname */ scanInputName, /* sourceid */ sourceid, /* ignore signal timeout */ false, /* follow_nit */ true, /* test decryption */ true, scanFTAOnly, scanServiceRequirements, // stuff needed for particular scans /* mplexid */ 0, startChan, freq_std, mod, tbl); ret = qApp->exec(); } return (ret) ? GENERIC_EXIT_NOT_OK : GENERIC_EXIT_OK; } if (doScanList) { vector<ScanInfo> scans = LoadScanList(); cout<<" scanid cardid sourceid processed date"<<endl; for (uint i = 0; i < scans.size(); i++) { printf("%5i %6i %8i %8s %20s\n", scans[i].scanid, scans[i].cardid, scans[i].sourceid, (scans[i].processed) ? "yes" : "no", scans[i].scandate.toString().toAscii().constData()); } cout<<endl; return GENERIC_EXIT_OK; } if (scanImport) { vector<ScanInfo> scans = LoadScanList(); cout<<"*** SCAN IMPORT START ***"<<endl; { ScanDTVTransportList list = LoadScan(scanImport); ChannelImporter ci(false, true, true, true, false, scanFTAOnly, scanServiceRequirements); ci.Process(list); } cout<<"*** SCAN IMPORT END ***"<<endl; return GENERIC_EXIT_OK; } MythTranslation::load("mythfrontend"); QString themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME); QString themedir = GetMythUI()->FindThemeDir(themename); if (themedir.isEmpty()) { LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find theme '%1'") .arg(themename)); return GENERIC_EXIT_NO_THEME; } MythMainWindow *mainWindow = GetMythMainWindow(); mainWindow->Init(); mainWindow->setWindowTitle(QObject::tr("MythTV Setup")); // We must reload the translation after a language change and this // also means clearing the cached/loaded theme strings, so reload the // theme which also triggers a translation reload if (LanguageSelection::prompt()) { if (!reloadTheme()) return GENERIC_EXIT_NO_THEME; } if (!UpgradeTVDatabaseSchema(true)) { LOG(VB_GENERAL, LOG_ERR, "Couldn't upgrade database to new schema."); return GENERIC_EXIT_DB_OUTOFDATE; } // Refresh Global/Main Menu keys after DB update in case there was no DB // when they were written originally mainWindow->ReloadKeys(); if (!startPrompt) startPrompt = new StartPrompter(); startPrompt->handleStart(); // Let the user select buttons, type values, scan for channels, etc. if (!RunMenu(themedir, themename) && !resetTheme(themedir, themename)) return GENERIC_EXIT_NO_THEME; ExpertSettingsEditor *expertEditor = NULL; if (expertMode) { MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); expertEditor = new ExpertSettingsEditor(mainStack, "Expert Settings Editor"); if (expertEditor->Create()) mainStack->AddScreen(expertEditor); else { delete expertEditor; expertEditor = NULL; LOG(VB_GENERAL, LOG_ERR, "Unable to create expert settings editor window"); return GENERIC_EXIT_OK; } } qApp->exec(); }
int main(int argc, char *argv[]) { QString geometry = QString::null; QString display = QString::null; bool doScan = false; bool doScanList = false; bool doScanSaveOnly = false; bool scanInteractive = true; bool expertMode = false; uint scanImport = 0; bool scanFTAOnly = false; ServiceRequirements scanServiceRequirements = kRequireAV; uint scanCardId = 0; QString scanTableName = "atsc-vsb8-us"; QString scanInputName = ""; bool use_display = true; for(int argpos = 1; argpos < argc; ++argpos) { if (!strcmp(argv[argpos], "-h") || !strcmp(argv[argpos], "--help") || !strcmp(argv[argpos], "--usage")) { print_usage(); return GENERIC_EXIT_OK; } #ifdef USING_X11 // Remember any -display or -geometry argument // which QApplication init will remove. else if (argpos+1 < argc && !strcmp(argv[argpos],"-geometry")) geometry = argv[argpos+1]; else if (argpos+1 < argc && !strcmp(argv[argpos],"-display")) display = argv[argpos+1]; #endif else if (QString(argv[argpos]).left(6) == "--scan") { use_display = false; print_verbose_messages = VB_NONE; verboseString = ""; } } #ifdef Q_WS_MACX // Without this, we can't set focus to any of the CheckBoxSetting, and most // of the MythPushButton widgets, and they don't use the themed background. QApplication::setDesktopSettingsAware(FALSE); #endif QApplication a(argc, argv, use_display); QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHTV_SETUP); QMap<QString, QString> settingsOverride; VERBOSE(VB_IMPORTANT, QString("%1 version: %2 [%3] www.mythtv.org") .arg(MYTH_APPNAME_MYTHTV_SETUP) .arg(MYTH_SOURCE_PATH) .arg(MYTH_SOURCE_VERSION)); for(int argpos = 1; argpos < a.argc(); ++argpos) { if (!strcmp(a.argv()[argpos],"-display") || !strcmp(a.argv()[argpos],"--display")) { if (a.argc()-1 > argpos) { display = a.argv()[argpos+1]; if (display.startsWith("-")) { cerr << "Invalid or missing argument to -display option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } else ++argpos; } else { cerr << "Missing argument to -display option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } } else if (!strcmp(a.argv()[argpos],"-geometry") || !strcmp(a.argv()[argpos],"--geometry")) { if (a.argc()-1 > argpos) { geometry = a.argv()[argpos+1]; if (geometry.startsWith("-")) { cerr << "Invalid or missing argument to " "-geometry option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } else ++argpos; } else { cerr << "Missing argument to -geometry option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } } else if (!strcmp(a.argv()[argpos],"-l") || !strcmp(a.argv()[argpos],"--logfile")) { if (a.argc()-1 > argpos) { logfile = a.argv()[argpos+1]; if (logfile.startsWith("-")) { cerr << "Invalid or missing argument" " to -l/--logfile option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } else { ++argpos; } } else { cerr << "Missing argument to -l/--logfile option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } } else if (!strcmp(a.argv()[argpos],"-v") || !strcmp(a.argv()[argpos],"--verbose")) { if (a.argc()-1 > argpos) { if (parse_verbose_arg(a.argv()[argpos+1]) == GENERIC_EXIT_INVALID_CMDLINE) return GENERIC_EXIT_INVALID_CMDLINE; ++argpos; } else { cerr << "Missing argument to -v/--verbose option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } } else if (!strcmp(a.argv()[argpos],"-O") || !strcmp(a.argv()[argpos],"--override-setting")) { if (a.argc()-1 > argpos) { QString tmpArg = a.argv()[argpos+1]; if (tmpArg.startsWith("-")) { cerr << "Invalid or missing argument to " "-O/--override-setting option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } QStringList pairs = tmpArg.split(","); for (int index = 0; index < pairs.size(); ++index) { QStringList tokens = pairs[index].split("="); tokens[0].replace(QRegExp("^[\"']"), ""); tokens[0].replace(QRegExp("[\"']$"), ""); tokens[1].replace(QRegExp("^[\"']"), ""); tokens[1].replace(QRegExp("[\"']$"), ""); settingsOverride[tokens[0]] = tokens[1]; } } else { cerr << "Invalid or missing argument to " "-O/--override-setting option\n"; return GENERIC_EXIT_INVALID_CMDLINE; } ++argpos; } else if (!strcmp(a.argv()[argpos],"--expert")) { expertMode = true; } else if (!strcmp(a.argv()[argpos],"--scan-list")) { doScanList = true; } else if (!strcmp(a.argv()[argpos],"--scan-import")) { if (a.argc()-1 > argpos) { QString tmpArg = a.argv()[argpos + 1]; scanImport = tmpArg.toUInt(); ++argpos; if (a.argc()-1 > argpos) { tmpArg = a.argv()[argpos + 1]; scanFTAOnly = tmpArg.toUInt(); ++argpos; } if (a.argc()-1 > argpos) { tmpArg = a.argv()[argpos + 1]; tmpArg = tmpArg.toLower(); scanServiceRequirements = kRequireNothing; if (tmpArg.contains("radio")) scanServiceRequirements = kRequireAudio; if (tmpArg.contains("tv")) scanServiceRequirements = kRequireAV; if (tmpArg.contains("tv+radio") || tmpArg.contains("radio+tv")) scanServiceRequirements = kRequireAudio; if (tmpArg.contains("all")) scanServiceRequirements = kRequireNothing; ++argpos; } } else { cerr << "Missing scan number for import, please run " << "--scan-list to list importable scans." << endl; return GENERIC_EXIT_INVALID_CMDLINE; } } else if (!strcmp(a.argv()[argpos],"--scan-save-only")) { doScanSaveOnly = true; } else if (!strcmp(a.argv()[argpos],"--scan-non-interactive")) { scanInteractive = false; } else if (!strcmp(a.argv()[argpos],"--scan")) { if (a.argc()-1 > argpos) { scanTableName = a.argv()[argpos + 1]; ++argpos; } if (a.argc()-1 > argpos) { QString tmpArg = a.argv()[argpos + 1]; scanCardId = tmpArg.toUInt(); ++argpos; } if (a.argc()-1 > argpos) { scanInputName = a.argv()[argpos + 1]; ++argpos; } doScan = true; } else { cerr << "Invalid argument: " << a.argv()[argpos] << endl; print_usage(); return GENERIC_EXIT_INVALID_CMDLINE; } } if (logfile.size()) { if (log_rotate(1) < 0) cerr << "cannot open logfile; using stdout/stderr" << endl; else { VERBOSE(VB_IMPORTANT, QString("%1 version: %2 [%3] www.mythtv.org") .arg(MYTH_APPNAME_MYTHTV_SETUP) .arg(MYTH_SOURCE_PATH) .arg(MYTH_SOURCE_VERSION)); signal(SIGHUP, &log_rotate_handler); } } if (!display.isEmpty()) { MythUIHelper::SetX11Display(display); } if (!geometry.isEmpty()) { MythUIHelper::ParseGeometryOverride(geometry); } gContext = new MythContext(MYTH_BINARY_VERSION); std::auto_ptr<MythContext> contextScopeDelete(gContext); // Override settings as early as possible to cover bootstrapped screens // such as the language prompt if (settingsOverride.size()) { QMap<QString, QString>::iterator it; for (it = settingsOverride.begin(); it != settingsOverride.end(); ++it) { VERBOSE(VB_IMPORTANT, QString("Setting '%1' being forced to '%2'") .arg(it.key()).arg(*it)); gCoreContext->OverrideSettingForSession(it.key(), *it); } } if (!gContext->Init(use_display)) // No Upnp, Prompt for db { VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); return GENERIC_EXIT_NO_MYTHCONTEXT; } if (!GetMythDB()->HaveSchema()) { if (!InitializeMythSchema()) return GENERIC_EXIT_DB_ERROR; } if (use_display) { gCoreContext->SetSetting("Theme", DEFAULT_UI_THEME); GetMythUI()->LoadQtConfig(); QString fileprefix = GetConfDir(); QDir dir(fileprefix); if (!dir.exists()) dir.mkdir(fileprefix); } if (doScan) { bool okCardID = scanCardId; QStringList inputnames = CardUtil::GetInputNames(scanCardId); okCardID &= !inputnames.empty(); if (scanInputName.isEmpty()) scanInputName = CardUtil::GetDefaultInput(scanCardId); bool okInputName = inputnames.contains(scanInputName); doScan = (okCardID && okInputName); if (!okCardID) { cerr << "You must enter a valid cardid to scan." << endl; vector<uint> cardids = CardUtil::GetCardIDs(); if (cardids.empty()) { cerr << "But no cards have been defined on this host" << endl; return GENERIC_EXIT_INVALID_CMDLINE; } cerr << "Valid cards: " << endl; for (uint i = 0; i < cardids.size(); i++) { fprintf(stderr, "%5i: %s %s\n", cardids[i], CardUtil::GetRawCardType(cardids[i]) .toAscii().constData(), CardUtil::GetVideoDevice(cardids[i]) .toAscii().constData()); } return GENERIC_EXIT_INVALID_CMDLINE; } if (!okInputName) { cerr << "You must enter a valid input to scan this card." << endl; cerr << "Valid inputs: " << endl; for (int i = 0; i < inputnames.size(); i++) { cerr << inputnames[i].toAscii().constData() << endl; } return GENERIC_EXIT_INVALID_CMDLINE; } } if (doScan) { int ret = 0; int firstBreak = scanTableName.indexOf("-"); int secondBreak = scanTableName.lastIndexOf("-"); if (!firstBreak || !secondBreak || firstBreak == secondBreak) { cerr << "Failed to parse the frequence table parameter " << scanTableName.toLocal8Bit().constData() << endl << "Please make sure it is in the format freq_std-" "modulation-country." << endl; return GENERIC_EXIT_INVALID_CMDLINE; } QString freq_std = scanTableName.mid(0, firstBreak).toLower(); QString mod = scanTableName.mid( firstBreak+1, secondBreak-firstBreak-1).toLower(); QString tbl = scanTableName.mid(secondBreak+1).toLower(); uint inputid = CardUtil::GetInputID(scanCardId, scanInputName); uint sourceid = CardUtil::GetSourceID(inputid); QMap<QString,QString> startChan; { ChannelScannerCLI scanner(doScanSaveOnly, scanInteractive); scanner.Scan( (freq_std=="atsc") ? ScanTypeSetting::FullScan_ATSC : ((freq_std=="dvbt") ? ScanTypeSetting::FullScan_DVBT : ScanTypeSetting::FullScan_ATSC), /* cardid */ scanCardId, /* inputname */ scanInputName, /* sourceid */ sourceid, /* ignore signal timeout */ false, /* follow_nit */ true, /* test decryption */ true, scanFTAOnly, scanServiceRequirements, // stuff needed for particular scans /* mplexid */ 0, startChan, freq_std, mod, tbl); ret = a.exec(); } return (ret) ? GENERIC_EXIT_NOT_OK : GENERIC_EXIT_OK; } if (doScanList) { vector<ScanInfo> scans = LoadScanList(); cout<<" scanid cardid sourceid processed date"<<endl; for (uint i = 0; i < scans.size(); i++) { printf("%5i %6i %8i %8s %20s\n", scans[i].scanid, scans[i].cardid, scans[i].sourceid, (scans[i].processed) ? "yes" : "no", scans[i].scandate.toString().toAscii().constData()); } cout<<endl; return GENERIC_EXIT_OK; } if (scanImport) { vector<ScanInfo> scans = LoadScanList(); cout<<"*** SCAN IMPORT START ***"<<endl; { ScanDTVTransportList list = LoadScan(scanImport); ChannelImporter ci(false, true, true, true, false, scanFTAOnly, scanServiceRequirements); ci.Process(list); } cout<<"*** SCAN IMPORT END ***"<<endl; return GENERIC_EXIT_OK; } MythTranslation::load("mythfrontend"); QString themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME); QString themedir = GetMythUI()->FindThemeDir(themename); if (themedir.isEmpty()) { VERBOSE(VB_IMPORTANT, QString("Couldn't find theme '%1'") .arg(themename)); return GENERIC_EXIT_NO_THEME; } MythMainWindow *mainWindow = GetMythMainWindow(); mainWindow->Init(); mainWindow->setWindowTitle(QObject::tr("MythTV Setup")); // We must reload the translation after a language change and this // also means clearing the cached/loaded theme strings, so reload the // theme which also triggers a translation reload if (LanguageSelection::prompt()) { if (!reloadTheme()) return GENERIC_EXIT_NO_THEME; } if (!UpgradeTVDatabaseSchema(true)) { VERBOSE(VB_IMPORTANT, "Couldn't upgrade database to new schema."); return GENERIC_EXIT_DB_OUTOFDATE; } // Refresh Global/Main Menu keys after DB update in case there was no DB // when they were written originally mainWindow->ResetKeys(); if (!startPrompt) startPrompt = new StartPrompter(); startPrompt->handleStart(); // Let the user select buttons, type values, scan for channels, etc. if (!RunMenu(themedir, themename) && !resetTheme(themedir, themename)) return GENERIC_EXIT_NO_THEME; ExpertSettingsEditor *expertEditor = NULL; if (expertMode) { MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); expertEditor = new ExpertSettingsEditor(mainStack, "Expert Settings Editor"); if (expertEditor->Create()) mainStack->AddScreen(expertEditor); else { delete expertEditor; expertEditor = NULL; VERBOSE(VB_IMPORTANT, "Unable to create expert settings editor " "window"); return GENERIC_EXIT_OK; } } qApp->exec(); // Main menu callback to ExitPrompter does CheckSetup(), cleanup and exit. }