• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files

globalsettings.cpp

Go to the documentation of this file.
00001 
00002 // -*- Mode: c++ -*-
00003 
00004 // Standard UNIX C headers
00005 #include <unistd.h>
00006 #include <fcntl.h>
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 
00010 // Qt headers
00011 #include <qapplication.h>
00012 #include <qevent.h>
00013 #include <qnamespace.h>
00014 #include <qstylefactory.h>
00015 #include <qsqldatabase.h>
00016 #include <qfile.h>
00017 #include <qdialog.h>
00018 #include <qcursor.h>
00019 #include <qdir.h>
00020 #include <qimage.h>
00021 
00022 // MythTV headers
00023 #include "libmyth/mythconfig.h"
00024 #include "libmyth/mythcontext.h"
00025 #include "libmyth/mythdbcon.h"
00026 #include "libmyth/dbsettings.h"
00027 #include "libmyth/langsettings.h"
00028 #include "libmythtv/mpeg/iso639.h"
00029 #include "playbackbox.h"
00030 #include "globalsettings.h"
00031 #include "libmythtv/recordingprofile.h"
00032 #include "libmythtv/scheduledrecording.h"
00033 #include "libmyth/util-x11.h"
00034 #include "libmyth/DisplayRes.h"
00035 #include "libmyth/uitypes.h"
00036 #include "libmythtv/cardutil.h"
00037 #include "libmyth/themeinfo.h"
00038 #include "libmyth/mythconfig.h"
00039 
00040 static HostComboBox *AudioOutputDevice()
00041 {
00042     HostComboBox *gc = new HostComboBox("AudioOutputDevice", true);
00043     gc->setLabel(QObject::tr("Audio output device"));
00044 
00045 #ifdef USING_ALSA
00046     gc->addSelection("ALSA:default",       "ALSA:default");
00047     gc->addSelection("ALSA:spdif",         "ALSA:spdif");
00048     gc->addSelection("ALSA:surround51",    "ALSA:surround51");
00049     gc->addSelection("ALSA:analog",        "ALSA:analog");
00050     gc->addSelection("ALSA:digital",       "ALSA:digital");
00051     gc->addSelection("ALSA:mixed-analog",  "ALSA:mixed-analog");
00052     gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital");
00053 #endif
00054 #ifdef USING_OSS
00055     QDir dev("/dev", "dsp*", QDir::Name, QDir::System);
00056     gc->fillSelectionsFromDir(dev);
00057     dev.setNameFilter("adsp*");
00058     gc->fillSelectionsFromDir(dev);
00059 
00060     dev.setPath("/dev/sound");
00061     if (dev.exists())
00062     {
00063         dev.setNameFilter("dsp*");
00064         gc->fillSelectionsFromDir(dev);
00065         dev.setNameFilter("adsp*");
00066         gc->fillSelectionsFromDir(dev);
00067     }
00068 #endif
00069 #ifdef USING_ARTS
00070     gc->addSelection("ARTS:", "ARTS:");
00071 #endif
00072 #ifdef USING_JACK
00073     gc->addSelection("JACK:output", "JACK:output"); 
00074 #endif
00075 #ifdef USING_COREAUDIO
00076     gc->addSelection("CoreAudio:", "CoreAudio:"); 
00077 #endif
00078 #ifdef USING_MINGW
00079         gc->addSelection("Windows:");
00080 #endif
00081 #ifdef USING_DIRECTX
00082         gc->addSelection("DirectX:");
00083 #endif
00084     gc->addSelection("NULL", "NULL");
00085 
00086     return gc;
00087 }
00088 
00089 static HostComboBox *MaxAudioChannels()
00090 {
00091     HostComboBox *gc = new HostComboBox("MaxChannels",false);
00092     gc->setLabel(QObject::tr("Max Audio Channels"));
00093     gc->addSelection(QObject::tr("Stereo"), "2", true); // default
00094     gc->addSelection(QObject::tr("5.1"), "6");
00095     gc->setHelpText(
00096             QObject::tr(
00097                 "Set the maximum number of audio channels to be decoded. "
00098                 "This is for multi-channel/surround audio playback."));
00099     return gc;
00100 }
00101 
00102 static HostComboBox *AudioUpmixType()
00103 {
00104     HostComboBox *gc = new HostComboBox("AudioUpmixType",false);
00105     gc->setLabel(QObject::tr("Upmix"));
00106     gc->addSelection(QObject::tr("Passive"), "0", true); // default
00107     gc->addSelection(QObject::tr("Active Simple"), "1");
00108     gc->addSelection(QObject::tr("Active Linear"), "2");
00109     gc->setHelpText(
00110             QObject::tr(
00111                 "Set the audio upmix type for 2ch to 6ch conversion. "
00112                 "This is for multi-channel/surround audio playback. "
00113                 "'Passive' is the least demanding on the CPU. "
00114                 "'Active Simple' is more demanding and 'Active Linear' "
00115                 "is the most demanding (but highest quality)."));
00116     return gc;
00117 }
00118 
00119 static HostComboBox *PassThroughOutputDevice()
00120 {
00121     HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
00122 
00123     gc->setLabel(QObject::tr("Passthrough output device"));
00124     gc->addSelection(QObject::tr("Default"), "Default");
00125 #ifndef USING_MINGW
00126     gc->addSelection("ALSA:iec958:{ AES0 0x02 }", "ALSA:iec958:{ AES0 0x02 }");
00127 #endif
00128 
00129     gc->setHelpText(QObject::tr("Audio output device to use for AC3 and "
00130                     "DTS passthrough. Default is the same as Audio output "
00131                     "device. This value is currently only used with ALSA "
00132                     "sound output."));
00133     return gc;
00134 }
00135 
00136 static HostCheckBox *MythControlsVolume()
00137 {
00138     HostCheckBox *gc = new HostCheckBox("MythControlsVolume");
00139     gc->setLabel(QObject::tr("Use internal volume controls"));
00140     gc->setValue(true);
00141     gc->setHelpText(QObject::tr("MythTV can control the PCM and master "
00142                     "mixer volume.  If you prefer to use an external mixer "
00143                     "program, then disable this option."));
00144     return gc;
00145 }
00146 
00147 static HostComboBox *MixerDevice()
00148 {
00149     HostComboBox *gc = new HostComboBox("MixerDevice", true);
00150     gc->setLabel(QObject::tr("Mixer Device"));
00151 
00152 #ifdef USING_OSS
00153     QDir dev("/dev", "mixer*", QDir::Name, QDir::System);
00154     gc->fillSelectionsFromDir(dev);
00155 
00156     dev.setPath("/dev/sound");
00157     if (dev.exists())
00158     {
00159         gc->fillSelectionsFromDir(dev);
00160     }
00161 #endif
00162 #ifdef USING_ALSA
00163     gc->addSelection("ALSA:default", "ALSA:default");
00164 #endif
00165 #ifdef USING_DIRECTX
00166     gc->addSelection("DirectX:", "DirectX:");
00167 #endif
00168 #ifdef USING_WINAUDIO
00169     gc->addSelection("Windows:", "Windows:");
00170 #endif
00171 
00172     return gc;
00173 }
00174 
00175 static const char* MixerControlControls[] = { "PCM",
00176                                               "Master" };
00177 
00178 static HostComboBox *MixerControl()
00179 {
00180     HostComboBox *gc = new HostComboBox("MixerControl", true);
00181     gc->setLabel(QObject::tr("Mixer Controls"));
00182     for (unsigned int i = 0; i < sizeof(MixerControlControls) / sizeof(char*); 
00183          ++i) 
00184     {
00185         gc->addSelection(QObject::tr(MixerControlControls[i]), 
00186                          MixerControlControls[i]);
00187     }
00188 
00189     gc->setHelpText(QObject::tr("Changing the volume adjusts the selected mixer."));
00190     return gc;
00191 }
00192 
00193 static HostSlider *MixerVolume()
00194 {
00195     HostSlider *gs = new HostSlider("MasterMixerVolume", 0, 100, 1);
00196     gs->setLabel(QObject::tr("Master Mixer Volume"));
00197     gs->setValue(70);
00198     gs->setHelpText(QObject::tr("Initial volume for the Master Mixer.  "
00199                     "This affects all sound created by the sound card.  "
00200                     "Note: Do not set this too low."));
00201     return gs;
00202 }
00203 
00204 static HostSlider *PCMVolume()
00205 {
00206     HostSlider *gs = new HostSlider("PCMMixerVolume", 0, 100, 1);
00207     gs->setLabel(QObject::tr("PCM Mixer Volume"));
00208     gs->setValue(70);
00209     gs->setHelpText(QObject::tr("Initial volume for PCM output.  Using the "
00210                     "volume keys in MythTV will adjust this parameter."));
00211     return gs;
00212 }
00213 
00214 static HostCheckBox *IndividualMuteControl()
00215 {
00216     HostCheckBox *gc = new HostCheckBox("IndividualMuteControl");
00217     gc->setLabel(QObject::tr("Independent Muting of Left and Right Audio "
00218                  "Channels"));
00219     gc->setValue(false);
00220     gc->setHelpText(QObject::tr("Enable muting of just the left or right "
00221                     "channel.  Useful if your broadcaster puts the "
00222                     "original language on one channel, and a dubbed "
00223                     "version of the program on the other one.  This "
00224                     "modifies the behavior of the Mute key."));
00225     return gc;
00226 }
00227 
00228 static HostCheckBox *AC3PassThrough()
00229 {
00230     HostCheckBox *gc = new HostCheckBox("AC3PassThru");
00231     gc->setLabel(QObject::tr("Enable AC3 to SPDIF passthrough"));
00232     gc->setValue(false);
00233     gc->setHelpText(QObject::tr("Enable sending AC3 audio directly to your "
00234                     "sound card's SPDIF output, on sources which contain "
00235                     "AC3 soundtracks (usually digital TV).  Requires that "
00236                     "the audio output device be set to something suitable."));
00237     return gc;
00238 }
00239 
00240 static HostCheckBox *DTSPassThrough()
00241 {
00242     HostCheckBox *gc = new HostCheckBox("DTSPassThru");
00243     gc->setLabel(QObject::tr("Enable DTS to SPDIF passthrough"));
00244     gc->setValue(false);
00245     gc->setHelpText(QObject::tr("Enable sending DTS audio directly to your "
00246                     "sound card's SPDIF output, on sources which contain "
00247                     "DTS soundtracks (usually DVDs).  Requires that the "
00248                     "audio output device be set to something suitable."));
00249     return gc;
00250 }
00251 
00252 static HostCheckBox *DecodeExtraAudio()
00253 {
00254     HostCheckBox *gc = new HostCheckBox("DecodeExtraAudio");
00255     gc->setLabel(QObject::tr("Extra audio buffering"));
00256     gc->setValue(true);
00257     gc->setHelpText(QObject::tr("Enable this setting if MythTV is playing "
00258                     "\"crackly\" audio and you are using hardware encoding. "
00259                     "This setting will have no effect "
00260                     "on MPEG-4 or RTJPEG video. MythTV will keep extra "
00261                     "audio data in its internal buffers to workaround "
00262                     "this bug."));
00263     return gc;
00264 }
00265 
00266 static HostComboBox *PIPLocationComboBox()
00267 {
00268     HostComboBox *gc = new HostComboBox("PIPLocation");
00269     gc->setLabel(QObject::tr("PIP Video Location"));
00270     for (uint loc = 0; loc < kPIP_END; loc++)
00271         gc->addSelection(toString((PIPLocation) loc), QString::number(loc));
00272     gc->setHelpText(QObject::tr("Location of PIP Video window."));
00273     return gc;
00274 }
00275 
00276 static GlobalLineEdit *AllRecGroupPassword()
00277 {
00278     GlobalLineEdit *be = new GlobalLineEdit("AllRecGroupPassword");
00279     be->setLabel(QObject::tr("Password required to view all recordings"));
00280     be->setValue("");
00281     be->setHelpText(QObject::tr("If given, a password must be entered to "
00282                     "view the complete list of all recordings."));
00283     return be;
00284 }
00285 
00286 static HostComboBox *DisplayRecGroup()
00287 {
00288     HostComboBox *gc = new HostComboBox("DisplayRecGroup");
00289     gc->setLabel(QObject::tr("Default group filter to apply"));
00290 
00291     gc->addSelection(QObject::tr("All Programs"), QString("All Programs"));
00292     gc->addSelection(QObject::tr("Default"), QString("Default"));
00293 
00294     MSqlQuery query(MSqlQuery::InitCon());
00295     query.prepare("SELECT DISTINCT recgroup from recorded;");
00296 
00297     if (query.exec() && query.isActive() && query.size() > 0)
00298     {
00299         while (query.next())
00300         {
00301             if (query.value(0).toString() != "Default")
00302             {
00303                 QString recgroup = QString::fromUtf8(query.value(0).toString());
00304                 gc->addSelection(recgroup, recgroup);
00305             }
00306         }
00307     }
00308 
00309     query.prepare("SELECT DISTINCT category from recorded;");
00310 
00311     if (query.exec() && query.isActive() && query.size() > 0)
00312     {
00313         while (query.next())
00314         {
00315             QString key = QString::fromUtf8(query.value(0).toString());
00316             gc->addSelection(key, key);
00317         }
00318     }
00319 
00320     gc->setHelpText(QObject::tr("Default group filter to apply "
00321                     "on the View Recordings screen."));
00322     return gc;
00323 }
00324 
00325 static HostCheckBox *QueryInitialFilter()
00326 {
00327     HostCheckBox *gc = new HostCheckBox("QueryInitialFilter");
00328     gc->setLabel(QObject::tr("Always prompt for initial group filter"));
00329     gc->setValue(false);
00330     gc->setHelpText(QObject::tr("Always prompt the user for the initial filter "
00331                     "to apply when entering the Watch Recordings screen."));
00332 
00333     return gc;
00334 }
00335 
00336 static HostCheckBox *RememberRecGroup()
00337 {
00338     HostCheckBox *gc = new HostCheckBox("RememberRecGroup");
00339     gc->setLabel(QObject::tr("Save current group filter when changed"));
00340     gc->setValue(true);
00341     gc->setHelpText(QObject::tr("Remember the last selected filter "
00342                     "instead of displaying the default filter "
00343                     "whenever you enter the playback screen."));
00344 
00345     return gc;
00346 }
00347 
00348 static HostComboBox *DefaultView()
00349 {
00350     HostComboBox *gc = new HostComboBox("DisplayGroupDefaultView");
00351     gc->setLabel(QObject::tr("Default View"));
00352 
00353     gc->addSelection(QObject::tr("Show Titles only"),
00354             QString::number(PlaybackBox::TitlesOnly));
00355     gc->addSelection(QObject::tr("Show Titles and Categories"),
00356             QString::number(PlaybackBox::TitlesCategories));
00357     gc->addSelection(QObject::tr(
00358                 "Show Titles, Categories, and Recording Groups"),
00359             QString::number(PlaybackBox::TitlesCategoriesRecGroups));
00360     gc->addSelection(QObject::tr("Show Titles and Recording Groups"),
00361             QString::number(PlaybackBox::TitlesRecGroups));
00362     gc->addSelection(QObject::tr("Show Categories only"),
00363             QString::number(PlaybackBox::Categories));
00364     gc->addSelection(QObject::tr("Show Categories and Recording Groups"),
00365             QString::number(PlaybackBox::CategoriesRecGroups));
00366     gc->addSelection(QObject::tr("Show Recording Groups only"),
00367             QString::number(PlaybackBox::RecGroups));
00368 
00369     gc->setHelpText(QObject::tr("Select what type of grouping to show on the "
00370                     "Watch Recordings screen by default."));
00371 
00372     return gc;
00373 }
00374 
00375 static HostCheckBox *UseGroupNameAsAllPrograms()
00376 {
00377     HostCheckBox *gc = new HostCheckBox("DispRecGroupAsAllProg");
00378     gc->setLabel(QObject::tr("Show filter name instead of \"All Programs\""));
00379     gc->setValue(false);
00380     gc->setHelpText(QObject::tr("Use the name of the display filter currently "
00381                     "applied in place of the term \"All Programs\" in the "
00382                     "playback screen."));
00383     return gc;
00384 }
00385 
00386 static HostCheckBox *LiveTVInAllPrograms()
00387 {
00388     HostCheckBox *gc = new HostCheckBox("LiveTVInAllPrograms");
00389     gc->setLabel(QObject::tr("Show 'LiveTV' recordings when using "
00390                              "\"All Programs\" filter"));
00391     gc->setValue(false);
00392     gc->setHelpText(QObject::tr("If this setting is disabled, LiveTV "
00393                     "recordings will only be visible via the special "
00394                     "\"LiveTV\" Recording Group."));
00395     return gc;
00396 }
00397 
00398 static HostCheckBox *PBBStartInTitle()
00399 {
00400     HostCheckBox *gc = new HostCheckBox("PlaybackBoxStartInTitle");
00401     gc->setLabel(QObject::tr("Start in Title section"));
00402     gc->setValue(true);
00403     gc->setHelpText(QObject::tr("If enabled, the selector highlight will "
00404                     "start on the Program titles window, otherwise the "
00405                     "selector will default to the recordings."));
00406     return gc;
00407 }
00408 
00409 static HostCheckBox *PBBShowGroupSummary()
00410 {
00411     HostCheckBox *gc = new HostCheckBox("ShowGroupInfo");
00412     gc->setLabel(QObject::tr("Show group summary"));
00413     gc->setValue(false);
00414     gc->setHelpText(QObject::tr("While selecting a group, show a group "
00415                     "summary instead of showing info about the first episode "
00416                     "in that group."));
00417     return gc;
00418 }
00419 
00420 static HostCheckBox *SmartForward()
00421 {
00422     HostCheckBox *gc = new HostCheckBox("SmartForward");
00423     gc->setLabel(QObject::tr("Smart Fast Forwarding"));
00424     gc->setValue(false);
00425     gc->setHelpText(QObject::tr("If enabled, then immediately after "
00426                     "rewinding, only skip forward the same amount as "
00427                     "skipping backwards."));
00428     return gc;
00429 }
00430 
00431 static HostCheckBox *ExactSeeking()
00432 {
00433     HostCheckBox *gc = new HostCheckBox("ExactSeeking");
00434     gc->setLabel(QObject::tr("Seek to exact frame"));
00435     gc->setValue(false);
00436     gc->setHelpText(QObject::tr("If enabled, seeking is frame exact, but "
00437                     "slower."));
00438     return gc;
00439 }
00440 
00441 static GlobalComboBox *CommercialSkipMethod()
00442 {
00443     GlobalComboBox *bc = new GlobalComboBox("CommercialSkipMethod");
00444     bc->setLabel(QObject::tr("Commercial Skip Method"));
00445 
00446     // need to keep this in sync with libs/libmythtv/channelsettings.cpp
00447     bc->addSelection(QObject::tr("All Available Methods"), "255");
00448     bc->addSelection(QObject::tr("Blank Frame Detection"), "1");
00449     bc->addSelection(QObject::tr("Blank Frame + Scene Change"), "3");
00450     bc->addSelection(QObject::tr("Scene Change Detection"), "2");
00451     bc->addSelection(QObject::tr("Logo Detection"), "4");
00452     bc->addSelection(QObject::tr("Experimental"), "511");
00453     bc->setHelpText(QObject::tr("This determines the method used by MythTV to "
00454                     "detect when commercials start and end."));
00455     return bc;
00456 }
00457 
00458 static HostComboBox *AutoCommercialSkip()
00459 {
00460     HostComboBox *gc = new HostComboBox("AutoCommercialSkip");
00461     gc->setLabel(QObject::tr("Automatically Skip Commercials"));
00462     gc->addSelection(QObject::tr("Off"), "0");
00463     gc->addSelection(QObject::tr("Notify, but do not skip"), "2");
00464     gc->addSelection(QObject::tr("Automatically Skip"), "1");
00465     gc->setHelpText(QObject::tr("Automatically skip commercial breaks that "
00466                     "have been flagged during Automatic Commercial Flagging "
00467                     "or by the mythcommflag program, or just notify that a "
00468                     "commercial has been detected."));
00469     return gc;
00470 }
00471 
00472 static GlobalCheckBox *AutoCommercialFlag()
00473 {
00474     GlobalCheckBox *bc = new GlobalCheckBox("AutoCommercialFlag");
00475     bc->setLabel(QObject::tr("Run commercial flagger"));
00476     bc->setValue(true);
00477     bc->setHelpText(QObject::tr("This is the default value used for the Auto-"
00478                     "Commercial Flagging setting when a new scheduled "
00479                     "recording is created."));
00480     return bc;
00481 }
00482 
00483 static GlobalCheckBox *AutoTranscode()
00484 {
00485     GlobalCheckBox *bc = new GlobalCheckBox("AutoTranscode");
00486     bc->setLabel(QObject::tr("Run transcoder"));
00487     bc->setValue(false);
00488     bc->setHelpText(QObject::tr("This is the default value used for the Auto-"
00489                     "Transcode setting when a new scheduled "
00490                     "recording is created."));
00491     return bc;
00492 }
00493 
00494 static GlobalComboBox *DefaultTranscoder()
00495 {
00496     GlobalComboBox *bc = new GlobalComboBox("DefaultTranscoder");
00497     bc->setLabel(QObject::tr("Default Transcoder"));
00498     RecordingProfile::fillSelections(bc, RecordingProfile::TranscoderGroup,
00499                                      true);
00500     bc->setHelpText(QObject::tr("This is the default value used for the "
00501                     "transcoder setting when a new scheduled "
00502                     "recording is created."));
00503     return bc;
00504 }
00505 
00506 static GlobalSpinBox *DeferAutoTranscodeDays()
00507 {
00508     GlobalSpinBox *gs = new GlobalSpinBox("DeferAutoTranscodeDays", 0, 365, 1);
00509     gs->setLabel(QObject::tr("Deferral days for Auto-Transcode jobs"));
00510     gs->setHelpText(QObject::tr("If non-zero, Auto-Transcode jobs will be "
00511                     "scheduled to run this many days after a recording "
00512                     "completes instead of immediately afterwards."));
00513     gs->setValue(0);
00514     return gs;
00515 }
00516 
00517 static GlobalCheckBox *AutoRunUserJob(uint job_num)
00518 {
00519     QString dbStr = QString("AutoRunUserJob%1").arg(job_num);
00520     QString label = QObject::tr("Run User Job #%1")
00521         .arg(job_num);
00522     GlobalCheckBox *bc = new GlobalCheckBox(dbStr);
00523     bc->setLabel(label);
00524     bc->setValue(false);
00525     bc->setHelpText(QObject::tr("This is the default value used for the "
00526                     "'Run %1' setting when a new scheduled "
00527                     "recording is created.")
00528                     .arg(gContext->GetSetting(QString("UserJobDesc%1")
00529                          .arg(job_num))));
00530     return bc;
00531 }
00532 
00533 static GlobalCheckBox *AggressiveCommDetect()
00534 {
00535     GlobalCheckBox *bc = new GlobalCheckBox("AggressiveCommDetect");
00536     bc->setLabel(QObject::tr("Strict Commercial Detection"));
00537     bc->setValue(true);
00538     bc->setHelpText(QObject::tr("Enable stricter Commercial Detection code.  "
00539                     "Disable if some commercials are not being detected."));
00540     return bc;
00541 }
00542 
00543 static GlobalCheckBox *CommSkipAllBlanks()
00544 {
00545     GlobalCheckBox *bc = new GlobalCheckBox("CommSkipAllBlanks");
00546     bc->setLabel(QObject::tr("Skip blank frames after commercials"));
00547     bc->setValue(true);
00548     bc->setHelpText(QObject::tr("When using Blank Frame Detection and "
00549                     "Auto-Flagging, include blank frames following commercial "
00550                     "breaks as part of the commercial break."));
00551     return bc;
00552 }
00553 
00554 static HostSpinBox *CommRewindAmount()
00555 {
00556     HostSpinBox *gs = new HostSpinBox("CommRewindAmount", 0, 10, 1);
00557     gs->setLabel(QObject::tr("Commercial Skip Auto-Rewind Amount"));
00558     gs->setHelpText(QObject::tr("If set, MythTV will automatically rewind "
00559                     "this many seconds after performing a commercial skip."));
00560     gs->setValue(0);
00561     return gs;
00562 }
00563 
00564 static HostSpinBox *CommNotifyAmount()
00565 {
00566     HostSpinBox *gs = new HostSpinBox("CommNotifyAmount", 0, 10, 1);
00567     gs->setLabel(QObject::tr("Commercial Skip Notify Amount"));
00568     gs->setHelpText(QObject::tr("If set, MythTV will act like a commercial "
00569                     "begins this many seconds early.  This can be useful "
00570                     "when commercial notification is used in place of "
00571                     "automatic skipping."));
00572     gs->setValue(0);
00573     return gs;
00574 }
00575 
00576 static GlobalSpinBox *MaximumCommercialSkip()
00577 {
00578     GlobalSpinBox *bs = new GlobalSpinBox("MaximumCommercialSkip", 0, 3600, 10);
00579     bs->setLabel(QObject::tr("Maximum commercial skip (in seconds)"));
00580     bs->setHelpText(QObject::tr("MythTV will discourage long manual commercial "
00581                     "skips.  Skips which are longer than this will require the "
00582                     "user to hit the SKIP key twice.  Automatic commercial "
00583                     "skipping is not affected by this limit."));
00584     bs->setValue(3600);
00585     return bs;
00586 }
00587 
00588 static GlobalSpinBox *MergeShortCommBreaks()
00589 {
00590     GlobalSpinBox *bs = new GlobalSpinBox("MergeShortCommBreaks", 0, 3600, 5);
00591     bs->setLabel(QObject::tr("Merge short commercial breaks (in seconds)"));
00592     bs->setHelpText(QObject::tr("Treat consecutive commercial breaks shorter "
00593                     "than this as one break when skipping forward. Useful if "
00594                     "you have to skip a few times during breaks. Applies to "
00595                     "automatic skipping as well. Set to 0 to disable."));
00596     bs->setValue(0);
00597     return bs;
00598 }
00599 
00600 static GlobalSpinBox *AutoExpireExtraSpace()
00601 {
00602     GlobalSpinBox *bs = new GlobalSpinBox("AutoExpireExtraSpace", 0, 200, 1);
00603     bs->setLabel(QObject::tr("Extra Disk Space"));
00604     bs->setHelpText(QObject::tr("Extra disk space (in Gigabytes) that you want " 
00605                     "to keep free on the recording file systems beyond what "
00606                     "MythTV requires."));
00607     bs->setValue(1);
00608     return bs;
00609 };
00610 
00611 static GlobalCheckBox *AutoExpireInsteadOfDelete()
00612 {
00613     GlobalCheckBox *cb = new GlobalCheckBox("AutoExpireInsteadOfDelete");
00614     cb->setLabel(QObject::tr("Auto Expire Instead of Delete Recording"));
00615     cb->setValue(false);
00616     cb->setHelpText(QObject::tr("Instead of deleting a recording, "
00617                     "move recording to the 'Deleted' recgroup and turn on "
00618                     "autoexpire."));
00619     return cb;
00620 }
00621 
00622 static GlobalSpinBox *DeletedMaxAge()
00623 {
00624     GlobalSpinBox *bs = new GlobalSpinBox("DeletedMaxAge", 0, 365, 1);
00625     bs->setLabel(QObject::tr("Deleted Max Age"));
00626     bs->setHelpText(QObject::tr("When set to a number greater than zero, "
00627                     "AutoExpire will force expiration of Deleted recordings "
00628                     "when they are this many days old."));
00629     bs->setValue(0);
00630     return bs;
00631 };
00632 
00633 static GlobalCheckBox *DeletedFifoOrder()
00634 {
00635     GlobalCheckBox *cb = new GlobalCheckBox("DeletedFifoOrder");
00636     cb->setLabel(QObject::tr("Expire in deleted order"));
00637     cb->setValue(false);
00638     cb->setHelpText(QObject::tr(
00639                     "Expire Deleted recordings in the order which they were "
00640                     "originally deleted."));
00641     return cb;
00642 };
00643 
00644 class DeletedExpireOptions : public TriggeredConfigurationGroup
00645 {
00646     public:
00647      DeletedExpireOptions() :
00648          TriggeredConfigurationGroup(false, false, false, false)
00649          {
00650              setLabel(QObject::tr("DeletedExpireOptions"));
00651              Setting* enabled = AutoExpireInsteadOfDelete();
00652              addChild(enabled);
00653              setTrigger(enabled);
00654 
00655              HorizontalConfigurationGroup* settings =
00656                  new HorizontalConfigurationGroup(false);
00657              settings->addChild(DeletedFifoOrder());
00658              settings->addChild(DeletedMaxAge());
00659              addTarget("1", settings);
00660 
00661              // show nothing if fillEnabled is off
00662              addTarget("0", new HorizontalConfigurationGroup(true));
00663          };
00664 };
00665 
00666 static GlobalComboBox *AutoExpireMethod()
00667 {
00668     GlobalComboBox *bc = new GlobalComboBox("AutoExpireMethod");
00669     bc->setLabel(QObject::tr("Auto Expire Method"));
00670     bc->addSelection(QObject::tr("Oldest Show First"), "1");
00671     bc->addSelection(QObject::tr("Lowest Priority First"), "2");
00672     bc->addSelection(QObject::tr("Weighted Time/Priority Combination"), "3");
00673     bc->setHelpText(QObject::tr("Method used to determine which recorded "
00674                     "shows to delete first.  LiveTV recordings will always "
00675                     "expire before normal recordings."));
00676     bc->setValue(1);
00677     return bc;
00678 }
00679 
00680 static GlobalCheckBox *AutoExpireWatchedPriority() 
00681 {
00682     GlobalCheckBox *bc = new GlobalCheckBox("AutoExpireWatchedPriority"); 
00683     bc->setLabel(QObject::tr("Watched before UNwatched")); 
00684     bc->setValue(false); 
00685     bc->setHelpText(QObject::tr("If set, programs that have been marked as "
00686                     "watched will be expired before programs that have not "
00687                     "been watched."));
00688     return bc;
00689 }
00690 
00691 static GlobalSpinBox *AutoExpireDayPriority()
00692 {
00693     GlobalSpinBox *bs = new GlobalSpinBox("AutoExpireDayPriority", 1, 400, 1);
00694     bs->setLabel(QObject::tr("Priority Weight"));
00695     bs->setHelpText(QObject::tr("The number of days bonus a program gets for "
00696                     "each priority point. This is only used when the Weighted "
00697                     "Time/Priority Auto Expire Method is selected."));
00698     bs->setValue(3);
00699     return bs;
00700 };
00701 
00702 static GlobalCheckBox *AutoExpireDefault()
00703 {
00704     GlobalCheckBox *bc = new GlobalCheckBox("AutoExpireDefault");
00705     bc->setLabel(QObject::tr("Auto Expire Default"));
00706     bc->setValue(true);
00707     bc->setHelpText(QObject::tr("When enabled, any new recording schedules "
00708                     "will be marked as eligible for Auto-Expiration. "
00709                     "Existing schedules will keep their current value."));
00710     return bc;
00711 }
00712 
00713 static GlobalSpinBox *AutoExpireLiveTVMaxAge()
00714 {
00715     GlobalSpinBox *bs = new GlobalSpinBox("AutoExpireLiveTVMaxAge", 1, 365, 1);
00716     bs->setLabel(QObject::tr("LiveTV Max Age"));
00717     bs->setHelpText(QObject::tr("AutoExpire will force expiration of LiveTV "
00718                     "recordings when they are this many days old. LiveTV "
00719                     "recordings may also be expired early if necessary to "
00720                     "free up disk space."));
00721     bs->setValue(1);
00722     return bs;
00723 };
00724 
00725 #if 0
00726 static GlobalSpinBox *MinRecordDiskThreshold()
00727 {
00728     GlobalSpinBox *bs = new GlobalSpinBox("MinRecordDiskThreshold",
00729                                             0, 1000000, 100);
00730     bs->setLabel(QObject::tr("New Recording Free Disk Space Threshold "
00731                  "(in Megabytes)"));
00732     bs->setHelpText(QObject::tr("MythTV will stop scheduling new recordings on "
00733                     "a backend when its free disk space falls below this "
00734                     "value."));
00735     bs->setValue(300);
00736     return bs;
00737 }
00738 #endif
00739 
00740 static GlobalCheckBox *RerecordWatched() 
00741 {
00742     GlobalCheckBox *bc = new GlobalCheckBox("RerecordWatched"); 
00743     bc->setLabel(QObject::tr("Re-record Watched")); 
00744     bc->setValue(true); 
00745     bc->setHelpText(QObject::tr("If set, programs that have been marked as "
00746                     "watched and are auto-expired will be re-recorded if "
00747                     "they are shown again."));
00748     return bc;
00749 }
00750 
00751 static GlobalSpinBox *RecordPreRoll()
00752 {
00753     GlobalSpinBox *bs = new GlobalSpinBox("RecordPreRoll", 0, 600, 60, true);
00754     bs->setLabel(QObject::tr("Time to record before start of show "
00755                  "(in seconds)"));
00756     bs->setHelpText(QObject::tr("This global setting allows the recorder "
00757                     "to start before the scheduled start time. It does "
00758                     "not affect the scheduler. It is ignored when two shows "
00759                     "have been scheduled without enough time in between."));
00760     bs->setValue(0);
00761     return bs;
00762 }
00763 
00764 static GlobalSpinBox *RecordOverTime()
00765 {
00766     GlobalSpinBox *bs = new GlobalSpinBox("RecordOverTime", 0, 1800, 60, true);
00767     bs->setLabel(QObject::tr("Time to record past end of show (in seconds)"));
00768     bs->setValue(0);
00769     bs->setHelpText(QObject::tr("This global setting allows the recorder "
00770                     "to record beyond the scheduled end time. It does "
00771                     "not affect the scheduler. It is ignored when two shows "
00772                     "have been scheduled without enough time in between."));
00773     return bs;
00774 }
00775 
00776 static GlobalLineEdit *OverTimeCategory()
00777 {
00778     GlobalLineEdit *ge = new GlobalLineEdit("OverTimeCategory");
00779     ge->setLabel(QObject::tr("Category of shows to be extended"));
00780     ge->setValue(QObject::tr("category name"));
00781     ge->setHelpText(QObject::tr("For a specific category (e.g. "
00782                     "\"Sports event\"), request that shows be autoextended. "
00783                     "Only works if a show's category can be determined."));
00784     return ge;
00785 }
00786 
00787 static GlobalSpinBox *CategoryOverTime()
00788 {
00789     GlobalSpinBox *bs = new GlobalSpinBox("CategoryOverTime",
00790                                           0, 180, 60, true);
00791     bs->setLabel(QObject::tr("Record past end of show (in minutes)"));
00792     bs->setValue(30);
00793     bs->setHelpText(QObject::tr("For the specified category, an attempt "
00794                     "will be made to extend the recording by the specified "
00795                     "time.  It is ignored when two shows have been scheduled "
00796                     "without enough time in between."));
00797     return bs;
00798 }
00799 
00800 static VerticalConfigurationGroup *CategoryOverTimeSettings()
00801 {
00802     VerticalConfigurationGroup *vcg =
00803         new VerticalConfigurationGroup(false, false);
00804 
00805     vcg->setLabel(QObject::tr("Category record over-time"));
00806     vcg->setUseLabel(true);
00807     vcg->addChild(OverTimeCategory());
00808     vcg->addChild(CategoryOverTime());
00809     return vcg;
00810 }
00811 
00812 static QString trunc(const QString &str, uint len)
00813 {
00814     if (str.length() > len)
00815         return str.mid(0, len - 5) + " . . . ";
00816     return str;
00817 }
00818 
00819 static QString pad(const QString &str, uint len)
00820 {
00821     QString tmp = str;
00822 
00823     while (tmp.length() + 4 < len)
00824         tmp += "    ";
00825 
00826     while (tmp.length() < len)
00827         tmp += " ";
00828 
00829     return tmp;
00830 }
00831 
00832 PlaybackProfileItemConfig::PlaybackProfileItemConfig(ProfileItem &_item) :
00833     item(_item)
00834 {
00835     setLabel(QObject::tr("Profile Item"));
00836 
00837     HorizontalConfigurationGroup *row[2];
00838 
00839     row[0]    = new HorizontalConfigurationGroup(false, false, true, true);
00840     cmp[0]    = new TransComboBoxSetting();
00841     width[0]  = new TransSpinBoxSetting(0, 1920, 64, true);
00842     height[0] = new TransSpinBoxSetting(0, 1088, 64, true);
00843     row[1]    = new HorizontalConfigurationGroup(false, false, true, true);
00844     cmp[1]    = new TransComboBoxSetting();
00845     width[1]  = new TransSpinBoxSetting(0, 1920, 64, true);
00846     height[1] = new TransSpinBoxSetting(0, 1088, 64, true);
00847     decoder   = new TransComboBoxSetting();
00848     max_cpus  = new TransSpinBoxSetting(1, ENABLE_THREADS ? 4 : 1, 1, true);
00849     vidrend   = new TransComboBoxSetting();
00850     osdrend   = new TransComboBoxSetting();
00851     osdfade   = new TransCheckBoxSetting();
00852     deint0    = new TransComboBoxSetting();
00853     deint1    = new TransComboBoxSetting();
00854     filters   = new TransLineEditSetting(true);
00855 
00856     for (uint i = 0; i < 2; i++)
00857     {
00858         const QString kCMP[6] = { "", "<", "<=", "==", ">=", ">" };
00859         for (uint j = 0; j < 6; j++)
00860             cmp[i]->addSelection(kCMP[j]);
00861 
00862         cmp[i]->setLabel(tr("Match Criteria"));
00863         width[i]->setName(QString("w%1").arg(i));
00864         width[i]->setLabel(tr("W"));
00865         height[i]->setName(QString("h%1").arg(i));
00866         height[i]->setLabel(tr("H"));
00867 
00868         row[i]->addChild(cmp[i]);
00869         row[i]->addChild(width[i]);
00870         row[i]->addChild(height[i]);
00871     }
00872 
00873     HorizontalConfigurationGroup *vid_row =
00874         new HorizontalConfigurationGroup(false, false, true, true);
00875     HorizontalConfigurationGroup *osd_row =
00876         new HorizontalConfigurationGroup(false, false, true, true);
00877 
00878     decoder->setLabel(tr("Decoder"));
00879     max_cpus->setLabel(tr("Max CPUs"));
00880     vidrend->setLabel(tr("Video Renderer"));
00881     osdrend->setLabel(tr("OSD Renderer"));
00882     osdfade->setLabel(tr("OSD Fade"));
00883     deint0->setLabel(tr("Primary Deinterlacer"));
00884     deint1->setLabel(tr("Fallback Deinterlacer"));
00885     filters->setLabel(tr("Custom Filters"));
00886 
00887     max_cpus->setHelpText(
00888         tr("Maximum number of CPU cores used for decoding.") +
00889         (ENABLE_THREADS ? "" :
00890          tr(" Multithreaded decoding disabled-only one CPU "
00891             "will be used, please recompile with "
00892             "--enable-ffmpeg-pthreads to enable.")));
00893 
00894     filters->setHelpText(
00895         QObject::tr("Example Custom filter list: 'ivtc,denoise3d'"));
00896 
00897     osdfade->setHelpText(
00898         tr("When unchecked the OSD will not fade away but instead "
00899            "will disappear abruptly.") + "\n" +
00900         tr("Uncheck this if the video studders while the OSD is "
00901            "fading away."));
00902 
00903     vid_row->addChild(decoder);
00904     vid_row->addChild(max_cpus);
00905 
00906     osd_row->addChild(vidrend);
00907     osd_row->addChild(osdrend);
00908     osd_row->addChild(osdfade);
00909 
00910     VerticalConfigurationGroup *grp =
00911         new VerticalConfigurationGroup(false, false, true, true);
00912     grp->addChild(row[0]);
00913     grp->addChild(row[1]);
00914     grp->addChild(vid_row);
00915     grp->addChild(osd_row);
00916     addChild(grp);
00917 
00918     VerticalConfigurationGroup *page2 =
00919         new VerticalConfigurationGroup(false, false, true, true);
00920     page2->addChild(deint0);
00921     page2->addChild(deint1);
00922     page2->addChild(filters);
00923     addChild(page2);
00924 
00925     connect(decoder, SIGNAL(valueChanged(const QString&)),
00926             this,    SLOT(decoderChanged(const QString&)));\
00927     connect(vidrend, SIGNAL(valueChanged(const QString&)),
00928             this,    SLOT(vrenderChanged(const QString&)));
00929     connect(osdrend, SIGNAL(valueChanged(const QString&)),
00930             this,    SLOT(orenderChanged(const QString&)));
00931     connect(deint0, SIGNAL(valueChanged(const QString&)),
00932             this,    SLOT(deint0Changed(const QString&)));
00933     connect(deint1, SIGNAL(valueChanged(const QString&)),
00934             this,    SLOT(deint1Changed(const QString&)));
00935 }
00936 
00937 void PlaybackProfileItemConfig::load(void)
00938 {
00939     for (uint i = 0; i < 2; i++)
00940     {
00941         QString     pcmp  = item.Get(QString("pref_cmp%1").arg(i));
00942         QStringList clist = QStringList::split(" ", pcmp);
00943 
00944         if (clist.size() == 0)
00945             clist<<((i) ? "" : ">");
00946         if (clist.size() == 1)
00947             clist<<"0";
00948         if (clist.size() == 2)
00949             clist<<"0";
00950 
00951         cmp[i]->setValue(clist[0]);
00952         width[i]->setValue(clist[1].toInt());
00953         height[i]->setValue(clist[2].toInt());
00954     }
00955 
00956     QString pdecoder  = item.Get("pref_decoder");
00957     QString pmax_cpus = item.Get("pref_max_cpus");
00958     QString prenderer = item.Get("pref_videorenderer");
00959     QString posd      = item.Get("pref_osdrenderer");
00960     QString posdfade  = item.Get("pref_osdfade");
00961     QString pdeint0   = item.Get("pref_deint0");
00962     QString pdeint1   = item.Get("pref_deint1");
00963     QString pfilter   = item.Get("pref_filters");
00964     bool    found     = false;
00965 
00966     QString     dech = VideoDisplayProfile::GetDecoderHelp();
00967     QStringList decr = VideoDisplayProfile::GetDecoders();
00968     QStringList decn = VideoDisplayProfile::GetDecoderNames();
00969     QStringList::const_iterator itr = decr.begin();
00970     QStringList::const_iterator itn = decn.begin();
00971     for (; (itr != decr.end()) && (itn != decn.end()); itr++, itn++)
00972     {
00973         decoder->addSelection(*itn, *itr, (*itr == pdecoder));
00974         found |= (*itr == pdecoder);
00975     }
00976     if (!found && !pdecoder.isEmpty())
00977     {
00978         decoder->SelectSetting::addSelection(
00979             VideoDisplayProfile::GetDecoderName(pdecoder), pdecoder, true);
00980     }
00981     decoder->setHelpText(VideoDisplayProfile::GetDecoderHelp(pdecoder));
00982 
00983     if (!pmax_cpus.isEmpty())
00984         max_cpus->setValue(pmax_cpus.toUInt());
00985     if (!prenderer.isEmpty())
00986         vidrend->setValue(prenderer);
00987     if (!posd.isEmpty())
00988         osdrend->setValue(posd);
00989 
00990     osdfade->setValue((!posdfade.isEmpty()) ? (bool) posdfade.toInt() : true);
00991 
00992     if (!pdeint0.isEmpty())
00993         deint0->setValue(pdeint0);
00994     if (!pdeint1.isEmpty())
00995         deint1->setValue(pdeint1);
00996     if (!pfilter.isEmpty())
00997         filters->setValue(pfilter);
00998 }
00999 
01000 void PlaybackProfileItemConfig::save(void)
01001 {
01002     for (uint i = 0; i < 2; i++)
01003     {
01004         QString val = QString("pref_cmp%1").arg(i);
01005         QString data = "";
01006         if (!cmp[i]->getValue().isEmpty())
01007         {
01008             data = QString("%1 %2 %3")
01009                 .arg(cmp[i]->getValue())
01010                 .arg(width[i]->intValue())
01011                 .arg(height[i]->intValue());
01012         }
01013         item.Set(val, data);
01014     }
01015 
01016     item.Set("pref_decoder",       decoder->getValue());
01017     item.Set("pref_max_cpus",      max_cpus->getValue());
01018     item.Set("pref_videorenderer", vidrend->getValue());
01019     item.Set("pref_osdrenderer",   osdrend->getValue());
01020     item.Set("pref_osdfade",       (osdfade->boolValue()) ? "1" : "0");
01021     item.Set("pref_deint0",        deint0->getValue());
01022     item.Set("pref_deint1",        deint1->getValue());
01023 
01024     QString tmp0 = filters->getValue();
01025     QString tmp1 = vidrend->getValue();
01026     QString tmp3 = VideoDisplayProfile::IsFilterAllowed(tmp1) ? tmp0 : "";
01027     item.Set("pref_filters", tmp3);
01028 }
01029 
01030 void PlaybackProfileItemConfig::decoderChanged(const QString &dec)
01031 {
01032     QString     vrenderer = vidrend->getValue();
01033     QStringList renderers = VideoDisplayProfile::GetVideoRenderers(dec);
01034     QStringList::const_iterator it;
01035 
01036     QString prenderer = QString::null;
01037     for (it = renderers.begin(); it != renderers.end(); it++)
01038         prenderer = (*it == vrenderer) ? vrenderer : prenderer;
01039     if (prenderer.isEmpty())
01040         prenderer = VideoDisplayProfile::GetPreferredVideoRenderer(dec);
01041 
01042     vidrend->clearSelections();
01043     for (it = renderers.begin(); it != renderers.end(); it++)
01044     {
01045         if (*it != "null")
01046             vidrend->addSelection(*it, *it, (*it == prenderer));
01047     }
01048 
01049     decoder->setHelpText(VideoDisplayProfile::GetDecoderHelp(dec));
01050 }
01051 
01052 void PlaybackProfileItemConfig::vrenderChanged(const QString &renderer)
01053 {
01054     QStringList osds    = VideoDisplayProfile::GetOSDs(renderer);
01055     QStringList deints  = VideoDisplayProfile::GetDeinterlacers(renderer);
01056     QString     losd    = osdrend->getValue();
01057     QString     ldeint0 = deint0->getValue();
01058     QString     ldeint1 = deint1->getValue();
01059     QStringList::const_iterator it;
01060 
01061     osdrend->clearSelections();
01062     for (it = osds.begin(); it != osds.end(); it++)
01063         osdrend->addSelection(*it, *it, (*it == losd));
01064 
01065     deint0->clearSelections();
01066     for (it = deints.begin(); it != deints.end(); it++)
01067     {
01068         deint0->addSelection(VideoDisplayProfile::GetDeinterlacerName(*it),
01069                              *it, (*it == ldeint0));
01070     }
01071 
01072     deint1->clearSelections();
01073     for (it = deints.begin(); it != deints.end(); it++)
01074     {
01075         if (!(*it).contains("bobdeint") && !(*it).contains("doublerate"))
01076             deint1->addSelection(VideoDisplayProfile::GetDeinterlacerName(*it),
01077                                  *it, (*it == ldeint1));
01078     }
01079 
01080     filters->setEnabled(VideoDisplayProfile::IsFilterAllowed(renderer));
01081     vidrend->setHelpText(VideoDisplayProfile::GetVideoRendererHelp(renderer));
01082 }
01083 
01084 void PlaybackProfileItemConfig::orenderChanged(const QString &renderer)
01085 {
01086     osdrend->setHelpText(VideoDisplayProfile::GetOSDHelp(renderer));
01087 }
01088 
01089 void PlaybackProfileItemConfig::deint0Changed(const QString &deint)
01090 {
01091     deint0->setHelpText(
01092         QObject::tr("Main deinterlacing method.") + " " +
01093         VideoDisplayProfile::GetDeinterlacerHelp(deint));
01094 }
01095 
01096 void PlaybackProfileItemConfig::deint1Changed(const QString &deint)
01097 {
01098     deint1->setHelpText(
01099         QObject::tr("Fallback deinterlacing method.") + " " +
01100         VideoDisplayProfile::GetDeinterlacerHelp(deint));
01101 }
01102 
01103 PlaybackProfileConfig::PlaybackProfileConfig(const QString &profilename) :
01104     VerticalConfigurationGroup(false, false, true, true),
01105     profile_name(profilename), needs_save(false),
01106     groupid(0), last_main(NULL)
01107 {
01108     groupid = VideoDisplayProfile::GetProfileGroupID(
01109         profilename, gContext->GetHostName());
01110 
01111     items = VideoDisplayProfile::LoadDB(groupid);
01112 
01113     InitUI();
01114 }
01115 
01116 PlaybackProfileConfig::~PlaybackProfileConfig()
01117 {
01118 }
01119 
01120 void PlaybackProfileConfig::InitLabel(uint i)
01121 {
01122     if (!labels[i])
01123         return;
01124 
01125     QString andStr = QObject::tr("&", "and");
01126     QString cmp0   = items[i].Get("pref_cmp0");
01127     QString cmp1   = items[i].Get("pref_cmp1");
01128     QString str    = QObject::tr("if rez") + " " + cmp0;
01129 
01130     if (!cmp1.isEmpty())
01131         str += " " + andStr + " " + cmp1;
01132 
01133     str += " -> ";
01134     str += items[i].Get("pref_decoder");
01135     str += " " + andStr + " ";
01136     str += items[i].Get("pref_videorenderer");
01137     str.replace("-blit", "");
01138     str.replace("ivtv " + andStr + " ivtv", "ivtv");
01139     str.replace("xvmc " + andStr + " xvmc", "xvmc");
01140     str.replace("xvmc", "XvMC");
01141     str.replace("xv", "XVideo");
01142 
01143     labels[i]->setValue(pad(trunc(str, 48), 48));
01144 }
01145 
01146 void PlaybackProfileConfig::InitUI(void)
01147 {
01148     VerticalConfigurationGroup *main =
01149         new VerticalConfigurationGroup(false, false, true, true);
01150 
01151     HorizontalConfigurationGroup *rows =
01152         new HorizontalConfigurationGroup(false, false, true, true);
01153     VerticalConfigurationGroup *column1 =
01154         new VerticalConfigurationGroup(false, false, true, true);
01155     VerticalConfigurationGroup *column2 =
01156         new VerticalConfigurationGroup(false, false, true, true);
01157 
01158     labels.resize(items.size());
01159 
01160     for (uint i = 0; i < items.size(); i++)
01161     {
01162         labels[i] = new TransLabelSetting();
01163         InitLabel(i);
01164         column1->addChild(labels[i]);
01165     }
01166 
01167     editProf.resize(items.size());
01168     delProf.resize(items.size());
01169     priority.resize(items.size());
01170 
01171     for (uint i = 0; i < items.size(); i++)
01172     {
01173         HorizontalConfigurationGroup *grp =
01174             new HorizontalConfigurationGroup(false, false, true, true);
01175 
01176         editProf[i] = new TransButtonSetting(QString("edit%1").arg(i));
01177         delProf[i]  = new TransButtonSetting(QString("del%1").arg(i));
01178         priority[i] = new TransSpinBoxSetting(1, items.size(), 1);
01179         priority[i]->setName(QString("pri%1").arg(i));
01180 
01181         editProf[i]->setLabel(QObject::tr("Edit"));
01182         delProf[i]->setLabel(QObject::tr("Delete"));
01183         priority[i]->setValue(i + 1);
01184         items[i].Set("pref_priority", QString::number(i + 1));
01185 
01186         grp->addChild(editProf[i]);
01187         grp->addChild(delProf[i]);
01188         grp->addChild(priority[i]);
01189 
01190         connect(editProf[i], SIGNAL(pressed(QString)),
01191                 this,        SLOT  (pressed(QString)));
01192         connect(delProf[i],  SIGNAL(pressed(QString)),
01193                 this,        SLOT  (pressed(QString)));
01194         connect(priority[i], SIGNAL(valueChanged(   const QString&, int)),
01195                 this,        SLOT(  priorityChanged(const QString&, int)));
01196 
01197         column2->addChild(grp);
01198     }
01199 
01200     rows->addChild(column1);
01201     rows->addChild(column2);
01202 
01203     TransButtonSetting *addEntry = new TransButtonSetting("addentry");
01204     addEntry->setLabel(QObject::tr("Add New Entry"));
01205 
01206     main->addChild(rows);
01207     main->addChild(addEntry);
01208 
01209     connect(addEntry, SIGNAL(pressed(QString)),
01210             this,     SLOT  (pressed(QString)));
01211 
01212     if (last_main)
01213         replaceChild(last_main, main);
01214     else
01215         addChild(main);
01216 
01217     last_main = main;
01218 }
01219 
01220 void PlaybackProfileConfig::load(void)
01221 {
01222     // Already loaded data in constructor...
01223 }
01224 
01225 void PlaybackProfileConfig::save(void)
01226 {
01227     if (!needs_save)
01228         return; // nothing to do..
01229 
01230     bool ok = VideoDisplayProfile::DeleteDB(groupid, del_items);
01231     if (!ok)
01232     {
01233         VERBOSE(VB_IMPORTANT,
01234                 "PlaybackProfileConfig::save() -- failed to delete items");
01235         return;
01236     }
01237 
01238     ok = VideoDisplayProfile::SaveDB(groupid, items);
01239     if (!ok)
01240     {
01241         VERBOSE(VB_IMPORTANT,
01242                 "PlaybackProfileConfig::save() -- failed to save items");
01243         return;
01244     }
01245 }
01246 
01247 void PlaybackProfileConfig::pressed(QString cmd)
01248 {
01249     if (cmd.left(4) == "edit")
01250     {
01251         uint i = cmd.mid(4).toUInt();
01252         PlaybackProfileItemConfig itemcfg(items[i]);
01253 
01254         if (itemcfg.exec() != QDialog::Accepted)
01255             VERBOSE(VB_IMPORTANT, QString("edit #%1").arg(i) + " rejected");
01256 
01257         InitLabel(i);
01258         needs_save = true;
01259     }
01260     else if (cmd.left(3) == "del")
01261     {
01262         uint i = cmd.mid(3).toUInt();
01263         del_items.push_back(items[i]);
01264         items.erase(items.begin() + i);
01265 
01266         InitUI();
01267         needs_save = true;
01268     }
01269     else if (cmd == "addentry")
01270     {
01271         ProfileItem item;
01272         PlaybackProfileItemConfig itemcfg(item);
01273 
01274         if (itemcfg.exec() != QDialog::Accepted)
01275             VERBOSE(VB_IMPORTANT, "addentry rejected");
01276 
01277         items.push_back(item);
01278         InitUI();
01279         needs_save = true;        
01280     }
01281 
01282     repaint();
01283 }
01284 
01285 void PlaybackProfileConfig::priorityChanged(const QString &name, int val)
01286 {
01287     uint i = name.mid(3).toInt();
01288     uint j = i;
01289 
01290     priority[i]->SetRelayEnabled(false);
01291 
01292     if (((int)items[i].GetPriority() < val) &&
01293         (i + 1 < priority.size())           &&
01294         ((int)items[i+1].GetPriority() == val))
01295     {
01296         j++;
01297         priority[j]->SetRelayEnabled(false);
01298 
01299         swap(i, j);
01300         priority[j]->setFocus();
01301     }
01302     else if (((int)items[i].GetPriority() > val) &&
01303              (i > 0) &&
01304              ((int)items[i-1].GetPriority() == val))
01305     {
01306         j--;
01307         priority[j]->SetRelayEnabled(false);
01308 
01309         swap(i, j);
01310 
01311         priority[j]->setFocus();
01312     }
01313     else
01314     {
01315         priority[i]->setValue((int) items[i].GetPriority());
01316     }
01317 
01318     needs_save = true;
01319 
01320     repaint();
01321 
01322     priority[i]->SetRelayEnabled(true);
01323     if (i != j)
01324         priority[j]->SetRelayEnabled(true);
01325 }
01326 
01327 void PlaybackProfileConfig::swap(int i, int j)
01328 {
01329     int pri_i = items[i].GetPriority();
01330     int pri_j = items[j].GetPriority();
01331 
01332     ProfileItem item = items[j];
01333     items[j] = items[i];
01334     items[i] = item;
01335 
01336     priority[i]->setValue(pri_i);
01337     priority[j]->setValue(pri_j);
01338 
01339     items[i].Set("pref_priority", QString::number(pri_i));
01340     items[j].Set("pref_priority", QString::number(pri_j));
01341 
01342     const QString label_i = labels[i]->getValue();
01343     const QString label_j = labels[j]->getValue();
01344     labels[i]->setValue(label_j);
01345     labels[j]->setValue(label_i);
01346 }
01347 
01348 PlaybackProfileConfigs::PlaybackProfileConfigs(const QString &str) :
01349     TriggeredConfigurationGroup(false, true,  true, true,
01350                                 false, false, true, true), grouptrigger(NULL)
01351 {
01352     setLabel(QObject::tr("Playback Profiles") + str);
01353 
01354     QString host = gContext->GetHostName();
01355     QStringList profiles = VideoDisplayProfile::GetProfiles(host);
01356     if (profiles.empty())
01357     {
01358         VideoDisplayProfile::CreateProfiles(host);
01359         profiles = VideoDisplayProfile::GetProfiles(host);
01360     }
01361     if (profiles.empty())
01362         return;
01363 
01364     if (!profiles.contains("Normal") &&
01365         !profiles.contains("High Quality") &&
01366         !profiles.contains("Slim"))
01367     {
01368         VideoDisplayProfile::CreateNewProfiles(host);
01369         profiles = VideoDisplayProfile::GetProfiles(host);
01370     }
01371 
01372     QString profile = VideoDisplayProfile::GetDefaultProfileName(host);
01373     if (!profiles.contains(profile))
01374     {
01375         profile = (profiles.contains("Normal")) ? "Normal" : profiles[0];
01376         VideoDisplayProfile::SetDefaultProfileName(profile, host);
01377     }
01378 
01379     grouptrigger = new HostComboBox("DefaultVideoPlaybackProfile");
01380     grouptrigger->setLabel(QObject::tr("Current Video Playback Profile"));
01381     QStringList::const_iterator it;
01382     for (it = profiles.begin(); it != profiles.end(); it++)
01383         grouptrigger->addSelection(QObject::tr(*it), *it);
01384 
01385     HorizontalConfigurationGroup *grp =
01386         new HorizontalConfigurationGroup(false, false, true, true);
01387     TransButtonSetting *addProf = new TransButtonSetting("add");
01388     TransButtonSetting *delProf = new TransButtonSetting("del");
01389 
01390     addProf->setLabel(QObject::tr("Add New"));
01391     delProf->setLabel(QObject::tr("Delete"));
01392 
01393     grp->addChild(grouptrigger);
01394     grp->addChild(addProf);
01395     grp->addChild(delProf);
01396 
01397     addChild(grp);
01398 
01399     setTrigger(grouptrigger);
01400     for (it = profiles.begin(); it != profiles.end(); ++it)
01401         addTarget(*it, new PlaybackProfileConfig(*it));
01402     setSaveAll(true);
01403 
01404     connect(addProf, SIGNAL(pressed( QString)),
01405             this,    SLOT  (btnPress(QString)));
01406     connect(delProf, SIGNAL(pressed( QString)),
01407             this,    SLOT  (btnPress(QString)));
01408 }
01409 
01410 PlaybackProfileConfigs::~PlaybackProfileConfigs()
01411 {
01412     //VERBOSE(VB_IMPORTANT, "~PlaybackProfileConfigs()");
01413 }
01414 
01415 void PlaybackProfileConfigs::btnPress(QString cmd)
01416 {
01417     if (cmd == "add")
01418     {
01419         QString name = QString::null;
01420 
01421         QString host = gContext->GetHostName();
01422         QStringList not_ok_list = VideoDisplayProfile::GetProfiles(host);
01423 
01424         bool ok = true;
01425         while (ok)
01426         {
01427             QString msg = QObject::tr("Enter Playback Group Name");
01428 
01429             ok = MythPopupBox::showGetTextPopup(
01430                 gContext->GetMainWindow(), msg, msg, name);
01431 
01432             if (!ok)
01433                 return;
01434 
01435             if (not_ok_list.contains(name) || name.isEmpty())
01436             {
01437                 msg = (name.isEmpty()) ?
01438                     QObject::tr(
01439                         "Sorry, playback group\nname can not be blank.") :
01440                     QObject::tr(
01441                         "Sorry, playback group name\n"
01442                         "'%1' is already being used.").arg(name);
01443 
01444                 MythPopupBox::showOkPopup(
01445                     gContext->GetMainWindow(), QObject::tr("Error"), msg);
01446 
01447                 continue;
01448             }
01449 
01450             break;
01451         }
01452 
01453         VideoDisplayProfile::CreateProfileGroup(name, gContext->GetHostName());
01454         addTarget(name, new PlaybackProfileConfig(name));
01455 
01456         if (grouptrigger)
01457             grouptrigger->addSelection(name, name, true);
01458     }
01459     else if ((cmd == "del") && grouptrigger)
01460     {
01461         const QString name = grouptrigger->getSelectionLabel();
01462         if (!name.isEmpty())
01463         {
01464             removeTarget(name);
01465             VideoDisplayProfile::DeleteProfileGroup(
01466                 name, gContext->GetHostName());
01467         }
01468     }
01469 
01470     repaint();
01471 }
01472 
01473 void PlaybackProfileConfigs::triggerChanged(const QString &trig)
01474 {
01475     TriggeredConfigurationGroup::triggerChanged(trig);
01476 }
01477 
01478 static HostComboBox *PlayBoxOrdering()
01479 {
01480     QString str[4] =
01481     {
01482         QObject::tr("Sort all sub-titles/multi-titles Ascending"),
01483         QObject::tr("Sort all sub-titles/multi-titles Descending"),
01484         QObject::tr("Sort sub-titles Descending, multi-titles Ascending"),
01485         QObject::tr("Sort sub-titles Ascending, multi-titles Descending"),
01486     };
01487     QString help = QObject::tr(
01488         "Selects how to sort show episodes. Sub-titles refers to the "
01489         "episodes listed under a specific show title. Multi-title "
01490         "refers to sections (e.g. \"All Programs\") which list "
01491         "multiple titles. Sections in parentheses are not affected.");
01492 
01493     HostComboBox *gc = new HostComboBox("PlayBoxOrdering");
01494     gc->setLabel(QObject::tr("Episode sort orderings"));
01495 
01496     for (int i = 0; i < 4; i++)
01497         gc->addSelection(str[i], QString::number(i));
01498 
01499     gc->setValue(1);
01500     gc->setHelpText(help);
01501 
01502     return gc;
01503 }
01504 
01505 static HostComboBox *PlayBoxEpisodeSort()
01506 {
01507     HostComboBox *gc = new HostComboBox("PlayBoxEpisodeSort");
01508     gc->setLabel(QObject::tr("Sort Episodes"));
01509     gc->addSelection(QObject::tr("Record date"), "Date");
01510     gc->addSelection(QObject::tr("Original Air date"), "OrigAirDate");
01511     gc->addSelection(QObject::tr("Program ID"), "Id");
01512     gc->setHelpText(QObject::tr("Selects how to sort a shows episodes"));
01513     return gc;
01514 }
01515 
01516 static HostCheckBox *StickyKeys()
01517 {
01518     HostCheckBox *gc = new HostCheckBox("StickyKeys");
01519     gc->setLabel(QObject::tr("Sticky keys"));
01520     gc->setValue(false);
01521     gc->setHelpText(QObject::tr("If enabled, fast forward and rewind "
01522                     "continue after the key is released.  Pressing the key "
01523                     "again increases the fast forward or rewind speed.  The "
01524                     "alternate fast forward and rewind keys always behave in "
01525                     "this way."));
01526     return gc;
01527 }
01528 
01529 static HostSpinBox *FFRewReposTime()
01530 {
01531     HostSpinBox *gs = new HostSpinBox("FFRewReposTime", 0, 200, 5);
01532     gs->setLabel(QObject::tr("Fast forward/rewind reposition amount"));
01533     gs->setValue(100);
01534     gs->setHelpText(QObject::tr("When exiting sticky keys fast forward/rewind "
01535                     "mode, reposition this many 1/100th seconds before "
01536                     "resuming normal playback. This "
01537                     "compensates for the reaction time between seeing "
01538                     "where to resume playback and actually exiting seeking."));
01539     return gs;
01540 }
01541 
01542 static HostCheckBox *FFRewReverse()
01543 {
01544     HostCheckBox *gc = new HostCheckBox("FFRewReverse");
01545     gc->setLabel(QObject::tr("Reverse direction in fast forward/rewind"));
01546     gc->setValue(true);
01547     gc->setHelpText(QObject::tr("If enabled, pressing the sticky rewind key "
01548                     "in fast forward mode switches to rewind mode, and "
01549                     "vice versa.  If disabled, it will decrease the "
01550                     "current speed or switch to play mode if "
01551                     "the speed can't be decreased further."));
01552     return gc; 
01553 }
01554 
01555 static HostSpinBox *OSDGeneralTimeout()
01556 {
01557     HostSpinBox *gs = new HostSpinBox("OSDGeneralTimeout", 1, 30, 1);
01558     gs->setLabel(QObject::tr("General OSD time-out (sec)"));
01559     gs->setValue(2);
01560     gs->setHelpText(QObject::tr("Length of time an on-screen display "
01561                     "window will be visible."));
01562     return gs;
01563 }
01564 
01565 static HostSpinBox *OSDProgramInfoTimeout()
01566 {
01567     HostSpinBox *gs = new HostSpinBox("OSDProgramInfoTimeout", 1, 30, 1);
01568     gs->setLabel(QObject::tr("Program Info OSD time-out"));
01569     gs->setValue(3);
01570     gs->setHelpText(QObject::tr("Length of time the on-screen display "
01571                     "will display program information."));
01572     return gs;
01573 }
01574 
01575 static HostSpinBox *OSDNotifyTimeout()
01576 {
01577     HostSpinBox *gs = new HostSpinBox("OSDNotifyTimeout", 1, 30, 1);
01578     gs->setLabel(QObject::tr("UDP Notify OSD time-out"));
01579     gs->setValue(5);
01580     gs->setHelpText(QObject::tr("How many seconds an on-screen display "
01581                     "will be active for UDP Notify events."));
01582     return gs;
01583 }
01584 
01585 static HostSpinBox *ThemeCacheSize()
01586 {
01587     HostSpinBox *gs = new HostSpinBox("ThemeCacheSize", 1, 1000, 1, true);
01588     gs->setLabel(QObject::tr("Theme cache size"));
01589     gs->setValue(1);
01590     gs->setHelpText(QObject::tr(
01591                         "Maximum number of prescaled themes to cache."));
01592 
01593     return gs;
01594 }
01595 
01596 static HostComboBox *MenuTheme()
01597 {
01598     HostComboBox *gc = new HostComboBox("MenuTheme");
01599     gc->setLabel(QObject::tr("Menu theme"));
01600 
01601     QDir themes(gContext->GetThemesParentDir());
01602     themes.setFilter(QDir::Dirs);
01603     themes.setSorting(QDir::Name | QDir::IgnoreCase);
01604     gc->addSelection(QObject::tr("Default"), "default");
01605     const QFileInfoList *fil = themes.entryInfoList(QDir::Dirs);
01606     if (!fil)
01607         return gc;
01608 
01609     QFileInfoListIterator it( *fil );
01610     QFileInfo *theme;
01611 
01612     for( ; it.current() != 0 ; ++it ) {
01613         theme = it.current();
01614         QFileInfo xml(theme->absFilePath() + "/mainmenu.xml");
01615 
01616         if (theme->fileName()[0] != '.' && xml.exists())
01617             gc->addSelection(theme->fileName());
01618     }
01619 
01620     return gc;
01621 }
01622 
01623 static HostComboBox *OSDFont()
01624 {
01625     HostComboBox *gc = new HostComboBox("OSDFont");
01626     gc->setLabel(QObject::tr("OSD font"));
01627     QDir ttf(gContext->GetFontsDir(), gContext->GetFontsNameFilter());
01628     gc->fillSelectionsFromDir(ttf, false);
01629 
01630     return gc;
01631 }
01632 
01633 static HostComboBox *OSDCCFont()
01634 {
01635     HostComboBox *gc = new HostComboBox("OSDCCFont");
01636     gc->setLabel(QObject::tr("CC font"));
01637     QDir ttf(gContext->GetFontsDir(), gContext->GetFontsNameFilter());
01638     gc->fillSelectionsFromDir(ttf, false);
01639     gc->setHelpText(QObject::tr("Closed Caption font"));
01640 
01641     return gc;
01642 }
01643 
01644 static HostSpinBox *OSDCC708TextZoomPercentage(void)
01645 {
01646     HostSpinBox *gs = new HostSpinBox("OSDCC708TextZoom", 50, 200, 5);
01647     gs->setLabel(QObject::tr("Text zoom percentage"));
01648     gs->setValue(100);
01649     gs->setHelpText(QObject::tr("Use this to enlarge or shrink captions."));
01650 
01651     return gs;
01652 }
01653 
01654 static HostComboBox *OSDCC708DefaultFontType(void)
01655 {
01656     HostComboBox *hc = new HostComboBox("OSDCC708DefaultFontType");
01657     hc->setLabel(QObject::tr("Default Caption Font Type"));
01658     hc->setHelpText(
01659         QObject::tr("This allows you to set which font type to use "
01660                     "when the broadcaster does not specify a font."));
01661 
01662     QString types[] =
01663     {
01664         "MonoSerif", "PropSerif", "MonoSansSerif", "PropSansSerif",
01665         "Casual",    "Cursive",   "Capitals",
01666     };
01667     QString typeNames[] =
01668     {
01669         QObject::tr("Monospaced serif"),
01670         QObject::tr("Proportional serif"),
01671         QObject::tr("Monospaced sans serif"),
01672         QObject::tr("Proportional sans serif"),
01673         QObject::tr("Casual"),
01674         QObject::tr("Cursive"),
01675         QObject::tr("Capitals"),
01676     };
01677     for (uint i = 0; i < 7; i++)
01678         hc->addSelection(typeNames[i], types[i]);
01679     return hc;
01680 }
01681 
01682 static VerticalConfigurationGroup *OSDCC708Settings(void)
01683 {
01684     VerticalConfigurationGroup *grp =
01685         new VerticalConfigurationGroup(false, true, true, true);
01686     grp->setLabel(QObject::tr("ATSC Caption Settings"));
01687 
01688 // default text zoom 1.0
01689     grp->addChild(OSDCC708TextZoomPercentage());
01690 
01691 // force X lines of captions
01692 // force caption character color
01693 // force caption character border color
01694 // force background color
01695 // force background opacity
01696 
01697 // set default font type
01698     grp->addChild(OSDCC708DefaultFontType());
01699 
01700     return grp;
01701 }
01702 
01703 static HostComboBox *OSDCC708Font(
01704     const QString &subtype, const QString &subtypeName,
01705     const QString &subtypeNameForHelp)
01706 {
01707     HostComboBox *gc = new HostComboBox(
01708         QString("OSDCC708%1Font").arg(subtype));
01709 
01710     gc->setLabel(subtypeName);
01711     QDir ttf(gContext->GetFontsDir(), gContext->GetFontsNameFilter());
01712     gc->fillSelectionsFromDir(ttf, false);
01713     gc->setHelpText(
01714         QObject::tr("ATSC %1 closed caption font.").arg(subtypeNameForHelp));
01715 
01716     return gc;
01717 }
01718 
01719 static HorizontalConfigurationGroup *OSDCC708Fonts(void)
01720 {
01721     HorizontalConfigurationGroup *grpmain =
01722         new HorizontalConfigurationGroup(false, true, true, true);
01723     grpmain->setLabel(QObject::tr("ATSC Caption Fonts"));
01724     VerticalConfigurationGroup *col[] =
01725     {
01726         new VerticalConfigurationGroup(false, false, true, true),
01727         new VerticalConfigurationGroup(false, false, true, true),
01728     };
01729     QString types[] =
01730     {
01731         "MonoSerif", "PropSerif", "MonoSansSerif", "PropSansSerif",
01732         "Casual",    "Cursive",   "Capitals",
01733     };
01734     QString typeNames[] =
01735     {
01736         QObject::tr("Monospaced Serif"),
01737         QObject::tr("Proportional Serif"),
01738         QObject::tr("Monospaced Sans Serif"),
01739         QObject::tr("Proportional Sans Serif"),
01740         QObject::tr("Casual"),
01741         QObject::tr("Cursive"),
01742         QObject::tr("Capitals"),
01743     };
01744     QString subtypes[] = { "%1", "%1Italic", };
01745 
01746     TransLabelSetting *col0 = new TransLabelSetting();
01747     col0->setValue(QObject::tr("Regular Font"));
01748 
01749     TransLabelSetting *col1 = new TransLabelSetting();
01750     col1->setValue(QObject::tr("Italic Font"));
01751 
01752     col[0]->addChild(col0);
01753     col[1]->addChild(col1);
01754 
01755     uint i = 0;
01756     for (uint j = 0; j < 7; j++)
01757     {
01758         col[i]->addChild(OSDCC708Font(subtypes[i].arg(types[j]),
01759                                       typeNames[j], typeNames[j]));
01760     }
01761     grpmain->addChild(col[i]);
01762 
01763     i = 1;
01764     for (uint j = 0; j < 7; j++)
01765     {
01766         col[i]->addChild(OSDCC708Font(
01767                              subtypes[i].arg(types[j]), "",
01768                              QObject::tr("Italic") + " " + typeNames[j]));
01769     }
01770 
01771     grpmain->addChild(col[i]);
01772 
01773     return grpmain;
01774 }
01775 
01776 static HostComboBox *OSDThemeFontSizeType()
01777 {
01778     HostComboBox *gc = new HostComboBox("OSDThemeFontSizeType");
01779     gc->setLabel(QObject::tr("Font size"));
01780     gc->addSelection(QObject::tr("default"), "default");
01781     gc->addSelection(QObject::tr("small"), "small");
01782     gc->addSelection(QObject::tr("big"), "big");
01783     gc->setHelpText(QObject::tr("default: TV, small: monitor, big:"));
01784     return gc;
01785 }
01786 
01787 static HostComboBox *ChannelOrdering()
01788 {
01789     HostComboBox *gc = new HostComboBox("ChannelOrdering");
01790     gc->setLabel(QObject::tr("Channel ordering"));
01791     gc->addSelection(QObject::tr("channel number"), "channum");
01792     gc->addSelection(QObject::tr("channel name"),   "callsign");
01793     return gc;
01794 }
01795 
01796 static HostSpinBox *VertScanPercentage()
01797 {
01798     HostSpinBox *gs = new HostSpinBox("VertScanPercentage", -100, 100, 1);
01799     gs->setLabel(QObject::tr("Vertical scaling"));
01800     gs->setValue(0);
01801     gs->setHelpText(QObject::tr(
01802                         "Adjust this if the image does not fill your "
01803                         "screen vertically. Range -100% to 100%"));
01804     return gs;
01805 }
01806 
01807 static HostSpinBox *HorizScanPercentage()
01808 {
01809     HostSpinBox *gs = new HostSpinBox("HorizScanPercentage", -100, 100, 1);
01810     gs->setLabel(QObject::tr("Horizontal scaling"));
01811     gs->setValue(0);
01812     gs->setHelpText(QObject::tr(
01813                         "Adjust this if the image does not fill your "
01814                         "screen horizontally. Range -100% to 100%"));
01815     return gs;
01816 };
01817 
01818 static HostSpinBox *XScanDisplacement()
01819 {
01820     HostSpinBox *gs = new HostSpinBox("XScanDisplacement", -50, 50, 1);
01821     gs->setLabel(QObject::tr("Scan displacement (X)"));
01822     gs->setValue(0);
01823     gs->setHelpText(QObject::tr("Adjust this to move the image horizontally."));
01824     return gs; 
01825 }
01826 
01827 static HostSpinBox *YScanDisplacement()
01828 {
01829     HostSpinBox *gs = new HostSpinBox("YScanDisplacement", -50, 50, 1);
01830     gs->setLabel(QObject::tr("Scan displacement (Y)"));
01831     gs->setValue(0);
01832     gs->setHelpText(QObject::tr("Adjust this to move the image vertically."));
01833     return gs;
01834 };
01835 
01836 static HostCheckBox *AlwaysStreamFiles() 
01837 {
01838     HostCheckBox *gc = new HostCheckBox("AlwaysStreamFiles");
01839     gc->setLabel(QObject::tr("Always stream recordings from the backend"));
01840     gc->setValue(false);
01841     gc->setHelpText(QObject::tr(
01842                         "Enable this setting if you want MythTV to "
01843                         "always stream files from a remote backend "
01844                         "instead of directly reading a recording "
01845                         "file if it is accessible locally."));
01846     return gc;
01847 }
01848 
01849 static HostCheckBox *UseVideoTimebase()
01850 {
01851     HostCheckBox *gc = new HostCheckBox("UseVideoTimebase");
01852     gc->setLabel(QObject::tr("Use video as timebase"));
01853     gc->setValue(false);
01854     gc->setHelpText(QObject::tr("Use the video as the timebase and warp "
01855                     "the audio to keep it in sync. (Experimental)"));
01856     return gc;
01857 }
01858 
01859 static HostCheckBox *CCBackground()
01860 {
01861     HostCheckBox *gc = new HostCheckBox("CCBackground");
01862     gc->setLabel(QObject::tr("Black background for analog closed captioning"));
01863     gc->setValue(false);
01864     gc->setHelpText(QObject::tr(
01865                         "If enabled, analog captions will be displayed "
01866                         "over a black space for maximum contrast. Otherwise, "
01867                         "captions will use outlined text over the picture."));
01868     return gc;
01869 }
01870 
01871 static HostCheckBox *DefaultCCMode()
01872 {
01873     HostCheckBox *gc = new HostCheckBox("DefaultCCMode");
01874     gc->setLabel(QObject::tr("Always display closed captioning or subtitles"));
01875     gc->setValue(false);
01876     gc->setHelpText(QObject::tr(
01877                         "If enabled, captions will be displayed "
01878                         "when playing back recordings or watching "
01879                         "live TV.  Closed Captioning can be turned on or off "
01880                         "by pressing \"T\" during playback."));
01881     return gc;
01882 }
01883 
01884 static HostCheckBox *PreferCC708()
01885 {
01886     HostCheckBox *gc = new HostCheckBox("Prefer708Captions");
01887     gc->setLabel(QObject::tr("Prefer EIA-708 over EIA-608 captions"));
01888     gc->setValue(true);
01889     gc->setHelpText(
01890         QObject::tr(
01891             "When enabled the new EIA-708 captions will be preferred over "
01892             "the old EIA-608 captions in ATSC streams.") + " " +
01893         QObject::tr(
01894             "This is the default, but as of early 2008 most stations are "
01895             "not broadcasting useable EIA-708 captions."));
01896 
01897     return gc;
01898 }
01899 
01900 static HostCheckBox *EnableMHEG()
01901 {
01902     HostCheckBox *gc = new HostCheckBox("EnableMHEG");
01903     gc->setLabel(QObject::tr("Enable Interactive TV"));
01904     gc->setValue(false);
01905     gc->setHelpText(QObject::tr(
01906                         "If enabled, interactive TV applications (MHEG) will "
01907                         "be activated.  This is used for teletext and logos for "
01908                         "radio and channels that are currently off-air."));
01909     return gc;
01910 }
01911 
01912 static HostCheckBox *PersistentBrowseMode()
01913 {
01914     HostCheckBox *gc = new HostCheckBox("PersistentBrowseMode");
01915     gc->setLabel(QObject::tr("Always use Browse mode when changing channels "
01916                  "in LiveTV"));
01917     gc->setValue(true);
01918     gc->setHelpText(QObject::tr("If enabled, Browse mode will "
01919                     "automatically be activated whenever you use Channel "
01920                     "UP/DOWN while watching Live TV."));
01921     return gc;
01922 }
01923 
01924 static HostCheckBox *AggressiveBuffer()
01925 {
01926     HostCheckBox *gc = new HostCheckBox("AggressiveSoundcardBuffer");
01927     gc->setLabel(QObject::tr("Aggressive Sound card Buffering"));
01928     gc->setValue(false);
01929     gc->setHelpText(QObject::tr("If enabled, MythTV will pretend to have "
01930                    "a smaller sound card buffer than is really present.  This "
01931                    "may speed up seeking, but can also cause playback "
01932                    "problems."));
01933     return gc;
01934 }
01935 
01936 static HostCheckBox *ClearSavedPosition()
01937 {
01938     HostCheckBox *gc = new HostCheckBox("ClearSavedPosition");
01939     gc->setLabel(QObject::tr("Clear Saved Position on playback"));
01940     gc->setValue(true);
01941     gc->setHelpText(QObject::tr("Automatically clear saved position on a "
01942                     "recording when the recording is played back.  If "
01943                     "disabled, you can mark the beginning with rewind "
01944                     "then save position."));
01945     return gc;
01946 }
01947 
01948 static HostCheckBox *AltClearSavedPosition()
01949 {
01950     HostCheckBox *gc = new HostCheckBox("AltClearSavedPosition");
01951     gc->setLabel(QObject::tr("Alternate Clear Saved Position"));
01952     gc->setValue(true);
01953     gc->setHelpText(QObject::tr("During playback the Select key "
01954                     "(Enter or Space) will alternate between \"Position "
01955                     "Saved\" and \"Position Cleared\". If disabled, the "
01956                     "Select key will save the current position for each "
01957                     "keypress."));
01958     return gc;
01959 }
01960 
01961 #ifdef USING_XV
01962 static HostCheckBox *UsePicControls()
01963 {
01964     HostCheckBox *gc = new HostCheckBox("UseOutputPictureControls");
01965     gc->setLabel(QObject::tr("Enable picture controls"));
01966     gc->setValue(false);
01967     gc->setHelpText(
01968         QObject::tr(
01969             "If enabled, MythTV attempts to initialize picture controls "
01970             "(brightness, contrast, etc.) that are applied during playback."));
01971     return gc;
01972 }
01973 #endif
01974 
01975 static HostCheckBox *AudioNagSetting()
01976 {
01977     HostCheckBox *gc = new HostCheckBox("AudioNag");
01978     gc->setLabel(QObject::tr("Warn on no audio output"));
01979     gc->setValue(true);
01980     gc->setHelpText(QObject::tr("If enabled, MythTV will warn you "
01981                     "if it can't access the soundcard."));
01982     return gc;
01983 }
01984 
01985 static HostLineEdit *UDPNotifyPort()
01986 {
01987     HostLineEdit *ge = new HostLineEdit("UDPNotifyPort");
01988     ge->setLabel(QObject::tr("UDP Notify Port"));
01989     ge->setValue("6948");
01990     ge->setHelpText(QObject::tr("During playback, MythTV will listen for "
01991                     "connections from the \"mythtvosd\" or \"mythudprelay\" "
01992                     "programs on this port.  See the README in "
01993                     "contrib/mythnotify/ for additional information."));
01994     return ge;
01995 }
01996 
01997 static HostComboBox *PlaybackExitPrompt()
01998 {
01999     HostComboBox *gc = new HostComboBox("PlaybackExitPrompt");
02000     gc->setLabel(QObject::tr("Action on playback exit"));
02001     gc->addSelection(QObject::tr("Just exit"), "0");
02002     gc->addSelection(QObject::tr("Save position and exit"), "2");
02003     gc->addSelection(QObject::tr("Always prompt (excluding Live TV)"), "1");
02004     gc->addSelection(QObject::tr("Always prompt (including Live TV)"), "4");
02005     gc->addSelection(QObject::tr("Prompt for Live TV only"), "8");
02006     gc->setHelpText(QObject::tr("If set to prompt, a menu will be displayed "
02007                     "when you exit playback mode.  The options available will "
02008                     "allow you to save your position, delete the "
02009                     "recording, or continue watching."));
02010     return gc;
02011 }
02012 
02013 static HostCheckBox *EndOfRecordingExitPrompt()
02014 {
02015     HostCheckBox *gc = new HostCheckBox("EndOfRecordingExitPrompt");
02016     gc->setLabel(QObject::tr("Prompt at end of recording"));
02017     gc->setValue(false);
02018     gc->setHelpText(QObject::tr("If set, a menu will be displayed allowing "
02019                     "you to delete the recording when it has finished "
02020                     "playing."));
02021     return gc;
02022 }
02023 
02024 static HostCheckBox *JumpToProgramOSD()
02025 {
02026     HostCheckBox *gc = new HostCheckBox("JumpToProgramOSD");
02027     gc->setLabel(QObject::tr("Jump to Program OSD"));
02028     gc->setValue(true);
02029     gc->setHelpText(QObject::tr(
02030                         "Set the choice between viewing the current "
02031                         "recording group in the OSD, or showing the "
02032                         "'Watch Recording' screen when 'Jump to Program' "
02033                         "is activated. If set, the recordings are shown "
02034                         "in the OSD"));
02035     return gc;
02036 }
02037 
02038 static HostCheckBox *ContinueEmbeddedTVPlay()
02039 {
02040     HostCheckBox *gc = new HostCheckBox("ContinueEmbeddedTVPlay");
02041     gc->setLabel(QObject::tr("Continue Playback When Embedded"));
02042     gc->setValue(false);
02043     gc->setHelpText(QObject::tr(
02044                     "This option continues TV playback when the TV window "
02045                     "is embedded in the upcoming program list or recorded "
02046                     "list. The default is to pause the recorded show when "
02047                     "embedded."));
02048     return gc;
02049 }
02050 
02051 static HostCheckBox *AutomaticSetWatched()
02052 {
02053     HostCheckBox *gc = new HostCheckBox("AutomaticSetWatched");
02054     gc->setLabel(QObject::tr("Automatically mark a recording as watched"));
02055     gc->setValue(false);
02056     gc->setHelpText(QObject::tr("If set, when you exit near the end of a "
02057                     "recording it will be marked as watched. The automatic "
02058                     "detection is not foolproof, so do not enable this "
02059                     "setting if you don't want an unwatched recording marked "
02060                     "as watched."));
02061     return gc;
02062 }
02063 
02064 static HostCheckBox *GeneratePreviewPixmaps()
02065 {
02066     HostCheckBox *gc = new HostCheckBox("GeneratePreviewPixmaps");
02067     gc->setLabel(QObject::tr("Display thumbnail preview images of "
02068                  "recordings"));
02069     gc->setValue(false);
02070     gc->setHelpText(QObject::tr("If enabled, a static image of the recording will "
02071                     "be displayed on the \"Watch a Recording\" menu."));
02072     return gc;
02073 }
02074 
02075 static GlobalSpinBox *PreviewPixmapOffset()
02076 {
02077     GlobalSpinBox *bs = new GlobalSpinBox("PreviewPixmapOffset", 0, 600, 1);
02078     bs->setLabel(QObject::tr("Time offset for thumbnail preview images"));
02079     bs->setHelpText(QObject::tr("MythTV will use this offset to make a "
02080                     "thumbnail image this many seconds from the beginning "
02081                     "of the recording, unless this offset happens to be "
02082                     "between cutpoints or inside a flagged advertisement."));
02083     bs->setValue(64);
02084     return bs;
02085 }
02086 
02087 static HostCheckBox *PreviewFromBookmark()
02088 {
02089     HostCheckBox *gc = new HostCheckBox("PreviewFromBookmark");
02090     gc->setLabel(QObject::tr("Generate preview image from a bookmark "
02091                  "if possible"));
02092     gc->setValue(true);
02093     gc->setHelpText(QObject::tr("If enabled, MythTV will ignore the above "
02094                     "time offset, and use the bookmark inside the recording "
02095                     "as the offset for creating a thumbnail image. "
02096                     "As with the above, MythTV will honour cutlists "
02097                     "and increase this offset if necessary."));
02098     return gc;
02099 }
02100 
02101 static HostCheckBox *PlaybackPreview()
02102 {
02103     HostCheckBox *gc = new HostCheckBox("PlaybackPreview");
02104     gc->setLabel(QObject::tr("Display live preview of recordings"));
02105     gc->setValue(true);
02106     gc->setHelpText(QObject::tr("When enabled, a preview of the recording "
02107                     "will play in a small window on the \"Watch a "
02108                     "Recording\" menu."));
02109     return gc;
02110 }
02111 
02112 static HostCheckBox *PlayBoxTransparency()
02113 {
02114     HostCheckBox *gc = new HostCheckBox("PlayBoxTransparency");
02115     gc->setLabel(QObject::tr("Use Transparent Boxes"));
02116     gc->setValue(true);
02117     gc->setHelpText(QObject::tr("If enabled, the Watch Recording and Delete "
02118                     "Recording screens will use transparency. Disable "
02119                     "if selecting the recordings is slow due to high "
02120                     "CPU usage."));
02121     return gc;
02122 }
02123 
02124 static HostComboBox *PlayBoxShading()
02125 {
02126     HostComboBox *gc = new HostComboBox("PlayBoxShading");
02127     gc->setLabel(QObject::tr("Popup Background Shading Method"));
02128     gc->addSelection(QObject::tr("Fill"), "0");
02129     gc->addSelection(QObject::tr("Image"), "1");
02130     gc->addSelection(QObject::tr("None"), "2");
02131 
02132     gc->setHelpText(QObject::tr("\"Fill\" is the quickest shading method. "
02133                     "\"Image\" is somewhat slow, but has a higher visual "
02134                     "quality. No shading will be the fastest."));
02135     return gc;
02136 }
02137 
02138 static HostCheckBox *UseVirtualKeyboard()
02139 {
02140     HostCheckBox *gc = new HostCheckBox("UseVirtualKeyboard");
02141     gc->setLabel(QObject::tr("Use line edit virtual keyboards"));
02142     gc->setValue(true);
02143     gc->setHelpText(QObject::tr("Allows you to use a virtual keyboard "
02144                     "in Myth line edit boxes.  To use, hit OK/Select "
02145                     "while a line edit is in focus."));
02146     return gc;
02147 }
02148 
02149 static HostComboBox *AllowQuitShutdown()
02150 {
02151     HostComboBox *gc = new HostComboBox("AllowQuitShutdown");
02152     gc->setLabel(QObject::tr("System Exit key"));
02153     gc->addSelection(QObject::tr("ESC"), "4");
02154     gc->addSelection(QObject::tr("No exit key"), "0");
02155     gc->addSelection(QObject::tr("Control-ESC"), "1");
02156     gc->addSelection(QObject::tr("Meta-ESC"), "2");
02157     gc->addSelection(QObject::tr("Alt-ESC"), "3");
02158     gc->setHelpText(QObject::tr("MythTV is designed to run continuously. If "
02159                     "you wish, you may use the ESC key or the ESC key + a "
02160                     "modifier to exit MythTV. Do not choose a key combination "
02161                     "that will be intercepted by your window manager."));
02162     return gc;
02163 }
02164 
02165 static HostComboBox *OverrideExitMenu()
02166 {
02167     HostComboBox *gc = new HostComboBox("OverrideExitMenu");
02168     gc->setLabel(QObject::tr("Customise exit menu options"));
02169     gc->addSelection(QObject::tr("Autodetect"), "0");
02170     gc->addSelection(QObject::tr("Show quit"), "1");
02171     gc->addSelection(QObject::tr("Show quit and shutdown"), "2");
02172     gc->addSelection(QObject::tr("Show quit, reboot and shutdown"), "3");
02173     gc->addSelection(QObject::tr("Show shutdown"), "4");
02174     gc->addSelection(QObject::tr("Show reboot"), "5");
02175     gc->addSelection(QObject::tr("Show reboot and shutdown"), "6");
02176     gc->setHelpText(QObject::tr("By default, only remote frontends are shown "
02177                     "the shutdown option on the exit menu. Here you can force "
02178                     "specific shutdown and reboot options to be displayed."));
02179     return gc;
02180 }
02181 
02182 static HostCheckBox *NoPromptOnExit()
02183 {
02184     HostCheckBox *gc = new HostCheckBox("NoPromptOnExit");
02185     gc->setLabel(QObject::tr("Confirm Exit"));
02186     gc->setValue(true);
02187     gc->setHelpText(QObject::tr("When enabled, MythTV will prompt "
02188                     "for confirmation when you press the System Exit "
02189                     "key."));
02190     return gc;
02191 }
02192 
02193 static HostLineEdit *RebootCommand()
02194 {
02195     HostLineEdit *ge = new HostLineEdit("RebootCommand");
02196     ge->setLabel(QObject::tr("Reboot command"));
02197     ge->setValue("reboot");
02198     ge->setHelpText(QObject::tr("Command or script to run if you select "
02199                     "the reboot option from the exit menu, if the option "
02200                     "is displayed. You must configure an exit key to "
02201                     "display the exit menu."));
02202     return ge;
02203 }
02204 
02205 static HostLineEdit *HaltCommand()
02206 {
02207     HostLineEdit *ge = new HostLineEdit("HaltCommand");
02208     ge->setLabel(QObject::tr("Halt command"));
02209     ge->setValue("halt");
02210     ge->setHelpText(QObject::tr("Command or script to run if you select "
02211                     "the shutdown option from the exit menu, if the option "
02212                     "is displayed. You must configure an exit key to "
02213                     "display the exit menu."));
02214     return ge;
02215 }
02216 
02217 static HostLineEdit *LircKeyPressedApp()
02218 {
02219     HostLineEdit *ge = new HostLineEdit("LircKeyPressedApp");
02220     ge->setLabel(QObject::tr("Keypress Application"));
02221     ge->setValue("");
02222     ge->setHelpText(QObject::tr("External application or script to run when "
02223                     "a keypress is received by LIRC."));
02224     return ge;
02225 }
02226 
02227 static HostCheckBox *UseArrowAccels()
02228 {
02229     HostCheckBox *gc = new HostCheckBox("UseArrowAccels");
02230     gc->setLabel(QObject::tr("Use Arrow Key Accelerators"));
02231     gc->setValue(true);
02232     gc->setHelpText(QObject::tr("If enabled, Arrow key accelerators will "
02233                     "be used, with LEFT performing an exit action and "
02234                     "RIGHT selecting the current item."));
02235     return gc;
02236 }
02237 
02238 static HostLineEdit *SetupPinCode()
02239 {
02240     HostLineEdit *ge = new HostLineEdit("SetupPinCode");
02241     ge->setLabel(QObject::tr("Setup Pin Code"));
02242     ge->setHelpText(QObject::tr("This PIN is used to control access to the "
02243                     "setup menus. If you want to use this feature, then "
02244                     "setting the value to all numbers will make your life "
02245                     "much easier.  Set it to blank to disable."));
02246     return ge;
02247 }
02248 
02249 static HostCheckBox *SetupPinCodeRequired()
02250 {
02251     HostCheckBox *gc = new HostCheckBox("SetupPinCodeRequired");
02252     gc->setLabel(QObject::tr("Require Setup PIN") + "    ");
02253     gc->setValue(false);
02254     gc->setHelpText(QObject::tr("If set, you will not be able to return "
02255                     "to this screen and reset the Setup PIN without first "
02256                     "entering the current PIN."));
02257     return gc;
02258 }
02259 
02260 static HostComboBox *XineramaScreen()
02261 {
02262     HostComboBox *gc = new HostComboBox("XineramaScreen", false);
02263     int num = GetNumberOfXineramaScreens();
02264     for (int i=0; i<num; ++i)
02265         gc->addSelection(QString::number(i), QString::number(i));
02266     gc->addSelection(QObject::tr("All"), QString::number(-1));
02267     gc->setLabel(QObject::tr("Display on screen"));
02268     gc->setValue(0);
02269     gc->setHelpText(QObject::tr("Run on the specified screen or "
02270                     "spanning all screens."));
02271     return gc;
02272 }
02273 
02274 
02275 static HostComboBox *XineramaMonitorAspectRatio()
02276 {
02277     HostComboBox *gc = new HostComboBox("XineramaMonitorAspectRatio");
02278     gc->setLabel(QObject::tr("Monitor Aspect Ratio"));
02279     gc->addSelection(QObject::tr("4:3"),   "1.3333");
02280     gc->addSelection(QObject::tr("16:9"),  "1.7777");
02281     gc->addSelection(QObject::tr("16:10"), "1.6");
02282     gc->setHelpText(QObject::tr(
02283                         "The aspect ratio of a Xinerama display can not be "
02284                         "queried from the display, so it must be specified."));
02285     return gc;
02286 }
02287 
02288 static HostComboBox *LetterboxingColour()
02289 {
02290     HostComboBox *gc = new HostComboBox("LetterboxColour");
02291     gc->setLabel(QObject::tr("Letterboxing Color"));
02292     for (int m = kLetterBoxColour_Black; m < kLetterBoxColour_END; m++)
02293         gc->addSelection(toString((LetterBoxColour)m), QString::number(m));
02294     gc->setHelpText(
02295         QObject::tr(
02296             "By default MythTV uses black letterboxing to match broadcaster "
02297             "letterboxing, but those with plasma screens may prefer gray "
02298             "to minimize burn-in.") +
02299         QObject::tr("Currently only works with XVideo video renderer."));
02300     return gc;
02301 }
02302 
02303 static HostComboBox *AspectOverride()
02304 {
02305     HostComboBox *gc = new HostComboBox("AspectOverride");
02306     gc->setLabel(QObject::tr("Video Aspect Override"));
02307     for (int m = kAspect_Off; m < kAspect_END; m++)
02308         gc->addSelection(toString((AspectOverrideMode)m), QString::number(m));
02309     gc->setHelpText(QObject::tr(
02310                         "When enabled, these will override the aspect "
02311                         "ratio specified by any broadcaster for all "
02312                         "video streams."));
02313     return gc;
02314 }
02315 
02316 static HostComboBox *AdjustFill()
02317 {
02318     HostComboBox *gc = new HostComboBox("AdjustFill");
02319     gc->setLabel(QObject::tr("Zoom"));
02320     for (int m = kAdjustFill_Off; m < kAdjustFill_END; m++)
02321         gc->addSelection(toString((AdjustFillMode)m), QString::number(m));
02322     gc->setHelpText(QObject::tr(
02323                         "When enabled, these will apply a predefined "
02324                         "zoom to all video playback in MythTV."));
02325     return gc;
02326 }
02327 
02328 // Theme settings
02329 
02330 static HostSpinBox *GuiWidth()
02331 {
02332     HostSpinBox *gs = new HostSpinBox("GuiWidth", 0, 1920, 8, true);
02333     gs->setLabel(QObject::tr("GUI width (px)"));
02334     gs->setValue(0);
02335     gs->setHelpText(QObject::tr("The width of the GUI.  Do not make the GUI "
02336                     "wider than your actual screen resolution.  Set to 0 to "
02337                     "automatically scale to fullscreen."));
02338     return gs;
02339 }
02340 
02341 static HostSpinBox *GuiHeight()
02342 {
02343     HostSpinBox *gs = new HostSpinBox("GuiHeight", 0, 1600, 8, true);
02344     gs->setLabel(QObject::tr("GUI height (px)"));
02345     gs->setValue(0);
02346     gs->setHelpText(QObject::tr("The height of the GUI.  Do not make the GUI "
02347                     "taller than your actual screen resolution.  Set to 0 to "
02348                     "automatically scale to fullscreen."));
02349     return gs;
02350 }
02351 
02352 static HostSpinBox *GuiOffsetX()
02353 {
02354     HostSpinBox *gs = new HostSpinBox("GuiOffsetX", -3840, 3840, 32, true);
02355     gs->setLabel(QObject::tr("GUI X offset"));
02356     gs->setValue(0);
02357     gs->setHelpText(QObject::tr("The horizontal offset the GUI will be "
02358                     "displayed at.  May only work if run in a window."));
02359     return gs;
02360 }
02361 
02362 static HostSpinBox *GuiOffsetY()
02363 {
02364     HostSpinBox *gs = new HostSpinBox("GuiOffsetY", -1600, 1600, 8, true);
02365     gs->setLabel(QObject::tr("GUI Y offset"));
02366     gs->setValue(0);
02367     gs->setHelpText(QObject::tr("The vertical offset the GUI will be "
02368                     "displayed at."));
02369     return gs;
02370 }
02371 
02372 #if 0
02373 static HostSpinBox *DisplaySizeWidth()
02374 {
02375     HostSpinBox *gs = new HostSpinBox("DisplaySizeWidth", 0, 10000, 1);
02376     gs->setLabel(QObject::tr("Display Size - Width"));
02377     gs->setValue(0);
02378     gs->setHelpText(QObject::tr("Horizontal size of the monitor or TV. Used "
02379                     "to calculate the actual aspect ratio of the display. This "
02380                     "will override the DisplaySize from the system."));
02381     return gs;
02382 }
02383 
02384 static HostSpinBox *DisplaySizeHeight()
02385 {
02386     HostSpinBox *gs = new HostSpinBox("DisplaySizeHeight", 0, 10000, 1);
02387     gs->setLabel(QObject::tr("Display Size - Height"));
02388     gs->setValue(0);
02389     gs->setHelpText(QObject::tr("Vertical size of the monitor or TV. Used "
02390                     "to calculate the actual aspect ratio of the display. This "
02391                     "will override the DisplaySize from the system."));
02392     return gs;
02393 }
02394 #endif
02395 
02396 static HostCheckBox *GuiSizeForTV()
02397 {
02398     HostCheckBox *gc = new HostCheckBox("GuiSizeForTV");
02399     gc->setLabel(QObject::tr("Use GUI size for TV playback"));
02400     gc->setValue(true);
02401     gc->setHelpText(QObject::tr("If enabled, use the above size for TV, "
02402                     "otherwise use full screen."));
02403     return gc;
02404 }
02405 
02406 #if defined(USING_XRANDR) || defined(CONFIG_DARWIN)
02407 static HostCheckBox *UseVideoModes()
02408 {
02409     HostCheckBox *gc = new HostCheckBox("UseVideoModes");
02410     gc->setLabel(QObject::tr("Separate video modes for GUI and TV playback"));
02411     gc->setValue(false);
02412     gc->setHelpText(QObject::tr("Switch X Window video modes for TV. "
02413                     "Requires \"xrandr\" support."));
02414     return gc;
02415 }
02416 
02417 static HostSpinBox *VidModeWidth(int idx)
02418 {
02419     HostSpinBox *gs = new HostSpinBox(QString("VidModeWidth%1").arg(idx),
02420                                             0, 1920, 16, true);
02421     gs->setLabel((idx<1) ? QObject::tr("In X"): "");
02422     gs->setLabelAboveWidget(idx<1);
02423     gs->setValue(0);
02424     gs->setHelpText(QObject::tr("Horizontal resolution of video "
02425                     "which needs a special output resolution."));
02426     return gs;
02427 }
02428 
02429 static HostSpinBox *VidModeHeight(int idx)
02430 {
02431     HostSpinBox *gs = new HostSpinBox(QString("VidModeHeight%1").arg(idx),
02432                                             0, 1080, 16, true);
02433     gs->setLabel((idx<1) ? QObject::tr("In Y"): "");
02434     gs->setLabelAboveWidget(idx<1);
02435     gs->setValue(0);
02436     gs->setHelpText(QObject::tr("Vertical resolution of video "
02437                     "which needs a special output resolution."));
02438     return gs;
02439 }
02440 
02441 static HostComboBox *GuiVidModeResolution()
02442 {
02443     HostComboBox *gc = new HostComboBox("GuiVidModeResolution");
02444     gc->setLabel(QObject::tr("GUI"));
02445     gc->setLabelAboveWidget(true);
02446     gc->setHelpText(QObject::tr("Resolution of screen "
02447                     "when not watching a video."));
02448     
02449     const vector<DisplayResScreen> scr = GetVideoModes();
02450     for (uint i=0; i<scr.size(); ++i)
02451     {
02452         int w = scr[i].Width(), h = scr[i].Height();
02453         QString sel = QString("%1x%2").arg(w).arg(h);
02454         gc->addSelection(sel, sel);
02455     }
02456     
02457     // if no resolution setting, set it with a reasonable initial value
02458     if (scr.size() && ("" == gContext->GetSetting("GuiVidModeResolution")))
02459     {
02460         int w = 0, h = 0;
02461         gContext->GetResolutionSetting("GuiVidMode", w, h);
02462         if ((w <= 0) || (h <= 0))
02463             (w = 640), (h = 480);
02464 
02465         DisplayResScreen dscr(w, h, -1, -1, -1.0, 0);
02466         short rate = -1;
02467         int i = DisplayResScreen::FindBestMatch(scr, dscr, rate);
02468         gc->setValue((i >= 0) ? i : scr.size()-1);
02469     }
02470 
02471     return gc;
02472 }
02473 
02474 static HostComboBox *TVVidModeResolution(int idx=-1)
02475 {
02476     QString dhelp = QObject::tr("Default screen resolution "
02477                                 "when watching a video.");
02478     QString ohelp = QObject::tr("Screen resolution when watching a "
02479                                 "video at a specific resolution.");
02480 
02481     QString qstr = (idx<0) ? "TVVidModeResolution" :
02482         QString("TVVidModeResolution%1").arg(idx);
02483     HostComboBox *gc = new HostComboBox(qstr);
02484     QString lstr = (idx<0) ? QObject::tr("Video Output") :
02485         ((idx<1) ? QObject::tr("Output") : "");
02486     QString hstr = (idx<0) ? dhelp : ohelp;
02487 
02488     gc->setLabel(lstr);
02489     gc->setLabelAboveWidget(idx<1);
02490     gc->setHelpText(hstr);
02491     
02492     const vector<DisplayResScreen> scr = GetVideoModes();
02493     for (uint i=0; i<scr.size(); ++i)
02494     {        
02495         QString sel = QString("%1x%2").arg(scr[i].Width()).arg(scr[i].Height());
02496         gc->addSelection(sel, sel);
02497     }
02498     return gc;
02499 }
02500 
02501 static HostRefreshRateComboBox *TVVidModeRefreshRate(int idx=-1)
02502 {
02503     QString dhelp = QObject::tr("Default refresh rate "
02504                                 "when watching a video.");
02505     QString ohelp = QObject::tr("Refresh rate when watching a "
02506                                 "video at a specific resolution.");
02507     QString qstr = (idx<0) ? "TVVidModeRefreshRate" :
02508         QString("TVVidModeRefreshRate%1").arg(idx);
02509     HostRefreshRateComboBox *gc = new HostRefreshRateComboBox(qstr);
02510     QString lstr = (idx<1) ? QObject::tr("Rate") : "";
02511     QString hstr = (idx<0) ? dhelp : ohelp;
02512 
02513     gc->setLabel(lstr);
02514     gc->setLabelAboveWidget(idx<1);
02515     gc->setHelpText(hstr);
02516     gc->setEnabled(false);
02517     return gc;
02518 }
02519 
02520 static HostComboBox *TVVidModeForceAspect(int idx=-1)
02521 {
02522     QString dhelp = QObject::tr("Aspect ratio when watching a video.");
02523     QString ohelp = QObject::tr("Aspect ratio when watching a "
02524                     "video at a specific resolution.");
02525 
02526     QString qstr = (idx<0) ? "TVVidModeForceAspect" :
02527         QString("TVVidModeForceAspect%1").arg(idx);
02528     HostComboBox *gc = new HostComboBox(qstr);
02529     gc->setLabel( (idx<1) ? QObject::tr("Aspect") : "" );
02530     gc->setLabelAboveWidget(idx<1);
02531 
02532     QString hstr = (idx<0) ? dhelp : ohelp;
02533     gc->setHelpText(hstr+"  "+
02534         QObject::tr("Leave at \"Default\" to use ratio reported by "
02535                     "the monitor.  Set to 16:9 or 4:3 to "
02536                     "force a specific aspect ratio."));
02537     gc->addSelection(QObject::tr("Default"), "0.0");
02538     gc->addSelection("16:9", "1.77777777777");
02539     gc->addSelection("4:3",  "1.33333333333");
02540     return gc;
02541 }
02542 
02543 class VideoModeSettings : public TriggeredConfigurationGroup
02544 {
02545   public:
02546     VideoModeSettings() :
02547         TriggeredConfigurationGroup(false, true, false, false)
02548     {
02549         setLabel(QObject::tr("Video Mode Settings"));
02550         setUseLabel(false);
02551 
02552         Setting *videomode = UseVideoModes();
02553         addChild(videomode);
02554         setTrigger(videomode);
02555 
02556         ConfigurationGroup* defaultsettings =
02557             new HorizontalConfigurationGroup(false, false);
02558 
02559         HostComboBox *res = TVVidModeResolution();
02560         HostRefreshRateComboBox *rate = TVVidModeRefreshRate();
02561         defaultsettings->addChild(GuiVidModeResolution());
02562         defaultsettings->addChild(res);
02563         defaultsettings->addChild(rate);
02564         defaultsettings->addChild(TVVidModeForceAspect());
02565         connect(res, SIGNAL(valueChanged(const QString&)),
02566                 rate, SLOT(ChangeResolution(const QString&)));
02567 
02568         ConfigurationGroup* overrides =
02569             new GridConfigurationGroup(5, true, true, false, true);
02570         overrides->setLabel("Overrides for specific video sizes");
02571             
02572         for (int idx = 0; idx < 3; ++idx)
02573         {
02574             //input side
02575             overrides->addChild(VidModeWidth(idx));
02576             overrides->addChild(VidModeHeight(idx));
02577             // output side
02578             overrides->addChild(res = TVVidModeResolution(idx));
02579             overrides->addChild(rate = TVVidModeRefreshRate(idx));
02580             overrides->addChild(TVVidModeForceAspect(idx));
02581             connect(res, SIGNAL(valueChanged(const QString&)),
02582                     rate, SLOT(ChangeResolution(const QString&)));
02583         }
02584 
02585         ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
02586         settings->addChild(defaultsettings);
02587         settings->addChild(overrides);
02588 
02589         addTarget("1", settings);
02590         addTarget("0", new VerticalConfigurationGroup(true));
02591     }
02592 };
02593 #endif
02594 
02595 static HostCheckBox *HideMouseCursor()
02596 {
02597     HostCheckBox *gc = new HostCheckBox("HideMouseCursor");
02598     gc->setLabel(QObject::tr("Hide Mouse Cursor in MythTV"));
02599     gc->setValue(true);
02600     gc->setHelpText(QObject::tr("Toggles mouse cursor visibility. "
02601                     "Most of the MythTV GUI does not respond "
02602                     "to mouse clicks. Use this option to avoid "
02603                     "\"losing\" your mouse cursor."));
02604     return gc;
02605 };
02606 
02607 
02608 static HostCheckBox *RunInWindow()
02609 {
02610     HostCheckBox *gc = new HostCheckBox("RunFrontendInWindow");
02611     gc->setLabel(QObject::tr("Run the frontend in a window"));
02612     gc->setValue(false);
02613     gc->setHelpText(QObject::tr("Toggles between windowed and "
02614                     "borderless operation."));
02615     return gc;
02616 }
02617 
02618 static HostCheckBox *RandomTheme()
02619 {
02620     HostCheckBox *gc = new HostCheckBox("RandomTheme");
02621     gc->setLabel(QObject::tr("Use a random theme"));
02622     gc->setValue(false);
02623     gc->setHelpText(QObject::tr("Use a random theme each time MythTV is "
02624                     "started."));
02625     return gc;
02626 }
02627 
02628 static HostComboBox *MythDateFormat()
02629 {
02630     HostComboBox *gc = new HostComboBox("DateFormat");
02631     gc->setLabel(QObject::tr("Date format"));
02632 
02633     QDate sampdate = QDate::currentDate();
02634     QString sampleStr =
02635         QObject::tr("Samples are shown using today's date.");
02636 
02637     if (sampdate.month() == sampdate.day())
02638     {
02639         sampdate = sampdate.addDays(1);
02640         sampleStr =
02641             QObject::tr("Samples are shown using tomorrow's date.");
02642     }
02643 
02644     gc->addSelection(sampdate.toString("ddd MMM d"), "ddd MMM d");
02645     gc->addSelection(sampdate.toString("ddd d MMM"), "ddd d MMM");
02646     gc->addSelection(sampdate.toString("ddd MMMM d"), "ddd MMMM d");
02647     gc->addSelection(sampdate.toString("ddd d MMMM"), "ddd d MMMM");
02648     gc->addSelection(sampdate.toString("dddd MMM d"), "dddd MMM d");
02649     gc->addSelection(sampdate.toString("dddd d MMM"), "dddd d MMM");
02650     gc->addSelection(sampdate.toString("MMM d"), "MMM d");
02651     gc->addSelection(sampdate.toString("d MMM"), "d MMM");
02652     gc->addSelection(sampdate.toString("MM/dd"), "MM/dd");
02653     gc->addSelection(sampdate.toString("dd/MM"), "dd/MM");
02654     gc->addSelection(sampdate.toString("MM.dd"), "MM.dd");
02655     gc->addSelection(sampdate.toString("dd.MM"), "dd.MM");
02656     gc->addSelection(sampdate.toString("M/d/yyyy"), "M/d/yyyy");
02657     gc->addSelection(sampdate.toString("d/M/yyyy"), "d/M/yyyy");
02658     gc->addSelection(sampdate.toString("MM.dd.yyyy"), "MM.dd.yyyy");
02659     gc->addSelection(sampdate.toString("dd.MM.yyyy"), "dd.MM.yyyy");
02660     gc->addSelection(sampdate.toString("yyyy-MM-dd"), "yyyy-MM-dd");
02661     gc->addSelection(sampdate.toString("ddd MMM d yyyy"), "ddd MMM d yyyy");
02662     gc->addSelection(sampdate.toString("ddd d MMM yyyy"), "ddd d MMM yyyy");
02663     gc->addSelection(sampdate.toString("ddd yyyy-MM-dd"), "ddd yyyy-MM-dd");
02664     gc->setHelpText(QObject::tr("Your preferred date format.") + " " +
02665                     sampleStr);
02666     return gc;
02667 }
02668 
02669 static HostComboBox *MythShortDateFormat()
02670 {
02671     HostComboBox *gc = new HostComboBox("ShortDateFormat");
02672     gc->setLabel(QObject::tr("Short Date format"));
02673 
02674     QDate sampdate = QDate::currentDate();
02675     QString sampleStr =
02676         QObject::tr("Samples are shown using today's date.");
02677 
02678     if (sampdate.month() == sampdate.day())
02679     {
02680         sampdate = sampdate.addDays(1);
02681         sampleStr =
02682             QObject::tr("Samples are shown using tomorrow's date.");
02683     }
02684 
02685     gc->addSelection(sampdate.toString("M/d"), "M/d");
02686     gc->addSelection(sampdate.toString("d/M"), "d/M");
02687     gc->addSelection(sampdate.toString("MM/dd"), "MM/dd");
02688     gc->addSelection(sampdate.toString("dd/MM"), "dd/MM");
02689     gc->addSelection(sampdate.toString("MM.dd"), "MM.dd");
02690     gc->addSelection(sampdate.toString("dd.MM."), "dd.MM.");
02691     gc->addSelection(sampdate.toString("M.d."), "M.d.");
02692     gc->addSelection(sampdate.toString("d.M."), "d.M.");
02693     gc->addSelection(sampdate.toString("MM-dd"), "MM-dd");
02694     gc->addSelection(sampdate.toString("dd-MM"), "dd-MM");
02695     gc->addSelection(sampdate.toString("MMM d"), "MMM d");
02696     gc->addSelection(sampdate.toString("d MMM"), "d MMM");
02697     gc->addSelection(sampdate.toString("ddd d"), "ddd d");
02698     gc->addSelection(sampdate.toString("d ddd"), "d ddd");
02699     gc->addSelection(sampdate.toString("ddd M/d"), "ddd M/d");
02700     gc->addSelection(sampdate.toString("ddd d/M"), "ddd d/M");
02701     gc->addSelection(sampdate.toString("M/d ddd"), "M/d ddd");
02702     gc->addSelection(sampdate.toString("d/M ddd"), "d/M ddd");
02703     gc->setHelpText(QObject::tr("Your preferred short date format.") + " " +
02704                     sampleStr);
02705     return gc;
02706 }
02707 
02708 static HostComboBox *MythTimeFormat()
02709 {
02710     HostComboBox *gc = new HostComboBox("TimeFormat");
02711     gc->setLabel(QObject::tr("Time format"));
02712 
02713     QTime samptime = QTime::currentTime();
02714 
02715     gc->addSelection(samptime.toString("h:mm AP"), "h:mm AP");
02716     gc->addSelection(samptime.toString("h:mm ap"), "h:mm ap");
02717     gc->addSelection(samptime.toString("hh:mm AP"), "hh:mm AP");
02718     gc->addSelection(samptime.toString("hh:mm ap"), "hh:mm ap");
02719     gc->addSelection(samptime.toString("h:mm"), "h:mm");
02720     gc->addSelection(samptime.toString("hh:mm"), "hh:mm");
02721     gc->addSelection(samptime.toString("hh.mm"), "hh.mm");
02722     gc->setHelpText(QObject::tr("Your preferred time format.  You must choose "
02723                     "a format with \"AM\" or \"PM\" in it, otherwise your "
02724                     "time display will be 24-hour or \"military\" time."));
02725     return gc;
02726 }
02727 
02728 static HostComboBox *ThemeFontSizeType()
02729 {
02730     HostComboBox *gc = new HostComboBox("ThemeFontSizeType");
02731     gc->setLabel(QObject::tr("Font size"));
02732     gc->addSelection(QObject::tr("default"), "default");
02733     gc->addSelection(QObject::tr("small"), "small");
02734     gc->addSelection(QObject::tr("big"), "big");
02735     gc->setHelpText(QObject::tr("default: TV, small: monitor, big:"));
02736     return gc;
02737 }
02738 
02739 static HostComboBox *ThemePainter()
02740 {
02741     HostComboBox *gc = new HostComboBox("ThemePainter");
02742     gc->setLabel(QObject::tr("Paint Engine"));
02743     gc->addSelection(QObject::tr("Qt"), "qt");
02744     gc->addSelection(QObject::tr("OpenGL"), "opengl");
02745     gc->setHelpText(QObject::tr("This selects what MythTV uses to draw.  If "
02746                     "you have decent hardware, select OpenGL. Changing this "
02747                     "requires a restart."));
02748     return gc;
02749 }
02750 
02751 ThemeSelector::ThemeSelector(QString label):
02752     HostImageSelect(label) {
02753 
02754     ThemeType themetype = THEME_UI;
02755 
02756     if (label == "Theme")
02757     {
02758         themetype = THEME_UI;
02759         setLabel(QObject::tr("UI Theme"));
02760     }
02761     else if (label == "OSDTheme")
02762     {
02763         themetype = THEME_OSD;
02764         setLabel(QObject::tr("OSD Theme"));
02765     }
02766     else if (label == "MenuTheme")
02767     {
02768         themetype = THEME_MENU;
02769         setLabel(QObject::tr("Menu Theme"));
02770     }
02771 
02772     QDir themes(gContext->GetThemesParentDir());
02773     themes.setFilter(QDir::Dirs);
02774     themes.setSorting(QDir::Name | QDir::IgnoreCase);
02775 
02776     const QFileInfoList *fil = themes.entryInfoList(QDir::Dirs);
02777     if (!fil)
02778         return;
02779 
02780     QFileInfoListIterator it( *fil );
02781     QFileInfo *theme;
02782 
02783     for( ; it.current() != 0 ; ++it ) {
02784         theme = it.current();
02785 
02786         if (theme->fileName() == "." || theme->fileName() == ".."
02787                 || theme->fileName() == "default"
02788                 || theme->fileName() == "default-wide")
02789             continue;
02790 
02791         QFileInfo preview;
02792         QString name;
02793 
02794         ThemeInfo *themeinfo = new ThemeInfo(theme->absFilePath());
02795 
02796         if (!themeinfo)
02797             continue;
02798 
02799         name = themeinfo->Name();
02800         preview = QFileInfo(themeinfo->PreviewPath());
02801 
02802         if (name.isEmpty() || !(themeinfo->Type() & themetype))
02803         {
02804             delete themeinfo;
02805             continue;
02806         }
02807 
02808         if ((themeinfo->Type() & THEME_UI) & themeinfo->IsWide())
02809             name += QString(" (%1)").arg(QObject::tr("Widescreen"));
02810 
02811         if (!preview.exists())
02812         {
02813             VERBOSE(VB_IMPORTANT, QString("Theme %1 missing preview image.")
02814                                     .arg(theme->fileName()));
02815             QString defaultpreview = themes.absPath();
02816             if (themeinfo->IsWide())
02817             {
02818                 defaultpreview += "/default-wide/preview.png";
02819             }
02820             else
02821             {
02822                 defaultpreview += "/default/preview.png";
02823             }
02824             preview = QFileInfo(defaultpreview);
02825         }
02826 
02827         delete themeinfo;
02828 
02829         QImage* previewImage = new QImage(preview.absFilePath());
02830         if (previewImage->width() == 0 || previewImage->height() == 0) {
02831             VERBOSE(VB_IMPORTANT, QString("Problem reading theme preview image"
02832                                           " %1").arg(preview.filePath()));
02833             continue;
02834         }
02835 
02836         addImageSelection(name, previewImage, theme->fileName());
02837     }
02838 
02839     if (themetype & THEME_UI)
02840         setValue("G.A.N.T");
02841 }
02842 
02843 class StyleSetting: public HostComboBox {
02844 public:
02845     StyleSetting():
02846         HostComboBox("Style") {
02847         setLabel(QObject::tr("Qt Style"));
02848         fillSelections();
02849         setHelpText(QObject::tr("At startup, MythTV will change the Qt "
02850                     "widget style to this setting.  If \"Desktop Style\" "
02851                     "is selected, MythTV will use the existing desktop "
02852                     "setting."));
02853     };
02854 
02855     void fillSelections(void) {
02856         clearSelections();
02857         addSelection(QObject::tr("Desktop Style"), "");
02858         QStyleFactory factory;
02859         QStringList list = factory.keys();
02860         QStringList::iterator iter = list.begin();
02861         for (; iter != list.end(); iter++ )
02862             addSelection(*iter);
02863     };
02864 
02865     void load() {
02866         fillSelections();
02867         HostComboBox::load();
02868     };
02869 };
02870 
02871 static HostComboBox *ChannelFormat()
02872 {
02873     HostComboBox *gc = new HostComboBox("ChannelFormat");
02874     gc->setLabel(QObject::tr("Channel format"));
02875     gc->addSelection(QObject::tr("number"), "<num>");
02876     gc->addSelection(QObject::tr("number callsign"), "<num> <sign>");
02877     gc->addSelection(QObject::tr("number name"), "<num> <name>");
02878     gc->addSelection(QObject::tr("callsign"), "<sign>");
02879     gc->addSelection(QObject::tr("name"), "<name>");
02880     gc->setHelpText(QObject::tr("Your preferred channel format."));
02881     gc->setValue(1);
02882     return gc;
02883 }
02884 
02885 static HostComboBox *LongChannelFormat()
02886 {
02887     HostComboBox *gc = new HostComboBox("LongChannelFormat");
02888     gc->setLabel(QObject::tr("Long Channel format"));
02889     gc->addSelection(QObject::tr("number"), "<num>");
02890     gc->addSelection(QObject::tr("number callsign"), "<num> <sign>");
02891     gc->addSelection(QObject::tr("number name"), "<num> <name>");
02892     gc->addSelection(QObject::tr("callsign"), "<sign>");
02893     gc->addSelection(QObject::tr("name"), "<name>");
02894     gc->setHelpText(QObject::tr("Your preferred long channel format."));
02895     gc->setValue(2);
02896     return gc;
02897 }
02898 
02899 static HostCheckBox *SmartChannelChange()
02900 {
02901     HostCheckBox *gc = new HostCheckBox("SmartChannelChange");
02902     gc->setLabel(QObject::tr("Change channels immediately without select"));
02903     gc->setValue(false);
02904     gc->setHelpText(QObject::tr("When a complete channel number is entered "
02905                     "MythTV will switch to that channel immediately without "
02906                     "requiring you to hit the select button."));
02907     return gc;
02908 }
02909 
02910 static GlobalCheckBox *LastFreeCard()
02911 {
02912     GlobalCheckBox *bc = new GlobalCheckBox("LastFreeCard");
02913     bc->setLabel(QObject::tr("Avoid conflicts between live TV and "
02914                  "scheduled shows"));
02915     bc->setValue(false);
02916     bc->setHelpText(QObject::tr("If enabled, live TV will choose a tuner card "
02917                     "that is less likely to have scheduled recordings "
02918                     "rather than the best card available."));
02919     return bc;
02920 }
02921 
02922 static GlobalCheckBox *LiveTVPriority()
02923 {
02924     GlobalCheckBox *bc = new GlobalCheckBox("LiveTVPriority");
02925     bc->setLabel(QObject::tr("Allow live TV to move scheduled shows"));
02926     bc->setValue(false);
02927     bc->setHelpText(QObject::tr("If enabled, scheduled recordings will "
02928                     "be moved to other cards (where possible), so that "
02929                     "live TV will not be interrupted."));
02930     return bc;
02931 }
02932 
02933 static HostSpinBox *QtFontBig()
02934 {
02935     HostSpinBox *gs = new HostSpinBox("QtFontBig", 1, 48, 1);
02936     gs->setLabel(QObject::tr("\"Big\" font"));
02937     gs->setValue(25);
02938     gs->setHelpText(QObject::tr("Default size is 25."));
02939     return gs;
02940 }
02941 
02942 static HostSpinBox *QtFontMedium()
02943 {
02944     HostSpinBox *gs = new HostSpinBox("QtFontMedium", 1, 48, 1);
02945     gs->setLabel(QObject::tr("\"Medium\" font"));
02946     gs->setValue(16);
02947     gs->setHelpText(QObject::tr("Default size is 16."));
02948     return gs;
02949 }
02950 
02951 static HostSpinBox *QtFontSmall()
02952 {
02953     HostSpinBox *gs = new HostSpinBox("QtFontSmall", 1, 48, 1);
02954     gs->setLabel(QObject::tr("\"Small\" font"));
02955     gs->setValue(12);
02956     gs->setHelpText(QObject::tr("Default size is 12."));
02957     return gs;
02958 }
02959 
02960 static HostSpinBox *QtFonTweak()
02961 {
02962     HostSpinBox *gs = new HostSpinBox("QtFonTweak", -30, 30, 1);
02963     gs->setLabel(QObject::tr("Fine tune font size (\%)"));
02964     gs->setValue(0);
02965     gs->setHelpText(QObject::tr("Fine tune all font sizes by this percentage. "
02966                     "Font sizes should be the correct relative size if the "
02967                     "X11 DPI (dots per inch) is set to 100."));
02968     return gs;
02969 }
02970 
02971 // EPG settings
02972 static HostCheckBox *EPGScrollType()
02973 {
02974     HostCheckBox *gc = new HostCheckBox("EPGScrollType");
02975     gc->setLabel(QObject::tr("Floating Program Guide Selector"));
02976     gc->setValue(true);
02977     gc->setHelpText(QObject::tr("If enabled, the program guide's selector "
02978                     "will be free to move throughout the guide, otherwise "
02979                     "it will stay in the center of the guide at all times."));
02980     return gc;
02981 }
02982 
02983 static HostComboBox *EPGFillType()
02984 {
02985     HostComboBox *gc = new HostComboBox("EPGFillType");
02986     gc->setLabel(QObject::tr("Guide Shading Method"));
02987     gc->addSelection(QObject::tr("Alpha - Transparent (CPU Usage - High)"),
02988                      QString::number((int)UIGuideType::Alpha));
02989     gc->addSelection(QObject::tr("Blender - Transparent (CPU Usage - Middle)"),
02990                      QString::number((int)UIGuideType::Dense));
02991     gc->addSelection(QObject::tr("Eco - Transparent (CPU Usage - Low)"),
02992                      QString::number((int)UIGuideType::Eco));
02993     gc->addSelection(QObject::tr("Solid (CPU Usage - Middle)"),
02994                      QString::number((int)UIGuideType::Solid));
02995     return gc;
02996 };
02997 
02998 static HostCheckBox *EPGShowCategoryColors()
02999 {
03000     HostCheckBox *gc = new HostCheckBox("EPGShowCategoryColors");
03001     gc->setLabel(QObject::tr("Display Genre Colors"));
03002     gc->setHelpText(QObject::tr("Colorize program guide using "
03003                     "genre colors. (Not available for all grabbers.)"));
03004     gc->setValue(true);
03005     return gc;
03006 }
03007 
03008 static HostCheckBox *EPGShowCategoryText()
03009 {
03010     HostCheckBox *gc = new HostCheckBox("EPGShowCategoryText");
03011     gc->setLabel(QObject::tr("Display Genre Text"));
03012     gc->setHelpText(QObject::tr("(Not available for all grabbers.)"));
03013     gc->setValue(true);
03014     return gc;
03015 }
03016 
03017 static HostCheckBox *EPGShowChannelIcon()
03018 {
03019     HostCheckBox *gc = new HostCheckBox("EPGShowChannelIcon");
03020     gc->setLabel(QObject::tr("Display the channel icons"));
03021     gc->setHelpText(QObject::tr("Display the icons/logos for the channels "
03022                     "in the guide.  See section 9.5 of the "
03023                     "Installation Guide for how to grab icons."));
03024     gc->setValue(true);
03025     return gc;
03026 }
03027 
03028 static HostCheckBox *EPGShowFavorites()
03029 {
03030     HostCheckBox *gc = new HostCheckBox("EPGShowFavorites");
03031     gc->setLabel(QObject::tr("Only display 'favorite' channels"));
03032     gc->setHelpText(QObject::tr("If enabled, the EPG will initially display "
03033                     "only the channels marked as favorites. Pressing "
03034                     "\"4\" will toggle between displaying favorites and all "
03035                     "channels."));
03036     gc->setValue(false);
03037     return gc;
03038 }
03039 
03040 static HostSpinBox *EPGChanDisplay()
03041 {
03042     HostSpinBox *gs = new HostSpinBox("chanPerPage", 3, 12, 1);
03043     gs->setLabel(QObject::tr("Channels to Display"));
03044     gs->setValue(5);
03045     return gs;
03046 }
03047 
03048 static HostSpinBox *EPGTimeDisplay()
03049 {
03050     HostSpinBox *gs = new HostSpinBox("timePerPage", 1, 5, 1);
03051     gs->setLabel(QObject::tr("Time Blocks (30 mins) to Display"));
03052     gs->setValue(4);
03053     return gs;
03054 }
03055 
03056 static GlobalCheckBox *EPGEnableJumpToChannel()
03057 {
03058     GlobalCheckBox *gc = new GlobalCheckBox("EPGEnableJumpToChannel");
03059     gc->setLabel(QObject::tr("Allow channel jumping in guide"));
03060     gc->setHelpText(QObject::tr("If enabled, you will be able to press numbers "
03061                     "and jump the selection to whatever channel you enter."));
03062     gc->setValue(false);
03063     return gc;
03064 }
03065 
03066 // General RecPriorities settings
03067 
03068 static GlobalCheckBox *GRSchedMoveHigher()
03069 {
03070     GlobalCheckBox *bc = new GlobalCheckBox("SchedMoveHigher");
03071     bc->setLabel(QObject::tr("Reschedule Higher Priorities"));
03072     bc->setHelpText(QObject::tr("Move higher priority programs to other "
03073                     "cards and showings when resolving conflicts.  This "
03074                     "can be used to record lower priority programs that "
03075                     "would otherwise not be recorded, but risks missing "
03076                     "a higher priority program if the schedule changes."));
03077     bc->setValue(true);
03078     return bc;
03079 }
03080 
03081 static GlobalCheckBox *GRSchedOpenEnd()
03082 {
03083     GlobalCheckBox *bc = new GlobalCheckBox("SchedOpenEnd");
03084     bc->setLabel(QObject::tr("Avoid back to back recordings from different "
03085                     "channels"));
03086     bc->setHelpText(QObject::tr("If set, the scheduler will avoid assigning "
03087                     "shows from different channels to the same card if their "
03088                     "end time and start time match. This will be allowed "
03089                     "when necessary in order to resolve conflicts."));
03090     bc->setValue(false);
03091     return bc;
03092 }
03093 
03094 static GlobalSpinBox *GRDefaultStartOffset()
03095 {
03096     GlobalSpinBox *bs = new GlobalSpinBox("DefaultStartOffset",
03097                                           -10, 30, 5, true);
03098     bs->setLabel(QObject::tr("Default 'Start Early' minutes for new "
03099                              "recording rules"));
03100     bs->setHelpText(QObject::tr("Set this to '0' unless you expect that the "
03101                     "majority of your show times will not match your TV "
03102                     "listings. This sets the initial start early or start "
03103                     "late time when rules are created. These can then be "
03104                     "adjusted per recording rule."));
03105     bs->setValue(0);
03106     return bs;
03107 }
03108 
03109 static GlobalSpinBox *GRDefaultEndOffset()
03110 {
03111     GlobalSpinBox *bs = new GlobalSpinBox("DefaultEndOffset",
03112                                           -10, 30, 5, true);
03113     bs->setLabel(QObject::tr("Default 'End Late' minutes for new "
03114                              "recording rules"));
03115     bs->setHelpText(QObject::tr("Set this to '0' unless you expect that the "
03116                     "majority of your show times will not match your TV "
03117                     "listings. This sets the initial end late or end early "
03118                     "time when rules are created. These can then be adjusted "
03119                     "per recording rule."));
03120     bs->setValue(0);
03121     return bs;
03122 }
03123 
03124 static GlobalCheckBox *GRComplexPriority()
03125 {
03126     GlobalCheckBox *bc = new GlobalCheckBox("ComplexPriority");
03127     bc->setLabel(QObject::tr("Complex Prioritization"));
03128     bc->setHelpText(QObject::tr("If set, per rule plus type priorities "
03129                     "will be used for primary prioritization with all other "
03130                     "priorities having a secondary effect. Unset so that all "
03131                     "are treated equally in a single total priority as "
03132                     "described in the HOWTO."));
03133     bc->setValue(false);
03134     return bc;
03135 }
03136 
03137 static GlobalSpinBox *GRPrefInputRecPriority()
03138 {
03139     GlobalSpinBox *bs = new GlobalSpinBox("PrefInputPriority", 1, 99, 1);
03140     bs->setLabel(QObject::tr("Preferred Input Priority"));
03141     bs->setHelpText(QObject::tr("Additional priority when a showing "
03142                     "matches the preferred input selected in the 'Scheduling "
03143                     "Options' section of the recording rule."));
03144     bs->setValue(2);
03145     return bs;
03146 }
03147 
03148 static GlobalSpinBox *GRHDTVRecPriority()
03149 {
03150     GlobalSpinBox *bs = new GlobalSpinBox("HDTVRecPriority", -99, 99, 1);
03151     bs->setLabel(QObject::tr("HDTV Recording Priority"));
03152     bs->setHelpText(QObject::tr("Additional priority when a showing "
03153                     "is marked as an HDTV broadcast in the TV listings."));
03154     bs->setValue(0);
03155     return bs;
03156 }
03157 
03158 static GlobalSpinBox *GRSingleRecordRecPriority()
03159 {
03160     GlobalSpinBox *bs = new GlobalSpinBox("SingleRecordRecPriority",
03161                                             -99, 99, 1);
03162     bs->setLabel(QObject::tr("Single Recordings Priority"));
03163     bs->setHelpText(QObject::tr("Single Recordings will receive this "
03164                     "additional recording priority value."));
03165     bs->setValue(1);
03166     return bs;
03167 }
03168 
03169 static GlobalSpinBox *GRWeekslotRecordRecPriority()
03170 {
03171     GlobalSpinBox *bs = new GlobalSpinBox("WeekslotRecordRecPriority",
03172                                             -99, 99, 1);
03173     bs->setLabel(QObject::tr("Weekslot Recordings Priority"));
03174     bs->setHelpText(QObject::tr("Weekslot Recordings will receive this "
03175                     "additional recording priority value."));
03176     bs->setValue(0);
03177     return bs;
03178 }
03179 
03180 static GlobalSpinBox *GRTimeslotRecordRecPriority()
03181 {
03182     GlobalSpinBox *bs = new GlobalSpinBox("TimeslotRecordRecPriority",
03183                                             -99, 99, 1);
03184     bs->setLabel(QObject::tr("Timeslot Recordings Priority"));
03185     bs->setHelpText(QObject::tr("Timeslot Recordings will receive this "
03186                     "additional recording priority value."));
03187     bs->setValue(0);
03188     return bs;
03189 }
03190 
03191 static GlobalSpinBox *GRChannelRecordRecPriority()
03192 {
03193     GlobalSpinBox *bs = new GlobalSpinBox("ChannelRecordRecPriority",
03194                                             -99, 99, 1);
03195     bs->setLabel(QObject::tr("Channel Recordings Priority"));
03196     bs->setHelpText(QObject::tr("Channel Recordings will receive this "
03197                     "additional recording priority value."));
03198     bs->setValue(0);
03199     return bs;
03200 }
03201 
03202 static GlobalSpinBox *GRAllRecordRecPriority()
03203 {
03204     GlobalSpinBox *bs = new GlobalSpinBox("AllRecordRecPriority",
03205                                             -99, 99, 1);
03206     bs->setLabel(QObject::tr("All Recordings Priority"));
03207     bs->setHelpText(QObject::tr("The 'All' Recording type will receive this "
03208                     "additional recording priority value."));
03209     bs->setValue(0);
03210     return bs;
03211 }
03212 
03213 static GlobalSpinBox *GRFindOneRecordRecPriority()
03214 {
03215     GlobalSpinBox *bs = new GlobalSpinBox("FindOneRecordRecPriority",
03216                                             -99, 99, 1);
03217     bs->setLabel(QObject::tr("Find One Recordings Priority"));
03218     bs->setHelpText(QObject::tr("Find One, Find Weekly and Find Daily "
03219                     "recording types will receive this "
03220                     "additional recording priority value."));
03221     bs->setValue(-1);
03222     return bs;
03223 }
03224 
03225 static GlobalSpinBox *GROverrideRecordRecPriority()
03226 {
03227     GlobalSpinBox *bs = new GlobalSpinBox("OverrideRecordRecPriority",
03228                                             -99, 99, 1);
03229     bs->setLabel(QObject::tr("Override Recordings Priority"));
03230     bs->setHelpText(QObject::tr("Override Recordings will receive this "
03231                     "additional recording priority value."));
03232     bs->setValue(0);
03233     return bs;
03234 }
03235 
03236 static HostLineEdit *DefaultTVChannel()
03237 {
03238     HostLineEdit *ge = new HostLineEdit("DefaultTVChannel");
03239     ge->setLabel(QObject::tr("Guide starts at channel"));
03240     ge->setValue("3");
03241     ge->setHelpText(QObject::tr("The program guide starts on this channel if "
03242                     "it is run from outside of LiveTV mode."));
03243     return ge;
03244 }
03245 
03246 static HostLineEdit *UnknownTitle()
03247 {
03248     HostLineEdit *ge = new HostLineEdit("UnknownTitle");
03249     ge->setLabel(QObject::tr("What to call 'unknown' programs"));
03250     ge->setValue(QObject::tr("Unknown"));
03251     return ge;
03252 }
03253 
03254 static HostLineEdit *UnknownCategory()
03255 {
03256     HostLineEdit *ge = new HostLineEdit("UnknownCategory");
03257     ge->setLabel(QObject::tr("What category to give 'unknown' programs"));
03258     ge->setValue(QObject::tr("Unknown"));
03259     return ge;
03260 }
03261 
03262 static HostCheckBox *SelectChangesChannel()
03263 {
03264     HostCheckBox *gc = new HostCheckBox("SelectChangesChannel");
03265     gc->setLabel(QObject::tr("Use select to change the channel in the program "
03266                  "guide"));
03267     gc->setValue(false);
03268     gc->setHelpText(QObject::tr("If enabled, the Select key will change the "
03269                     "channel while using the program guide during live TV.  "
03270                     "If disabled, the select key will bring up the recording "
03271                     "options screen."));
03272     return gc;
03273 }
03274 
03275 static HostSpinBox *EPGRecThreshold()
03276 {
03277     HostSpinBox *gs = new HostSpinBox("SelChangeRecThreshold", 1, 600, 1);
03278     gs->setLabel(QObject::tr("Record Threshold"));
03279     gs->setValue(16);
03280     gs->setHelpText(QObject::tr("If the option to use Select to change the channel "
03281                     "is on, pressing Select on a show that is at least "
03282                     "this many minutes into the future will schedule a "
03283                     "recording."));
03284     return gs;
03285 }
03286 
03287 class AudioSettings : public TriggeredConfigurationGroup
03288 {
03289   public:
03290      AudioSettings() :
03291          TriggeredConfigurationGroup(false, true, false, false)
03292      {
03293          setLabel(QObject::tr("Audio"));
03294          setUseLabel(false);
03295 
03296          addChild(AudioOutputDevice());
03297          addChild(PassThroughOutputDevice());
03298 
03299          // General boolean settings
03300          VerticalConfigurationGroup *vgrp0 =
03301              new VerticalConfigurationGroup(false, false, true, true);
03302          vgrp0->addChild(AC3PassThrough());
03303          vgrp0->addChild(DTSPassThrough());
03304 
03305          HorizontalConfigurationGroup *agrp =
03306              new HorizontalConfigurationGroup(false, false, true, true);
03307          agrp->addChild(MaxAudioChannels());
03308          agrp->addChild(AudioUpmixType());
03309          addChild(agrp);
03310 
03311          VerticalConfigurationGroup *vgrp1 =
03312              new VerticalConfigurationGroup(false, false, true, true);
03313          vgrp1->addChild(AggressiveBuffer());
03314 
03315          Setting* volumeControl = MythControlsVolume();
03316          vgrp1->addChild(volumeControl);
03317 
03318          HorizontalConfigurationGroup *tgrp =
03319              new HorizontalConfigurationGroup(false, false, true, true);
03320          tgrp->addChild(vgrp0);
03321          tgrp->addChild(vgrp1);
03322          addChild(tgrp);
03323 
03324          // Make volume control trigger for mixer settings
03325          setTrigger(volumeControl);
03326 
03327          // Mixer settings
03328          ConfigurationGroup *settings =
03329              new VerticalConfigurationGroup(false, false, true, true);
03330          HorizontalConfigurationGroup *mixgrp =
03331              new HorizontalConfigurationGroup(false, false, true, true);
03332          mixgrp->addChild(MixerDevice());
03333          mixgrp->addChild(MixerControl());
03334          settings->addChild(mixgrp);
03335          settings->addChild(MixerVolume());
03336          settings->addChild(PCMVolume());
03337          settings->addChild(IndividualMuteControl());
03338 
03339          // Show Mixer config only if internal volume controls enabled
03340          addTarget("0", new VerticalConfigurationGroup(false, false));
03341          addTarget("1", settings);
03342      };
03343 };
03344 
03345 static HostComboBox *MythLanguage()
03346 {
03347     HostComboBox *gc = new HostComboBox("Language");
03348     gc->setLabel(QObject::tr("Language"));
03349     LanguageSettings::fillSelections(gc);
03350     gc->setHelpText(
03351         QObject::tr("Your preferred language for the user interface."));
03352     return gc;
03353 }
03354 
03355 static void ISO639_fill_selections(SelectSetting *widget, uint i)
03356 {
03357     widget->clearSelections();
03358     QString q = QString("ISO639Language%1").arg(i);
03359     QString lang = gContext->GetSetting(q, "").lower();
03360 
03361     if ((lang.isEmpty() || lang == "aar") && 
03362         !gContext->GetSetting("Language", "").isEmpty())
03363     {
03364         lang = iso639_str2_to_str3(gContext->GetLanguage().lower());
03365     }
03366 
03367     QMap<int,QString>::iterator it  = _iso639_key_to_english_name.begin();
03368     QMap<int,QString>::iterator ite = _iso639_key_to_english_name.end();
03369     
03370     for (; it != ite; ++it)
03371     {
03372         QString desc = (*it);
03373         int idx = desc.find(";");
03374         if (idx > 0)
03375             desc = desc.left(idx);
03376 
03377         const QString il = iso639_key_to_str3(it.key());
03378         widget->addSelection(desc, il, il == lang);
03379     }
03380 }
03381 
03382 static HostComboBox *ISO639PreferredLanguage(uint i)
03383 {
03384     HostComboBox *gc = new HostComboBox(QString("ISO639Language%1").arg(i));
03385     gc->setLabel(QObject::tr("Guide Language #%1").arg(i+1));
03386     // We should try to get language from "MythLanguage"
03387     // then use code 2 to code 3 map in iso639.h
03388     ISO639_fill_selections(gc, i);
03389     gc->setHelpText(
03390         QObject::tr("Your #%1 preferred language for "
03391                     "Program Guide Data and captions.").arg(i+1));
03392     return gc;
03393 }
03394 
03395 static HostCheckBox *EnableXbox()
03396 {
03397     HostCheckBox *gc = new HostCheckBox("EnableXbox");
03398     gc->setLabel(QObject::tr("Enable Xbox Hardware"));
03399     gc->setHelpText(QObject::tr("This enables support for Xbox specific "
03400                     "hardware. Requires a frontend restart for changes to "
03401                     "take effect."));
03402     gc->setValue(false);
03403     return gc;
03404 }
03405 
03406 static HostCheckBox *NetworkControlEnabled()
03407 {
03408     HostCheckBox *gc = new HostCheckBox("NetworkControlEnabled");
03409     gc->setLabel(QObject::tr("Enable Network Remote Control interface"));
03410     gc->setHelpText(QObject::tr("This enables support for controlling "
03411                     "mythfrontend over the network."));
03412     gc->setValue(false);
03413     return gc;
03414 }
03415 
03416 static HostSpinBox *NetworkControlPort()
03417 {
03418     HostSpinBox *gs = new HostSpinBox("NetworkControlPort", 1025, 65535, 1);
03419     gs->setLabel(QObject::tr("Network Remote Control Port"));
03420     gs->setValue(6546);
03421     gs->setHelpText(QObject::tr("This specifies what port the Network Remote "
03422                     "Control interface will listen on for new connections."));
03423     return gs;
03424 }
03425 
03426 static HostCheckBox *RealtimePriority()
03427 {
03428     HostCheckBox *gc = new HostCheckBox("RealtimePriority");
03429     gc->setLabel(QObject::tr("Enable realtime priority threads"));
03430     gc->setHelpText(QObject::tr("When running mythfrontend with root "
03431                     "privileges, some threads can be given enhanced priority. "
03432                     "Disable this if mythfrontend freezes during video "
03433                     "playback."));
03434     gc->setValue(true);
03435     return gc;
03436 }
03437 
03438 static HostComboBox *XboxBlinkBIN()
03439 {
03440     HostComboBox *gc = new HostComboBox("XboxBlinkBIN");
03441     gc->setLabel(QObject::tr("Xbox Linux Distribution"));
03442     gc->addSelection("GentooX","led");
03443     gc->addSelection(QObject::tr("Other"),"blink");
03444     gc->setHelpText(QObject::tr("The program used to control the "
03445                     "LED on the Xbox is dependant on which distribution is "
03446                     "installed. \"led\" will be used on GentooX, \"blink\" "
03447                     "on other Xbox distributions."));
03448     return gc;
03449 }
03450 
03451 static HostComboBox *XboxLEDDefault()
03452 {
03453     HostComboBox *gc = new HostComboBox("XboxLEDDefault");
03454     gc->setLabel(QObject::tr("Default LED color"));
03455     gc->addSelection(QObject::tr("Off"), "nnnn");
03456     gc->addSelection(QObject::tr("Green"),"gggg");
03457     gc->addSelection(QObject::tr("Orange"),"oooo");
03458     gc->addSelection(QObject::tr("Red"),"rrrr");
03459     gc->setHelpText(QObject::tr("Sets the LED color when it is not "
03460                     "being used for status indication."));
03461     return gc;
03462 }
03463 
03464 static HostComboBox *XboxLEDRecording()
03465 {
03466     HostComboBox *gc = new HostComboBox("XboxLEDRecording");
03467     gc->setLabel(QObject::tr("Recording LED mode"));
03468     gc->addSelection(QObject::tr("Off"), "nnnn");
03469     gc->addSelection(QObject::tr("Green"),"gggg");
03470     gc->addSelection(QObject::tr("Orange"),"oooo");
03471     gc->addSelection(QObject::tr("Red"),"rrrr");
03472     gc->setHelpText(QObject::tr("Sets the LED color when a backend is "
03473                     "recording."));
03474     return gc;
03475 }
03476 
03477 static HostCheckBox *XboxLEDNonLiveTV()
03478 {
03479     HostCheckBox *gc = new HostCheckBox("XboxLEDNonLiveTV");
03480     gc->setLabel(QObject::tr("Ignore LiveTV Recordings"));
03481     gc->setHelpText(QObject::tr("Recording monitoring will "
03482                     "ignore LiveTV recordings."));
03483     gc->setValue(false)