|
MythTV
0.26-pre
|
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: */
1.7.6.1