MythTV  master
globalsettings.cpp
Go to the documentation of this file.
1 
2 // -*- Mode: c++ -*-
3 
4 // Standard UNIX C headers
5 #include <fcntl.h>
6 #include <sys/stat.h>
7 #include <sys/types.h>
8 #include <unistd.h>
9 
10 // Qt headers
11 #include <QApplication>
12 #include <QCursor>
13 #include <QDialog>
14 #include <QDir>
15 #include <QEvent>
16 #include <QFile>
17 #include <QFileInfo>
18 #include <QFontDatabase>
19 #include <QImage>
20 #include <QtGlobal>
21 
22 // MythTV headers
23 #include "libmyth/dbsettings.h"
24 #include "libmyth/langsettings.h"
25 #include "libmythbase/iso639.h"
26 #include "libmythbase/mythconfig.h"
28 #include "libmythbase/mythdbcon.h"
29 #include "libmythbase/mythdirs.h"
31 #include "libmythbase/mythpower.h"
33 #include "libmythbase/mythsystem.h"
35 #include "libmythtv/cardutil.h"
36 #include "libmythtv/channelgroup.h"
38 #include "libmythtv/playgroup.h" //Used for playBackGroup, to be remove at one point
41 #include "libmythui/mythdisplay.h"
43 #include "libmythui/mythuihelper.h"
44 #include "libmythui/themeinfo.h"
45 #ifdef USING_OPENGL
47 #endif
48 #ifdef USING_AIRPLAY
50 #endif
51 #ifdef USING_VAAPI
53 #endif
54 
55 // MythFrontend
56 #include "globalsettings.h"
57 #include "playbackbox.h"
58 
60 // was previously *DecodeExtraAudio()
61 {
62  auto *gc = new HostSpinBoxSetting("AudioReadAhead",0,5000,10,10);
63 
64  gc->setLabel(PlaybackSettings::tr("Audio read ahead (ms)"));
65 
66  gc->setValue(100);
67 
68  gc->setHelpText(PlaybackSettings::tr(
69  "Increase this value if audio cuts out frequently. This is more "
70  "likely to occur when adjusting audio sync to a negative value. "
71  "If using high negative audio sync values you may need to set a large "
72  "value here. Default is 100."));
73  return gc;
74 }
75 
77 {
78  auto *gc = new HostComboBoxSetting("ColourPrimariesMode");
79  gc->setLabel(PlaybackSettings::tr("Primary colourspace conversion"));
83  gc->setHelpText(PlaybackSettings::tr(
84  "Converting between different primary colourspaces incurs a small "
85  "performance penalty but in some situations the difference in output is "
86  "negligible. The default ('Auto') behaviour is to only enforce "
87  "this conversion when there is a significant difference between source "
88  "colourspace primaries and the display."));
89  return gc;
90 }
91 
93 {
94  auto *gc = new HostCheckBoxSetting("ChromaUpsamplingFilter");
95  gc->setLabel(PlaybackSettings::tr("Enable Chroma Upsampling Filter when deinterlacing"));
96  gc->setHelpText(PlaybackSettings::tr(
97  "The 'Chroma upsampling error' affects the quality of interlaced material "
98  "for the most common, standard video formats and results in jagged/indistinct "
99  "edges to brightly coloured areas of video. This filter attempts to fix "
100  "the problem in the OpenGL shaders. It adds a small amount of overhead to "
101  "video rendering but may not be suitable in all cases. Enabled by default."));
102  gc->setValue(false);
103  return gc;
104 }
105 
106 #ifdef USING_VAAPI
108 {
109  auto *ge = new HostTextEditSetting("VAAPIDevice");
110 
111  ge->setLabel(MainGeneralSettings::tr("Decoder Device for VAAPI hardware decoding"));
112 
113  ge->setValue("");
114 
115  QString help = MainGeneralSettings::tr(
116  "Use this if your system does not detect the VAAPI device. "
117  "Example: '/dev/dri/renderD128'.");
118 
119  ge->setHelpText(help);
120 
121  // update VideoDisplayProfile statics if this changes
122  QObject::connect(ge, &HostTextEditSetting::ChangeSaved, ge,
123  []()
124  {
125  QString device = gCoreContext->GetSetting("VAAPIDevice");
126  LOG(VB_GENERAL, LOG_INFO, QString("New VAAPI device (%1) - resetting profiles").arg(device));
129  });
130  return ge;
131 }
132 #endif
133 
135 {
136  auto *gc = new HostCheckBoxSetting("FFMPEGTS");
137 
138  gc->setLabel(PlaybackSettings::tr("Use FFmpeg's original MPEG-TS demuxer"));
139 
140  gc->setValue(false);
141 
142  gc->setHelpText(PlaybackSettings::tr("Experimental: Enable this setting to "
143  "use FFmpeg's native demuxer. "
144  "Try this when encountering playback issues."));
145  return gc;
146 }
147 
149 {
150  auto *gc = new HostComboBoxSetting("DisplayRecGroup");
151 
152  gc->setLabel(PlaybackSettings::tr("Default group filter to apply"));
153 
154 
155  gc->addSelection(PlaybackSettings::tr("All Programs"), QString("All Programs"));
156  gc->addSelection(QCoreApplication::translate("(Common)", "Default"),
157  QString("Default"));
158 
159  MSqlQuery query(MSqlQuery::InitCon());
160  query.prepare("SELECT DISTINCT recgroup from recorded;");
161 
162  if (query.exec())
163  {
164  while (query.next())
165  {
166  if (query.value(0).toString() != "Default")
167  {
168  QString recgroup = query.value(0).toString();
169  gc->addSelection(recgroup, recgroup);
170  }
171  }
172  }
173 
174  query.prepare("SELECT DISTINCT category from recorded;");
175 
176  if (query.exec())
177  {
178  while (query.next())
179  {
180  QString key = query.value(0).toString();
181  gc->addSelection(key, key);
182  }
183  }
184 
185  gc->setHelpText(PlaybackSettings::tr("Default group filter to apply on the "
186  "View Recordings screen."));
187  return gc;
188 }
189 
191 {
192  auto *gc = new HostCheckBoxSetting("QueryInitialFilter");
193 
194  gc->setLabel(PlaybackSettings::tr("Always prompt for initial group "
195  "filter"));
196 
197  gc->setValue(false);
198 
199  gc->setHelpText(PlaybackSettings::tr("If enabled, always prompt the user "
200  "for the initial filter to apply "
201  "when entering the Watch Recordings "
202  "screen."));
203  return gc;
204 }
205 
207 {
208  auto *gc = new HostCheckBoxSetting("RememberRecGroup");
209 
210  gc->setLabel(PlaybackSettings::tr("Save current group filter when "
211  "changed"));
212 
213  gc->setValue(true);
214 
215  gc->setHelpText(PlaybackSettings::tr("If enabled, remember the last "
216  "selected filter instead of "
217  "displaying the default filter "
218  "whenever you enter the playback "
219  "screen."));
220  return gc;
221 }
222 
224 {
225  auto *gc = new HostCheckBoxSetting("RecGroupsFocusable");
226 
227  gc->setLabel(PlaybackSettings::tr("Change Recording Group using the arrow "
228  "keys"));
229 
230  gc->setValue(false);
231 
232  gc->setHelpText(PlaybackSettings::tr("If enabled, change recording group "
233  "directly using the arrow keys "
234  "instead of having to use < and >. "
235  "Requires theme support for this "
236  "feature."));
237  return gc;
238 }
239 
240 
242 {
243  auto *gc = new HostCheckBoxSetting("PlaybackBoxStartInTitle");
244 
245  gc->setLabel(PlaybackSettings::tr("Start in group list"));
246 
247  gc->setValue(true);
248 
249  gc->setHelpText(PlaybackSettings::tr("If enabled, the focus will start on "
250  "the group list, otherwise the focus "
251  "will default to the recordings."));
252  return gc;
253 }
254 
256 {
257  auto *gc = new HostCheckBoxSetting("SmartForward");
258 
259  gc->setLabel(PlaybackSettings::tr("Smart fast forwarding"));
260 
261  gc->setValue(false);
262 
263  gc->setHelpText(PlaybackSettings::tr("If enabled, then immediately after "
264  "rewinding, only skip forward the "
265  "same amount as skipping backwards."));
266  return gc;
267 }
268 
270 {
271  auto *bc = new GlobalComboBoxSetting("CommercialSkipMethod");
272 
273  bc->setLabel(GeneralSettings::tr("Commercial detection method"));
274 
275  bc->setHelpText(GeneralSettings::tr("This determines the method used by "
276  "MythTV to detect when commercials "
277  "start and end."));
278 
279  std::deque<int> tmp = GetPreferredSkipTypeCombinations();
280 
281  for (int pref : tmp)
282  bc->addSelection(SkipTypeToString(pref), QString::number(pref));
283 
284  return bc;
285 }
286 
288 {
289  auto *gc = new GlobalCheckBoxSetting("CommFlagFast");
290 
291  gc->setLabel(GeneralSettings::tr("Enable experimental speedup of "
292  "commercial detection"));
293 
294  gc->setValue(false);
295 
296  gc->setHelpText(GeneralSettings::tr("If enabled, experimental commercial "
297  "detection speedups will be enabled."));
298  return gc;
299 }
300 
302 {
303  auto *gc = new HostComboBoxSetting("AutoCommercialSkip");
304 
305  gc->setLabel(PlaybackSettings::tr("Automatically skip commercials"));
306 
307  gc->addSelection(QCoreApplication::translate("(Common)", "Off"), "0");
308  gc->addSelection(PlaybackSettings::tr("Notify, but do not skip",
309  "Skip commercials"), "2");
310  gc->addSelection(PlaybackSettings::tr("Automatically Skip",
311  "Skip commercials"), "1");
312 
313  gc->setHelpText(PlaybackSettings::tr("Automatically skip commercial breaks "
314  "that have been flagged during "
315  "automatic commercial detection "
316  "or by the mythcommflag program, or "
317  "just notify that a commercial has "
318  "been detected."));
319  return gc;
320 }
321 
323 {
324  auto *gs = new GlobalSpinBoxSetting("DeferAutoTranscodeDays", 0, 365, 1);
325 
326  gs->setLabel(GeneralSettings::tr("Deferral days for auto transcode jobs"));
327 
328  gs->setHelpText(GeneralSettings::tr("If non-zero, automatic transcode jobs "
329  "will be scheduled to run this many "
330  "days after a recording completes "
331  "instead of immediately afterwards."));
332 
333  gs->setValue(0);
334 
335  return gs;
336 }
337 
339 {
340  auto *bc = new GlobalCheckBoxSetting("AggressiveCommDetect");
341 
342  bc->setLabel(GeneralSettings::tr("Strict commercial detection"));
343 
344  bc->setValue(true);
345 
346  bc->setHelpText(GeneralSettings::tr("Enable stricter commercial detection "
347  "code. Disable if some commercials are "
348  "not being detected."));
349  return bc;
350 }
351 
353 {
354  auto *gs = new HostSpinBoxSetting("CommRewindAmount", 0, 10, 1);
355 
356  gs->setLabel(PlaybackSettings::tr("Commercial skip automatic rewind amount "
357  "(secs)"));
358 
359  gs->setHelpText(PlaybackSettings::tr("MythTV will automatically rewind "
360  "this many seconds after performing a "
361  "commercial skip."));
362 
363  gs->setValue(0);
364 
365  return gs;
366 }
367 
369 {
370  auto *gs = new HostSpinBoxSetting("CommNotifyAmount", 0, 10, 1);
371 
372  gs->setLabel(PlaybackSettings::tr("Commercial skip notify amount (secs)"));
373 
374  gs->setHelpText(PlaybackSettings::tr("MythTV will act like a commercial "
375  "begins this many seconds early. This "
376  "can be useful when commercial "
377  "notification is used in place of "
378  "automatic skipping."));
379 
380  gs->setValue(0);
381 
382  return gs;
383 }
384 
386 {
387  auto *bs = new GlobalSpinBoxSetting("MaximumCommercialSkip", 0, 3600, 10);
388 
389  bs->setLabel(PlaybackSettings::tr("Maximum commercial skip (secs)"));
390 
391  bs->setHelpText(PlaybackSettings::tr("MythTV will discourage long manual "
392  "commercial skips. Skips which are "
393  "longer than this will require the "
394  "user to hit the SKIP key twice. "
395  "Automatic commercial skipping is "
396  "not affected by this limit."));
397 
398  bs->setValue(3600);
399 
400  return bs;
401 }
402 
404 {
405  auto *bs = new GlobalSpinBoxSetting("MergeShortCommBreaks", 0, 3600, 5);
406 
407  bs->setLabel(PlaybackSettings::tr("Merge short commercial breaks (secs)"));
408 
409  bs->setHelpText(PlaybackSettings::tr("Treat consecutive commercial breaks "
410  "shorter than this as one break when "
411  "skipping forward. Useful if you have "
412  "to skip a few times during breaks. "
413  "Applies to automatic skipping as "
414  "well. Set to 0 to disable."));
415 
416  bs->setValue(0);
417 
418  return bs;
419 }
420 
422 {
423  auto *bs = new GlobalSpinBoxSetting("AutoExpireExtraSpace", 0, 200, 1);
424 
425  bs->setLabel(GeneralSettings::tr("Extra disk space (GB)"));
426 
427  bs->setHelpText(GeneralSettings::tr("Extra disk space (in gigabytes) "
428  "beyond what MythTV requires that "
429  "you want to keep free on the "
430  "recording file systems."));
431 
432  bs->setValue(1);
433 
434  return bs;
435 };
436 
437 #if 0
438 static GlobalCheckBoxSetting *AutoExpireInsteadOfDelete()
439 {
440  GlobalCheckBoxSetting *cb = new GlobalCheckBoxSetting("AutoExpireInsteadOfDelete");
441 
442  cb->setLabel(DeletedExpireOptions::tr("Auto-Expire instead of delete recording"));
443 
444  cb->setValue(false);
445 
446  cb->setHelpText(DeletedExpireOptions::tr("If enabled, move deleted recordings to the "
447  "'Deleted' recgroup and turn on autoexpire "
448  "instead of deleting immediately."));
449  return cb;
450 }
451 #endif
452 
454 {
455  auto *bs = new GlobalSpinBoxSetting("DeletedMaxAge", -1, 365, 1);
456 
457  bs->setLabel(GeneralSettings::tr("Time to retain deleted recordings "
458  "(days)"));
459 
460  bs->setHelpText(GeneralSettings::tr("Determines the maximum number of days "
461  "before undeleting a recording will "
462  "become impossible. A value of zero "
463  "means the recording will be "
464  "permanently deleted between 5 and 20 "
465  "minutes later. A value of minus one "
466  "means recordings will be retained "
467  "until space is required. A recording "
468  "will always be removed before this "
469  "time if the space is needed for a new "
470  "recording."));
471  bs->setValue(0);
472  return bs;
473 };
474 
475 #if 0
476 // If this is ever reactivated, re-add the translations...
477 class DeletedExpireOptions : public TriggeredConfigurationGroup
478 {
479  public:
480  DeletedExpireOptions() :
481  TriggeredConfigurationGroup(false, false, false, false)
482  {
483  setLabel("DeletedExpireOptions");
484  Setting* enabled = AutoExpireInsteadOfDelete();
485  addChild(enabled);
486  setTrigger(enabled);
487 
488  HorizontalConfigurationGroup* settings =
489  new HorizontalConfigurationGroup(false);
490  settings->addChild(DeletedMaxAge());
491  addTarget("1", settings);
492 
493  // show nothing if fillEnabled is off
494  addTarget("0", new HorizontalConfigurationGroup(true));
495  };
496 };
497 #endif
498 
500 {
501  auto *bc = new GlobalComboBoxSetting("AutoExpireMethod");
502 
503  bc->setLabel(GeneralSettings::tr("Auto-Expire method"));
504 
505  bc->addSelection(GeneralSettings::tr("Oldest show first"), "1");
506  bc->addSelection(GeneralSettings::tr("Lowest priority first"), "2");
507  bc->addSelection(GeneralSettings::tr("Weighted time/priority combination"),
508  "3");
509 
510  bc->setHelpText(GeneralSettings::tr("Method used to determine which "
511  "recorded shows to delete first. "
512  "Live TV recordings will always "
513  "expire before normal recordings."));
514  bc->setValue(1);
515 
516  return bc;
517 }
518 
520 {
521  auto *bc = new GlobalCheckBoxSetting("AutoExpireWatchedPriority");
522 
523  bc->setLabel(GeneralSettings::tr("Watched before unwatched"));
524 
525  bc->setValue(false);
526 
527  bc->setHelpText(GeneralSettings::tr("If enabled, programs that have been "
528  "marked as watched will be expired "
529  "before programs that have not "
530  "been watched."));
531  return bc;
532 }
533 
535 {
536  auto *bs = new GlobalSpinBoxSetting("AutoExpireDayPriority", 1, 400, 1);
537 
538  bs->setLabel(GeneralSettings::tr("Priority weight"));
539 
540  bs->setHelpText(GeneralSettings::tr("The number of days bonus a program "
541  "gets for each priority point. This "
542  "is only used when the Weighted "
543  "time/priority Auto-Expire method "
544  "is selected."));
545  bs->setValue(3);
546 
547  return bs;
548 };
549 
551 {
552  auto *bs = new GlobalSpinBoxSetting("AutoExpireLiveTVMaxAge", 1, 365, 1);
553 
554  bs->setLabel(GeneralSettings::tr("Live TV max age (days)"));
555 
556  bs->setHelpText(GeneralSettings::tr("Auto-Expire will force expiration of "
557  "Live TV recordings when they are this "
558  "many days old. Live TV recordings may "
559  "also be expired early if necessary to "
560  "free up disk space."));
561  bs->setValue(1);
562 
563  return bs;
564 };
565 
566 #if 0
567 // Translations have been removed, please put back if reactivated...
568 static GlobalSpinBoxSetting *MinRecordDiskThreshold()
569 {
570  GlobalSpinBoxSetting *bs = new GlobalSpinBoxSetting("MinRecordDiskThreshold",
571  0, 1000000, 100);
572  bs->setLabel("New recording free disk space threshold "
573  "(MB)");
574  bs->setHelpText("MythTV will stop scheduling new recordings on "
575  "a backend when its free disk space (in megabytes) falls "
576  "below this value.");
577  bs->setValue(300);
578  return bs;
579 }
580 #endif
581 
583 {
584  auto *bc = new GlobalCheckBoxSetting("RerecordWatched");
585 
586  bc->setLabel(GeneralSettings::tr("Re-record watched"));
587 
588  bc->setValue(false);
589 
590  bc->setHelpText(GeneralSettings::tr("If enabled, programs that have been "
591  "marked as watched and are "
592  "Auto-Expired will be re-recorded if "
593  "they are shown again."));
594  return bc;
595 }
596 
598 {
599  auto *bs = new GlobalSpinBoxSetting("RecordPreRoll", 0, 600, 60, 1);
600 
601  bs->setLabel(GeneralSettings::tr("Time to record before start of show "
602  "(secs)"));
603 
604  bs->setHelpText(GeneralSettings::tr("This global setting allows the "
605  "recorder to start before the "
606  "scheduled start time. It does not "
607  "affect the scheduler. It is ignored "
608  "when two shows have been scheduled "
609  "without enough time in between."));
610  bs->setValue(0);
611 
612  return bs;
613 }
614 
616 {
617  auto *bs = new GlobalSpinBoxSetting("RecordOverTime", 0, 1800, 60, 1);
618 
619  bs->setLabel(GeneralSettings::tr("Time to record past end of show (secs)"));
620 
621  bs->setValue(0);
622 
623  bs->setHelpText(GeneralSettings::tr("This global setting allows the "
624  "recorder to record beyond the "
625  "scheduled end time. It does not "
626  "affect the scheduler. It is ignored "
627  "when two shows have been scheduled "
628  "without enough time in between."));
629  return bs;
630 }
631 
633 {
634  auto *bs = new GlobalSpinBoxSetting("MaxStartGap", 0, 300, 1, 15);
635 
636  bs->setLabel(GeneralSettings::tr("Maximum Start Gap (secs)"));
637 
638  bs->setValue(15);
639 
640  bs->setHelpText(GeneralSettings::tr("If more than this number of seconds "
641  "is missing at the start of a recording "
642  "that will be regarded as a gap for "
643  "assessing recording quality. The recording "
644  "may be marked as damaged."));
645  return bs;
646 }
647 
649 {
650  auto *bs = new GlobalSpinBoxSetting("MaxEndGap", 0, 300, 1, 15);
651 
652  bs->setLabel(GeneralSettings::tr("Maximum End Gap (secs)"));
653 
654  bs->setValue(15);
655 
656  bs->setHelpText(GeneralSettings::tr("If more than this number of seconds "
657  "is missing at the end of a recording "
658  "that will be regarded as a gap for "
659  "assessing recording quality. The recording "
660  "may be marked as damaged."));
661  return bs;
662 }
663 
665 {
666  auto *bs = new GlobalSpinBoxSetting("MinimumRecordingQuality", 0, 100, 1, 10);
667 
668  bs->setLabel(GeneralSettings::tr("Minimum Recording Quality (percent)"));
669 
670  bs->setValue(95);
671 
672  bs->setHelpText(GeneralSettings::tr("If recording quality is below this value the "
673  "recording is marked as damaged."));
674  return bs;
675 }
676 
678 {
679  auto *gc = new GlobalComboBoxSetting("OverTimeCategory");
680 
681  gc->setLabel(GeneralSettings::tr("Category of shows to be extended"));
682 
683  gc->setHelpText(GeneralSettings::tr("For a special category (e.g. "
684  "\"Sports event\"), request that "
685  "shows be autoextended. Only works "
686  "if a show's category can be "
687  "determined."));
688 
689  MSqlQuery query(MSqlQuery::InitCon());
690 
691  query.prepare("SELECT DISTINCT category FROM program GROUP BY category;");
692 
693  gc->addSelection("", "");
694  if (query.exec())
695  {
696  while (query.next())
697  {
698  QString key = query.value(0).toString();
699  if (!key.trimmed().isEmpty())
700  gc->addSelection(key, key);
701  }
702  }
703 
704  return gc;
705 }
706 
708 {
709  auto *bs = new GlobalSpinBoxSetting("CategoryOverTime", 0, 180, 60, 1);
710 
711  bs->setLabel(GeneralSettings::tr("Record past end of show (mins)"));
712 
713  bs->setValue(30);
714 
715  bs->setHelpText(GeneralSettings::tr("For the specified category, an "
716  "attempt will be made to extend "
717  "the recording by the specified "
718  "number of minutes. It is ignored "
719  "when two shows have been scheduled "
720  "without enough time in-between."));
721  return bs;
722 }
723 
725 {
726  auto *vcg = new GroupSetting();
727 
728  vcg->setLabel(GeneralSettings::tr("Category record over-time"));
729 
730  vcg->addChild(OverTimeCategory());
731  vcg->addChild(CategoryOverTime());
732 
733  return vcg;
734 }
735 
737  PlaybackProfileConfig *parent, uint idx, MythVideoProfileItem &_item) :
738  m_item(_item), m_parentConfig(parent), m_index(idx)
739 {
745  m_maxCpus = new TransMythUISpinBoxSetting(1, HAVE_THREADS ? VIDEO_MAX_CPUS : 1, 1, 1);
755 
756  const QString rangeHelp(tr(" Valid formats for the setting are "
757  "[nnnn - nnnn], [> nnnn], [>= nnnn], [< nnnn], "
758  "[<= nnnn]. Also [nnnn] for an exact match. "
759  "You can also use more than 1 expression with & between."));
760  const QString rangeHelpDec(tr("Numbers can have up to 3 decimal places."));
761  m_widthRange->setLabel(tr("Width Range"));
762  m_widthRange->setHelpText(tr("Optional setting to restrict this profile "
763  "to videos with a selected width range. ") + rangeHelp);
764  m_heightRange->setLabel(tr("Height Range"));
765  m_heightRange->setHelpText(tr("Optional setting to restrict this profile "
766  "to videos with a selected height range. ") + rangeHelp);
767  m_codecs->setLabel(tr("Video Formats"));
768  m_codecs->addSelection(tr("All formats"), " ", true);
769  m_codecs->addSelection("MPEG2", "mpeg2video");
770  m_codecs->addSelection("MPEG4", "mpeg4");
771  m_codecs->addSelection("H264", "h264");
772  m_codecs->addSelection("HEVC", "hevc");
773  m_codecs->addSelection("VP8", "vp8");
774  m_codecs->addSelection("VP9", "vp9");
775  m_codecs->addSelection("AV1", "av1");
776  m_codecs->setHelpText(tr("Optional setting to restrict this profile "
777  "to a video format or formats. You can also type in a format "
778  "or several formats separated by space. "
779  "To find the format for a video use ffprobe and look at the "
780  "word after \"Video:\". Also you can get a complete list "
781  "of available formats with ffmpeg -codecs."));
782  m_framerate->setLabel(tr("Frame Rate Range"));
783  m_framerate->setHelpText(tr("Optional setting to restrict this profile "
784  "to a range of frame rates. ") + rangeHelp +" "+rangeHelpDec);
785  m_decoder->setLabel(tr("Decoder"));
786  m_maxCpus->setLabel(tr("Max CPUs"));
787  m_skipLoop->setLabel(tr("Deblocking filter"));
788  m_vidRend->setLabel(tr("Video renderer"));
789  m_upscaler->setLabel(tr("Video scaler"));
790  auto scalers = MythVideoProfile::GetUpscalers();
791  for (const auto & scaler : scalers)
792  m_upscaler->addSelection(scaler.first, scaler.second);
793 
794  QString shaderdesc = "\t" + tr("Prefer OpenGL deinterlacers");
795  QString driverdesc = "\t" + tr("Prefer driver deinterlacers");
796  QString shaderhelp = tr("If possible, use GLSL shaders for deinterlacing in "
797  "preference to software deinterlacers. Note: Even if "
798  "disabled, shaders may be used if deinterlacing is "
799  "enabled but software deinterlacers are unavailable.");
800  QString driverhelp = tr("If possible, use hardware drivers (e.g. VDPAU, VAAPI) "
801  "for deinterlacing in preference to software and OpenGL "
802  "deinterlacers. Note: Even if disabled, driver deinterlacers "
803  "may be used if deinterlacing is enabled but other "
804  "deinterlacers are unavailable.");
805 
806  m_singleDeint->setLabel(tr("Deinterlacer quality (single rate)"));
807  m_singleShader->setLabel(shaderdesc);
808  m_singleDriver->setLabel(driverdesc);
809  m_doubleDeint->setLabel(tr("Deinterlacer quality (double rate)"));
810  m_doubleShader->setLabel(shaderdesc);
811  m_doubleDriver->setLabel(driverdesc);
812 
813  m_singleShader->setHelpText(shaderhelp);
814  m_doubleShader->setHelpText(shaderhelp);
815  m_singleDriver->setHelpText(driverhelp);
816  m_doubleDriver->setHelpText(driverhelp);
818  tr("Set the quality for single rate deinterlacing. Use 'None' to disable. "
819  "Higher quality deinterlacers require more system processing and resources. "
820  "Software deinterlacers are used by default unless OpenGL or driver preferences "
821  "are enabled."));
823  tr("Set the quality for double rate deinterlacing - which is only used "
824  "if the display can support the required frame rate. Use 'None' to "
825  "disable double rate deinterlacing."));
826 
827  m_singleShader->setEnabled(false);
828  m_singleDriver->setEnabled(false);
829  m_doubleShader->setEnabled(false);
830  m_doubleDriver->setEnabled(false);
831 
832  const QList<QPair<QString,QString> >& options = MythVideoProfile::GetDeinterlacers();
833  for (const auto & option : qAsConst(options))
834  {
835  m_singleDeint->addSelection(option.second, option.first);
836  m_doubleDeint->addSelection(option.second, option.first);
837  }
838 
840  tr("Maximum number of CPU cores used for video decoding and filtering.") +
841  (HAVE_THREADS ? "" :
842  tr(" Multithreaded decoding disabled-only one CPU "
843  "will be used, please recompile with "
844  "--enable-ffmpeg-pthreads to enable.")));
845 
847  tr("When unchecked the deblocking loopfilter will be disabled. ") + "\n" +
848  tr("Disabling will significantly reduce the load on the CPU for software decoding of "
849  "H.264 and HEVC material but may significantly reduce video quality."));
850 
852  "The default scaler provides good quality in the majority of situations. "
853  "Higher quality scalers may offer some benefit when scaling very low "
854  "resolution material but may not be as fast."));
855 
865 
872 
873  connect(m_widthRange, qOverload<const QString&>(&StandardSetting::valueChanged),
875  connect(m_heightRange, qOverload<const QString&>(&StandardSetting::valueChanged),
877  connect(m_codecs, qOverload<const QString&>(&StandardSetting::valueChanged),
879  connect(m_framerate, qOverload<const QString&>(&StandardSetting::valueChanged),
881  connect(m_decoder, qOverload<const QString&>(&StandardSetting::valueChanged),
883  connect(m_vidRend, qOverload<const QString&>(&StandardSetting::valueChanged),
885  connect(m_singleDeint, qOverload<const QString&>(&StandardSetting::valueChanged),
887  connect(m_doubleDeint, qOverload<const QString&>(&StandardSetting::valueChanged),
889 }
890 
892 {
893  return m_index;
894 }
895 
897 {
898  QString width_value;
899  QString height_value;
900  // pref_cmp0 and pref_cmp1 are no longer used. This code
901  // is here to convery them to the new settings cond_width
902  // and cond_height
903  for (uint i = 0; i < 2; ++i)
904  {
905  QString pcmp = m_item.Get(QString("pref_cmp%1").arg(i));
906  if (pcmp == "> 0 0")
907  continue;
908  QStringList clist = pcmp.split(" ");
909 
910  if (clist.size() < 3)
911  continue;
912  if (!width_value.isEmpty())
913  {
914  width_value.append("&");
915  height_value.append("&");
916  }
917  width_value.append(clist[0]+clist[1]);
918  height_value.append(clist[0]+clist[2]);
919  }
920 
921  QString tmp = m_item.Get(COND_WIDTH).trimmed();
922  if (!tmp.isEmpty())
923  {
924  if (!width_value.isEmpty())
925  width_value.append("&");
926  width_value.append(tmp);
927  }
928  tmp = m_item.Get(COND_HEIGHT).trimmed();
929  if (!tmp.isEmpty())
930  {
931  if (!height_value.isEmpty())
932  height_value.append("&");
933  height_value.append(tmp);
934  }
935 
936  m_widthRange->setValue(width_value);
937  m_heightRange->setValue(height_value);
938  auto codecs = m_item.Get(COND_CODECS);
939  if (codecs.isEmpty())
940  codecs = " ";
941  m_codecs->setValue(codecs);
943 
944  QString pdecoder = m_item.Get(PREF_DEC);
945  QString pmax_cpus = m_item.Get(PREF_CPUS);
946  QString pskiploop = m_item.Get(PREF_LOOP);
947  QString prenderer = m_item.Get(PREF_RENDER);
948  QString psingledeint = m_item.Get(PREF_DEINT1X);
949  QString pdoubledeint = m_item.Get(PREF_DEINT2X);
950  auto upscale = m_item.Get(PREF_UPSCALE);
951  if (upscale.isEmpty())
952  upscale = UPSCALE_DEFAULT;
953  bool found = false;
954 
955  QString dech = MythVideoProfile::GetDecoderHelp();
956  QStringList decr = MythVideoProfile::GetDecoders();
957  QStringList decn = MythVideoProfile::GetDecoderNames();
958  QStringList::const_iterator itr = decr.cbegin();
959  QStringList::const_iterator itn = decn.cbegin();
961  m_decoder->setHelpText(dech);
962  for (; (itr != decr.cend()) && (itn != decn.cend()); ++itr, ++itn)
963  {
964  m_decoder->addSelection(*itn, *itr, (*itr == pdecoder));
965  found |= (*itr == pdecoder);
966  }
967  if (!found && !pdecoder.isEmpty())
968  m_decoder->addSelection(MythVideoProfile::GetDecoderName(pdecoder), pdecoder, true);
970 
971  if (!pmax_cpus.isEmpty())
972  m_maxCpus->setValue(pmax_cpus.toInt());
973 
974  m_skipLoop->setValue((!pskiploop.isEmpty()) ? (pskiploop.toInt() > 0) : true);
975  m_upscaler->setValue(upscale);
976 
977  if (!prenderer.isEmpty())
978  m_vidRend->setValue(prenderer);
979 
982 
984 }
985 
987 {
988  m_item.Set("pref_cmp0", QString());
989  m_item.Set("pref_cmp1", QString());
996  m_item.Set(PREF_LOOP, (m_skipLoop->boolValue()) ? "1" : "0");
1001 }
1002 
1004 {
1005  bool ok = true;
1006  QString oldvalue = m_item.Get(COND_WIDTH);
1007  m_item.Set(COND_WIDTH, val);
1008  m_item.CheckRange(COND_WIDTH, 640, &ok);
1009  if (!ok)
1010  {
1011  ShowOkPopup(tr("Invalid width specification(%1), discarded").arg(val));
1012  m_widthRange->setValue(oldvalue);
1013  }
1014  InitLabel();
1015 }
1016 
1018 {
1019  bool ok = true;
1020  QString oldvalue = m_item.Get(COND_HEIGHT);
1021  m_item.Set(COND_HEIGHT,val);
1022  m_item.CheckRange(COND_HEIGHT, 480, &ok);
1023  if (!ok)
1024  {
1025  ShowOkPopup(tr("Invalid height specification(%1), discarded").arg(val));
1026  m_heightRange->setValue(oldvalue);
1027  }
1028  InitLabel();
1029 }
1030 
1032 {
1033  bool ok = true;
1034  QString oldvalue = m_item.Get(COND_RATE);
1035  m_item.Set(COND_RATE,val);
1036  m_item.CheckRange(COND_RATE, 25.0F, &ok);
1037  if (!ok)
1038  {
1039  ShowOkPopup(tr("Invalid frame rate specification(%1), discarded").arg(val));
1040  m_framerate->setValue(oldvalue);
1041  }
1042  InitLabel();
1043 }
1044 
1046 {
1047  QString vrenderer = m_vidRend->getValue();
1048  QStringList renderers = MythVideoProfile::GetVideoRenderers(dec);
1049 
1050  QString prenderer;
1051  for (const auto & rend : qAsConst(renderers))
1052  prenderer = (rend == vrenderer) ? vrenderer : prenderer;
1053  if (prenderer.isEmpty())
1055 
1057  for (const auto & rend : qAsConst(renderers))
1058  {
1059  if ((!rend.contains("null")))
1061  rend, (rend == prenderer));
1062  }
1063  QString vrenderer2 = m_vidRend->getValue();
1064  vrenderChanged(vrenderer2);
1065 
1067  InitLabel();
1068 }
1069 
1070 void PlaybackProfileItemConfig::vrenderChanged(const QString &renderer)
1071 {
1073  InitLabel();
1074 }
1075 
1077 {
1078  bool enabled = Quality != DEINT_QUALITY_NONE;
1079  m_singleShader->setEnabled(enabled);
1080  m_singleDriver->setEnabled(enabled);
1081 }
1082 
1084 {
1085  bool enabled = Quality != DEINT_QUALITY_NONE;
1086  m_doubleShader->setEnabled(enabled);
1087  m_doubleDriver->setEnabled(enabled);
1088 }
1089 
1100  QString &Value)
1101 {
1102  bool enabled = true;
1103 
1104  if (Value.contains(DEINT_QUALITY_HIGH))
1105  {
1106  Deint->setValue(DEINT_QUALITY_HIGH);
1107  }
1108  else if (Value.contains(DEINT_QUALITY_MEDIUM))
1109  {
1111  }
1112  else if (Value.contains(DEINT_QUALITY_LOW))
1113  {
1114  Deint->setValue(DEINT_QUALITY_LOW);
1115  }
1116  else
1117  {
1118  enabled = false;
1119  Deint->setValue(DEINT_QUALITY_NONE);
1120  }
1121 
1122  Shader->setValue(Value.contains(DEINT_QUALITY_SHADER));
1123  Driver->setValue(Value.contains(DEINT_QUALITY_DRIVER));
1124  Shader->setEnabled(enabled);
1125  Driver->setEnabled(enabled);
1126 }
1127 
1131 {
1132  QStringList values;
1133  QString quality = Deint->getValue();
1134  if (quality == DEINT_QUALITY_LOW || quality == DEINT_QUALITY_MEDIUM || quality == DEINT_QUALITY_HIGH)
1135  values.append(quality);
1136  else
1137  values.append(DEINT_QUALITY_NONE);
1138 
1139  // N.B. save these regardless to preserve preferences
1140  if (Shader->boolValue())
1141  values.append(DEINT_QUALITY_SHADER);
1142  if (Driver->boolValue())
1143  values.append(DEINT_QUALITY_DRIVER);
1144 
1145  return values.join(":");
1146 }
1147 
1149 {
1150  QStringList actions;
1151 
1152  if (GetMythMainWindow()->TranslateKeyPress("Global", e, actions))
1153  return true;
1154 
1155  if (std::any_of(actions.cbegin(), actions.cend(),
1156  [](const QString & action) { return action == "DELETE"; } ))
1157  {
1158  ShowDeleteDialog();
1159  return true;
1160  }
1161 
1162  return false;
1163 }
1164 
1166 {
1167  QString message = tr("Remove this profile item?");
1168  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
1169  auto *confirmDelete = new MythConfirmationDialog(popupStack, message, true);
1170 
1171  if (confirmDelete->Create())
1172  {
1173  connect(confirmDelete, &MythConfirmationDialog::haveResult,
1175  popupStack->AddScreen(confirmDelete);
1176  }
1177  else
1178  delete confirmDelete;
1179 }
1180 
1182 {
1183  if (doDelete)
1185 }
1186 
1188 {
1190 }
1191 
1193 {
1195 }
1196 
1198  StandardSetting *parent) :
1199  m_profileName(std::move(profilename))
1200 {
1201  setVisible(false);
1205  InitUI(parent);
1206 }
1207 
1209 {
1210  QStringList restrict;
1211  QString width = m_widthRange->getValue();
1212  if (!width.isEmpty())
1213  restrict << tr("Width", "video formats") + " " + width;
1214  QString height = m_heightRange->getValue();
1215  if (!height.isEmpty())
1216  restrict << tr("Height", "video formats") + " " + height;
1217  QString codecsval = m_codecs->getValue().trimmed();
1218  if (!codecsval.isEmpty())
1219  restrict << tr("Formats", "video formats") + " " + codecsval.toUpper();
1220  QString framerateval = m_framerate->getValue();
1221  if (!framerateval.isEmpty())
1222  restrict << tr("framerate") + " " + framerateval;
1223 
1224  QString str;
1225  if (!restrict.isEmpty())
1226  str += restrict.join(" ") + " -> ";
1228  str += " " + tr("&", "and") + ' ';
1230  setLabel(str);
1231 }
1232 
1234 {
1236  m_markForDeletion->setLabel(tr("Mark for deletion"));
1237  m_addNewEntry = new ButtonStandardSetting(tr("Add New Entry"));
1238 
1241 
1244 
1245  for (size_t i = 0; i < m_items.size(); ++i)
1246  InitProfileItem(i, parent);
1247 }
1248 
1250  uint i, StandardSetting *parent)
1251 {
1252  auto *ppic = new PlaybackProfileItemConfig(this, i, m_items[i]);
1253 
1254  m_items[i].Set("pref_priority", QString::number(i + 1));
1255 
1256  parent->addTargetedChild(m_profileName, ppic);
1257  m_profiles.push_back(ppic);
1258  return ppic;
1259 }
1260 
1262 {
1264  {
1267  return;
1268  }
1269 
1270  for (PlaybackProfileItemConfig *profile : qAsConst(m_profiles))
1271  {
1272  profile->Save();
1273  }
1274 
1276  if (!ok)
1277  {
1278  LOG(VB_GENERAL, LOG_ERR,
1279  "PlaybackProfileConfig::Save() -- failed to delete items");
1280  return;
1281  }
1282 
1284  if (!ok)
1285  {
1286  LOG(VB_GENERAL, LOG_ERR,
1287  "PlaybackProfileConfig::Save() -- failed to save items");
1288  return;
1289  }
1290 }
1291 
1293  PlaybackProfileItemConfig *profileToDelete)
1294 {
1295  for (PlaybackProfileItemConfig *profile : qAsConst(m_profiles))
1296  profile->Save();
1297 
1298  uint i = profileToDelete->GetIndex();
1299  m_delItems.push_back(m_items[i]);
1300  m_items.erase(m_items.begin() + i);
1301 
1302  ReloadSettings();
1303 }
1304 
1306 {
1307  for (PlaybackProfileItemConfig *profile : qAsConst(m_profiles))
1308  profile->Save();
1309  m_items.emplace_back();
1310  ReloadSettings();
1311 }
1312 
1314 {
1317 
1318  for (StandardSetting *setting : qAsConst(m_profiles))
1320  m_profiles.clear();
1321 
1322  InitUI(getParent());
1323  for (StandardSetting *setting : qAsConst(m_profiles))
1324  setting->Load();
1325  emit getParent()->settingsChanged();
1326  setChanged(true);
1327 }
1328 
1329 // This function doesn't guarantee that no exceptions will be thrown.
1330 // NOLINTNEXTLINE(performance-noexcept-swap)
1331 void PlaybackProfileConfig::swap(int indexA, int indexB)
1332 {
1333  for (PlaybackProfileItemConfig *profile : qAsConst(m_profiles))
1334  profile->Save();
1335 
1336  QString pri_i = QString::number(m_items[indexA].GetPriority());
1337  QString pri_j = QString::number(m_items[indexB].GetPriority());
1338 
1339  MythVideoProfileItem item = m_items[indexB];
1340  m_items[indexB] = m_items[indexA];
1341  m_items[indexA] = item;
1342 
1343  m_items[indexA].Set("pref_priority", pri_i);
1344  m_items[indexB].Set("pref_priority", pri_j);
1345 
1346  ReloadSettings();
1347 }
1348 
1350 {
1351  auto *grouptrigger = new HostComboBoxSetting("DefaultVideoPlaybackProfile");
1352  grouptrigger->setLabel(
1353  QCoreApplication::translate("PlaybackProfileConfigs",
1354  "Current Video Playback Profile"));
1355 
1356  QString host = gCoreContext->GetHostName();
1358  QStringList profiles = MythVideoProfile::GetProfiles(host);
1359 
1361  if (!profiles.contains(profile))
1362  {
1363  profile = (profiles.contains("Normal")) ? "Normal" : profiles[0];
1365  }
1366 
1367  for (const auto & prof : qAsConst(profiles))
1368  {
1369  grouptrigger->addSelection(ProgramInfo::i18n(prof), prof);
1370  grouptrigger->addTargetedChild(prof,
1371  new PlaybackProfileConfig(prof, grouptrigger));
1372  }
1373 
1374  return grouptrigger;
1375 }
1376 
1378 {
1379  QString msg = tr("Enter Playback Profile Name");
1380 
1381  MythScreenStack *popupStack =
1382  GetMythMainWindow()->GetStack("popup stack");
1383 
1384  auto *settingdialog = new MythTextInputDialog(popupStack, msg);
1385 
1386  if (settingdialog->Create())
1387  {
1388  connect(settingdialog, &MythTextInputDialog::haveResult,
1390  popupStack->AddScreen(settingdialog);
1391  }
1392  else
1393  delete settingdialog;
1394 }
1395 
1397 {
1398  QString host = gCoreContext->GetHostName();
1399  QStringList not_ok_list = MythVideoProfile::GetProfiles(host);
1400 
1401  if (not_ok_list.contains(name) || name.isEmpty())
1402  {
1403  QString msg = (name.isEmpty()) ?
1404  tr("Sorry, playback group\nname cannot be blank.") :
1405  tr("Sorry, playback group name\n"
1406  "'%1' is already being used.").arg(name);
1407 
1408  ShowOkPopup(msg);
1409 
1410  return;
1411  }
1412 
1416 
1417  m_playbackProfiles->addSelection(name, name, true);
1418 }
1419 
1421 {
1422  std::array<QString,4> str
1423  {
1424  PlaybackSettings::tr("Sort all sub-titles/multi-titles Ascending"),
1425  PlaybackSettings::tr("Sort all sub-titles/multi-titles Descending"),
1426  PlaybackSettings::tr("Sort sub-titles Descending, multi-titles "
1427  "Ascending"),
1428  PlaybackSettings::tr("Sort sub-titles Ascending, multi-titles Descending"),
1429  };
1430 
1431  QString help = PlaybackSettings::tr("Selects how to sort show episodes. "
1432  "Sub-titles refers to the episodes "
1433  "listed under a specific show title. "
1434  "Multi-title refers to sections (e.g. "
1435  "\"All Programs\") which list multiple "
1436  "titles. Sections in parentheses are "
1437  "not affected.");
1438 
1439  auto *gc = new HostComboBoxSetting("PlayBoxOrdering");
1440 
1441  gc->setLabel(PlaybackSettings::tr("Episode sort orderings"));
1442 
1443  for (size_t i = 0; i < str.size(); ++i)
1444  gc->addSelection(str[i], QString::number(i));
1445 
1446  gc->setValue(3);
1447  gc->setHelpText(help);
1448 
1449  return gc;
1450 }
1451 
1453 {
1454  auto *gc = new HostComboBoxSetting("PlayBoxEpisodeSort");
1455 
1456  gc->setLabel(PlaybackSettings::tr("Sort episodes"));
1457 
1458  gc->addSelection(PlaybackSettings::tr("Record date"), "Date");
1459  gc->addSelection(PlaybackSettings::tr("Season/Episode"), "Season");
1460  gc->addSelection(PlaybackSettings::tr("Original air date"), "OrigAirDate");
1461  gc->addSelection(PlaybackSettings::tr("Program ID"), "Id");
1462 
1463  gc->setHelpText(PlaybackSettings::tr("Selects how to sort a show's "
1464  "episodes"));
1465 
1466  return gc;
1467 }
1468 
1470 {
1471  auto *gs = new HostSpinBoxSetting("FFRewReposTime", 0, 200, 5);
1472 
1473  gs->setLabel(PlaybackSettings::tr("Fast forward/rewind reposition amount"));
1474 
1475  gs->setValue(100);
1476 
1477  gs->setHelpText(PlaybackSettings::tr("When exiting sticky keys fast "
1478  "forward/rewind mode, reposition "
1479  "this many 1/100th seconds before "
1480  "resuming normal playback. This "
1481  "compensates for the reaction time "
1482  "between seeing where to resume "
1483  "playback and actually exiting "
1484  "seeking."));
1485  return gs;
1486 }
1487 
1489 {
1490  auto *gc = new HostCheckBoxSetting("FFRewReverse");
1491 
1492  gc->setLabel(PlaybackSettings::tr("Reverse direction in fast "
1493  "forward/rewind"));
1494 
1495  gc->setValue(true);
1496 
1497  gc->setHelpText(PlaybackSettings::tr("If enabled, pressing the sticky "
1498  "rewind key in fast forward mode "
1499  "switches to rewind mode, and "
1500  "vice versa. If disabled, it will "
1501  "decrease the current speed or "
1502  "switch to play mode if the speed "
1503  "can't be decreased further."));
1504  return gc;
1505 }
1506 
1507 static void AddPaintEngine(GroupSetting* Group)
1508 {
1509  if (!Group)
1510  return;
1511 
1512  const QStringList options = MythPainterWindow::GetPainters();
1513 
1514  // Don't show an option if there is no choice. Do not offer Qt painter (but
1515  // MythPainterWindow will accept 'Qt' if overriden from the command line)
1516  if (options.size() <= 1)
1517  return;
1518 
1519  QString pref = GetMythDB()->GetSetting("PaintEngine", MythPainterWindow::GetDefaultPainter());
1520  auto* paint = new HostComboBoxSetting("PaintEngine");
1521  paint->setLabel(AppearanceSettings::tr("Paint engine"));
1522  for (const auto & option : options)
1523  paint->addSelection(option, option, option == pref);
1524 
1525  paint->setHelpText(AppearanceSettings::tr("This selects what MythTV uses to draw. "));
1526  Group->addChild(paint);
1527 }
1528 
1530 {
1531  auto *gc = new HostComboBoxSetting("MenuTheme");
1532 
1533  gc->setLabel(AppearanceSettings::tr("Menu theme"));
1534 
1535  QList<ThemeInfo> themelist = GetMythUI()->GetThemes(THEME_MENU);
1536 
1537  QList<ThemeInfo>::iterator it;
1538  for( it = themelist.begin(); it != themelist.end(); ++it )
1539  {
1540  gc->addSelection((*it).GetName(), (*it).GetDirectoryName(),
1541  (*it).GetDirectoryName() == "defaultmenu");
1542  }
1543 
1544  return gc;
1545 }
1546 
1547 #if 0
1548 static HostComboBoxSetting *DecodeVBIFormat()
1549 {
1550  QString beVBI = gCoreContext->GetSetting("VbiFormat");
1551  QString fmt = beVBI.toLower().left(4);
1552  int sel = (fmt == "pal ") ? 1 : ((fmt == "ntsc") ? 2 : 0);
1553 
1554  HostComboBoxSetting *gc = new HostComboBoxSetting("DecodeVBIFormat");
1555 
1556  gc->setLabel(OSDSettings::tr("Decode VBI format"));
1557 
1558  gc->addSelection(OSDSettings::tr("None"), "none",
1559  0 == sel);
1560  gc->addSelection(OSDSettings::tr("PAL teletext"), "pal_txt",
1561  1 == sel);
1562  gc->addSelection(OSDSettings::tr("NTSC closed caption"), "ntsc_cc",
1563  2 == sel);
1564 
1565  gc->setHelpText(
1566  OSDSettings::tr("If enabled, this overrides the mythtv-setup setting "
1567  "used during recording when decoding captions."));
1568 
1569  return gc;
1570 }
1571 #endif
1572 
1574 {
1575  static const QRegularExpression crlf { "[\r\n]" };
1576  static const QRegularExpression suffix { "(//.*)" };
1577 
1578  auto *gc = new HostComboBoxSetting("SubtitleCodec");
1579 
1580  gc->setLabel(OSDSettings::tr("Subtitle Codec"));
1581 
1582  // Translations are now done via FFmpeg(iconv). Get the list of
1583  // encodings that iconv supports.
1584  QScopedPointer<MythSystem>
1585  cmd(MythSystem::Create({"iconv", "-l"},
1587  cmd->Wait();
1588  QString results = cmd->GetStandardOutputStream()->readAll();
1589 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
1590  QStringList list = results.toLower().split(crlf, QString::SkipEmptyParts);
1591 #else
1592  QStringList list = results.toLower().split(crlf, Qt::SkipEmptyParts);
1593 #endif
1594  list.replaceInStrings(suffix, "");
1595  list.sort();
1596 
1597  for (const auto & codec : qAsConst(list))
1598  {
1599  QString val = QString(codec);
1600  gc->addSelection(val, val, val.toLower() == "utf-8");
1601  }
1602 
1603  return gc;
1604 }
1605 
1607 {
1608  auto *gc = new HostComboBoxSetting("ChannelOrdering");
1609 
1610  gc->setLabel(GeneralSettings::tr("Channel ordering"));
1611 
1612  gc->addSelection(GeneralSettings::tr("channel number"), "channum");
1613  gc->addSelection(GeneralSettings::tr("callsign"), "callsign");
1614 
1615  return gc;
1616 }
1617 
1619 {
1620  auto *gs = new HostSpinBoxSetting("VertScanPercentage", -100, 100, 1);
1621 
1622  gs->setLabel(PlaybackSettings::tr("Vertical scaling"));
1623 
1624  gs->setValue(0);
1625 
1626  gs->setHelpText(PlaybackSettings::tr("Adjust this if the image does not "
1627  "fill your screen vertically. Range "
1628  "-100% to 100%"));
1629  return gs;
1630 }
1631 
1633 {
1634  auto *gs = new HostSpinBoxSetting("HorizScanPercentage", -100, 100, 1);
1635 
1636  gs->setLabel(PlaybackSettings::tr("Horizontal scaling"));
1637 
1638  gs->setValue(0);
1639 
1640  gs->setHelpText(PlaybackSettings::tr("Adjust this if the image does not "
1641  "fill your screen horizontally. Range "
1642  "-100% to 100%"));
1643  return gs;
1644 };
1645 
1647 {
1648  auto *gs = new HostSpinBoxSetting("XScanDisplacement", -50, 50, 1);
1649 
1650  gs->setLabel(PlaybackSettings::tr("Scan displacement (X)"));
1651 
1652  gs->setValue(0);
1653 
1654  gs->setHelpText(PlaybackSettings::tr("Adjust this to move the image "
1655  "horizontally."));
1656 
1657  return gs;
1658 }
1659 
1661 {
1662  auto *gs = new HostSpinBoxSetting("YScanDisplacement", -50, 50, 1);
1663 
1664  gs->setLabel(PlaybackSettings::tr("Scan displacement (Y)"));
1665 
1666  gs->setValue(0);
1667 
1668  gs->setHelpText(PlaybackSettings::tr("Adjust this to move the image "
1669  "vertically."));
1670 
1671  return gs;
1672 };
1673 
1675 {
1676  auto *gc = new HostCheckBoxSetting("DefaultCCMode");
1677 
1678  gc->setLabel(OSDSettings::tr("Always display closed captioning or "
1679  "subtitles"));
1680 
1681  gc->setValue(false);
1682 
1683  gc->setHelpText(OSDSettings::tr("If enabled, captions will be displayed "
1684  "when playing back recordings or watching "
1685  "Live TV. Closed Captioning can be turned "
1686  "on or off by pressing \"T\" during"
1687  "playback."));
1688  return gc;
1689 }
1690 
1692 {
1693  auto *gc = new HostCheckBoxSetting("EnableMHEG");
1694 
1695  gc->setLabel(OSDSettings::tr("Enable interactive TV"));
1696 
1697  gc->setValue(false);
1698 
1699  gc->setHelpText(OSDSettings::tr("If enabled, interactive TV applications "
1700  "(MHEG) will be activated. This is used "
1701  "for teletext and logos for radio and "
1702  "channels that are currently off-air."));
1703  return gc;
1704 }
1705 
1707 {
1708  auto *gc = new HostCheckBoxSetting("EnableMHEGic");
1709  gc->setLabel(OSDSettings::tr("Enable network access for interactive TV"));
1710  gc->setValue(true);
1711  gc->setHelpText(OSDSettings::tr("If enabled, interactive TV applications "
1712  "(MHEG) will be able to access interactive "
1713  "content over the Internet. This is used "
1714  "for BBC iPlayer."));
1715  return gc;
1716 }
1717 
1719 {
1720  auto *combo = new HostComboBoxSetting("AudioVisualiser");
1721  combo->setLabel(OSDSettings::tr("Visualiser for audio only playback"));
1722  combo->setHelpText(OSDSettings::tr("Select a visualisation to use when there "
1723  "is no video. Defaults to none."));
1724  combo->addSelection("None", "");
1726  for (const auto & visual : qAsConst(visuals))
1727  combo->addSelection(visual, visual);
1728  return combo;
1729 }
1730 
1732 {
1733  auto *gc = new HostCheckBoxSetting("PersistentBrowseMode");
1734 
1735  gc->setLabel(OSDSettings::tr("Always use browse mode in Live TV"));
1736 
1737  gc->setValue(true);
1738 
1739  gc->setHelpText(OSDSettings::tr("If enabled, browse mode will "
1740  "automatically be activated whenever "
1741  "you use channel up/down while watching "
1742  "Live TV."));
1743  return gc;
1744 }
1745 
1747 {
1748  auto *gc = new HostCheckBoxSetting("BrowseAllTuners");
1749 
1750  gc->setLabel(OSDSettings::tr("Browse all channels"));
1751 
1752  gc->setValue(false);
1753 
1754  gc->setHelpText(OSDSettings::tr("If enabled, browse mode will show "
1755  "channels on all available recording "
1756  "devices, instead of showing channels "
1757  "on just the current recorder."));
1758  return gc;
1759 }
1760 
1762 {
1763  auto *gc = new HostCheckBoxSetting("UseProgStartMark");
1764 
1765  gc->setLabel(PlaybackSettings::tr("Playback from start of program"));
1766 
1767  gc->setValue(false);
1768 
1769  gc->setHelpText(PlaybackSettings::tr("If enabled and no bookmark is set, "
1770  "playback starts at the program "
1771  "scheduled start time rather than "
1772  "the beginning of the recording. "
1773  "Useful for automatically skipping "
1774  "'start early' parts of a recording."));
1775  return gc;
1776 }
1777 
1779 {
1780  auto *gc = new HostComboBoxSetting("PlaybackExitPrompt");
1781 
1782  gc->setLabel(PlaybackSettings::tr("Action on playback exit"));
1783 
1784  gc->addSelection(PlaybackSettings::tr("Just exit"), "0");
1785  gc->addSelection(PlaybackSettings::tr("Clear last played position and exit"), "16");
1786  gc->addSelection(PlaybackSettings::tr("Always prompt (excluding Live TV)"),
1787  "1");
1788  gc->addSelection(PlaybackSettings::tr("Always prompt (including Live TV)"),
1789  "4");
1790  gc->addSelection(PlaybackSettings::tr("Prompt for Live TV only"), "8");
1791 
1792  gc->setHelpText(PlaybackSettings::tr("If set to prompt, a menu will be "
1793  "displayed when you exit playback "
1794  "mode. The options available will "
1795  "allow you delete the recording, "
1796  "continue watching, or exit."));
1797  return gc;
1798 }
1799 
1801 {
1802  auto *gc = new HostCheckBoxSetting("EndOfRecordingExitPrompt");
1803 
1804  gc->setLabel(PlaybackSettings::tr("Prompt at end of recording"));
1805 
1806  gc->setValue(false);
1807 
1808  gc->setHelpText(PlaybackSettings::tr("If enabled, a menu will be displayed "
1809  "allowing you to delete the recording "
1810  "when it has finished playing."));
1811  return gc;
1812 }
1813 
1815 {
1816  auto *gc = new HostCheckBoxSetting("MusicChoiceEnabled");
1817 
1818  gc->setLabel(PlaybackSettings::tr("Enable Music Choice"));
1819 
1820  gc->setValue(false);
1821 
1822  gc->setHelpText(PlaybackSettings::tr("Enable this to improve playing of Music Choice channels "
1823  "or recordings from those channels. "
1824  "These are audio channels with slide show "
1825  "from some cable providers. "
1826  "In unusual situations this could cause lip sync problems "
1827  "watching normal videos or TV shows."));
1828  return gc;
1829 }
1830 
1832 {
1833  auto *gc = new HostCheckBoxSetting("JumpToProgramOSD");
1834 
1835  gc->setLabel(PlaybackSettings::tr("Jump to program OSD"));
1836 
1837  gc->setValue(true);
1838 
1839  gc->setHelpText(PlaybackSettings::tr("Set the choice between viewing the "
1840  "current recording group in the OSD, "
1841  "or showing the 'Watch Recording' "
1842  "screen when 'Jump to Program' is "
1843  "activated. If enabled, the "
1844  "recordings are shown in the OSD"));
1845  return gc;
1846 }
1847 
1849 {
1850  auto *gc = new HostCheckBoxSetting("ContinueEmbeddedTVPlay");
1851 
1852  gc->setLabel(PlaybackSettings::tr("Continue playback when embedded"));
1853 
1854  gc->setValue(false);
1855 
1856  gc->setHelpText(PlaybackSettings::tr("If enabled, TV playback continues "
1857  "when the TV window is embedded in "
1858  "the upcoming program list or "
1859  "recorded list. The default is to "
1860  "pause the recorded show when "
1861  "embedded."));
1862  return gc;
1863 }
1864 
1866 {
1867  auto *gc = new HostCheckBoxSetting("AutomaticSetWatched");
1868 
1869  gc->setLabel(PlaybackSettings::tr("Automatically mark a recording as "
1870  "watched"));
1871 
1872  gc->setValue(false);
1873 
1874  gc->setHelpText(PlaybackSettings::tr("If enabled, when you exit near the "
1875  "end of a recording it will be marked "
1876  "as watched. The automatic detection "
1877  "is not foolproof, so do not enable "
1878  "this setting if you don't want an "
1879  "unwatched recording marked as "
1880  "watched."));
1881  return gc;
1882 }
1883 
1885 {
1886  auto *gs = new HostSpinBoxSetting("LiveTVIdleTimeout", 0, 3600, 1);
1887 
1888  gs->setLabel(PlaybackSettings::tr("Live TV idle timeout (mins)"));
1889 
1890  gs->setValue(0);
1891 
1892  gs->setHelpText(PlaybackSettings::tr("Exit Live TV automatically if left "
1893  "idle for the specified number of "
1894  "minutes. 0 disables the timeout."));
1895  return gs;
1896 }
1897 
1898 // static HostCheckBoxSetting *PlaybackPreview()
1899 // {
1900 // HostCheckBoxSetting *gc = new HostCheckBoxSetting("PlaybackPreview");
1901 //
1902 // gc->setLabel(PlaybackSettings::tr("Display live preview of recordings"));
1903 //
1904 // gc->setValue(true);
1905 //
1906 // gc->setHelpText(PlaybackSettings::tr("If enabled, a preview of the recording "
1907 // "will play in a small window on the \"Watch a "
1908 // "Recording\" menu."));
1909 //
1910 // return gc;
1911 // }
1912 //
1913 // static HostCheckBoxSetting *HWAccelPlaybackPreview()
1914 // {
1915 // HostCheckBoxSetting *gc = new HostCheckBoxSetting("HWAccelPlaybackPreview");
1916 //
1917 // gc->setLabel(PlaybackSettings::tr("Use HW Acceleration for live recording preview"));
1918 //
1919 // gc->setValue(false);
1920 //
1921 // gc->setHelpText(
1922 // PlaybackSettings::tr(
1923 // "If enabled, live recording preview will use hardware "
1924 // "acceleration. The video renderer used is determined by the "
1925 // "selected CPU profile. Disable if playback is sluggish or "
1926 // "causes high CPU load"));
1927 //
1928 // return gc;
1929 // }
1930 
1932 {
1933  auto *gc = new HostCheckBoxSetting("UseVirtualKeyboard");
1934 
1935  gc->setLabel(MainGeneralSettings::tr("Use line edit virtual keyboards"));
1936 
1937  gc->setValue(true);
1938 
1939  gc->setHelpText(MainGeneralSettings::tr("If enabled, you can use a virtual "
1940  "keyboard in MythTV's line edit "
1941  "boxes. To use, hit SELECT (Enter "
1942  "or Space) while a line edit is in "
1943  "focus."));
1944  return gc;
1945 }
1946 
1948 {
1949  auto *gs = new HostSpinBoxSetting("FrontendIdleTimeout", 0, 360, 5);
1950 
1951  gs->setLabel(MainGeneralSettings::tr("Idle time before entering standby "
1952  "mode (minutes)"));
1953 
1954  gs->setValue(90);
1955 
1956  gs->setHelpText(MainGeneralSettings::tr("Number of minutes to wait when "
1957  "the frontend is idle before "
1958  "entering standby mode. Standby "
1959  "mode allows the backend to power "
1960  "down if configured to do so. Any "
1961  "remote or mouse input will cause "
1962  "the countdown to start again "
1963  "and/or exit idle mode. Video "
1964  "playback suspends the countdown. "
1965  "A value of zero prevents the "
1966  "frontend automatically entering "
1967  "standby."));
1968  return gs;
1969 }
1970 
1972 {
1973  auto * checkbox = new HostCheckBoxSetting("ConfirmPowerEvent");
1974  checkbox->setValue(true);
1975  checkbox->setLabel(MainGeneralSettings::tr("Confirm before suspending/shutting down"));
1976  checkbox->setHelpText(MainGeneralSettings::tr(
1977  "If enabled (the default) then the user will always be asked to confirm before the system "
1978  "is shutdown, suspended or rebooted."));
1979  return checkbox;
1980 }
1981 
1983 {
1984  auto *gc = new HostComboBoxSetting("OverrideExitMenu");
1985 
1986  gc->setLabel(MainGeneralSettings::tr("Customize exit menu options"));
1987 
1988  gc->addSelection(MainGeneralSettings::tr("Default"), "0");
1989  gc->addSelection(MainGeneralSettings::tr("Show quit"), "1");
1990  gc->addSelection(MainGeneralSettings::tr("Show quit and suspend"), "9");
1991  gc->addSelection(MainGeneralSettings::tr("Show quit and shutdown"), "2");
1992  gc->addSelection(MainGeneralSettings::tr("Show quit, reboot and shutdown"), "3");
1993  gc->addSelection(MainGeneralSettings::tr("Show quit, reboot, shutdown and suspend"), "10");
1994  gc->addSelection(MainGeneralSettings::tr("Show shutdown"), "4");
1995  gc->addSelection(MainGeneralSettings::tr("Show reboot"), "5");
1996  gc->addSelection(MainGeneralSettings::tr("Show reboot and shutdown"), "6");
1997  gc->addSelection(MainGeneralSettings::tr("Show standby"), "7");
1998  gc->addSelection(MainGeneralSettings::tr("Show suspend"), "8");
1999 
2000  QString helptext = MainGeneralSettings::tr("By default, only remote frontends are shown "
2001  "the shutdown option on the exit menu. Here "
2002  "you can force specific shutdown, reboot and suspend "
2003  "options to be displayed.");
2004  if (Power)
2005  {
2006  QStringList supported = Power->GetFeatureList();
2007  if (!supported.isEmpty())
2008  {
2009  helptext.prepend(MainGeneralSettings::tr(
2010  "This system supports '%1' without additional setup. ")
2011  .arg(supported.join(", ")));
2012  }
2013  else
2014  {
2015  helptext.append(MainGeneralSettings::tr(
2016  " This system appears to have no power options available. Try "
2017  "setting the Halt/Reboot/Suspend commands below."));
2018  }
2019  }
2020  gc->setHelpText(helptext);
2021 
2022  return gc;
2023 }
2024 
2025 #ifndef Q_OS_ANDROID
2027 {
2028  auto *ge = new HostTextEditSetting("RebootCommand");
2029  ge->setLabel(MainGeneralSettings::tr("Reboot command"));
2030  ge->setValue("");
2031  QString help = MainGeneralSettings::tr(
2032  "Optional. Script to run if you select the reboot option from the "
2033  "exit menu, if the option is displayed. You must configure an "
2034  "exit key to display the exit menu.");
2035  if (Power && Power->IsFeatureSupported(MythPower::FeatureRestart))
2036  {
2037  help.append(MainGeneralSettings::tr(
2038  " Note: This system appears to support reboot without using this setting."));
2039  }
2040  ge->setHelpText(help);
2041  return ge;
2042 }
2043 
2045 {
2046  auto *suspend = new HostTextEditSetting("SuspendCommand");
2047  suspend->setLabel(MainGeneralSettings::tr("Suspend command"));
2048  suspend->setValue("");
2049  QString help = MainGeneralSettings::tr(
2050  "Optional: Script to run if you select the suspend option from the "
2051  "exit menu, if the option is displayed.");
2052 
2053  if (Power && Power->IsFeatureSupported(MythPower::FeatureSuspend))
2054  {
2055  help.append(MainGeneralSettings::tr(
2056  " Note: This system appears to support suspend without using this setting."));
2057  }
2058  suspend->setHelpText(help);
2059  return suspend;
2060 }
2061 
2063 {
2064  auto *ge = new HostTextEditSetting("HaltCommand");
2065  ge->setLabel(MainGeneralSettings::tr("Halt command"));
2066  ge->setValue("");
2067  QString help = MainGeneralSettings::tr("Optional. Script to run if you "
2068  "select the shutdown option from "
2069  "the exit menu, if the option is "
2070  "displayed. You must configure an "
2071  "exit key to display the exit "
2072  "menu.");
2073  if (Power && Power->IsFeatureSupported(MythPower::FeatureShutdown))
2074  {
2075  help.append(MainGeneralSettings::tr(
2076  " Note: This system appears to support shutdown without using this setting."));
2077  }
2078 
2079  ge->setHelpText(help);
2080  return ge;
2081 }
2082 #endif
2083 
2085 {
2086  auto *ge = new HostTextEditSetting("LircSocket");
2087 
2088  ge->setLabel(MainGeneralSettings::tr("LIRC daemon socket"));
2089 
2090  /* lircd socket moved from /dev/ to /var/run/lirc/ in lirc 0.8.6 */
2091  QString lirc_socket = "/dev/lircd";
2092 
2093  if (!QFile::exists(lirc_socket))
2094  lirc_socket = "/var/run/lirc/lircd";
2095 
2096  ge->setValue(lirc_socket);
2097 
2098  QString help = MainGeneralSettings::tr("UNIX socket or IP address[:port] "
2099  "to connect in order to communicate "
2100  "with the LIRC Daemon.");
2101  ge->setHelpText(help);
2102 
2103  return ge;
2104 }
2105 
2107 {
2108  auto *ge = new HostTextEditSetting("ScreenShotPath");
2109 
2110  ge->setLabel(MainGeneralSettings::tr("Screen shot path"));
2111 
2112  ge->setValue("/tmp/");
2113 
2114  ge->setHelpText(MainGeneralSettings::tr("Path to screenshot storage "
2115  "location. Should be writable "
2116  "by the frontend"));
2117 
2118  return ge;
2119 }
2120 
2122 {
2123  auto *ge = new HostTextEditSetting("SetupPinCode");
2124 
2125  ge->setLabel(MainGeneralSettings::tr("Setup PIN code"));
2126 
2127  ge->setHelpText(MainGeneralSettings::tr("This PIN is used to control "
2128  "access to the setup menus. "
2129  "If you want to use this feature, "
2130  "then setting the value to all "
2131  "numbers will make your life much "
2132  "easier. Set it to blank to "
2133  "disable. If enabled, you will not "
2134  "be able to return to this screen "
2135  "and reset the Setup PIN without "
2136  "first entering the current PIN."));
2137  return ge;
2138 }
2139 
2141 {
2142  auto *gc = new HostComboBoxSetting("XineramaScreen", false);
2143  gc->setLabel(AppearanceSettings::tr("Display on screen"));
2144  gc->setValue(0);
2145  gc->setHelpText(AppearanceSettings::tr("Run on the specified screen or "
2146  "spanning all screens."));
2147  return gc;
2148 }
2149 
2150 
2152 {
2153  auto *gc = new HostComboBoxSetting("XineramaMonitorAspectRatio");
2154 
2155  gc->setLabel(AppearanceSettings::tr("Screen aspect ratio"));
2156  gc->addSelection(AppearanceSettings::tr("Auto (Assume square pixels)"), "-1.0");
2157  gc->addSelection(AppearanceSettings::tr("Auto (Detect from display)"), "0.0");
2158  gc->addSelection("16:9", "1.7777");
2159  gc->addSelection("16:10", "1.6");
2160  gc->addSelection("21:9", "2.3704"); // N.B. Actually 64:27
2161  gc->addSelection("32:9", "3.5555");
2162  gc->addSelection("256:135", "1.8963"); // '4K HD'
2163  gc->addSelection("3:2", "1.5");
2164  gc->addSelection("5:4", "1.25");
2165  gc->addSelection("4:3", "1.3333");
2166  gc->addSelection(AppearanceSettings::tr("16:18 (16:9 Above and below)"), "0.8888");
2167  gc->addSelection(AppearanceSettings::tr("32:10 (16:10 Side by side)"), "3.2");
2168  gc->addSelection(AppearanceSettings::tr("16:20 (16:10 Above and below)"), "0.8");
2169  gc->setHelpText(AppearanceSettings::tr(
2170  "This setting applies to video playback only, not to the GUI. "
2171  "Most modern displays have square pixels and the aspect ratio of the screen can be "
2172  "computed from the resolution (default). "
2173  "The aspect ratio can also be automatically detected from the connected display "
2174  "- though this may be slightly less accurate. If automatic detection fails, the correct "
2175  "aspect ratio can be specified here. Note: Some values (e.g 32:10) are "
2176  "primarily intended for multiscreen setups."));
2177  return gc;
2178 }
2179 
2181 {
2182  auto *gc = new HostComboBoxSetting("LetterboxColour");
2183 
2184  gc->setLabel(PlaybackSettings::tr("Letterboxing color"));
2185 
2186  for (int m = kLetterBoxColour_Black; m < kLetterBoxColour_END; ++m)
2187  gc->addSelection(toString((LetterBoxColour)m), QString::number(m));
2188 
2189  gc->setHelpText(PlaybackSettings::tr("By default MythTV uses black "
2190  "letterboxing to match broadcaster "
2191  "letterboxing, but those with plasma "
2192  "screens may prefer gray to minimize "
2193  "burn-in."));
2194  return gc;
2195 }
2196 
2198 {
2199  auto * cb = new HostCheckBoxSetting("DiscardStereo3D");
2200  cb->setValue(true);
2201  cb->setLabel("Discard 3D stereoscopic fields");
2202  cb->setHelpText(PlaybackSettings::tr(
2203  "If 'Side by Side' or 'Top and Bottom' 3D material is detected, "
2204  "enabling this setting will discard one field (enabled by default)."));
2205  return cb;
2206 }
2207 
2209 {
2210  auto *gc = new HostComboBoxSetting("AspectOverride");
2211 
2212  gc->setLabel(PlaybackSettings::tr("Video aspect override"));
2213 
2214  for (int m = kAspect_Off; m < kAspect_END; ++m)
2215  gc->addSelection(toString((AspectOverrideMode)m), QString::number(m));
2216 
2217  gc->setHelpText(PlaybackSettings::tr("When enabled, these will override "
2218  "the aspect ratio specified by any "
2219  "broadcaster for all video streams."));
2220  return gc;
2221 }
2222 
2224 {
2225  auto *gc = new HostComboBoxSetting("AdjustFill");
2226 
2227  gc->setLabel(PlaybackSettings::tr("Zoom"));
2228 
2229  for (int m = kAdjustFill_Off; m < kAdjustFill_END; ++m)
2230  gc->addSelection(toString((AdjustFillMode)m), QString::number(m));
2232  QString::number(kAdjustFill_AutoDetect_DefaultOff));
2234  QString::number(kAdjustFill_AutoDetect_DefaultHalf));
2235 
2236  gc->setHelpText(PlaybackSettings::tr("When enabled, these will apply a "
2237  "predefined zoom to all video "
2238  "playback in MythTV."));
2239  return gc;
2240 }
2241 
2242 // Theme settings
2243 
2245 {
2246  auto *gs = new HostSpinBoxSetting("GuiWidth", 0, 3840, 8, 1);
2247 
2248  gs->setLabel(AppearanceSettings::tr("GUI width (pixels)"));
2249 
2250  gs->setValue(0);
2251 
2252  gs->setHelpText(AppearanceSettings::tr("The width of the GUI. Do not make "
2253  "the GUI wider than your actual "
2254  "screen resolution. Set to 0 to "
2255  "automatically scale to "
2256  "fullscreen."));
2257  return gs;
2258 }
2259 
2261 {
2262  auto *gs = new HostSpinBoxSetting("GuiHeight", 0, 2160, 8, 1);
2263 
2264  gs->setLabel(AppearanceSettings::tr("GUI height (pixels)"));
2265 
2266  gs->setValue(0);
2267 
2268  gs->setHelpText(AppearanceSettings::tr("The height of the GUI. Do not make "
2269  "the GUI taller than your actual "
2270  "screen resolution. Set to 0 to "
2271  "automatically scale to "
2272  "fullscreen."));
2273  return gs;
2274 }
2275 
2277 {
2278  auto *gs = new HostSpinBoxSetting("GuiOffsetX", -3840, 3840, 32, 1);
2279 
2280  gs->setLabel(AppearanceSettings::tr("GUI X offset"));
2281 
2282  gs->setValue(0);
2283 
2284  gs->setHelpText(AppearanceSettings::tr("The horizontal offset where the "
2285  "GUI will be displayed. May only "
2286  "work if run in a window."));
2287  return gs;
2288 }
2289 
2291 {
2292  auto *gs = new HostSpinBoxSetting("GuiOffsetY", -1600, 1600, 8, 1);
2293 
2294  gs->setLabel(AppearanceSettings::tr("GUI Y offset"));
2295 
2296  gs->setValue(0);
2297 
2298  gs->setHelpText(AppearanceSettings::tr("The vertical offset where the "
2299  "GUI will be displayed."));
2300  return gs;
2301 }
2302 
2304 {
2305  auto *gc = new HostCheckBoxSetting("GuiSizeForTV");
2306 
2307  gc->setLabel(AppearanceSettings::tr("Use GUI size for TV playback"));
2308 
2309  gc->setValue(true);
2310 
2311  gc->setHelpText(AppearanceSettings::tr("If enabled, use the above size for "
2312  "TV, otherwise use full screen."));
2313  return gc;
2314 }
2315 
2317 {
2318  auto *gc = new HostCheckBoxSetting("ForceFullScreen");
2319 
2320  gc->setLabel(AppearanceSettings::tr("Force Full Screen for GUI and TV playback"));
2321 
2322  gc->setValue(false);
2323 
2324  gc->setHelpText(AppearanceSettings::tr(
2325  "Use Full Screen for GUI and TV playback independent of the settings for "
2326  "the GUI dimensions. This does not change the values of the GUI dimensions "
2327  "so it is easy to switch from window mode to full screen and back."));
2328  return gc;
2329 }
2330 
2332 {
2333  HostCheckBoxSetting *gc = new VideoModeSettings("UseVideoModes");
2334 
2335  gc->setLabel(VideoModeSettings::tr("Separate video modes for GUI and "
2336  "TV playback"));
2337 
2338  gc->setValue(false);
2339 
2340  gc->setHelpText(VideoModeSettings::tr(
2341  "Switch video modes for playback depending on the source "
2342  "resolution and frame rate."));
2343  return gc;
2344 }
2345 
2347 {
2348  auto *gs = new HostSpinBoxSetting(QString("VidModeWidth%1").arg(idx),
2349  0, 3840, 16, 1);
2350 
2351  gs->setLabel(VideoModeSettings::tr("In X", "Video mode width"));
2352 
2353  gs->setValue(0);
2354 
2355  gs->setHelpText(VideoModeSettings::tr("Horizontal resolution of video "
2356  "which needs a special output "
2357  "resolution."));
2358  return gs;
2359 }
2360 
2362 {
2363  auto *gs = new HostSpinBoxSetting(QString("VidModeHeight%1").arg(idx),
2364  0, 2160, 16, 1);
2365 
2366  gs->setLabel(VideoModeSettings::tr("In Y", "Video mode height"));
2367 
2368  gs->setValue(0);
2369 
2370  gs->setHelpText(VideoModeSettings::tr("Vertical resolution of video "
2371  "which needs a special output "
2372  "resolution."));
2373  return gs;
2374 }
2375 
2377 {
2378  auto *gc = new HostComboBoxSetting("GuiVidModeResolution");
2379 
2380  gc->setLabel(VideoModeSettings::tr("GUI"));
2381 
2382  gc->setHelpText(VideoModeSettings::tr("Resolution of screen when not "
2383  "watching a video."));
2384 
2385  MythDisplay* display = GetMythMainWindow()->GetDisplay();
2386  std::vector<MythDisplayMode> scr = display->GetVideoModes();
2387  for (auto & vmode : scr)
2388  {
2389  int w = vmode.Width();
2390  int h = vmode.Height();
2391  QString sel = QString("%1x%2").arg(w).arg(h);
2392  gc->addSelection(sel, sel);
2393  }
2394 
2395  // if no resolution setting, set it with a reasonable initial value
2396  if (!scr.empty() && (gCoreContext->GetSetting("GuiVidModeResolution").isEmpty()))
2397  {
2398  int w = 0;
2399  int h = 0;
2400  gCoreContext->GetResolutionSetting("GuiVidMode", w, h);
2401  if ((w <= 0) || (h <= 0))
2402  {
2403  w = 640;
2404  h = 480;
2405  }
2406 
2407  MythDisplayMode dscr(w, h, -1, -1, -1.0, 0);
2408  double rate = -1.0;
2409  int i = MythDisplayMode::FindBestMatch(scr, dscr, rate);
2410  gc->setValue((i >= 0) ? i : scr.size() - 1);
2411  }
2412 
2413  return gc;
2414 }
2415 
2417 {
2418  QString dhelp = VideoModeSettings::tr("Default screen resolution "
2419  "when watching a video.");
2420  QString ohelp = VideoModeSettings::tr("Screen resolution when watching a "
2421  "video at a specific resolution.");
2422 
2423  QString qstr = (idx<0) ? "TVVidModeResolution" :
2424  QString("TVVidModeResolution%1").arg(idx);
2425  auto *gc = new HostComboBoxSetting(qstr);
2426  QString lstr = (idx<0) ? VideoModeSettings::tr("Video output") :
2427  VideoModeSettings::tr("Output");
2428  QString hstr = (idx<0) ? dhelp : ohelp;
2429 
2430  gc->setLabel(lstr);
2431 
2432  gc->setHelpText(hstr);
2433 
2434  MythDisplay* display = GetMythMainWindow()->GetDisplay();
2435  std::vector<MythDisplayMode> scr = display->GetVideoModes();
2436  for (auto & vmode : scr)
2437  {
2438  QString sel = QString("%1x%2").arg(vmode.Width()).arg(vmode.Height());
2439  gc->addSelection(sel, sel);
2440  }
2441 
2442  return gc;
2443 }
2444 
2446 {
2447  const QString previousValue = getValue();
2448  const bool wasUnchanged = !haveChanged();
2449 
2450  clearSelections();
2451  QString resolution = setting->getValue();
2452  int hz50 = -1;
2453  int hz60 = -1;
2454  const std::vector<double> list = GetRefreshRates(resolution);
2455  addSelection(QObject::tr("Auto"), "0");
2456  for (size_t i = 0; i < list.size(); ++i)
2457  {
2458  QString sel = QString::number((double) list[i], 'f', 3);
2459  addSelection(sel + " Hz", sel, sel == previousValue);
2460  hz50 = (fabs(50.0 - list[i]) < 0.01) ? i : hz50;
2461  hz60 = (fabs(60.0 - list[i]) < 0.01) ? i : hz60;
2462  }
2463 
2464  // addSelection() will cause setValue() to be called, marking the setting as
2465  // changed even though the previous value might still be available. Mark it
2466  // as unchanged in this case if it wasn't already changed.
2467  if (wasUnchanged && previousValue == getValue())
2468  setChanged(false);
2469  else
2470  {
2471  if ("640x480" == resolution || "720x480" == resolution)
2472  setValue(hz60+1);
2473  if ("640x576" == resolution || "720x576" == resolution)
2474  setValue(hz50+1);
2475  }
2476 
2477  setEnabled(!list.empty());
2478 }
2479 
2480 std::vector<double> HostRefreshRateComboBoxSetting::GetRefreshRates(const QString &res)
2481 {
2482  QStringList slist = res.split("x");
2483  int width = 0;
2484  int height = 0;
2485  bool ok0 = false;
2486  bool ok1 = false;
2487  if (2 == slist.size())
2488  {
2489  width = slist[0].toInt(&ok0);
2490  height = slist[1].toInt(&ok1);
2491  }
2492 
2493  std::vector<double> result;
2494  if (ok0 && ok1)
2495  {
2496  QSize size(width, height);
2497  MythDisplay* display = GetMythMainWindow()->GetDisplay();
2498  result = display->GetRefreshRates(size);
2499  }
2500  return result;
2501 }
2502 
2504 {
2505  QString dhelp = VideoModeSettings::tr("Default refresh rate when watching "
2506  "a video. Leave at \"Auto\" to "
2507  "automatically use the best "
2508  "available");
2509  QString ohelp = VideoModeSettings::tr("Refresh rate when watching a "
2510  "video at a specific resolution. "
2511  "Leave at \"Auto\" to automatically "
2512  "use the best available");
2513 
2514  QString qstr = (idx<0) ? "TVVidModeRefreshRate" :
2515  QString("TVVidModeRefreshRate%1").arg(idx);
2516  auto *gc = new HostRefreshRateComboBoxSetting(qstr);
2517  QString lstr = VideoModeSettings::tr("Rate");
2518  QString hstr = (idx<0) ? dhelp : ohelp;
2519 
2520  gc->setLabel(lstr);
2521  gc->setHelpText(hstr);
2522  gc->setEnabled(false);
2523  return gc;
2524 }
2525 
2527 {
2528  QString dhelp = VideoModeSettings::tr("Aspect ratio when watching a "
2529  "video. Leave at \"%1\" to "
2530  "use ratio reported by the monitor. "
2531  "Set to 16:9 or 4:3 to force a "
2532  "specific aspect ratio.");
2533 
2534 
2535 
2536  QString ohelp = VideoModeSettings::tr("Aspect ratio when watching a "
2537  "video at a specific resolution. "
2538  "Leave at \"%1\" to use ratio "
2539  "reported by the monitor. Set to "
2540  "16:9 or 4:3 to force a specific "
2541  "aspect ratio.");
2542 
2543  QString qstr = (idx<0) ? "TVVidModeForceAspect" :
2544  QString("TVVidModeForceAspect%1").arg(idx);
2545 
2546  auto *gc = new HostComboBoxSetting(qstr);
2547 
2548  gc->setLabel(VideoModeSettings::tr("Aspect"));
2549 
2550  QString hstr = (idx<0) ? dhelp : ohelp;
2551 
2552  gc->setHelpText(hstr.arg(VideoModeSettings::tr("Default")));
2553 
2554  gc->addSelection(VideoModeSettings::tr("Default"), "0.0");
2555  gc->addSelection("16:9", "1.77777777777");
2556  gc->addSelection("4:3", "1.33333333333");
2557 
2558  return gc;
2559 }
2560 
2562 {
2564  item->setDrawArrow(getValue() == "1");
2565 }
2566 
2568 {
2569  auto *pause = new HostSpinBoxSetting("VideoModeChangePauseMS", 0, 5000, 100);
2570  pause->setLabel(VideoModeSettings::tr("Pause while switching video modes (ms)"));
2571  pause->setHelpText(VideoModeSettings::tr(
2572  "For most displays, switching video modes takes time and content can be missed. "
2573  "If non-zero, this setting will pause playback while the video mode is changed. "
2574  "The required pause length (in ms) will be dependant on the display's characteristics."));
2575  pause->setValue(0);
2576  return pause;
2577 }
2578 
2580 {
2584 
2586  addChild(res);
2587  addChild(rate);
2589  addChild(pause);
2590  connect(res, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
2592 
2593  auto *overrides = new GroupSetting();
2594 
2595  overrides->setLabel(tr("Overrides for specific video sizes"));
2596 
2597  for (int idx = 0; idx < 3; ++idx)
2598  {
2599  //input side
2600  overrides->addChild(VidModeWidth(idx));
2601  overrides->addChild(VidModeHeight(idx));
2602  // output side
2603  overrides->addChild(res = TVVidModeResolution(idx));
2604  overrides->addChild(rate = TVVidModeRefreshRate(idx));
2605  overrides->addChild(TVVidModeForceAspect(idx));
2606 
2607  connect(res, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
2609  }
2610 
2611  addChild(overrides);
2612 };
2613 
2615 {
2616  auto *gc = new HostCheckBoxSetting("HideMouseCursor");
2617 
2618  gc->setLabel(AppearanceSettings::tr("Hide mouse cursor in MythTV"));
2619 
2620  gc->setValue(false);
2621 
2622  gc->setHelpText(AppearanceSettings::tr("Toggles mouse cursor visibility "
2623  "for touchscreens. By default "
2624  "MythTV will auto-hide the cursor "
2625  "if the mouse doesn't move for a "
2626  "period, this setting disables the "
2627  "cursor entirely."));
2628  return gc;
2629 };
2630 
2631 
2633 {
2634  auto *gc = new HostCheckBoxSetting("RunFrontendInWindow");
2635 
2636  gc->setLabel(AppearanceSettings::tr("Use window border"));
2637 
2638  gc->setValue(false);
2639 
2640  gc->setHelpText(AppearanceSettings::tr("Toggles between windowed and "
2641  "borderless operation."));
2642  return gc;
2643 }
2644 
2646 {
2647  auto *gc = new HostCheckBoxSetting("AlwaysOnTop");
2648 
2649  gc->setLabel(AppearanceSettings::tr("Always On Top"));
2650 
2651  gc->setValue(false);
2652 
2653  gc->setHelpText(AppearanceSettings::tr("If enabled, MythTV will always be "
2654  "on top"));
2655  return gc;
2656 }
2657 
2659 {
2660  auto *gc = new HostCheckBoxSetting("SmoothTransitions");
2661 
2662  gc->setLabel(AppearanceSettings::tr("Smooth Transitions"));
2663 
2664  gc->setValue(true);
2665 
2666  gc->setHelpText(AppearanceSettings::tr("Enable smooth transitions with fade-in and fade-out of menu pages and enable GUI animations. "
2667  "Disabling this can make the GUI respond faster especially on low-powered machines."));
2668  return gc;
2669 }
2670 
2672 {
2673  auto *gs = new HostSpinBoxSetting("StartupScreenDelay", -1, 60, 1, 1,
2674  "Never show startup screen");
2675 
2676  gs->setLabel(AppearanceSettings::tr("Startup Screen Delay"));
2677 
2678  gs->setValue(2);
2679 
2680  gs->setHelpText(AppearanceSettings::tr(
2681  "The Startup Screen will show the progress of starting the frontend "
2682  "if frontend startup takes longer than this number of seconds."));
2683  return gs;
2684 }
2685 
2686 
2688 {
2689  auto *gs = new HostSpinBoxSetting("GUITEXTZOOM", 50, 150, 1, 1);
2690 
2691  gs->setLabel(AppearanceSettings::tr("GUI text zoom percentage"));
2692 
2693  gs->setValue(100);
2694 
2695  gs->setHelpText(AppearanceSettings::tr
2696  ("Adjust the themed defined font size by this percentage. "
2697  "mythfrontend needs restart for this to take effect."));
2698  return gs;
2699 }
2700 
2701 
2703 {
2704  auto *gc = new HostComboBoxSetting("DateFormat");
2705  gc->setLabel(AppearanceSettings::tr("Date format"));
2706 
2707  QDate sampdate = MythDate::current().toLocalTime().date();
2708  QString sampleStr = AppearanceSettings::tr("Samples are shown using "
2709  "today's date.");
2710 
2711  if (sampdate.month() == sampdate.day())
2712  {
2713  sampdate = sampdate.addDays(1);
2714  sampleStr = AppearanceSettings::tr("Samples are shown using "
2715  "tomorrow's date.");
2716  }
2717 
2718  QLocale locale = gCoreContext->GetQLocale();
2719 
2720  gc->addSelection(locale.toString(sampdate, "ddd MMM d"), "ddd MMM d");
2721  gc->addSelection(locale.toString(sampdate, "ddd d MMM"), "ddd d MMM");
2722  gc->addSelection(locale.toString(sampdate, "ddd MMMM d"), "ddd MMMM d");
2723  gc->addSelection(locale.toString(sampdate, "ddd d MMMM"), "ddd d MMMM");
2724  gc->addSelection(locale.toString(sampdate, "dddd MMM d"), "dddd MMM d");
2725  gc->addSelection(locale.toString(sampdate, "dddd d MMM"), "dddd d MMM");
2726  gc->addSelection(locale.toString(sampdate, "MMM d"), "MMM d");
2727  gc->addSelection(locale.toString(sampdate, "d MMM"), "d MMM");
2728  gc->addSelection(locale.toString(sampdate, "MM/dd"), "MM/dd");
2729  gc->addSelection(locale.toString(sampdate, "dd/MM"), "dd/MM");
2730  gc->addSelection(locale.toString(sampdate, "MM.dd"), "MM.dd");
2731  gc->addSelection(locale.toString(sampdate, "dd.MM"), "dd.MM");
2732  gc->addSelection(locale.toString(sampdate, "M/d/yyyy"), "M/d/yyyy");
2733  gc->addSelection(locale.toString(sampdate, "d/M/yyyy"), "d/M/yyyy");
2734  gc->addSelection(locale.toString(sampdate, "MM.dd.yyyy"), "MM.dd.yyyy");
2735  gc->addSelection(locale.toString(sampdate, "dd.MM.yyyy"), "dd.MM.yyyy");
2736  gc->addSelection(locale.toString(sampdate, "yyyy-MM-dd"), "yyyy-MM-dd");
2737  gc->addSelection(locale.toString(sampdate, "ddd MMM d yyyy"), "ddd MMM d yyyy");
2738  gc->addSelection(locale.toString(sampdate, "ddd d MMM yyyy"), "ddd d MMM yyyy");
2739  gc->addSelection(locale.toString(sampdate, "ddd yyyy-MM-dd"), "ddd yyyy-MM-dd");
2740 
2741  QString cn_long = QString("dddd yyyy") + QChar(0x5E74) +
2742  "M" + QChar(0x6708) + "d"+ QChar(0x65E5); // dddd yyyyå¹´M月dæ—¥
2743  gc->addSelection(locale.toString(sampdate, cn_long), cn_long);
2744  QString cn_med = QString("dddd ") +
2745  "M" + QChar(0x6708) + "d"+ QChar(0x65E5); // dddd M月dæ—¥
2746 
2747  gc->addSelection(locale.toString(sampdate, cn_med), cn_med);
2748 
2749  //: %1 gives additional information regarding the date format
2750  gc->setHelpText(AppearanceSettings::tr("Your preferred date format. %1")
2751  .arg(sampleStr));
2752 
2753  return gc;
2754 }
2755 
2757 {
2758  auto *gc = new HostComboBoxSetting("ShortDateFormat");
2759  gc->setLabel(AppearanceSettings::tr("Short date format"));
2760 
2761  QDate sampdate = MythDate::current().toLocalTime().date();
2762 
2763  QString sampleStr = AppearanceSettings::tr("Samples are shown using "
2764  "today's date.");
2765 
2766  if (sampdate.month() == sampdate.day())
2767  {
2768  sampdate = sampdate.addDays(1);
2769  sampleStr = AppearanceSettings::tr("Samples are shown using "
2770  "tomorrow's date.");
2771  }
2772  QLocale locale = gCoreContext->GetQLocale();
2773 
2774  gc->addSelection(locale.toString(sampdate, "M/d"), "M/d");
2775  gc->addSelection(locale.toString(sampdate, "d/M"), "d/M");
2776  gc->addSelection(locale.toString(sampdate, "MM/dd"), "MM/dd");
2777  gc->addSelection(locale.toString(sampdate, "dd/MM"), "dd/MM");
2778  gc->addSelection(locale.toString(sampdate, "MM.dd"), "MM.dd");
2779  gc->addSelection(locale.toString(sampdate, "dd.MM."), "dd.MM.");
2780  gc->addSelection(locale.toString(sampdate, "M.d."), "M.d.");
2781  gc->addSelection(locale.toString(sampdate, "d.M."), "d.M.");
2782  gc->addSelection(locale.toString(sampdate, "MM-dd"), "MM-dd");
2783  gc->addSelection(locale.toString(sampdate, "dd-MM"), "dd-MM");
2784  gc->addSelection(locale.toString(sampdate, "MMM d"), "MMM d");
2785  gc->addSelection(locale.toString(sampdate, "d MMM"), "d MMM");
2786  gc->addSelection(locale.toString(sampdate, "ddd d"), "ddd d");
2787  gc->addSelection(locale.toString(sampdate, "d ddd"), "d ddd");
2788  gc->addSelection(locale.toString(sampdate, "ddd M/d"), "ddd M/d");
2789  gc->addSelection(locale.toString(sampdate, "ddd d/M"), "ddd d/M");
2790  gc->addSelection(locale.toString(sampdate, "ddd d.M"), "ddd d.M");
2791  gc->addSelection(locale.toString(sampdate, "ddd dd.MM"), "ddd dd.MM");
2792  gc->addSelection(locale.toString(sampdate, "M/d ddd"), "M/d ddd");
2793  gc->addSelection(locale.toString(sampdate, "d/M ddd"), "d/M ddd");
2794 
2795  QString cn_short1 = QString("M") + QChar(0x6708) + "d" + QChar(0x65E5); // M月dæ—¥
2796 
2797  gc->addSelection(locale.toString(sampdate, cn_short1), cn_short1);
2798 
2799  QString cn_short2 = QString("ddd M") + QChar(0x6708) + "d" + QChar(0x65E5); // ddd M月dæ—¥
2800 
2801  gc->addSelection(locale.toString(sampdate, cn_short2), cn_short2);
2802 
2803  //: %1 gives additional information regarding the date format
2804  gc->setHelpText(AppearanceSettings::tr("Your preferred short date format. %1")
2805  .arg(sampleStr));
2806  return gc;
2807 }
2808 
2810 {
2811  auto *gc = new HostComboBoxSetting("TimeFormat");
2812 
2813  gc->setLabel(AppearanceSettings::tr("Time format"));
2814 
2815  QTime samptime = QTime::currentTime();
2816 
2817  QLocale locale = gCoreContext->GetQLocale();
2818 
2819  gc->addSelection(locale.toString(samptime, "h:mm AP"), "h:mm AP");
2820  gc->addSelection(locale.toString(samptime, "h:mm ap"), "h:mm ap");
2821  gc->addSelection(locale.toString(samptime, "hh:mm AP"), "hh:mm AP");
2822  gc->addSelection(locale.toString(samptime, "hh:mm ap"), "hh:mm ap");
2823  gc->addSelection(locale.toString(samptime, "h:mm"), "h:mm");
2824  gc->addSelection(locale.toString(samptime, "hh:mm"), "hh:mm");
2825  gc->addSelection(locale.toString(samptime, "hh.mm"), "hh.mm");
2826  gc->addSelection(locale.toString(samptime, "AP h:mm"), "AP h:mm");
2827 
2828  gc->setHelpText(AppearanceSettings::tr("Your preferred time format. You "
2829  "must choose a format with \"AM\" "
2830  "or \"PM\" in it, otherwise your "
2831  "time display will be 24-hour or "
2832  "\"military\" time."));
2833  return gc;
2834 }
2835 
2837 {
2838  auto *rgb = new HostCheckBoxSetting("GUIRGBLevels");
2839  rgb->setLabel(AppearanceSettings::tr("Use full range RGB output"));
2840  rgb->setValue(true);
2841  rgb->setHelpText("Enable (recommended) to supply full range RGB output to your display device. "
2842  "Disable to supply limited range RGB output. This setting applies to both the "
2843  "GUI and media playback. Ideally the value of this setting should match a "
2844  "similar setting on your TV or monitor.");
2845  return rgb;
2846 }
2847 
2849 {
2850  auto *gc = new HostComboBoxSetting("ChannelFormat");
2851 
2852  gc->setLabel(GeneralSettings::tr("Channel format"));
2853 
2854  gc->addSelection(GeneralSettings::tr("number"), "<num>");
2855  gc->addSelection(GeneralSettings::tr("number callsign"), "<num> <sign>");
2856  gc->addSelection(GeneralSettings::tr("number name"), "<num> <name>");
2857  gc->addSelection(GeneralSettings::tr("callsign"), "<sign>");
2858  gc->addSelection(GeneralSettings::tr("name"), "<name>");
2859 
2860  gc->setHelpText(GeneralSettings::tr("Your preferred channel format."));
2861 
2862  gc->setValue(1);
2863 
2864  return gc;
2865 }
2866 
2868 {
2869  auto *gc = new HostComboBoxSetting("LongChannelFormat");
2870 
2871  gc->setLabel(GeneralSettings::tr("Long channel format"));
2872 
2873  gc->addSelection(GeneralSettings::tr("number"), "<num>");
2874  gc->addSelection(GeneralSettings::tr("number callsign"), "<num> <sign>");
2875  gc->addSelection(GeneralSettings::tr("number name"), "<num> <name>");
2876  gc->addSelection(GeneralSettings::tr("callsign"), "<sign>");
2877  gc->addSelection(GeneralSettings::tr("name"), "<name>");
2878 
2879  gc->setHelpText(GeneralSettings::tr("Your preferred long channel format."));
2880 
2881  gc->setValue(2);
2882 
2883  return gc;
2884 }
2885 
2887 {
2888  auto *gc = new HostCheckBoxSetting("ChannelGroupRememberLast");
2889 
2890  gc->setLabel(ChannelGroupSettings::tr("Remember last channel group"));
2891 
2892  gc->setHelpText(ChannelGroupSettings::tr("If enabled, the EPG will "
2893  "initially display only the "
2894  "channels from the last channel "
2895  "group selected. Pressing \"4\" "
2896  "will toggle channel group."));
2897 
2898  gc->setValue(false);
2899 
2900  return gc;
2901 }
2902 
2904 {
2905  auto *gc = new HostComboBoxSetting("ChannelGroupDefault");
2906 
2907  gc->setLabel(ChannelGroupSettings::tr("Default channel group"));
2908 
2909  ChannelGroupList changrplist;
2910 
2911  changrplist = ChannelGroup::GetChannelGroups();
2912 
2913  gc->addSelection(ChannelGroupSettings::tr("All Channels"), "-1");
2914 
2915  ChannelGroupList::iterator it;
2916 
2917  for (it = changrplist.begin(); it < changrplist.end(); ++it)
2918  gc->addSelection(it->m_name, QString("%1").arg(it->m_grpId));
2919 
2920  gc->setHelpText(ChannelGroupSettings::tr("Default channel group to be "
2921  "shown in the EPG. Pressing "
2922  "GUIDE key will toggle channel "
2923  "group."));
2924  gc->setValue(false);
2925 
2926  return gc;
2927 }
2928 
2930 {
2931  auto *gc = new HostCheckBoxSetting("BrowseChannelGroup");
2932 
2933  gc->setLabel(GeneralSettings::tr("Browse/change channels from Channel "
2934  "Group"));
2935 
2936  gc->setHelpText(GeneralSettings::tr("If enabled, Live TV will browse or "
2937  "change channels from the selected "
2938  "channel group. The \"All Channels\" "
2939  "channel group may be selected to "
2940  "browse all channels."));
2941  gc->setValue(false);
2942 
2943  return gc;
2944 }
2945 
2946 #if 0
2947 static GlobalCheckBoxSetting *SortCaseSensitive()
2948 {
2949  auto *gc = new GlobalCheckBoxSetting("SortCaseSensitive");
2950  gc->setLabel(GeneralSettings::tr("Case-sensitive sorting"));
2951  gc->setValue(false);
2952  gc->setHelpText(GeneralSettings::tr("If enabled, all sorting will be "
2953  "case-sensitive. This would mean "
2954  "that \"bee movie\" would sort after "
2955  "\"Sea World\" as lower case letters "
2956  "sort after uppercase letters."));
2957  return gc;
2958 }
2959 #endif
2960 
2962 {
2963  auto *gc = new GlobalCheckBoxSetting("SortStripPrefixes");
2964 
2965  gc->setLabel(GeneralSettings::tr("Remove prefixes when sorting"));
2966  gc->setValue(true);
2967  gc->setHelpText(GeneralSettings::tr(
2968  "If enabled, all sorting will remove the common "
2969  "prefixes (The, A, An) from a string prior to "
2970  "sorting. For example, this would sort the titles "
2971  "\"Earth 2\", \"The Flash\", and \"Kings\" in that "
2972  "order. If disabled, they would sort as \"Earth 2\", "
2973  "\"Kings\", \"The Flash\"."));
2974  return gc;
2975 }
2976 
2978 {
2979  auto *gc = new GlobalTextEditSetting("SortPrefixExceptions");
2980 
2981  gc->setLabel(MainGeneralSettings::tr("Names exempt from prefix removal"));
2982  gc->setValue("");
2983  gc->setHelpText(MainGeneralSettings::tr(
2984  "This list of names will be exempt from removing "
2985  "the common prefixes (The, A, An) from a title or "
2986  "filename. Enter multiple names separated by "
2987  "semicolons."));
2988  return gc;
2989 }
2990 
2992 {
2993  auto *gc = new GlobalComboBoxSetting("ManualRecordStartChanType");
2994 
2995  gc->setLabel(GeneralSettings::tr("Starting channel for Manual Record"));
2996  gc->addSelection(GeneralSettings::tr("Guide Starting Channel"), "1", true);
2997  gc->addSelection(GeneralSettings::tr("Last Manual Record Channel"), "2");
2998  gc->setHelpText(GeneralSettings::tr(
2999  "When entering a new Manual Record Rule, "
3000  "the starting channel will default to this."));
3001  return gc;
3002 }
3003 
3004 // General RecPriorities settings
3005 
3007 {
3008  auto *bc = new GlobalComboBoxSetting("SchedOpenEnd");
3009 
3010  bc->setLabel(GeneralRecPrioritiesSettings::tr("Avoid back to back "
3011  "recordings"));
3012 
3013  bc->setHelpText(
3014  GeneralRecPrioritiesSettings::tr("Selects the situations where the "
3015  "scheduler will avoid assigning shows "
3016  "to the same card if their end time "
3017  "and start time match. This will be "
3018  "allowed when necessary in order to "
3019  "resolve conflicts."));
3020 
3021  bc->addSelection(GeneralRecPrioritiesSettings::tr("Never"), "0");
3022  bc->addSelection(GeneralRecPrioritiesSettings::tr("Different Channels"),
3023  "1");
3024  bc->addSelection(GeneralRecPrioritiesSettings::tr("Always"), "2");
3025 
3026  bc->setValue(0);
3027 
3028  return bc;
3029 }
3030 
3032 {
3033  auto *bs = new GlobalSpinBoxSetting("PrefInputPriority", 1, 99, 1);
3034 
3035  bs->setLabel(GeneralRecPrioritiesSettings::tr("Preferred input priority"));
3036 
3037  bs->setHelpText(GeneralRecPrioritiesSettings::tr("Additional priority when "
3038  "a showing matches the "
3039  "preferred input selected "
3040  "in the 'Scheduling "
3041  "Options' section of the "
3042  "recording rule."));
3043 
3044  bs->setValue(2);
3045  return bs;
3046 }
3047 
3049 {
3050  auto *bs = new GlobalSpinBoxSetting("HDTVRecPriority", -99, 99, 1);
3051 
3052  bs->setLabel(GeneralRecPrioritiesSettings::tr("HDTV recording priority"));
3053 
3054  bs->setHelpText(GeneralRecPrioritiesSettings::tr("Additional priority when "
3055  "a showing is marked as an "
3056  "HDTV broadcast in the TV "
3057  "listings."));
3058 
3059  bs->setValue(0);
3060 
3061  return bs;
3062 }
3063 
3065 {
3066  auto *bs = new GlobalSpinBoxSetting("WSRecPriority", -99, 99, 1);
3067 
3068  bs->setLabel(GeneralRecPrioritiesSettings::tr("Widescreen recording "
3069  "priority"));
3070 
3071  bs->setHelpText(GeneralRecPrioritiesSettings::tr("Additional priority when "
3072  "a showing is marked as "
3073  "widescreen in the TV "
3074  "listings."));
3075 
3076  bs->setValue(0);
3077 
3078  return bs;
3079 }
3080 
3082 {
3083  auto *bs = new GlobalSpinBoxSetting("SignLangRecPriority", -99, 99, 1);
3084 
3085  bs->setLabel(GeneralRecPrioritiesSettings::tr("Sign language recording "
3086  "priority"));
3087 
3088  bs->setHelpText(GeneralRecPrioritiesSettings::tr("Additional priority "
3089  "when a showing is "
3090  "marked as having "
3091  "in-vision sign "
3092  "language."));
3093 
3094  bs->setValue(0);
3095 
3096  return bs;
3097 }
3098 
3100 {
3101  auto *bs = new GlobalSpinBoxSetting("OnScrSubRecPriority", -99, 99, 1);
3102 
3103  bs->setLabel(GeneralRecPrioritiesSettings::tr("In-vision Subtitles "
3104  "Recording Priority"));
3105 
3106  bs->setHelpText(GeneralRecPrioritiesSettings::tr("Additional priority "
3107  "when a showing is marked "
3108  "as having in-vision "
3109  "subtitles."));
3110 
3111  bs->setValue(0);
3112 
3113  return bs;
3114 }
3115 
3117 {
3118  auto *bs = new GlobalSpinBoxSetting("CCRecPriority", -99, 99, 1);
3119 
3120  bs->setLabel(GeneralRecPrioritiesSettings::tr("Subtitles/CC recording "
3121  "priority"));
3122 
3123  bs->setHelpText(GeneralRecPrioritiesSettings::tr("Additional priority when "
3124  "a showing is marked as "
3125  "having subtitles or "
3126  "closed captioning (CC) "
3127  "available."));
3128 
3129  bs->setValue(0);
3130 
3131  return bs;
3132 }
3133 
3135 {
3136  auto *bs = new GlobalSpinBoxSetting("HardHearRecPriority", -99, 99, 1);
3137 
3138  bs->setLabel(GeneralRecPrioritiesSettings::tr("Hard of hearing priority"));
3139 
3140  bs->setHelpText(GeneralRecPrioritiesSettings::tr("Additional priority when "
3141  "a showing is marked as "
3142  "having support for "
3143  "viewers with impaired "
3144  "hearing."));
3145 
3146  bs->setValue(0);
3147 
3148  return bs;
3149 }
3150 
3152 {
3153  auto *bs = new GlobalSpinBoxSetting("AudioDescRecPriority", -99, 99, 1);
3154 
3155  bs->setLabel(GeneralRecPrioritiesSettings::tr("Audio described priority"));
3156 
3157  bs->setHelpText(GeneralRecPrioritiesSettings::tr("Additional priority when "
3158  "a showing is marked as "
3159  "being Audio Described."));
3160 
3161  bs->setValue(0);
3162 
3163  return bs;
3164 }
3165 
3167 {
3168  auto *ge = new HostTextEditSetting("DefaultTVChannel");
3169 
3170  ge->setLabel(EPGSettings::tr("Guide starts at channel"));
3171 
3172  ge->setValue("3");
3173 
3174  ge->setHelpText(EPGSettings::tr("The program guide starts on this channel "
3175  "if it is run from outside of Live TV "
3176  "mode. Leave blank to enable Live TV "
3177  "automatic start channel."));
3178 
3179  return ge;
3180 }
3181 
3183 {
3184  auto *gs = new HostSpinBoxSetting("SelChangeRecThreshold", 1, 600, 1);
3185 
3186  gs->setLabel(EPGSettings::tr("Record threshold"));
3187 
3188  gs->setValue(16);
3189 
3190  gs->setHelpText(EPGSettings::tr("Pressing SELECT on a show that is at "
3191  "least this many minutes into the future "
3192  "will schedule a recording."));
3193  return gs;
3194 }
3195 
3197 {
3198  auto *gc = new GlobalComboBoxSetting("Language");
3199 
3200  gc->setLabel(AppearanceSettings::tr("Language"));
3201 
3202  QMap<QString, QString> langMap = MythTranslation::getLanguages();
3203  QStringList langs = langMap.values();
3204  langs.sort();
3205  QString langCode = gCoreContext->GetSetting("Language").toLower();
3206 
3207  if (langCode.isEmpty())
3208  langCode = "en_US";
3209 
3210  gc->clearSelections();
3211 
3212  for (const auto & label : qAsConst(langs))
3213  {
3214  QString value = langMap.key(label);
3215  gc->addSelection(label, value, (value.toLower() == langCode));
3216  }
3217 
3218  gc->setHelpText(AppearanceSettings::tr("Your preferred language for the "
3219  "user interface."));
3220  return gc;
3221 }
3222 
3224 {
3225  widget->clearSelections();
3226  QString q = QString("ISO639Language%1").arg(i);
3227  QString lang = gCoreContext->GetSetting(q, "").toLower();
3228 
3229  if ((lang.isEmpty() || lang == "aar") &&
3230  !gCoreContext->GetSetting("Language", "").isEmpty())
3231  {
3232  lang = iso639_str2_to_str3(gCoreContext->GetLanguage().toLower());
3233  }
3234 
3235  QMap<int,QString>::iterator it = iso639_key_to_english_name.begin();
3236  QMap<int,QString>::iterator ite = iso639_key_to_english_name.end();
3237 
3238  for (; it != ite; ++it)
3239  {
3240  QString desc = (*it);
3241  int idx = desc.indexOf(";");
3242  if (idx > 0)
3243  desc = desc.left(idx);
3244 
3245  const QString il = iso639_key_to_str3(it.key());
3246  widget->addSelection(desc, il, il == lang);
3247  }
3248 }
3249 
3251 {
3252  auto *gc = new GlobalComboBoxSetting(QString("ISO639Language%1").arg(i));
3253 
3254  gc->setLabel(AppearanceSettings::tr("Guide language #%1").arg(i+1));
3255 
3256  // We should try to get language from "MythLanguage"
3257  // then use code 2 to code 3 map in iso639.h
3258  ISO639_fill_selections(gc, i);
3259 
3260  gc->setHelpText(AppearanceSettings::tr("Your #%1 preferred language for "
3261  "Program Guide data and captions.")
3262  .arg(i+1));
3263  return gc;
3264 }
3265 
3267 {
3268  auto *gc = new HostCheckBoxSetting("NetworkControlEnabled");
3269 
3270  gc->setLabel(MainGeneralSettings::tr("Enable Network Remote Control "
3271  "interface"));
3272 
3273  gc->setHelpText(MainGeneralSettings::tr("This enables support for "
3274  "controlling MythFrontend "
3275  "over the network."));
3276 
3277  gc->setValue(false);
3278 
3279  return gc;
3280 }
3281 
3283 {
3284  auto *gs = new HostSpinBoxSetting("NetworkControlPort", 1025, 65535, 1);
3285 
3286  gs->setLabel(MainGeneralSettings::tr("Network Remote Control port"));
3287 
3288  gs->setValue(6546);
3289 
3290  gs->setHelpText(MainGeneralSettings::tr("This specifies what port the "
3291  "Network Remote Control "
3292  "interface will listen on for "
3293  "new connections."));
3294  return gs;
3295 }
3296 
3298 {
3299  auto *ge = new HostTextEditSetting("UDPNotifyPort");
3300 
3301  ge->setLabel(MainGeneralSettings::tr("UDP notify port"));
3302 
3303  ge->setValue("6948");
3304 
3305  ge->setHelpText(MainGeneralSettings::tr("MythTV will listen for "
3306  "connections from the "
3307  "\"mythutil\" program on "
3308  "this port."));
3309  return ge;
3310 }
3311 
3312 #ifdef USING_LIBCEC
3313 static HostCheckBoxSetting *CECEnabled()
3314 {
3315  auto *gc = new HostCheckBoxSetting("libCECEnabled");
3316  gc->setLabel(MainGeneralSettings::tr("Enable CEC Control "
3317  "interface"));
3318  gc->setHelpText(MainGeneralSettings::tr("This enables "
3319  "controlling MythFrontend from a TV remote or powering the TV "
3320  "on and off from a MythTV remote "
3321  "if you have compatible hardware. "
3322  "These settings only take effect after a restart."));
3323  gc->setValue(true);
3324  return gc;
3325 }
3326 
3327 static HostCheckBoxSetting *CECPowerOnTVAllowed()
3328 {
3329  auto *gc = new HostCheckBoxSetting("PowerOnTVAllowed");
3330  gc->setLabel(MainGeneralSettings::tr("Allow Power On TV"));
3331  gc->setHelpText(MainGeneralSettings::tr("Enables your TV to be powered "
3332  "on from MythTV remote or when MythTV starts "
3333  "if you have compatible hardware."));
3334  gc->setValue(true);
3335  return gc;
3336 }
3337 
3338 static HostCheckBoxSetting *CECPowerOffTVAllowed()
3339 {
3340  auto *gc = new HostCheckBoxSetting("PowerOffTVAllowed");
3341  gc->setLabel(MainGeneralSettings::tr("Allow Power Off TV"));
3342  gc->setHelpText(MainGeneralSettings::tr("Enables your TV to be powered "
3343  "off from MythTV remote or when MythTV starts "
3344  "if you have compatible hardware."));
3345  gc->setValue(true);
3346  return gc;
3347 }
3348 
3349 static HostCheckBoxSetting *CECPowerOnTVOnStart()
3350 {
3351  auto *gc = new HostCheckBoxSetting("PowerOnTVOnStart");
3352  gc->setLabel(MainGeneralSettings::tr("Power on TV At Start"));
3353  gc->setHelpText(MainGeneralSettings::tr("Powers "
3354  "on your TV when you start MythTV "
3355  "if you have compatible hardware."));
3356  gc->setValue(true);
3357  return gc;
3358 }
3359 
3360 static HostCheckBoxSetting *CECPowerOffTVOnExit()
3361 {
3362  auto *gc = new HostCheckBoxSetting("PowerOffTVOnExit");
3363  gc->setLabel(MainGeneralSettings::tr("Power off TV At Exit"));
3364  gc->setHelpText(MainGeneralSettings::tr("Powers "
3365  "off your TV when you exit MythTV "
3366  "if you have compatible hardware."));
3367  gc->setValue(true);
3368  return gc;
3369 }
3370 
3371 #endif //USING_LIBCEC
3372 
3373 #ifdef USING_AIRPLAY
3374 // AirPlay Settings
3375 static HostCheckBoxSetting *AirPlayEnabled()
3376 {
3377  auto *gc = new HostCheckBoxSetting("AirPlayEnabled");
3378 
3379  gc->setLabel(MainGeneralSettings::tr("Enable AirPlay"));
3380 
3381  gc->setHelpText(MainGeneralSettings::tr("AirPlay lets you wirelessly view "
3382  "content on your TV from your "
3383  "iPhone, iPad, iPod Touch, or "
3384  "iTunes on your computer."));
3385 
3386  gc->setValue(true);
3387 
3388  return gc;
3389 }
3390 
3391 static HostCheckBoxSetting *AirPlayAudioOnly()
3392 {
3393  auto *gc = new HostCheckBoxSetting("AirPlayAudioOnly");
3394 
3395  gc->setLabel(MainGeneralSettings::tr("Only support AirTunes (no video)"));
3396 
3397  gc->setHelpText(MainGeneralSettings::tr("Only stream audio from your "
3398  "iPhone, iPad, iPod Touch, or "
3399  "iTunes on your computer"));
3400 
3401  gc->setValue(false);
3402 
3403  return gc;
3404 }
3405 
3406 static HostCheckBoxSetting *AirPlayPasswordEnabled()
3407 {
3408  auto *gc = new HostCheckBoxSetting("AirPlayPasswordEnabled");
3409 
3410  gc->setLabel(MainGeneralSettings::tr("Require password"));
3411 
3412  gc->setValue(false);
3413 
3414  gc->setHelpText(MainGeneralSettings::tr("Require a password to use "
3415  "AirPlay. Your iPhone, iPad, iPod "
3416  "Touch, or iTunes on your computer "
3417  "will prompt you when required"));
3418  return gc;
3419 }
3420 
3421 static HostTextEditSetting *AirPlayPassword()
3422 {
3423  auto *ge = new HostTextEditSetting("AirPlayPassword");
3424 
3425  ge->setLabel(MainGeneralSettings::tr("Password"));
3426 
3427  ge->setValue("0000");
3428 
3429  ge->setHelpText(MainGeneralSettings::tr("Your iPhone, iPad, iPod Touch, or "
3430  "iTunes on your computer will "
3431  "prompt you for this password "
3432  "when required"));
3433  return ge;
3434 }
3435 
3436 static GroupSetting *AirPlayPasswordSettings()
3437 {
3438  auto *hc = new GroupSetting();
3439 
3440  hc->setLabel(MainGeneralSettings::tr("AirPlay - Password"));
3441  hc->addChild(AirPlayPasswordEnabled());
3442  hc->addChild(AirPlayPassword());
3443 
3444  return hc;
3445 }
3446 
3447 static HostCheckBoxSetting *AirPlayFullScreen()
3448 {
3449  auto *gc = new HostCheckBoxSetting("AirPlayFullScreen");
3450 
3451  gc->setLabel(MainGeneralSettings::tr("AirPlay full screen playback"));
3452 
3453  gc->setValue(false);
3454 
3455  gc->setHelpText(MainGeneralSettings::tr("During music playback, displays "
3456  "album cover and various media "
3457  "information in full screen mode"));
3458  return gc;
3459 }
3460 
3461 //static TransLabelSetting *AirPlayInfo()
3462 //{
3463 // TransLabelSetting *ts = new TransLabelSetting();
3464 //
3465 // ts->setValue(MainGeneralSettings::tr("All AirPlay settings take effect "
3466 // "when you restart MythFrontend."));
3467 // return ts;
3468 //}
3469 
3470 //static TransLabelSetting *AirPlayRSAInfo()
3471 //{
3472 // TransLabelSetting *ts = new TransLabelSetting();
3473 //
3474 // if (MythRAOPConnection::LoadKey() == nullptr)
3475 // {
3476 // ts->setValue(MainGeneralSettings::tr("AirTunes RSA key couldn't be "
3477 // "loaded. Check http://www.mythtv.org/wiki/AirTunes/AirPlay. "
3478 // "Last Error: %1")
3479 // .arg(MythRAOPConnection::RSALastError()));
3480 // }
3481 // else
3482 // {
3483 // ts->setValue(MainGeneralSettings::tr("AirTunes RSA key successfully "
3484 // "loaded."));
3485 // }
3486 //
3487 // return ts;
3488 //}
3489 #endif
3490 
3492 {
3493  auto *gc = new HostCheckBoxSetting("RealtimePriority");
3494 
3495  gc->setLabel(PlaybackSettings::tr("Enable realtime priority threads"));
3496 
3497  gc->setHelpText(PlaybackSettings::tr("When running mythfrontend with root "
3498  "privileges, some threads can be "
3499  "given enhanced priority. Disable "
3500  "this if MythFrontend freezes during "
3501  "video playback."));
3502  gc->setValue(true);
3503 
3504  return gc;
3505 }
3506 
3508 {
3509  auto *ge = new HostTextEditSetting("IgnoreDevices");
3510 
3511  ge->setLabel(MainGeneralSettings::tr("Ignore devices"));
3512 
3513  ge->setValue("");
3514 
3515  ge->setHelpText(MainGeneralSettings::tr("If there are any devices that you "
3516  "do not want to be monitored, list "
3517  "them here with commas in-between. "
3518  "The plugins will ignore them. "
3519  "Requires restart."));
3520  return ge;
3521 }
3522 
3524 {
3525  auto *gc = new HostComboBoxSetting("DisplayGroupTitleSort");
3526 
3527  gc->setLabel(PlaybackSettings::tr("Sort titles"));
3528 
3529  gc->addSelection(PlaybackSettings::tr("Alphabetically"),
3530  QString::number(PlaybackBox::TitleSortAlphabetical));
3531  gc->addSelection(PlaybackSettings::tr("By recording priority"),
3532  QString::number(PlaybackBox::TitleSortRecPriority));
3533 
3534  gc->setHelpText(PlaybackSettings::tr("Sets the title sorting order when "
3535  "the view is set to Titles only."));
3536  return gc;
3537 }
3538 
3540 {
3541  auto *gc = new HostCheckBoxSetting("PlaybackWatchList");
3542 
3543  gc->setLabel(WatchListSettings::tr("Include the 'Watch List' group"));
3544 
3545  gc->setValue(true);
3546 
3547  gc->setHelpText(WatchListSettings::tr("The 'Watch List' is an abbreviated "
3548  "list of recordings sorted to "
3549  "highlight series and shows that "
3550  "need attention in order to keep up "
3551  "to date."));
3552  return gc;
3553 }
3554 
3556 {
3557  auto *gc = new HostCheckBoxSetting("PlaybackWLStart");
3558 
3559  gc->setLabel(WatchListSettings::tr("Start from the Watch List view"));
3560 
3561  gc->setValue(false);
3562 
3563  gc->setHelpText(WatchListSettings::tr("If enabled, the 'Watch List' will "
3564  "be the initial view each time you "
3565  "enter the Watch Recordings screen"));
3566  return gc;
3567 }
3568 
3570 {
3571  auto *gc = new HostCheckBoxSetting("PlaybackWLAutoExpire");
3572 
3573  gc->setLabel(WatchListSettings::tr("Exclude recordings not set for "
3574  "Auto-Expire"));
3575 
3576  gc->setValue(false);
3577 
3578  gc->setHelpText(WatchListSettings::tr("Set this if you turn off "
3579  "Auto-Expire only for recordings "
3580  "that you've seen and intend to "
3581  "keep. This option will exclude "
3582  "these recordings from the "
3583  "'Watch List'."));
3584  return gc;
3585 }
3586 
3588 {
3589  auto *gs = new HostSpinBoxSetting("PlaybackWLMaxAge", 30, 180, 10);
3590 
3591  gs->setLabel(WatchListSettings::tr("Maximum days counted in the score"));
3592 
3593  gs->setValue(60);
3594 
3595  gs->setHelpText(WatchListSettings::tr("The 'Watch List' scores are based "
3596  "on 1 point equals one day since "
3597  "recording. This option limits the "
3598  "maximum score due to age and "
3599  "affects other weighting factors."));
3600  return gs;
3601 }
3602 
3604 {
3605  auto *gs = new HostSpinBoxSetting("PlaybackWLBlackOut", 0, 5, 1);
3606 
3607  gs->setLabel(WatchListSettings::tr("Days to exclude weekly episodes after "
3608  "delete"));
3609 
3610  gs->setValue(2);
3611 
3612  gs->setHelpText(WatchListSettings::tr("When an episode is deleted or "
3613  "marked as watched, other episodes "
3614  "of the series are excluded from the "
3615  "'Watch List' for this interval of "
3616  "time. Daily shows also have a "
3617  "smaller interval based on this "
3618  "setting."));
3619  return gs;
3620 }
3621 
3623 {
3624  auto *gc = new HostCheckBoxSetting("MonitorDrives");
3625 
3626  gc->setLabel(MainGeneralSettings::tr("Media Monitor"));
3627 
3628  gc->setHelpText(MainGeneralSettings::tr("This enables support for "
3629  "monitoring your CD/DVD drives for "
3630  "new disks and launching the "
3631  "proper plugin to handle them. "
3632  "Requires restart."));
3633 
3634  gc->setValue(false);
3635 
3636  gc->addTargetedChild("1", IgnoreMedia());
3637 
3638  return gc;
3639 }
3640 
3642 {
3643  auto *gc = new HostCheckBoxSetting("LCDShowTime");
3644 
3645  gc->setLabel(LcdSettings::tr("Display time"));
3646 
3647  gc->setHelpText(LcdSettings::tr("Display current time on idle LCD "
3648  "display."));
3649 
3650  gc->setValue(true);
3651 
3652  return gc;
3653 }
3654 
3656 {
3657  auto *gc = new HostCheckBoxSetting("LCDShowRecStatus");
3658 
3659  gc->setLabel(LcdSettings::tr("Display recording status"));
3660 
3661  gc->setHelpText(LcdSettings::tr("Display current recordings information "
3662  "on LCD display."));
3663 
3664  gc->setValue(false);
3665 
3666  return gc;
3667 }
3668 
3670 {
3671  auto *gc = new HostCheckBoxSetting("LCDShowMenu");
3672 
3673  gc->setLabel(LcdSettings::tr("Display menus"));
3674 
3675  gc->setHelpText(LcdSettings::tr("Display selected menu on LCD display. "));
3676 
3677  gc->setValue(true);
3678 
3679  return gc;
3680 }
3681 
3683 {
3684  auto *gs = new HostSpinBoxSetting("LCDPopupTime", 1, 300, 1, 1);
3685 
3686  gs->setLabel(LcdSettings::tr("Menu pop-up time"));
3687 
3688  gs->setHelpText(LcdSettings::tr("How many seconds the menu will remain "
3689  "visible after navigation."));
3690 
3691  gs->setValue(5);
3692 
3693  return gs;
3694 }
3695 
3697 {
3698  auto *gc = new HostCheckBoxSetting("LCDShowMusic");
3699 
3700  gc->setLabel(LcdSettings::tr("Display music artist and title"));
3701 
3702  gc->setHelpText(LcdSettings::tr("Display playing artist and song title in "
3703  "MythMusic on LCD display."));
3704 
3705  gc->setValue(true);
3706 
3707  return gc;
3708 }
3709 
3711 {
3712  auto *gc = new HostComboBoxSetting("LCDShowMusicItems");
3713 
3714  gc->setLabel(LcdSettings::tr("Items"));
3715 
3716  gc->addSelection(LcdSettings::tr("Artist - Title"), "ArtistTitle");
3717  gc->addSelection(LcdSettings::tr("Artist [Album] Title"),
3718  "ArtistAlbumTitle");
3719 
3720  gc->setHelpText(LcdSettings::tr("Which items to show when playing music."));
3721 
3722  return gc;
3723 }
3724 
3726 {
3727  auto *gc = new HostCheckBoxSetting("LCDShowChannel");
3728 
3729  gc->setLabel(LcdSettings::tr("Display channel information"));
3730 
3731  gc->setHelpText(LcdSettings::tr("Display tuned channel information on LCD "
3732  "display."));
3733 
3734  gc->setValue(true);
3735 
3736  return gc;
3737 }
3738 
3740 {
3741  auto *gc = new HostCheckBoxSetting("LCDShowVolume");
3742 
3743  gc->setLabel(LcdSettings::tr("Display volume information"));
3744 
3745  gc->setHelpText(LcdSettings::tr("Display volume level information "
3746  "on LCD display."));
3747 
3748  gc->setValue(true);
3749 
3750  return gc;
3751 }
3752 
3754 {
3755  auto *gc = new HostCheckBoxSetting("LCDShowGeneric");
3756 
3757  gc->setLabel(LcdSettings::tr("Display generic information"));
3758 
3759  gc->setHelpText(LcdSettings::tr("Display generic information on LCD display."));
3760 
3761  gc->setValue(true);
3762 
3763  return gc;
3764 }
3765 
3767 {
3768  auto *gc = new HostCheckBoxSetting("LCDBacklightOn");
3769 
3770  gc->setLabel(LcdSettings::tr("Backlight always on"));
3771 
3772  gc->setHelpText(LcdSettings::tr("Turn on the backlight permanently on the "
3773  "LCD display."));
3774  gc->setValue(true);
3775 
3776  return gc;
3777 }
3778 
3780 {
3781  auto *gc = new HostCheckBoxSetting("LCDHeartBeatOn");
3782 
3783  gc->setLabel(LcdSettings::tr("Heartbeat always on"));
3784 
3785  gc->setHelpText(LcdSettings::tr("Turn on the LCD heartbeat."));
3786 
3787  gc->setValue(false);
3788 
3789  return gc;
3790 }
3791 
3793 {
3794  auto *gc = new HostCheckBoxSetting("LCDBigClock");
3795 
3796  gc->setLabel(LcdSettings::tr("Display large clock"));
3797 
3798  gc->setHelpText(LcdSettings::tr("On multiline displays try and display the "
3799  "time as large as possible."));
3800 
3801  gc->setValue(false);
3802 
3803  return gc;
3804 }
3805 
3807 {
3808  auto *ge = new HostTextEditSetting("LCDKeyString");
3809 
3810  ge->setLabel(LcdSettings::tr("LCD key order"));
3811 
3812  ge->setValue("ABCDEF");
3813 
3814  ge->setHelpText(
3815  LcdSettings::tr("Enter the 6 Keypad Return Codes for your LCD keypad "
3816  "in the order in which you want the functions "
3817  "up/down/left/right/yes/no to operate. (See "
3818  "lcdproc/server/drivers/hd44780.c/keyMapMatrix[] "
3819  "or the matrix for your display)"));
3820  return ge;
3821 }
3822 
3824 {
3825  auto *gc = new HostCheckBoxSetting("LCDEnable");
3826 
3827  gc->setLabel(LcdSettings::tr("Enable LCD device"));
3828 
3829  gc->setHelpText(LcdSettings::tr("Use an LCD display to view MythTV status "
3830  "information."));
3831 
3832  gc->setValue(false);
3833  gc->addTargetedChild("1", LCDShowTime());
3834  gc->addTargetedChild("1", LCDShowMenu());
3835  gc->addTargetedChild("1", LCDShowMusic());
3836  gc->addTargetedChild("1", LCDShowMusicItems());
3837  gc->addTargetedChild("1", LCDShowChannel());
3838  gc->addTargetedChild("1", LCDShowRecStatus());
3839  gc->addTargetedChild("1", LCDShowVolume());
3840  gc->addTargetedChild("1", LCDShowGeneric());
3841  gc->addTargetedChild("1", LCDBacklightOn());
3842  gc->addTargetedChild("1", LCDHeartBeatOn());
3843  gc->addTargetedChild("1", LCDBigClock());
3844  gc->addTargetedChild("1", LCDKeyString());
3845  gc->addTargetedChild("1", LCDPopupTime());
3846  return gc;
3847 }
3848 
3849 
3850 #ifdef Q_OS_DARWIN
3851 static HostCheckBoxSetting *MacGammaCorrect()
3852 {
3853  HostCheckBoxSetting *gc = new HostCheckBoxSetting("MacGammaCorrect");
3854 
3855  gc->setLabel(PlaybackSettings::tr("Enable gamma correction for video"));
3856 
3857  gc->setValue(false);
3858 
3859  gc->setHelpText(PlaybackSettings::tr("If enabled, QuickTime will correct "
3860  "the gamma of the video to match "
3861  "your monitor. Turning this off can "
3862  "save some CPU cycles."));
3863  return gc;
3864 }
3865 
3866 static HostCheckBoxSetting *MacScaleUp()
3867 {
3868  HostCheckBoxSetting *gc = new HostCheckBoxSetting("MacScaleUp");
3869 
3870  gc->setLabel(PlaybackSettings::tr("Scale video as necessary"));
3871 
3872  gc->setValue(true);
3873 
3874  gc->setHelpText(PlaybackSettings::tr("If enabled, video will be scaled to "
3875  "fit your window or screen. If "
3876  "unchecked, video will never be made "
3877  "larger than its actual pixel size."));
3878  return gc;
3879 }
3880 
3881 static HostSpinBoxSetting *MacFullSkip()
3882 {
3883  HostSpinBoxSetting *gs = new HostSpinBoxSetting("MacFullSkip", 0, 30, 1, true);
3884 
3885  gs->setLabel(PlaybackSettings::tr("Frames to skip in fullscreen mode"));
3886 
3887  gs->setValue(0);
3888 
3889  gs->setHelpText(PlaybackSettings::tr("Video displayed in fullscreen or "
3890  "non-windowed mode will skip this "
3891  "many frames for each frame drawn. "
3892  "Set to 0 to show every frame. Only "
3893  "valid when either \"Use GUI size for "
3894  "TV playback\" or \"Run the frontend "
3895  "in a window\" is not checked."));
3896  return gs;
3897 }
3898 
3899 static HostCheckBoxSetting *MacMainEnabled()
3900 {
3901  HostCheckBoxSetting *gc = new HostCheckBoxSetting("MacMainEnabled");
3902 
3903  gc->setLabel(MacMainSettings::tr("Video in main window"));
3904 
3905  gc->setValue(true);
3906 
3907  gc->setHelpText(MacMainSettings::tr("If enabled, video will be displayed "
3908  "in the main GUI window. Disable this "
3909  "when you only want video on the "
3910  "desktop or in a floating window. Only "
3911  "valid when \"Use GUI size for TV "
3912  "playback\" and \"Run the frontend in "
3913  "a window\" are checked."));
3914  return gc;
3915 }
3916 
3917 static HostSpinBoxSetting *MacMainSkip()
3918 {
3919  HostSpinBoxSetting *gs = new HostSpinBoxSetting("MacMainSkip", 0, 30, 1, true);
3920 
3921  gs->setLabel(MacMainSettings::tr("Frames to skip"));
3922 
3923  gs->setValue(0);
3924 
3925  gs->setHelpText(MacMainSettings::tr("Video in the main window will skip "
3926  "this many frames for each frame "
3927  "drawn. Set to 0 to show every "
3928  "frame."));
3929  return gs;
3930 }
3931 
3932 static HostSpinBoxSetting *MacMainOpacity()
3933 {
3934  HostSpinBoxSetting *gs = new HostSpinBoxSetting("MacMainOpacity", 0, 100, 5, false);
3935 
3936  gs->setLabel(MacMainSettings::tr("Opacity"));
3937 
3938  gs->setValue(100);
3939 
3940  gs->setHelpText(MacMainSettings::tr("The opacity of the main window. Set "
3941  "to 100 for completely opaque, set "
3942  "to 0 for completely transparent."));
3943  return gs;
3944 }
3945 
3946 static HostCheckBoxSetting *MacFloatEnabled()
3947 {
3948  HostCheckBoxSetting *gc = new HostCheckBoxSetting("MacFloatEnabled");
3949 
3950  gc->setLabel(MacFloatSettings::tr("Video in floating window"));
3951 
3952  gc->setValue(false);
3953 
3954  gc->setHelpText(MacFloatSettings::tr("If enabled, video will be displayed "
3955  "in a floating window. Only valid "
3956  "when \"Use GUI size for TV "
3957  "playback\" and \"Run the frontend "
3958  "in a window\" are checked."));
3959  return gc;
3960 }
3961 
3962 static HostSpinBoxSetting *MacFloatSkip()
3963 {
3964  HostSpinBoxSetting *gs = new HostSpinBoxSetting("MacFloatSkip", 0, 30, 1, true);
3965 
3966  gs->setLabel(MacFloatSettings::tr("Frames to skip"));
3967 
3968  gs->setValue(0);
3969 
3970  gs->setHelpText(MacFloatSettings::tr("Video in the floating window will "
3971  "skip this many frames for each "
3972  "frame drawn. Set to 0 to show "
3973  "every frame."));
3974  return gs;
3975 }
3976 
3977 static HostSpinBoxSetting *MacFloatOpacity()
3978 {
3979  HostSpinBoxSetting *gs = new HostSpinBoxSetting("MacFloatOpacity", 0, 100, 5, false);
3980 
3981  gs->setLabel(MacFloatSettings::tr("Opacity"));
3982 
3983  gs->setValue(100);
3984 
3985  gs->setHelpText(MacFloatSettings::tr("The opacity of the floating window. "
3986  "Set to 100 for completely opaque, "
3987  "set to 0 for completely "
3988  "transparent."));
3989  return gs;
3990 }
3991 
3992 static HostCheckBoxSetting *MacDockEnabled()
3993 {
3994  HostCheckBoxSetting *gc = new HostCheckBoxSetting("MacDockEnabled");
3995 
3996  gc->setLabel(MacDockSettings::tr("Video in the dock"));
3997 
3998  gc->setValue(true);
3999 
4000  gc->setHelpText(MacDockSettings::tr("If enabled, video will be displayed "
4001  "in the application's dock icon. Only "
4002  "valid when \"Use GUI size for TV "
4003  "playback\" and \"Run the frontend in "
4004  "a window\" are checked."));
4005  return gc;
4006 }
4007 
4008 static HostSpinBoxSetting *MacDockSkip()
4009 {
4010  HostSpinBoxSetting *gs = new HostSpinBoxSetting("MacDockSkip", 0, 30, 1, true);
4011 
4012  gs->setLabel(MacDockSettings::tr("Frames to skip"));
4013 
4014  gs->setValue(3);
4015 
4016  gs->setHelpText(MacDockSettings::tr("Video in the dock icon will skip this "
4017  "many frames for each frame drawn. Set "
4018  "to 0 to show every frame."));
4019  return gs;
4020 }
4021 
4022 static HostCheckBoxSetting *MacDesktopEnabled()
4023 {
4024  HostCheckBoxSetting *gc = new HostCheckBoxSetting("MacDesktopEnabled");
4025 
4026  gc->setLabel(MacDesktopSettings::tr("Video on the desktop"));
4027 
4028  gc->setValue(false);
4029 
4030  gc->setHelpText(MacDesktopSettings::tr("If enabled, video will be "
4031  "displayed on the desktop, "
4032  "behind the Finder icons. "
4033  "Only valid when \"Use GUI "
4034  "size for TV playback\" and "
4035  "\"Run the frontend in a "
4036  "window\" are checked."));
4037  return gc;
4038 }
4039 
4040 static HostSpinBoxSetting *MacDesktopSkip()
4041 {
4042  HostSpinBoxSetting *gs = new HostSpinBoxSetting("MacDesktopSkip", 0, 30, 1, true);
4043 
4044  gs->setLabel(MacDesktopSettings::tr("Frames to skip"));
4045 
4046  gs->setValue(0);
4047 
4048  gs->setHelpText(MacDesktopSettings::tr("Video on the desktop will skip "
4049  "this many frames for each frame "
4050  "drawn. Set to 0 to show every "
4051  "frame."));
4052  return gs;
4053 }
4054 #endif
4055 
4056 
4058 {
4059  public:
4061 
4062  private slots:
4063  void childChanged(StandardSetting* /*unused*/) override;
4064 
4065  private:
4071 };
4072 
4074 {
4075  setLabel(MainGeneralSettings::tr("Shutdown/Reboot Settings"));
4076  auto *power = MythPower::AcquireRelease(this, true);
4079 #ifndef Q_OS_ANDROID
4083 #endif
4085  if (power)
4086  MythPower::AcquireRelease(this, false);
4087  connect(m_overrideExitMenu, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
4089 }
4090 
4092 {
4094  return;
4095 
4096  bool confirmold = m_confirmCommand->isVisible();
4097  bool haltold = m_haltCommand->isVisible();
4098  bool rebootold = m_rebootCommand->isVisible();
4099  bool suspendold = m_suspendCommand->isVisible();
4100 
4101  switch (m_overrideExitMenu->getValue().toInt())
4102  {
4103  case 2:
4104  case 4:
4105  m_haltCommand->setVisible(true);
4106  m_rebootCommand->setVisible(false);
4107  m_suspendCommand->setVisible(false);
4109  break;
4110  case 3:
4111  case 6:
4112  m_haltCommand->setVisible(true);
4113  m_rebootCommand->setVisible(true);
4114  m_suspendCommand->setVisible(false);
4116  break;
4117  case 5:
4118  m_haltCommand->setVisible(false);
4119  m_rebootCommand->setVisible(true);
4120  m_suspendCommand->setVisible(false);
4122  break;
4123  case 8:
4124  case 9:
4125  m_haltCommand->setVisible(false);
4126  m_rebootCommand->setVisible(false);
4129  break;
4130  case 10:
4131  m_haltCommand->setVisible(true);
4132  m_rebootCommand->setVisible(true);
4135  break;
4136  case 0:
4137  case 1:
4138  default:
4139  m_haltCommand->setVisible(false);
4140  m_rebootCommand->setVisible(false);
4141  m_suspendCommand->setVisible(false);
4142  m_confirmCommand->setVisible(false);
4143  break;
4144  }
4145 
4146  if (confirmold != m_confirmCommand->isVisible() ||
4147  haltold != m_haltCommand->isVisible() ||
4148  rebootold != m_rebootCommand->isVisible() ||
4149  suspendold != m_suspendCommand->isVisible())
4150  {
4151  emit settingsChanged();
4152  }
4153 }
4154 
4156 {
4157 // DatabaseSettings::addDatabaseSettings(this);
4158  setLabel(tr("Main Settings"));
4159 
4160  addChild(new DatabaseSettings());
4161 
4162  auto *pin = new GroupSetting();
4163  pin->setLabel(tr("Settings Access"));
4164  pin->addChild(SetupPinCode());
4165  addChild(pin);
4166 
4167  auto *general = new GroupSetting();
4168  general->setLabel(tr("General"));
4169  general->addChild(UseVirtualKeyboard());
4170  general->addChild(ScreenShotPath());
4171 
4172  auto sh = getMythSortHelper();
4173  if (sh->hasPrefixes()) {
4174 #if 0
4175  // Last minute change. QStringRef::localeAwareCompare appears to
4176  // always do case insensitive sorting, so there's no point in
4177  // presenting this option to a user.
4178  general->addChild(SortCaseSensitive());
4179 #endif
4180  auto *stripPrefixes = SortStripPrefixes();
4181  general->addChild(stripPrefixes);
4182  stripPrefixes->addTargetedChild("1", SortPrefixExceptions());
4183  }
4184  general->addChild(ManualRecordStartChanType());
4185  addChild(general);
4186 
4188 
4190 
4191  auto *remotecontrol = new GroupSetting();
4192  remotecontrol->setLabel(tr("Remote Control"));
4193  remotecontrol->addChild(LircDaemonDevice());
4194  remotecontrol->addChild(NetworkControlEnabled());
4195  remotecontrol->addChild(NetworkControlPort());
4196  remotecontrol->addChild(UDPNotifyPort());
4197 #ifdef USING_LIBCEC
4198  HostCheckBoxSetting *cec = CECEnabled();
4199  remotecontrol->addChild(cec);
4200  m_cecPowerOnTVAllowed = CECPowerOnTVAllowed();
4201  m_cecPowerOffTVAllowed = CECPowerOffTVAllowed();
4202  m_cecPowerOnTVOnStart = CECPowerOnTVOnStart();
4203  m_cecPowerOffTVOnExit = CECPowerOffTVOnExit();
4204  cec->addTargetedChild("1",m_cecPowerOnTVAllowed);
4205  cec->addTargetedChild("1",m_cecPowerOffTVAllowed);
4206  cec->addTargetedChild("1",m_cecPowerOnTVOnStart);
4207  cec->addTargetedChild("1",m_cecPowerOffTVOnExit);
4208  connect(m_cecPowerOnTVAllowed, &MythUICheckBoxSetting::valueChanged,
4209  this, &MainGeneralSettings::cecChanged);
4210  connect(m_cecPowerOffTVAllowed, &MythUICheckBoxSetting::valueChanged,
4211  this, &MainGeneralSettings::cecChanged);
4212 #endif // USING_LIBCEC
4213  addChild(remotecontrol);
4214 
4215 #ifdef USING_AIRPLAY
4216  auto *airplay = new GroupSetting();
4217  airplay->setLabel(tr("AirPlay Settings"));
4218  airplay->addChild(AirPlayEnabled());
4219  airplay->addChild(AirPlayFullScreen());
4220  airplay->addChild(AirPlayAudioOnly());
4221  airplay->addChild(AirPlayPasswordSettings());
4222 // airplay->addChild(AirPlayInfo());
4223 // airplay->addChild(AirPlayRSAInfo());
4224  addChild(airplay);
4225 #endif
4226 }
4227 
4228 #ifdef USING_LIBCEC
4229 void MainGeneralSettings::cecChanged(bool /*setting*/)
4230 {
4231  if (m_cecPowerOnTVAllowed->boolValue())
4232  m_cecPowerOnTVOnStart->setEnabled(true);
4233  else
4234  {
4235  m_cecPowerOnTVOnStart->setEnabled(false);
4236  m_cecPowerOnTVOnStart->setValue(false);
4237  }
4238 
4239  if (m_cecPowerOffTVAllowed->boolValue())
4240  m_cecPowerOffTVOnExit->setEnabled(true);
4241  else
4242  {
4243  m_cecPowerOffTVOnExit->setEnabled(false);
4244  m_cecPowerOffTVOnExit->setValue(false);
4245  }
4246 }
4247 #endif // USING_LIBCEC
4248 
4250 {
4251  QStringList strlist( QString("REFRESH_BACKEND") );
4253  LOG(VB_GENERAL, LOG_ERR, QString("%1 called").arg(__FUNCTION__));
4255 }
4256 
4257 
4259 {
4260  public:
4261  PlayBackScaling();
4262  void updateButton(MythUIButtonListItem *item) override; // GroupSetting
4263 
4264  private slots:
4265  void childChanged(StandardSetting * /*setting*/) override; // StandardSetting
4266 
4267  private:
4272 };
4273 
4275 {
4276  setLabel(PlaybackSettings::tr("Scaling"));
4281  connect(m_vertScan, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
4283  connect(m_yScan, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
4285  connect(m_horizScan, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
4287  connect(m_xScan, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
4289 }
4290 
4291 
4293 {
4295  if (m_vertScan->getValue() == "0" &&
4296  m_horizScan->getValue() == "0" &&
4297  m_yScan->getValue() == "0" &&
4298  m_xScan->getValue() == "0")
4299  {
4300  item->SetText(PlaybackSettings::tr("No scaling"), "value");
4301  }
4302  else
4303  {
4304  item->SetText(QString("%1%x%2%+%3%+%4%")
4305  .arg(m_horizScan->getValue(),
4306  m_vertScan->getValue(),
4307  m_xScan->getValue(),
4308  m_yScan->getValue()),
4309  "value");
4310  }
4311 }
4312 
4314 {
4315  emit ShouldRedraw(this);
4316 }
4317 
4319  : StandardSettingDialog(stack, "playbacksettings", new PlaybackSettings())
4320 {
4321 }
4322 
4324 {
4326  if (item)
4327  {
4328  auto *config = item->GetData().value<PlaybackProfileItemConfig*>();
4329  if (config)
4331  }
4332 }
4333 
4334 
4336 {
4337  auto *menu = new MythMenu(tr("Playback Profile Menu"), this, "mainmenu");
4338 
4339  if (m_buttonList->GetItemPos(item) > 2)
4340  menu->AddItem(tr("Move Up"), &PlaybackSettingsDialog::MoveProfileItemUp);
4341  if (m_buttonList->GetItemPos(item) + 1 < m_buttonList->GetCount())
4342  menu->AddItem(tr("Move Down"), &PlaybackSettingsDialog::MoveProfileItemDown);
4343 
4344  menu->AddItem(tr("Delete"), &PlaybackSettingsDialog::DeleteProfileItem);
4345 
4346  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
4347 
4348  auto *menuPopup = new MythDialogBox(menu, popupStack, "menudialog");
4349  menuPopup->SetReturnEvent(this, "mainmenu");
4350 
4351  if (menuPopup->Create())
4352  popupStack->AddScreen(menuPopup);
4353  else
4354  delete menuPopup;
4355 }
4356 
4358 {
4360  if (item)
4361  {
4362  auto *config = item->GetData().value<PlaybackProfileItemConfig*>();
4363  if (config)
4364  {
4365  const int currentPos = m_buttonList->GetCurrentPos();
4366 
4367  config->DecreasePriority();
4368 
4369  m_buttonList->SetItemCurrent(currentPos + 1);
4370  }
4371  }
4372 }
4373 
4375 {
4377  if (item)
4378  {
4379  auto *config = item->GetData().value<PlaybackProfileItemConfig*>();
4380  if (config)
4381  {
4382  const int currentPos = m_buttonList->GetCurrentPos();
4383 
4384  config->IncreasePriority();
4385 
4386  m_buttonList->SetItemCurrent(currentPos - 1);
4387  }
4388  }
4389 }
4390 
4392 {
4393  auto *config = m_buttonList->GetDataValue().value<PlaybackProfileItemConfig*>();
4394  if (config)
4395  config->ShowDeleteDialog();
4396 }
4397 
4399 {
4400  setLabel(tr("Playback settings"));
4401 }
4402 
4404 {
4405  auto *general = new GroupSetting();
4406  general->setLabel(tr("General Playback"));
4407  general->addChild(JumpToProgramOSD());
4408  general->addChild(UseProgStartMark());
4409  general->addChild(AutomaticSetWatched());
4410  general->addChild(ContinueEmbeddedTVPlay());
4411  general->addChild(LiveTVIdleTimeout());
4412 
4413  general->addChild(FFmpegDemuxer());
4414 
4415  general->addChild(new PlayBackScaling());
4416  general->addChild(StereoDiscard());
4417  general->addChild(AspectOverride());
4418  general->addChild(AdjustFill());
4419 
4420  general->addChild(LetterboxingColour());
4421  general->addChild(PlaybackExitPrompt());
4422  general->addChild(EndOfRecordingExitPrompt());
4423  general->addChild(MusicChoiceEnabled());
4424  addChild(general);
4425 
4426  auto *advanced = new GroupSetting();
4427  advanced->setLabel(tr("Advanced Playback Settings"));
4428  advanced->addChild(RealtimePriority());
4429  advanced->addChild(AudioReadAhead());
4430  advanced->addChild(ColourPrimaries());
4431  advanced->addChild(ChromaUpsampling());
4432 #ifdef USING_VAAPI
4433  advanced->addChild(VAAPIDevice());
4434 #endif
4435 
4436  addChild(advanced);
4437 
4440 
4442  new ButtonStandardSetting(tr("Add a new playback profile"));
4446 
4447  auto *pbox = new GroupSetting();
4448  pbox->setLabel(tr("View Recordings"));
4449  pbox->addChild(PlayBoxOrdering());
4450  pbox->addChild(PlayBoxEpisodeSort());
4451  // Disabled until we re-enable live previews
4452  // pbox->addChild(PlaybackPreview());
4453  // pbox->addChild(HWAccelPlaybackPreview());
4454  pbox->addChild(PBBStartInTitle());
4455 
4456  auto *pbox2 = new GroupSetting();
4457  pbox2->setLabel(tr("Recording Groups"));
4458  pbox2->addChild(DisplayRecGroup());
4459  pbox2->addChild(QueryInitialFilter());
4460  pbox2->addChild(RememberRecGroup());
4461  pbox2->addChild(RecGroupMod());
4462 
4463  pbox->addChild(pbox2);
4464 
4465  pbox->addChild(DisplayGroupTitleSort());
4466 
4467  StandardSetting *playbackWatchList = PlaybackWatchList();
4468  playbackWatchList->addTargetedChild("1", PlaybackWLStart());
4469  playbackWatchList->addTargetedChild("1", PlaybackWLAutoExpire());
4470  playbackWatchList->addTargetedChild("1", PlaybackWLMaxAge());
4471  playbackWatchList->addTargetedChild("1", PlaybackWLBlackOut());
4472  pbox->addChild(playbackWatchList);
4473  addChild(pbox);
4474 
4475  auto *seek = new GroupSetting();
4476  seek->setLabel(tr("Seeking"));
4477  seek->addChild(SmartForward());
4478  seek->addChild(FFRewReposTime());
4479  seek->addChild(FFRewReverse());
4480 
4481  addChild(seek);
4482 
4483  auto *comms = new GroupSetting();
4484  comms->setLabel(tr("Commercial Skip"));
4485  comms->addChild(AutoCommercialSkip());
4486  comms->addChild(CommRewindAmount());
4487  comms->addChild(CommNotifyAmount());
4488  comms->addChild(MaximumCommercialSkip());
4489  comms->addChild(MergeShortCommBreaks());
4490 
4491  addChild(comms);
4492 
4493 #ifdef Q_OS_DARWIN
4494  GroupSetting* mac = new GroupSetting();
4495  mac->setLabel(tr("Mac OS X Video Settings"));
4496  mac->addChild(MacGammaCorrect());
4497  mac->addChild(MacScaleUp());
4498  mac->addChild(MacFullSkip());
4499 
4500  StandardSetting *floatEnabled = MacFloatEnabled();
4501  floatEnabled->addTargetedChild("1", MacFloatSkip());
4502  floatEnabled->addTargetedChild("1", MacFloatOpacity());
4503  mac->addChild(floatEnabled);
4504 
4505  StandardSetting *macMainEnabled = MacMainEnabled();
4506  macMainEnabled->addTargetedChild("1", MacMainSkip());
4507  macMainEnabled->addTargetedChild("1", MacMainOpacity());
4508  mac->addChild(macMainEnabled);
4509 
4510  StandardSetting *dockEnabled = MacDockEnabled();
4511  dockEnabled->addTargetedChild("1", MacDockSkip());
4512  mac->addChild(dockEnabled);
4513 
4514  StandardSetting* desktopEnabled = MacDesktopEnabled();
4515  desktopEnabled->addTargetedChild("1", MacDesktopSkip());
4516  mac->addChild(desktopEnabled);
4517 
4518  addChild(mac);
4519 #endif
4520 
4522 }
4523 
4525 {
4526  setLabel(tr("On-screen Display"));
4527 
4528  addChild(EnableMHEG());
4530  addChild(Visualiser());
4535 
4536  //GroupSetting *cc = new GroupSetting();
4537  //cc->setLabel(tr("Closed Captions"));
4538  //cc->addChild(DecodeVBIFormat());
4539  //addChild(cc);
4540 
4541 #ifdef Q_OS_MACOS
4542  // Any Mac OS-specific OSD stuff would go here.
4543 #endif
4544 }
4545 
4547 {
4548  setLabel(tr("General (Basic)"));
4549  auto *general = new GroupSetting();
4550  general->setLabel(tr("General (Basic)"));
4551  general->addChild(ChannelOrdering());
4552  general->addChild(ChannelFormat());
4553  general->addChild(LongChannelFormat());
4554 
4555  addChild(general);
4556 
4557  auto *autoexp = new GroupSetting();
4558 
4559  autoexp->setLabel(tr("General (Auto-Expire)"));
4560 
4561  autoexp->addChild(AutoExpireMethod());
4562 
4563  autoexp->addChild(RerecordWatched());
4564  autoexp->addChild(AutoExpireWatchedPriority());
4565 
4566  autoexp->addChild(AutoExpireLiveTVMaxAge());
4567  autoexp->addChild(AutoExpireDayPriority());
4568  autoexp->addChild(AutoExpireExtraSpace());
4569 
4570 // autoexp->addChild(new DeletedExpireOptions());
4571  autoexp->addChild(DeletedMaxAge());
4572 
4573  addChild(autoexp);
4574 
4575  auto *jobs = new GroupSetting();
4576 
4577  jobs->setLabel(tr("General (Jobs)"));
4578 
4579  jobs->addChild(CommercialSkipMethod());
4580  jobs->addChild(CommFlagFast());
4581  jobs->addChild(AggressiveCommDetect());
4582  jobs->addChild(DeferAutoTranscodeDays());
4583 
4584  addChild(jobs);
4585 
4586  auto *general2 = new GroupSetting();
4587 
4588  general2->setLabel(tr("General (Advanced)"));
4589 
4590  general2->addChild(RecordPreRoll());
4591  general2->addChild(RecordOverTime());
4592  general2->addChild(MaxStartGap());
4593  general2->addChild(MaxEndGap());
4594  general2->addChild(MinimumRecordingQuality());
4595  general2->addChild(CategoryOverTimeSettings());
4596  addChild(general2);
4597 
4598  auto *changrp = new GroupSetting();
4599 
4600  changrp->setLabel(tr("General (Channel Groups)"));
4601 
4602  changrp->addChild(ChannelGroupRememberLast());
4603  changrp->addChild(ChannelGroupDefault());
4604  changrp->addChild(BrowseChannelGroup());
4605 
4606  addChild(changrp);
4607 }
4608 
4610 {
4611  setLabel(tr("Program Guide"));
4612 
4615 }
4616 
4618 {
4619  auto *sched = new GroupSetting();
4620 
4621  sched->setLabel(tr("Scheduler Options"));
4622 
4623  sched->addChild(GRSchedOpenEnd());
4624  sched->addChild(GRPrefInputRecPriority());
4625  sched->addChild(GRHDTVRecPriority());
4626  sched->addChild(GRWSRecPriority());
4627 
4628  addChild(sched);
4629 
4630  auto *access = new GroupSetting();
4631 
4632  access->setLabel(tr("Accessibility Options"));
4633 
4634  access->addChild(GRSignLangRecPriority());
4635  access->addChild(GROnScrSubRecPriority());
4636  access->addChild(GRCCRecPriority());
4637  access->addChild(GRHardHearRecPriority());
4638  access->addChild(GRAudioDescRecPriority());
4639 
4640  addChild(access);
4641 }
4642 
4644 {
4645  public:
4646  GuiDimension();
4647  //QString getValue() override; // StandardSetting
4648  void updateButton(MythUIButtonListItem *item) override; // GroupSetting
4649 
4650  private slots:
4651  void childChanged(StandardSetting * /*setting*/) override; // StandardSetting
4652  private:
4657 };
4658 
4660 {
4661  setLabel(AppearanceSettings::tr("GUI dimension"));
4662  addChild(m_width = GuiWidth());
4666  connect(m_width, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
4668  connect(m_height, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
4670  connect(m_offsetX, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
4672  connect(m_offsetY, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
4674 }
4675 
4677 {
4679  if ((m_width->getValue() == "0" ||
4680  m_height->getValue() == "0") &&
4681  m_offsetX->getValue() == "0" &&
4682  m_offsetY->getValue() == "0")
4683  {
4684  item->SetText(AppearanceSettings::tr("Fullscreen"), "value");
4685  }
4686  else
4687  {
4688  item->SetText(QString("%1x%2+%3+%4")
4689  .arg(m_width->getValue(),
4690  m_height->getValue(),
4691  m_offsetX->getValue(),
4692  m_offsetY->getValue()),
4693  "value");
4694  }
4695 }
4696 
4698 {
4699  emit ShouldRedraw(this);
4700 }
4701 
4703 {
4704  QCoreApplication::processEvents();
4705  GetMythMainWindow()->JumpTo("Reload Theme");
4706 }
4707 
4709 {
4711  QList screens = QGuiApplication::screens();
4712  for (QScreen *qscreen : qAsConst(screens))
4713  {
4714  QString extra = MythDisplay::GetExtraScreenInfo(qscreen);
4715  m_screen->addSelection(qscreen->name() + extra, qscreen->name());
4716  }
4717  if (Screens > 1)
4718  m_screen->addSelection(AppearanceSettings::tr("All"), QString::number(-1));
4719 }
4720 
4722 {
4723  auto *screen = new GroupSetting();
4724  screen->setLabel(tr("Theme / Screen Settings"));
4725  addChild(screen);
4726 
4727  AddPaintEngine(screen);
4728  screen->addChild(MenuTheme());
4729  screen->addChild(GUIRGBLevels());
4730 
4734  screen->addChild(m_screen);
4735  screen->addChild(m_screenAspect);
4738 
4739  screen->addChild(ForceFullScreen());
4740  screen->addChild(new GuiDimension());
4741 
4742  screen->addChild(GuiSizeForTV());
4743  screen->addChild(HideMouseCursor());
4745  {
4746  screen->addChild(RunInWindow());
4747  screen->addChild(AlwaysOnTop());
4748  }
4749  screen->addChild(SmoothTransitions());
4750  screen->addChild(StartupScreenDelay());
4751  screen->addChild(GUIFontZoom());
4752 #ifdef USING_AIRPLAY
4753  screen->addChild(AirPlayFullScreen());
4754 #endif
4755 
4756  MythDisplay* display = GetMythMainWindow()->GetDisplay();
4757  if (display->VideoModesAvailable())
4758  {
4759  std::vector<MythDisplayMode> scr = display->GetVideoModes();
4760  if (!scr.empty())
4762  }
4763 
4764  auto *dates = new GroupSetting();
4765 
4766  dates->setLabel(tr("Localization"));
4767 
4768  dates->addChild(MythLanguage());
4769  dates->addChild(ISO639PreferredLanguage(0));
4770  dates->addChild(ISO639PreferredLanguage(1));
4771  dates->addChild(MythDateFormatCB());
4772  dates->addChild(MythShortDateFormat());
4773  dates->addChild(MythTimeFormat());
4774 
4775  addChild(dates);
4776 
4777  addChild(LCDEnable());
4778 }
4779 
4780 /*******************************************************************************
4781 * Channel Groups *
4782 *******************************************************************************/
4783 
4785 {
4786  auto *gc = new HostComboBoxSetting("Select from Channel Group");
4787  gc->setLabel(AppearanceSettings::tr("Select from Channel Group"));
4788  gc->addSelection("All Channels");
4789 
4790  // All automatic channel groups that have at least one channel
4791  auto list = ChannelGroup::GetAutomaticChannelGroups(false);
4792  for (const auto &chgrp : list)
4793  {
4794  gc->addSelection(chgrp.m_name);
4795  }
4796  gc->setHelpText(AppearanceSettings::tr(
4797  "Select the channel group to select channels from. "
4798  "\"All Channels\" lets you choose from all channels of all video sources. "
4799  "\"Priority\" lets you choose from all channels that have recording priority. "
4800  "The other values let you select a video source to choose channels from."));
4801  return gc;
4802 }
4803 
4805 {
4806  public:
4808  const QString &channum, const QString &name);
4809  uint getChannelId() const{return m_channelId;};
4810  private:
4811  uint m_channelId;
4812 
4813 };
4814 
4816  const QString &channum, const QString &channame)
4817  : m_channelId(chanid)
4818 {
4819  setLabel(QString("%1 %2").arg(channum, channame));
4820  setHelpText(ChannelGroupSettings::tr("Select/Unselect channels for this channel group"));
4821 }
4822 
4824  int groupId = -1)
4825  : m_groupId(groupId)
4826 {
4827  setLabel(groupName == "Favorites" ? tr("Favorites") : groupName);
4828  setValue(groupName);
4830  m_groupName->setLabel(groupName);
4831 }
4832 
4834 {
4835  //Change the name
4836  if ((m_groupName && m_groupName->haveChanged())
4837  || m_groupId == -1)
4838  {
4839  if (m_groupId == -1)//create a new group
4840  {
4841  MSqlQuery query(MSqlQuery::InitCon());
4842  QString newname = m_groupName ? m_groupName->getValue() : "undefined";
4843  QString qstr =
4844  "INSERT INTO channelgroupnames (name) VALUE (:NEWNAME);";
4845  query.prepare(qstr);
4846  query.bindValue(":NEWNAME", newname);
4847 
4848  if (!query.exec())
4849  MythDB::DBError("ChannelGroupSetting::Save 1", query);
4850  else
4851  {
4852  //update m_groupId
4853  QString qstr2 = "SELECT grpid FROM channelgroupnames "
4854  "WHERE name = :NEWNAME;";
4855  query.prepare(qstr2);
4856  query.bindValue(":NEWNAME", newname);
4857  if (!query.exec())
4858  MythDB::DBError("ChannelGroupSetting::Save 2", query);
4859  else
4860  if (query.next())
4861  m_groupId = query.value(0).toUInt();
4862  }
4863  }
4864  else
4865  {
4866  MSqlQuery query(MSqlQuery::InitCon());
4867  QString qstr = "UPDATE channelgroupnames set name = :NEWNAME "
4868  " WHERE name = :OLDNAME ;";
4869  query.prepare(qstr);
4870  query.bindValue(":NEWNAME", m_groupName->getValue());
4871  query.bindValue(":OLDNAME", getValue());
4872 
4873  if (!query.exec())
4874  MythDB::DBError("ChannelGroupSetting::Save 3", query);
4875  else
4876  if (query.next())
4877  m_groupId = query.value(0).toUInt();
4878  }
4879  }
4880 
4881  if (m_groupId == -1)
4882  return;
4883 
4884  QList<StandardSetting *> *children = getSubSettings();
4885  if (!children)
4886  return;
4887 
4888  QList<StandardSetting *>::const_iterator i;
4889  for (i = children->constBegin(); i != children->constEnd(); ++i)
4890  {
4891  if ((*i)->haveChanged())
4892  {
4893  if ((*i) != m_groupName)
4894  {
4895  auto *channel = dynamic_cast<ChannelCheckBoxSetting *>(*i);
4896  if (channel)
4897  {
4898  if (channel->boolValue())
4899  {
4900  ChannelGroup::AddChannel(channel->getChannelId(),
4901  m_groupId);
4902  }
4903  else
4904  {
4905  ChannelGroup::DeleteChannel(channel->getChannelId(),
4906  m_groupId);
4907  }
4908  }
4909  }
4910  }
4911  }
4912 }
4913 
4915 {
4916  if (VERBOSE_LEVEL_CHECK(VB_GENERAL, LOG_DEBUG))
4917  {
4918  QString group = m_groupSelection->getValue();
4919  int groupId = ChannelGroup::GetChannelGroupId(group);
4920  LOG(VB_GENERAL, LOG_INFO,
4921  QString("ChannelGroupSetting::LoadChannelGroup group:%1 groupId:%2")
4922  .arg(group).arg(groupId));
4923  }
4924 
4925  // Set the old checkboxes from the previously selected channel group invisible
4926  for (const auto &it : m_boxMap)
4927  {
4928  it.second->setVisible(false);
4929  }
4930 
4931  // And load the new collection
4933 
4934  // Using m_groupSelection instead of nullptr keeps the focus in the "Select from Channel Group" box
4936 }
4937 
4939 {
4940  QString fromGroup = m_groupSelection->getValue();
4941  int fromGroupId = ChannelGroup::GetChannelGroupId(fromGroup);
4942 
4943  MSqlQuery query(MSqlQuery::InitCon());
4944 
4945  if (fromGroupId == -1) // All Channels
4946  {
4947  query.prepare(
4948  "SELECT channel.chanid, channum, name, grpid FROM channel "
4949  "LEFT JOIN channelgroup "
4950  "ON (channel.chanid = channelgroup.chanid AND grpid = :GRPID) "
4951  "WHERE deleted IS NULL "
4952  "AND visible > 0 "
4953  "ORDER BY channum+0; "); // Order by numeric value of channel number
4954  query.bindValue(":GRPID", m_groupId);
4955  }
4956  else
4957  {
4958  query.prepare(
4959  "SELECT channel.chanid, channum, name, cg2.grpid FROM channel "
4960  "RIGHT JOIN channelgroup AS cg1 "
4961  "ON (channel.chanid = cg1.chanid AND cg1.grpid = :FROMGRPID) "
4962  "LEFT JOIN channelgroup AS cg2 "
4963  "ON (channel.chanid = cg2.chanid AND cg2.grpid = :GRPID) "
4964  "WHERE deleted IS NULL "
4965  "AND visible > 0 "
4966  "ORDER BY channum+0; "); // Order by numeric value of channel number
4967  query.bindValue(":GRPID", m_groupId);
4968  query.bindValue(":FROMGRPID", fromGroupId);
4969  }
4970 
4971  if (!query.exec() || !query.isActive())
4972  MythDB::DBError("ChannelGroupSetting::LoadChannelGroupChannels", query);
4973  else
4974  {
4975  while (query.next())
4976  {
4977  auto chanid = query.value(0).toUInt();
4978  auto channum = query.value(1).toString();
4979  auto name = query.value(2).toString();
4980  auto checked = !query.value(3).isNull();
4981  auto pair = std::make_pair(m_groupId, chanid);
4982 
4983  TransMythUICheckBoxSetting *checkBox = nullptr;
4984  auto it = m_boxMap.find(pair);
4985  if (it != m_boxMap.end())
4986  {
4987  checkBox = it->second;
4988  checkBox->setVisible(true);
4989  }
4990  else
4991  {
4992  checkBox = new ChannelCheckBoxSetting(chanid, channum, name);
4993  checkBox->setValue(checked);
4994  m_boxMap[pair] = checkBox;
4995  addChild(checkBox);
4996  }
4997  }
4998  }
4999 }
5000 
5002 {
5003  clearSettings();
5004 
5005  // We cannot rename the Favorites group, make it readonly
5007  m_groupName->setLabel(tr("Group name"));
5011 
5012  // Add channel group selection
5014  connect(m_groupSelection, qOverload<StandardSetting *>(&StandardSetting::valueChanged),
5017 
5019 
5021 }
5022 
5024 {
5025  // Cannot delete new group or Favorites
5026  return (m_groupId > 1);
5027 }
5028 
5030 {
5031  MSqlQuery query(MSqlQuery::InitCon());
5032 
5033  // Delete channels from this group
5034  query.prepare("DELETE FROM channelgroup WHERE grpid = :GRPID;");
5035  query.bindValue(":GRPID", m_groupId);
5036  if (!query.exec())
5037  MythDB::DBError("ChannelGroupSetting::deleteEntry 1", query);
5038 
5039  // Now delete the group from channelgroupnames
5040  query.prepare("DELETE FROM channelgroupnames WHERE grpid = :GRPID;");
5041  query.bindValue(":GRPID", m_groupId);
5042  if (!query.exec())
5043  MythDB::DBError("ChannelGroupSetting::deleteEntry 2", query);
5044 }
5045 
5047 {
5048  setLabel(tr("Channel Groups"));
5049 }
5050 
5052 {
5053  clearSettings();
5054  auto *newGroup = new ButtonStandardSetting(tr("(Create New Channel Group)"));
5055  connect(newGroup, &ButtonStandardSetting::clicked,
5057  addChild(newGroup);
5058 
5060  for (auto it = list.begin(); it < list.end(); ++it)
5061  {
5062  QString name = (it->m_name == "Favorites") ? tr("Favorites") : it->m_name;
5063  addChild(new ChannelGroupSetting(name, it->m_grpId));
5064  }
5065 
5066  // Load all the groups
5068 
5069  // TODO select the new one or the edited one
5070  emit settingsChanged(nullptr);
5071 }
5072 
5074 {
5075  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
5076  auto *settingdialog = new MythTextInputDialog(popupStack,
5077  tr("Enter the name of the new channel group"));
5078 
5079  if (settingdialog->Create())
5080  {
5081  connect(settingdialog, &MythTextInputDialog::haveResult,
5083  popupStack->AddScreen(settingdialog);
5084  }
5085  else
5086  {
5087  delete settingdialog;
5088  }
5089 }
5090 
5091 void ChannelGroupsSetting::CreateNewGroup(const QString& name)
5092 {
5093  auto *button = new ChannelGroupSetting(name, -1);
5094  button->setLabel(name);
5095  button->Load();
5096  addChild(button);
5097  emit settingsChanged(this);
5098 }
5099 
5100 // vim:set sw=4 ts=4 expandtab:
RunInWindow
static HostCheckBoxSetting * RunInWindow()
Definition: globalsettings.cpp:2632
PlaybackProfileConfig::InitUI
void InitUI(StandardSetting *parent)
Definition: globalsettings.cpp:1233
LCDPopupTime
static HostSpinBoxSetting * LCDPopupTime()
Definition: globalsettings.cpp:3682
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:216
LCDBacklightOn
static HostCheckBoxSetting * LCDBacklightOn()
Definition: globalsettings.cpp:3766
globalsettings.h
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:811
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
PlaybackProfileConfig::m_groupId
uint m_groupId
Definition: globalsettings.h:296
MythUIComboBoxSetting::clearSelections
void clearSelections()
Definition: standardsettings.cpp:514
GuiDimension::m_offsetX
StandardSetting * m_offsetX
Definition: globalsettings.cpp:4655
PlaybackWLStart
static HostCheckBoxSetting * PlaybackWLStart()
Definition: globalsettings.cpp:3555
MythVideoProfile::InitStatics
static void InitStatics(bool Reinit=false)
Definition: mythvideoprofile.cpp:1312
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
PlayBackScaling::m_xScan
StandardSetting * m_xScan
Definition: globalsettings.cpp:4270
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1587
PrimariesRelaxed
@ PrimariesRelaxed
Definition: videoouttypes.h:145
LCDShowMenu
static HostCheckBoxSetting * LCDShowMenu()
Definition: globalsettings.cpp:3669
PlaybackProfileConfig::DeleteProfileItem
void DeleteProfileItem(PlaybackProfileItemConfig *profile)
Definition: globalsettings.cpp:1292
PlayBoxOrdering
static HostComboBoxSetting * PlayBoxOrdering()
Definition: globalsettings.cpp:1420
PlaybackProfileItemConfig::Load
void Load(void) override
Definition: globalsettings.cpp:896
TransMythUICheckBoxSetting
Definition: standardsettings.h:411
SubtitleCodec
static HostComboBoxSetting * SubtitleCodec()
Definition: globalsettings.cpp:1573
MythPower
Definition: mythpower.h:23
MythUICheckBoxSetting::updateButton
void updateButton(MythUIButtonListItem *item) override
This method is called whenever the UI need to reflect a change Reimplement this If you widget need a ...
Definition: standardsettings.cpp:735
PlaybackProfileItemConfig::GetIndex
uint GetIndex(void) const
Definition: globalsettings.cpp:891
QueryInitialFilter
static HostCheckBoxSetting * QueryInitialFilter()
Definition: globalsettings.cpp:190
AppearanceSettings::m_display
MythDisplay * m_display
Definition: globalsettings.h:166
SortPrefixExceptions
static GlobalTextEditSetting * SortPrefixExceptions()
Definition: globalsettings.cpp:2977
StandardSetting::getLabel
QString getLabel(void) const
Definition: standardsettings.h:35
MythPower::FeatureSuspend
@ FeatureSuspend
Definition: mythpower.h:43
StandardSetting::setValue
virtual void setValue(const QString &newValue)
Definition: standardsettings.cpp:170
PlaybackSettings::NewPlaybackProfileSlot
void NewPlaybackProfileSlot(void) const
Definition: globalsettings.cpp:1377
LCDKeyString
static HostTextEditSetting * LCDKeyString()
Definition: globalsettings.cpp:3806
MythLanguage
static GlobalComboBoxSetting * MythLanguage()
Definition: globalsettings.cpp:3196
getMythSortHelper
std::shared_ptr< MythSortHelper > getMythSortHelper(void)
Get a pointer to the MythSortHelper singleton.
Definition: mythsorthelper.cpp:133
MythUIThemeHelper::GetThemes
QList< ThemeInfo > GetThemes(ThemeType Type)
Definition: mythuithemehelper.cpp:209
LCDShowGeneric
static HostCheckBoxSetting * LCDShowGeneric()
Definition: globalsettings.cpp:3753
GuiSizeForTV
static HostCheckBoxSetting * GuiSizeForTV()
Definition: globalsettings.cpp:2303
MythVideoProfile::GetProfileGroupID
static uint GetProfileGroupID(const QString &ProfileName, const QString &HostName)
Definition: mythvideoprofile.cpp:908
AggressiveCommDetect
static GlobalCheckBoxSetting * AggressiveCommDetect()
Definition: globalsettings.cpp:338
GRPrefInputRecPriority
static GlobalSpinBoxSetting * GRPrefInputRecPriority()
Definition: globalsettings.cpp:3031
PlaybackSettings::m_playbackProfiles
MythUIComboBoxSetting * m_playbackProfiles
Definition: globalsettings.h:47
PlaybackProfileItemConfig::m_heightRange
TransTextEditSetting * m_heightRange
Definition: globalsettings.h:251
PlaybackProfileItemConfig::m_upscaler
TransMythUIComboBoxSetting * m_upscaler
Definition: globalsettings.h:258
false
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:89
MythVideoProfile::SaveDB
static bool SaveDB(uint GroupId, std::vector< MythVideoProfileItem > &Items)
Definition: mythvideoprofile.cpp:572
MythVideoProfileItem
Definition: mythvideoprofile.h:55
PlaybackProfileConfig::m_addNewEntry
ButtonStandardSetting * m_addNewEntry
Definition: globalsettings.h:299
MythCoreContext::SendReceiveStringList
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
Definition: mythcorecontext.cpp:1370
MythVideoProfile::CreateProfiles
static void CreateProfiles(const QString &HostName)
Definition: mythvideoprofile.cpp:1073
MythVideoProfile::GetDeinterlacers
static const QList< QPair< QString, QString > > & GetDeinterlacers()
Definition: mythvideoprofile.cpp:1299
MythVideoProfile::CreateProfileGroup
static uint CreateProfileGroup(const QString &ProfileName, const QString &HostName)
Definition: mythvideoprofile.cpp:1002
PREF_LOOP
static constexpr const char * PREF_LOOP
Definition: mythvideoprofile.h:36
MythVideoProfile::DeleteProfileGroup
static bool DeleteProfileGroup(const QString &GroupName, const QString &HostName)
Definition: mythvideoprofile.cpp:1021
TVVidModeForceAspect
static HostComboBoxSetting * TVVidModeForceAspect(int idx=-1)
Definition: globalsettings.cpp:2526
AlwaysOnTop
static HostCheckBoxSetting * AlwaysOnTop()
Definition: globalsettings.cpp:2645
TransMythUIComboBoxSetting
Definition: standardsettings.h:272
DEINT_QUALITY_MEDIUM
static constexpr const char * DEINT_QUALITY_MEDIUM
Definition: mythvideoprofile.h:23
ForceFullScreen
static HostCheckBoxSetting * ForceFullScreen()
Definition: globalsettings.cpp:2316
TransTextEditSetting
Definition: standardsettings.h:161
PersistentBrowseMode
static HostCheckBoxSetting * PersistentBrowseMode()
Definition: globalsettings.cpp:1731
StandardSetting::removeTargetedChild
void removeTargetedChild(const QString &value, StandardSetting *child)
Definition: standardsettings.cpp:124
MythVideoProfile::LoadDB
static std::vector< MythVideoProfileItem > LoadDB(uint GroupId)
Definition: mythvideoprofile.cpp:491
StandardSettingDialog::m_buttonList
MythUIButtonList * m_buttonList
Definition: standardsettings.h:497
ShutDownRebootSetting::m_haltCommand
StandardSetting * m_haltCommand
Definition: globalsettings.cpp:4067
MythVideoProfile::GetVideoRendererHelp
static QString GetVideoRendererHelp(const QString &Renderer)
Definition: mythvideoprofile.cpp:1218
ButtonStandardSetting
Definition: standardsettings.h:450
PlaybackProfileItemConfig::vrenderChanged
void vrenderChanged(const QString &renderer)
Definition: globalsettings.cpp:1070
GuiDimension::updateButton
void updateButton(MythUIButtonListItem *item) override
This method is called whenever the UI need to reflect a change Reimplement this If you widget need a ...
Definition: globalsettings.cpp:4676
ChannelOrdering
static HostComboBoxSetting * ChannelOrdering()
Definition: globalsettings.cpp:1606
GRHardHearRecPriority
static GlobalSpinBoxSetting * GRHardHearRecPriority()
Definition: globalsettings.cpp:3134
AutoExpireDayPriority
static GlobalSpinBoxSetting * AutoExpireDayPriority()
Definition: globalsettings.cpp:534
GRSignLangRecPriority
static GlobalSpinBoxSetting * GRSignLangRecPriority()
Definition: globalsettings.cpp:3081
AdjustFill
static HostComboBoxSetting * AdjustFill()
Definition: globalsettings.cpp:2223
HostTextEditSetting
Definition: standardsettings.h:168
dbsettings.h
MergeShortCommBreaks
static GlobalSpinBoxSetting * MergeShortCommBreaks()
Definition: globalsettings.cpp:403
CurrentPlaybackProfile
static HostComboBoxSetting * CurrentPlaybackProfile()
Definition: globalsettings.cpp:1349
PlaybackWLMaxAge
static HostSpinBoxSetting * PlaybackWLMaxAge()
Definition: globalsettings.cpp:3587
GuiVidModeResolution
static HostComboBoxSetting * GuiVidModeResolution()
Definition: globalsettings.cpp:2376
MythMainWindow::JumpTo
void JumpTo(const QString &Destination, bool Pop=true)
Definition: mythmainwindow.cpp:1457
kAdjustFill_Off
@ kAdjustFill_Off
Definition: videoouttypes.h:74
MythTimeFormat
static HostComboBoxSetting * MythTimeFormat()
Definition: globalsettings.cpp:2809
PlaybackSettings
Definition: globalsettings.h:33
kLetterBoxColour_END
@ kLetterBoxColour_END
Definition: videoouttypes.h:91
PlaybackBox::TitleSortAlphabetical
@ TitleSortAlphabetical
Definition: playbackbox.h:84
HideMouseCursor
static HostCheckBoxSetting * HideMouseCursor()
Definition: globalsettings.cpp:2614
TransMythUISpinBoxSetting
Definition: standardsettings.h:353
SetupPinCode
static HostTextEditSetting * SetupPinCode()
Definition: globalsettings.cpp:2121
kLetterBoxColour_Black
@ kLetterBoxColour_Black
Definition: videoouttypes.h:89
LCDShowMusic
static HostCheckBoxSetting * LCDShowMusic()
Definition: globalsettings.cpp:3696
JumpToProgramOSD
static HostCheckBoxSetting * JumpToProgramOSD()
Definition: globalsettings.cpp:1831
DEINT_QUALITY_HIGH
static constexpr const char * DEINT_QUALITY_HIGH
Definition: mythvideoprofile.h:24
RecordPreRoll
static GlobalSpinBoxSetting * RecordPreRoll()
Definition: globalsettings.cpp:597
sched
Scheduler * sched
ChannelGroup::AddChannel
static bool AddChannel(uint chanid, int changrpid)
Definition: channelgroup.cpp:71
PlaybackProfileItemConfig
Definition: globalsettings.h:213
PlaybackProfileConfig::m_items
std::vector< MythVideoProfileItem > m_items
Definition: globalsettings.h:293
MythConfirmationDialog::haveResult
void haveResult(bool)
VERBOSE_LEVEL_CHECK
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
Definition: mythlogging.h:29
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
MythScreenStack
Definition: mythscreenstack.h:16
MainGeneralSettings::applyChange
void applyChange() override
Definition: globalsettings.cpp:4249
mythdbcon.h
LongChannelFormat
static HostComboBoxSetting * LongChannelFormat()
Definition: globalsettings.cpp:2867
Visualiser
static HostComboBoxSetting * Visualiser()
Definition: globalsettings.cpp:1718
AppearanceSettings::m_screenAspect
HostComboBoxSetting * m_screenAspect
Definition: globalsettings.h:165
GRSchedOpenEnd
static GlobalComboBoxSetting * GRSchedOpenEnd()
Definition: globalsettings.cpp:3006
AppearanceSettings::applyChange
void applyChange() override
Definition: globalsettings.cpp:4702
MythVideoProfile::GetVideoRenderers
static QStringList GetVideoRenderers(const QString &Decoder)
Definition: mythvideoprofile.cpp:1207
ChannelGroup::GetManualChannelGroups
static ChannelGroupList GetManualChannelGroups(bool includeEmpty=true)
Definition: channelgroup.cpp:189
GroupSetting::updateButton
void updateButton(MythUIButtonListItem *item) override
This method is called whenever the UI need to reflect a change Reimplement this If you widget need a ...
Definition: standardsettings.cpp:305
toUserString
QString toUserString(PrimariesMode Mode)
Definition: videoouttypes.h:149
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:617
kAspect_Off
@ kAspect_Off
Definition: videoouttypes.h:63
kRenderOpenGL
@ kRenderOpenGL
Definition: mythrender_base.h:19
ManualRecordStartChanType
static GlobalComboBoxSetting * ManualRecordStartChanType()
Definition: globalsettings.cpp:2991
VideoModeSettings
Definition: globalsettings.h:50
MythPower::FeatureShutdown
@ FeatureShutdown
Definition: mythpower.h:42
SkipTypeToString
QString SkipTypeToString(int flags)
Definition: programtypes.cpp:91
ISO639PreferredLanguage
static GlobalComboBoxSetting * ISO639PreferredLanguage(uint i)
Definition: globalsettings.cpp:3250
PlaybackSettingsDialog::ShowPlaybackProfileMenu
void ShowPlaybackProfileMenu(MythUIButtonListItem *item)
Definition: globalsettings.cpp:4335
StandardSetting::clearSettings
virtual void clearSettings()
Definition: standardsettings.cpp:160
GuiHeight
static HostSpinBoxSetting * GuiHeight()
Definition: globalsettings.cpp:2260
MythVideoProfile::GetUpscalers
static std::vector< std::pair< QString, QString > > GetUpscalers()
Definition: mythvideoprofile.cpp:720
COND_RATE
static constexpr const char * COND_RATE
Definition: mythvideoprofile.h:32
ISO639_fill_selections
static void ISO639_fill_selections(MythUIComboBoxSetting *widget, uint i)
Definition: globalsettings.cpp:3223
PlaybackProfileItemConfig::m_vidRend
TransMythUIComboBoxSetting * m_vidRend
Definition: globalsettings.h:257
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
playgroup.h
PlaybackProfileConfig::AddNewEntry
void AddNewEntry(void)
Definition: globalsettings.cpp:1305
PlayBackScaling::m_horizScan
StandardSetting * m_horizScan
Definition: globalsettings.cpp:4269
StandardSetting::addTargetedChild
void addTargetedChild(const QString &value, StandardSetting *setting)
Definition: standardsettings.cpp:117
PlaybackProfileItemConfig::heightChanged
void heightChanged(const QString &val)
Definition: globalsettings.cpp:1017
PlaybackWatchList
static HostCheckBoxSetting * PlaybackWatchList()
Definition: globalsettings.cpp:3539
PlaybackProfileConfig::ReloadSettings
void ReloadSettings(void)
Definition: globalsettings.cpp:1313
MythPainterWindow::GetDefaultPainter
static MUI_PUBLIC QString GetDefaultPainter()
Definition: mythpainterwindow.cpp:30
RerecordWatched
static GlobalCheckBoxSetting * RerecordWatched()
Definition: globalsettings.cpp:582
GROnScrSubRecPriority
static GlobalSpinBoxSetting * GROnScrSubRecPriority()
Definition: globalsettings.cpp:3099
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:50
PlaybackProfileConfig::InitProfileItem
StandardSetting * InitProfileItem(uint i, StandardSetting *parent)
Definition: globalsettings.cpp:1249
PlaybackWLAutoExpire
static HostCheckBoxSetting * PlaybackWLAutoExpire()
Definition: globalsettings.cpp:3569
ChannelGroup::GetChannelGroups
static ChannelGroupList GetChannelGroups(bool includeEmpty=true)
Definition: channelgroup.cpp:328
GroupSetting::GroupSetting
GroupSetting()=default
toDBString
QString toDBString(PrimariesMode Mode)
Definition: videoouttypes.h:156
ChannelGroupRememberLast
static HostCheckBoxSetting * ChannelGroupRememberLast()
Definition: globalsettings.cpp:2886
MythVideoProfile::GetVideoRendererName
static QString GetVideoRendererName(const QString &Renderer)
Definition: mythvideoprofile.cpp:847
PlaybackWLBlackOut
static HostSpinBoxSetting * PlaybackWLBlackOut()
Definition: globalsettings.cpp:3603
mythdirs.h
ChannelGroupSetting::m_groupName
TransTextEditSetting * m_groupName
Definition: globalsettings.h:321
mythsorthelper.h
PlayBoxEpisodeSort
static HostComboBoxSetting * PlayBoxEpisodeSort()
Definition: globalsettings.cpp:1452
UseVirtualKeyboard
static HostCheckBoxSetting * UseVirtualKeyboard()
Definition: globalsettings.cpp:1931
PlayBackScaling::m_vertScan
StandardSetting * m_vertScan
Definition: globalsettings.cpp:4268
AutoExpireWatchedPriority
static GlobalCheckBoxSetting * AutoExpireWatchedPriority()
Definition: globalsettings.cpp:519
LCDBigClock
static HostCheckBoxSetting * LCDBigClock()
Definition: globalsettings.cpp:3792
PlaybackProfileItemConfig::m_singleDeint
TransMythUIComboBoxSetting * m_singleDeint
Definition: globalsettings.h:259
PlaybackProfileItemConfig::m_doubleShader
TransMythUICheckBoxSetting * m_doubleShader
Definition: globalsettings.h:263
PlaybackProfileItemConfig::m_decoder
TransMythUIComboBoxSetting * m_decoder
Definition: globalsettings.h:254
PlaybackProfileItemConfig::DoubleQualityChanged
void DoubleQualityChanged(const QString &Quality)
Definition: globalsettings.cpp:1083
PREF_DEINT2X
static constexpr const char * PREF_DEINT2X
Definition: mythvideoprofile.h:39
MythTextInputDialog::haveResult
void haveResult(QString)
MythPower::IsFeatureSupported
bool IsFeatureSupported(Feature Supported)
Definition: mythpower.cpp:165
MainGeneralSettings::MainGeneralSettings
MainGeneralSettings()
Definition: globalsettings.cpp:4155
HostCheckBoxSetting
Definition: standardsettings.h:417
COND_WIDTH
static constexpr const char * COND_WIDTH
Definition: mythvideoprofile.h:30
PlaybackProfileItemConfig::m_skipLoop
TransMythUICheckBoxSetting * m_skipLoop
Definition: globalsettings.h:256
MythUIButtonList::GetCount
int GetCount() const
Definition: mythuibuttonlist.cpp:1652
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
StandardSetting::haveChanged
bool haveChanged()
Return true if the setting have changed or any of its children.
Definition: standardsettings.cpp:186
PlaybackProfileItemConfig::m_parentConfig
PlaybackProfileConfig * m_parentConfig
Definition: globalsettings.h:265
ChannelGroupSetting::Save
void Save() override
Definition: globalsettings.cpp:4833
PlaybackSettingsDialog::ShowMenu
void ShowMenu(void) override
Definition: globalsettings.cpp:4323
langsettings.h
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
mythvaapicontext.h
DatabaseSettings
Definition: dbsettings.h:10
MythTranslation::getLanguages
static QMap< QString, QString > getLanguages(void)
Definition: mythtranslation.cpp:118
ButtonStandardSetting::clicked
void clicked()
mythpainterwindow.h
mythsystem.h
PlaybackProfileConfig::m_profileName
QString m_profileName
Definition: globalsettings.h:295
MythUIButtonListItem::SetText
void SetText(const QString &text, const QString &name="", const QString &state="")
Definition: mythuibuttonlist.cpp:3268
FrontendIdleTimeout
static HostSpinBoxSetting * FrontendIdleTimeout()
Definition: globalsettings.cpp:1947
AutoCommercialSkip
static HostComboBoxSetting * AutoCommercialSkip()
Definition: globalsettings.cpp:301
MythMainWindow::GetDisplay
MythDisplay * GetDisplay()
Definition: mythmainwindow.cpp:253
RememberRecGroup
static HostCheckBoxSetting * RememberRecGroup()
Definition: globalsettings.cpp:206
MythUIButtonList::GetItemPos
int GetItemPos(MythUIButtonListItem *item) const
Definition: mythuibuttonlist.cpp:1695
PBBStartInTitle
static HostCheckBoxSetting * PBBStartInTitle()
Definition: globalsettings.cpp:241
hardwareprofile.os_detect.results
results
Definition: os_detect.py:296
PrimariesDisabled
@ PrimariesDisabled
Definition: videoouttypes.h:144
MythUIButtonListItem
Definition: mythuibuttonlist.h:41