MythTV  0.26-pre
channelsettings.cpp
Go to the documentation of this file.
00001 #include <QWidget>
00002 #include <QFile>
00003 
00004 #include "channelsettings.h"
00005 #include "channelutil.h"
00006 #include "programinfo.h" // for COMM_DETECT*, GetPreferredSkipTypeCombinations()
00007 #include "mpegtables.h"
00008 #include "mythdirs.h"
00009 #include "cardutil.h"
00010 
00011 QString ChannelDBStorage::GetWhereClause(MSqlBindings &bindings) const
00012 {
00013     QString fieldTag = (":WHERE" + id.getField().toUpper());
00014     QString query(id.getField() + " = " + fieldTag);
00015 
00016     bindings.insert(fieldTag, id.getValue());
00017 
00018     return query;
00019 }
00020 
00021 QString ChannelDBStorage::GetSetClause(MSqlBindings &bindings) const
00022 {
00023     QString fieldTag = (":SET" + id.getField().toUpper());
00024     QString nameTag = (":SET" + GetColumnName().toUpper());
00025 
00026     QString query(id.getField() + " = " + fieldTag + ", " +
00027                   GetColumnName() + " = " + nameTag);
00028 
00029     bindings.insert(fieldTag, id.getValue());
00030     bindings.insert(nameTag, user->GetDBValue());
00031 
00032     return query;
00033 }
00034 
00035 /*****************************************************************************
00036         Channel Options - Common
00037  *****************************************************************************/
00038 
00039 class Name : public LineEditSetting, public ChannelDBStorage
00040 {
00041   public:
00042     Name(const ChannelID &id) :
00043         LineEditSetting(this), ChannelDBStorage(this, id, "name")
00044     {
00045         setLabel(QObject::tr("Channel Name"));
00046     }
00047 };
00048 
00049 class Channum : public LineEditSetting, public ChannelDBStorage
00050 {
00051   public:
00052     Channum(const ChannelID &id) :
00053         LineEditSetting(this), ChannelDBStorage(this, id, "channum")
00054     {
00055         setLabel(QObject::tr("Channel Number"));
00056     }
00057 };
00058 
00059 class Source : public ComboBoxSetting, public ChannelDBStorage
00060 {
00061   public:
00062     Source(const ChannelID &id, uint _default_sourceid) :
00063         ComboBoxSetting(this), ChannelDBStorage(this, id, "sourceid"),
00064         default_sourceid(_default_sourceid)
00065     {
00066         setLabel(QObject::tr("Video Source"));
00067     }
00068 
00069     void Load(void)
00070     {
00071         fillSelections();
00072         ChannelDBStorage::Load();
00073 
00074         if (default_sourceid && !getValue().toUInt())
00075         {
00076             uint which = sourceid_to_index[default_sourceid];
00077             if (which)
00078                 setValue(which);
00079         }
00080     }
00081 
00082     void fillSelections(void)
00083     {
00084         addSelection(QObject::tr("[Not Selected]"), "0");
00085 
00086         MSqlQuery query(MSqlQuery::InitCon());
00087         query.prepare("SELECT name, sourceid "
00088                       "FROM videosource "
00089                       "ORDER BY sourceid");
00090 
00091         if (!query.exec() || !query.isActive())
00092         {
00093             MythDB::DBError("Source::fillSelections", query);
00094         }
00095         else
00096         {
00097             for (uint i = 1; query.next(); i++)
00098             {
00099                 sourceid_to_index[query.value(1).toUInt()] = i;
00100                 addSelection(query.value(0).toString(),
00101                              query.value(1).toString());
00102             }
00103         }
00104 
00105         sourceid_to_index[0] = 0; // Not selected entry.
00106     }
00107 
00108   private:
00109     uint            default_sourceid;
00110     QMap<uint,uint> sourceid_to_index;
00111 };
00112 
00113 class Callsign : public LineEditSetting, public ChannelDBStorage
00114 {
00115   public:
00116     Callsign(const ChannelID &id) :
00117         LineEditSetting(this), ChannelDBStorage(this, id, "callsign")
00118     {
00119         setLabel(QObject::tr("Callsign"));
00120     }
00121 };
00122 
00123 ChannelTVFormat::ChannelTVFormat(const ChannelID &id) :
00124     ComboBoxSetting(this), ChannelDBStorage(this, id, "tvformat")
00125 {
00126     setLabel(QObject::tr("TV Format"));
00127     setHelpText(
00128         QObject::tr(
00129             "If this channel uses a format other than TV "
00130             "Format in the General Backend Setup screen, set it here."));
00131 
00132     addSelection(QObject::tr("Default"), "Default");
00133 
00134     QStringList list = GetFormats();
00135     for (int i = 0; i < list.size(); i++)
00136         addSelection(list[i]);
00137 }
00138 
00139 QStringList ChannelTVFormat::GetFormats(void)
00140 {
00141     QStringList list;
00142 
00143     list.push_back("NTSC");
00144     list.push_back("NTSC-JP");
00145     list.push_back("PAL");
00146     list.push_back("PAL-60");
00147     list.push_back("PAL-BG");
00148     list.push_back("PAL-DK");
00149     list.push_back("PAL-D");
00150     list.push_back("PAL-I");
00151     list.push_back("PAL-M");
00152     list.push_back("PAL-N");
00153     list.push_back("PAL-NC");
00154     list.push_back("SECAM");
00155     list.push_back("SECAM-D");
00156     list.push_back("SECAM-DK");
00157 
00158     return list;
00159 }
00160 
00161 class TimeOffset : public SpinBoxSetting, public ChannelDBStorage
00162 {
00163   public:
00164     TimeOffset(const ChannelID &id) :
00165         SpinBoxSetting(this, -1440, 1440, 1),
00166         ChannelDBStorage(this, id, "tmoffset")
00167     {
00168         setLabel(QObject::tr("DataDirect") + " " + QObject::tr("Time Offset"));
00169         setHelpText(QObject::tr("Offset (in minutes) to apply to the program "
00170                     "guide data during import.  This can be used when the "
00171                     "listings for a particular channel are in a different "
00172                     "time zone.") + " " +
00173                     QObject::tr("(Works for DataDirect listings only.)"));
00174     }
00175 };
00176 
00177 class Priority : public SpinBoxSetting, public ChannelDBStorage
00178 {
00179   public:
00180     Priority(const ChannelID &id) :
00181         SpinBoxSetting(this, -99, 99, 1),
00182         ChannelDBStorage(this, id, "recpriority")
00183     {
00184         setLabel(QObject::tr("Priority"));
00185         setHelpText(
00186             QObject::tr("Number of priority points to be added to any "
00187                         "recording on this channel during scheduling.")+" "+
00188             QObject::tr("Use a positive number as the priority if you "
00189                         "want this to be a preferred channel, a "
00190                         "negative one to deprecate this channel."));
00191     }
00192 };
00193 
00194 class Icon : public LineEditSetting, public ChannelDBStorage
00195 {
00196   public:
00197     Icon(const ChannelID &id) :
00198         LineEditSetting(this), ChannelDBStorage(this, id, "icon")
00199     {
00200         setLabel(QObject::tr("Icon"));
00201         setHelpText(QObject::tr("Image file to use as the icon for this "
00202                                 "channel on various MythTV displays."));
00203     }
00204 };
00205 
00206 class VideoFilters : public LineEditSetting, public ChannelDBStorage
00207 {
00208   public:
00209     VideoFilters(const ChannelID &id) :
00210         LineEditSetting(this), ChannelDBStorage(this, id, "videofilters")
00211     {
00212         setLabel(QObject::tr("Video filters"));
00213         setHelpText(QObject::tr("Filters to be used when recording "
00214                                 "from this channel.  Not used with "
00215                                 "hardware encoding cards."));
00216 
00217     }
00218 };
00219 
00220 
00221 class OutputFilters : public LineEditSetting, public ChannelDBStorage
00222 {
00223   public:
00224     OutputFilters(const ChannelID &id) :
00225         LineEditSetting(this), ChannelDBStorage(this, id, "outputfilters")
00226     {
00227         setLabel(QObject::tr("Playback filters"));
00228         setHelpText(QObject::tr("Filters to be used when recordings "
00229                                 "from this channel are viewed.  "
00230                                 "Start with a plus to append to the "
00231                                 "global playback filters."));
00232     }
00233 };
00234 
00235 class XmltvID : public ComboBoxSetting, public ChannelDBStorage
00236 {
00237   public:
00238     XmltvID(const ChannelID &id, const QString &_sourceName) :
00239         ComboBoxSetting(this, true), ChannelDBStorage(this, id, "xmltvid"),
00240         sourceName(_sourceName)
00241     {
00242         setLabel(QObject::tr("XMLTV ID"));
00243         setHelpText(QObject::tr(
00244                         "ID used by listing services to get an exact "
00245                         "correspondance between a channel in your line-up "
00246                         "and a channel in their database. Normally this is "
00247                         "set automatically when 'mythfilldatabase' is run."));
00248     }
00249 
00250     void Load(void)
00251     {
00252         fillSelections();
00253         ChannelDBStorage::Load();
00254     }
00255 
00256     void fillSelections(void)
00257     {
00258         clearSelections();
00259 
00260         QString xmltvFile = GetConfDir() + '/' + sourceName + ".xmltv";
00261 
00262         if (QFile::exists(xmltvFile))
00263         {
00264             QFile file(xmltvFile);
00265             if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
00266                 return;
00267 
00268             QStringList idList;
00269 
00270             while (!file.atEnd())
00271             {
00272                 QByteArray line = file.readLine();
00273 
00274                 if (line.startsWith("channel="))
00275                 {
00276                     QString id = line.mid(8, -1).trimmed();
00277                     idList.append(id);
00278                 }
00279             }
00280 
00281             idList.sort();
00282 
00283             for (int x = 0; x < idList.size(); x++)
00284                 addSelection(idList.at(x), idList.at(x));
00285         }
00286     }
00287 
00288   private:
00289     QString sourceName;
00290 };
00291 
00292 class CommMethod : public ComboBoxSetting, public ChannelDBStorage
00293 {
00294   public:
00295     CommMethod(const ChannelID &id) :
00296        ComboBoxSetting(this), ChannelDBStorage(this, id, "commmethod")
00297     {
00298         setLabel(QObject::tr("Commercial Detection Method"));
00299         setHelpText(QObject::tr("Changes the method of "
00300                "commercial detection used for recordings on this channel or "
00301                "skips detection by marking the channel as Commercial Free."));
00302 
00303         deque<int> tmp = GetPreferredSkipTypeCombinations();
00304         tmp.push_front(COMM_DETECT_UNINIT);
00305         tmp.push_back(COMM_DETECT_COMMFREE);
00306 
00307         for (uint i = 0; i < tmp.size(); i++)
00308             addSelection(SkipTypeToString(tmp[i]), QString::number(tmp[i]));
00309     }
00310 };
00311 
00312 class Visible : public CheckBoxSetting, public ChannelDBStorage
00313 {
00314   public:
00315     Visible(const ChannelID &id) :
00316         CheckBoxSetting(this), ChannelDBStorage(this, id, "visible")
00317     {
00318         setValue(true);
00319         setLabel(QObject::tr("Visible"));
00320         setHelpText(QObject::tr("If enabled, the channel will be visible in the "
00321                     "EPG."));
00322     }
00323 };
00324 
00325 class OnAirGuide : public CheckBoxSetting, public ChannelDBStorage
00326 {
00327   public:
00328     OnAirGuide(const ChannelID &id) :
00329         CheckBoxSetting(this), ChannelDBStorage(this, id, "useonairguide")
00330     {
00331         setLabel(QObject::tr("Use on air guide"));
00332         setHelpText(QObject::tr("If enabled, guide information for this "
00333                     "channel will be updated using 'Over-the-Air' "
00334                     "program listings."));
00335     }
00336 };
00337 
00338 /*****************************************************************************
00339         Channel Options - Video 4 Linux
00340  *****************************************************************************/
00341 
00342 class Freqid : public LineEditSetting, public ChannelDBStorage
00343 {
00344   public:
00345     Freqid(const ChannelID &id) :
00346         LineEditSetting(this), ChannelDBStorage(this, id, "freqid")
00347     {
00348         setLabel(QObject::tr("Frequency")+" "+QObject::tr("or")+" "+
00349                  QObject::tr("Channel"));
00350         setHelpText(QObject::tr(
00351                         "Specify either the exact frequency (in kHz) or "
00352                         "a valid channel for your 'TV Format'."));
00353     }
00354 };
00355 
00356 class Finetune : public SliderSetting, public ChannelDBStorage
00357 {
00358   public:
00359     Finetune(const ChannelID& id)
00360         : SliderSetting(this, -300, 300, 1),
00361         ChannelDBStorage(this, id, "finetune")
00362     {
00363         setLabel(QObject::tr("Finetune")+" (kHz)");
00364         setHelpText(QObject::tr("Value to be added to your desired frequency "
00365                                 "(in kHz) for 'fine tuning'."));
00366     }
00367 };
00368 
00369 class Contrast : public SliderSetting, public ChannelDBStorage
00370 {
00371   public:
00372     Contrast(const ChannelID &id) :
00373         SliderSetting(this, 0, 65535, 655),
00374         ChannelDBStorage(this, id, "contrast")
00375     {
00376         setLabel(QObject::tr("Contrast"));
00377     }
00378 };
00379 
00380 class Brightness : public SliderSetting, public ChannelDBStorage
00381 {
00382   public:
00383     Brightness(const ChannelID &id) :
00384         SliderSetting(this, 0, 65535, 655),
00385         ChannelDBStorage(this, id, "brightness")
00386     {
00387         setLabel(QObject::tr("Brightness"));
00388     }
00389 };
00390 
00391 class Colour : public SliderSetting, public ChannelDBStorage
00392 {
00393   public:
00394     Colour(const ChannelID &id) :
00395         SliderSetting(this, 0, 65535, 655),
00396         ChannelDBStorage(this, id, "colour")
00397     {
00398         setLabel(QObject::tr("Color"));
00399     }
00400 };
00401 
00402 class Hue : public SliderSetting, public ChannelDBStorage
00403 {
00404   public:
00405     Hue(const ChannelID &id) :
00406         SliderSetting(this, 0, 65535, 655), ChannelDBStorage(this, id, "hue")
00407     {
00408         setLabel(QObject::tr("Hue"));
00409     }
00410 };
00411 
00412 ChannelOptionsCommon::ChannelOptionsCommon(const ChannelID &id,
00413                                            uint default_sourceid) :
00414     VerticalConfigurationGroup(false, true, false, false)
00415 {
00416     setLabel(QObject::tr("Channel Options - Common"));
00417     setUseLabel(false);
00418 
00419     addChild(new Name(id));
00420 
00421     Source *source = new Source(id, default_sourceid);
00422     source->Load();
00423 
00424     HorizontalConfigurationGroup *group1 =
00425         new HorizontalConfigurationGroup(false,false,true,true);
00426     VerticalConfigurationGroup *bottomhoz =
00427         new VerticalConfigurationGroup(false, true);
00428     VerticalConfigurationGroup *left =
00429         new VerticalConfigurationGroup(false, true);
00430     VerticalConfigurationGroup *right =
00431         new VerticalConfigurationGroup(false, true);
00432 
00433 
00434     left->addChild(new Channum(id));
00435     left->addChild(new Callsign(id));
00436     left->addChild(new Visible(id));
00437 
00438     right->addChild(source);
00439     right->addChild(new ChannelTVFormat(id));
00440     right->addChild(new Priority(id));
00441 
00442     group1->addChild(left);
00443     group1->addChild(right);
00444 
00445     bottomhoz->addChild(onairguide = new OnAirGuide(id));
00446     bottomhoz->addChild(xmltvID = new XmltvID(id, source->getSelectionLabel()));
00447     bottomhoz->addChild(new TimeOffset(id));
00448 
00449     addChild(group1);
00450     addChild(new CommMethod(id));
00451     addChild(new Icon(id));
00452     addChild(bottomhoz);
00453 
00454     connect(onairguide, SIGNAL(valueChanged(     bool)),
00455             this,       SLOT(  onAirGuideChanged(bool)));
00456     connect(source,     SIGNAL(valueChanged( const QString&)),
00457             this,       SLOT(  sourceChanged(const QString&)));
00458 };
00459 
00460 void ChannelOptionsCommon::Load(void)
00461 {
00462     VerticalConfigurationGroup::Load();
00463 }
00464 
00465 void ChannelOptionsCommon::onAirGuideChanged(bool fValue)
00466 {
00467     (void)fValue;
00468 }
00469 
00470 void ChannelOptionsCommon::sourceChanged(const QString& sourceid)
00471 {
00472     bool supports_eit  = true;
00473     bool uses_eit_only = false;
00474 
00475     MSqlQuery query(MSqlQuery::InitCon());
00476     query.prepare("SELECT cardtype "
00477                   "FROM capturecard, videosource, cardinput "
00478                   "WHERE cardinput.sourceid   = videosource.sourceid AND "
00479                   "      cardinput.cardid     = capturecard.cardid   AND "
00480                   "      videosource.sourceid = :SOURCEID");
00481     query.bindValue(":SOURCEID", sourceid);
00482 
00483     if (!query.exec() || !query.isActive())
00484         MythDB::DBError("sourceChanged -- supports eit", query);
00485     else
00486     {
00487         supports_eit = (query.size()) ? false : true;
00488         while (query.next())
00489         {
00490             supports_eit |= CardUtil::IsEITCapable(
00491                 query.value(0).toString().toUpper());
00492         }
00493 
00494         query.prepare("SELECT xmltvgrabber "
00495                       "FROM videosource "
00496                       "WHERE sourceid = :SOURCEID");
00497         query.bindValue(":SOURCEID", sourceid);
00498 
00499         if (!query.exec() || !query.isActive())
00500             MythDB::DBError("sourceChanged -- eit only", query);
00501         else
00502         {
00503             uses_eit_only = (query.size()) ? true : false;
00504             while (query.next())
00505             {
00506                 uses_eit_only &= (query.value(0).toString() == "eitonly");
00507             }
00508         }
00509     }
00510 
00511     onairguide->setEnabled(supports_eit);
00512     xmltvID->setEnabled(!uses_eit_only);
00513     xmltvID->Load();
00514 }
00515 
00516 ChannelOptionsFilters::ChannelOptionsFilters(const ChannelID& id) :
00517     VerticalConfigurationGroup(false, true, false, false)
00518 {
00519     setLabel(QObject::tr("Channel Options - Filters"));
00520     setUseLabel(false);
00521 
00522     addChild(new VideoFilters(id));
00523     addChild(new OutputFilters(id));
00524 }
00525 
00526 ChannelOptionsV4L::ChannelOptionsV4L(const ChannelID& id) :
00527     VerticalConfigurationGroup(false, true, false, false)
00528 {
00529     setLabel(QObject::tr("Channel Options - Video4Linux"));
00530     setUseLabel(false);
00531 
00532     addChild(new Freqid(id));
00533     addChild(new Finetune(id));
00534     addChild(new Contrast(id));
00535     addChild(new Brightness(id));
00536     addChild(new Colour(id));
00537     addChild(new Hue(id));
00538 };
00539 
00540 /*****************************************************************************
00541         Channel Options - Video 4 Linux
00542  *****************************************************************************/
00543 
00544 ChannelOptionsRawTS::ChannelOptionsRawTS(const ChannelID &id) :
00545     VerticalConfigurationGroup(false, true, false, false), cid(id)
00546 {
00547     setLabel(QObject::tr("Channel Options - Raw Transport Stream"));
00548     setUseLabel(false);
00549 
00550     const uint mx = kMaxPIDs;
00551     pids.resize(mx);
00552     sids.resize(mx);
00553     pcrs.resize(mx);
00554 
00555     for (uint i = 0; i < mx; i++)
00556     {
00557         HorizontalConfigurationGroup *row =
00558             new HorizontalConfigurationGroup(false, false, true, true);
00559         TransLabelSetting *label0 = new TransLabelSetting();
00560         label0->setLabel("    PID");
00561         TransLabelSetting *label1 = new TransLabelSetting();
00562         label1->setLabel("    StreamID");
00563         TransLabelSetting *label2 = new TransLabelSetting();
00564         label2->setLabel("    Is PCR");
00565         row->addChild(label0);
00566         row->addChild((pids[i] = new TransLineEditSetting()));
00567         row->addChild(label1);
00568         row->addChild((sids[i] = new TransComboBoxSetting()));
00569         for (uint j = 0x101; j <= 0x1ff; j++)
00570         {
00571             QString desc = StreamID::GetDescription(j&0xff);
00572             if (!desc.isEmpty())
00573                 sids[i]->addSelection(
00574                     QString("%1 (0x%2)")
00575                     .arg(desc).arg(j&0xff,2,16,QLatin1Char('0')),
00576                     QString::number(j), false);
00577         }
00578         for (uint j = 0x101; j <= 0x1ff; j++)
00579         {
00580             QString desc = StreamID::GetDescription(j&0xff);
00581             if (desc.isEmpty())
00582                 sids[i]->addSelection(
00583                     QString("0x%1").arg(j&0xff,2,16,QLatin1Char('0')),
00584                     QString::number(j), false);
00585         }
00586 /* we don't allow tables right now, PAT & PMT generated on the fly
00587         for (uint j = 0; j <= 0xff; j++)
00588         {
00589             QString desc = TableID::GetDescription(j);
00590             if (!desc.isEmpty())
00591             {
00592                 sids[i]->addSelection(
00593                     QString("%1 (0x%2)").arg(j,0,16,QLatin1Char('0')),
00594                     QString::number(j),
00595                     false);
00596             }
00597         }
00598 */
00599         row->addChild(label2);
00600         row->addChild((pcrs[i] = new TransCheckBoxSetting()));
00601         addChild(row);
00602     }
00603 };
00604 
00605 void ChannelOptionsRawTS::Load(void)
00606 {
00607     uint chanid = cid.getValue().toUInt();
00608 
00609     pid_cache_t pid_cache;
00610     if (!ChannelUtil::GetCachedPids(chanid, pid_cache))
00611         return;
00612 
00613     pid_cache_t::const_iterator it = pid_cache.begin();
00614     for (uint i = 0; i < kMaxPIDs && it != pid_cache.end(); )
00615     {
00616         if (!(it->IsPermanent()))
00617         {
00618             ++it;
00619             continue;
00620         }
00621 
00622         pids[i]->setValue(QString("0x%1")
00623                           .arg(it->GetPID(),2,16,QLatin1Char('0')));
00624         sids[i]->setValue(QString::number(it->GetComposite()&0x1ff));
00625         pcrs[i]->setValue(it->IsPCRPID());
00626         
00627         ++it;
00628         ++i;
00629     }
00630 }
00631 
00632 void ChannelOptionsRawTS::Save(void)
00633 {
00634     uint chanid = cid.getValue().toUInt();
00635 
00636     pid_cache_t pid_cache;
00637     for (uint i = 0; i < kMaxPIDs; i++)
00638     {
00639         bool ok;
00640         uint pid = pids[i]->getValue().toUInt(&ok, 0);
00641         if (!ok || !sids[i]->getValue().toUInt())
00642             continue;
00643 
00644         pid_cache.push_back(
00645             pid_cache_item_t(
00646                 pid, sids[i]->getValue().toUInt() | 0x10000 |
00647                 (pcrs[i]->getValue().toUInt() ? 0x200 : 0x0)));
00648     }
00649 
00650     ChannelUtil::SaveCachedPids(chanid, pid_cache, true /* delete_all */);
00651 }
00652 
00653 /* vim: set expandtab tabstop=4 shiftwidth=4: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends