00001 #include "scheduledrecording.h"
00002 #include "programinfo.h"
00003 #include "recordingprofile.h"
00004 #include "mythcontext.h"
00005 #include "proglist.h"
00006 #include "previouslist.h"
00007 #include "sr_items.h"
00008 #include "sr_root.h"
00009 #include "sr_dialog.h"
00010 #include "jobqueue.h"
00011 #include "mythdbcon.h"
00012 #include "viewschdiff.h"
00013
00014 #include <qlayout.h>
00015 #include <qlabel.h>
00016 #include <qapplication.h>
00017 #include <qregexp.h>
00018 #include <qsqlquery.h>
00019
00020
00021
00022
00023 class ScheduledRecordingDialog : public ConfigurationDialog
00024 {
00025 public:
00026 ScheduledRecordingDialog(ScheduledRecording *sr) : schedrec(sr)
00027 { addChild(schedrec); }
00028
00029 virtual MythDialog *dialogWidget(
00030 MythMainWindow *parent,
00031 const char *widgetName = "ScheduledRecordingDialog");
00032
00033 ScheduledRecording *schedrec;
00034 };
00035
00036 void ScheduledRecording::deleteLater()
00037 {
00038
00039
00040 if (dialog)
00041 {
00042 delete dialog;
00043 dialog = NULL;
00044 }
00045 else if (rootGroup)
00046 rootGroup->deleteLater();
00047
00048 ConfigurationGroup::deleteLater();
00049 }
00050
00051 ScheduledRecording::ScheduledRecording() :
00052 ConfigurationGroup(true, true, false, false)
00053 {
00054 m_pginfo = NULL;
00055 type = NULL;
00056 search = NULL;
00057 profile = NULL;
00058 dupin = NULL;
00059 dupmethod = NULL;
00060 autoexpire = NULL;
00061 autotranscode = NULL;
00062 transcoder = NULL;
00063 autocommflag = NULL;
00064 autouserjob1 = NULL;
00065 autouserjob2 = NULL;
00066 autouserjob3 = NULL;
00067 autouserjob4 = NULL;
00068 startoffset = NULL;
00069 endoffset = NULL;
00070 maxepisodes = NULL;
00071 maxnewest = NULL;
00072 recpriority = NULL;
00073 recgroup = NULL;
00074 storagegroup = NULL;
00075 playgroup = NULL;
00076 prefinput = NULL;
00077 inactive = NULL;
00078 searchType = "";
00079 searchForWhat = "";
00080
00081 longChannelFormat = gContext->GetSetting("LongChannelFormat", "<num> <name>");
00082 channelFormat = gContext->GetSetting("ChannelFormat", "<num> <sign>");
00083 timeFormat = gContext->GetSetting("TimeFormat", "h:mm AP");
00084 dateFormat = gContext->GetSetting("DateFormat", "ddd MMMM d");
00085 shortDateFormat = gContext->GetSetting("ShortDateFormat", "M/d");
00086
00087 addChild(id = new ID());
00088
00089 channel = new SRChannel(this);
00090 station = new SRStation(this);
00091 title = new SRTitle(this);
00092 subtitle = new SRSubtitle(this);
00093 description = new SRDescription(this);
00094 startTime = new SRStartTime(this);
00095 endTime = new SREndTime(this);
00096 startDate = new SRStartDate(this);
00097 endDate = new SREndDate(this);
00098 category = new SRCategory(this);
00099 seriesid = new SRSeriesid(this);
00100 programid = new SRProgramid(this);
00101 findday = new SRFindDay(this);
00102 findtime = new SRFindTime(this);
00103 findid = new SRFindId(this);
00104 parentid = new SRParentId(this);
00105 search = new SRRecSearchType(this);
00106 rootGroup = new RootSRGroup(this);
00107
00108 dialog = NULL;
00109 }
00110
00111 ScheduledRecording::~ScheduledRecording()
00112 {
00113 }
00114
00115 void ScheduledRecording::load()
00116 {
00117 if (getRecordID())
00118 {
00119 ConfigurationGroup::load();
00120
00121 QString tmpType = type->getValue();
00122 type->clearSelections();
00123 if (tmpType.toInt() == kOverrideRecord ||
00124 tmpType.toInt() == kDontRecord)
00125 type->addOverrideSelections();
00126 else
00127 type->addNormalSelections(!station->getValue().isEmpty(),
00128 search->intValue() == kManualSearch);
00129
00130 type->setValue(tmpType);
00131 type->setUnchanged();
00132
00133 fetchChannelInfo();
00134 }
00135 }
00136
00137
00138
00139 void ScheduledRecording::loadByProgram(const ProgramInfo* proginfo)
00140 {
00141 m_pginfo = proginfo;
00142
00143 if (proginfo->recordid)
00144 loadByID(proginfo->recordid);
00145 else
00146 setDefault(true);
00147
00148 if (search->intValue() == kNoSearch ||
00149 search->intValue() == kManualSearch)
00150 {
00151 setProgram(proginfo);
00152 if (!proginfo->recordid)
00153 playgroup->setValue(PlayGroup::GetInitialName(proginfo));
00154 }
00155 }
00156
00157 void ScheduledRecording::loadBySearch(RecSearchType lsearch,
00158 QString textname,
00159 QString forwhat)
00160 {
00161 QString from = "";
00162 loadBySearch(lsearch, textname, from, forwhat);
00163 }
00164 void ScheduledRecording::loadBySearch(RecSearchType lsearch,
00165 QString textname,
00166 QString from,
00167 QString forwhat)
00168 {
00169 MSqlQuery query(MSqlQuery::InitCon());
00170
00171 int rid = 0;
00172 query.prepare("SELECT recordid FROM record WHERE "
00173 "search = :SEARCH AND description LIKE :FORWHAT");
00174 query.bindValue(":SEARCH", lsearch);
00175 query.bindValue(":FORWHAT", forwhat);
00176
00177 if (query.exec() && query.isActive())
00178 {
00179 if (query.next())
00180 rid = query.value(0).toInt();
00181 }
00182 else
00183 MythContext::DBError("loadBySearch", query);
00184
00185 if (rid)
00186 loadByID(rid);
00187 else
00188 {
00189 setDefault(false);
00190 search->setValue(lsearch);
00191 searchForWhat = forwhat;
00192
00193 switch (lsearch)
00194 {
00195 case kPowerSearch:
00196 searchType = "(" + QObject::tr("Power Search") + ")";
00197 break;
00198 case kTitleSearch:
00199 searchType = "(" + QObject::tr("Title Search") + ")";
00200 break;
00201 case kKeywordSearch:
00202 searchType = "(" + QObject::tr("Keyword Search") + ")";
00203 break;
00204 case kPeopleSearch:
00205 searchType = "(" + QObject::tr("People Search") + ")";
00206 break;
00207 default:
00208 searchType = "(" + QObject::tr("Unknown Search") + ")";
00209 break;
00210 }
00211 QString ltitle = QString("%1 %2").arg(textname).arg(searchType);
00212 title->setValue(ltitle);
00213 subtitle->setValue(from);
00214 description->setValue(forwhat);
00215 findday->setValue((startDate->dateValue().dayOfWeek() + 1) % 7);
00216 QDate epoch = QDate::QDate (1970, 1, 1);
00217 findid->setValue(epoch.daysTo(startDate->dateValue()) + 719528);
00218 }
00219 }
00220
00221 void ScheduledRecording::modifyPowerSearchByID(int rid,
00222 QString textname,
00223 QString forwhat)
00224 {
00225 QString from = "";
00226 modifyPowerSearchByID(rid, textname, from, forwhat);
00227 }
00228
00229 void ScheduledRecording::modifyPowerSearchByID(int rid,
00230 QString textname,
00231 QString from,
00232 QString forwhat)
00233 {
00234 if (rid <= 0)
00235 return;
00236
00237 loadByID(rid);
00238 if (search->intValue() != kPowerSearch)
00239 return;
00240
00241 QString ltitle = textname + " (" + QObject::tr("Power Search") + ")";
00242 title->setValue(ltitle);
00243 subtitle->setValue(from);
00244 description->setValue(forwhat);
00245 }
00246
00247 void ScheduledRecording::fetchChannelInfo()
00248 {
00249
00250 if (channel->getValue().toInt() > 0)
00251 {
00252 MSqlQuery query(MSqlQuery::InitCon());
00253
00254 QString queryStr(QString("SELECT channum, callsign, name FROM channel "
00255 "WHERE chanid = '%1';").arg(channel->getValue()));
00256
00257 query.prepare(queryStr);
00258
00259 if (query.exec() && query.isActive() && query.size() > 0)
00260 {
00261 query.next();
00262 chanstr = query.value(0).toString();
00263 chansign = query.value(1).toString();
00264 channame = query.value(2).toString();
00265 }
00266 }
00267 else
00268 {
00269 chanstr = "";
00270 chansign = "";
00271 channame = "";
00272 }
00273 }
00274
00275
00276
00277 QString ScheduledRecording::ChannelText(QString format)
00278 {
00279 format.replace("<num>", chanstr)
00280 .replace("<sign>", chansign)
00281 .replace("<name>", channame);
00282
00283 return format;
00284 }
00285
00286
00287 void ScheduledRecording::ToMap(QMap<QString, QString>& progMap)
00288 {
00289 QString searchtitle = "";
00290
00291 if (m_pginfo && search->intValue() != kNoSearch &&
00292 search->intValue() != kManualSearch)
00293 {
00294 searchtitle = title->getValue();
00295 m_pginfo->ToMap(progMap);
00296 }
00297 else
00298 {
00299 progMap["title"] = title->getValue();
00300 progMap["subtitle"] = subtitle->getValue();
00301 progMap["description"] = description->getValue();
00302
00303 progMap["category"] = category->getValue();
00304 progMap["callsign"] = station->getValue();
00305
00306 progMap["starttime"] = startTime->getValue();
00307 progMap["startdate"] = startDate->getValue();
00308 progMap["endtime"] = endTime->getValue();
00309 progMap["enddate"] = endTime->getValue();
00310
00311
00312 if (chanstr.isEmpty())
00313 {
00314 progMap["channum"] = QObject::tr("Any");
00315 progMap["longchannel"] = QObject::tr("Any");
00316
00317 }
00318 else
00319 {
00320 progMap["channum"] = chanstr;
00321 progMap["longchannel"] = ChannelText(longChannelFormat);
00322 }
00323
00324 progMap["chanid"] = channel->getValue();
00325 progMap["channel"] = station->getValue();
00326
00327 QDateTime startts(startDate->dateValue(), startTime->timeValue());
00328 QDateTime endts(endDate->dateValue(), endTime->timeValue());
00329
00330 QString length;
00331 int hours, minutes, seconds;
00332 seconds = startts.secsTo(endts);
00333
00334 minutes = seconds / 60;
00335 progMap["lenmins"] = QString("%1 %2").arg(minutes).arg(QObject::tr("minutes"));
00336 hours = minutes / 60;
00337 minutes = minutes % 60;
00338 length.sprintf("%d:%02d", hours, minutes);
00339
00340 progMap["lentime"] = length;
00341
00342 progMap["timedate"] = startts.date().toString(dateFormat) + ", " +
00343 startts.time().toString(timeFormat) + " - " +
00344 endts.time().toString(timeFormat);
00345
00346 progMap["shorttimedate"] = startts.date().toString(shortDateFormat) + ", " +
00347 startts.time().toString(timeFormat) + " - " +
00348 endts.time().toString(timeFormat);
00349 }
00350
00351 int recType = type->getValue().toInt();
00352
00353 if (recType == kFindDailyRecord || recType == kFindWeeklyRecord)
00354 {
00355 QString findfrom = findtime->timeValue().toString(timeFormat);
00356 if (recType == kFindWeeklyRecord)
00357 {
00358 int daynum = (findday->intValue() + 5) % 7 + 1;
00359 findfrom = QString("%1, %2")
00360 .arg(QDate::shortDayName(daynum))
00361 .arg(findfrom);
00362 }
00363 progMap["subtitle"] = QString("(%1 %2) %3")
00364 .arg(findfrom).arg(tr("or later"))
00365 .arg(progMap["subtitle"]);
00366 }
00367
00368 progMap["searchtype"] = searchType;
00369 progMap["searchforwhat"] = searchForWhat;
00370
00371 if (searchtitle != "")
00372 {
00373 progMap["banner"] = searchtitle;
00374
00375 if (progMap["subtitle"] == "")
00376 progMap["episode"] = progMap["title"];
00377 else
00378 progMap["episode"] = QString("%1 - \"%2\"")
00379 .arg(progMap["title"])
00380 .arg(progMap["subtitle"]);
00381 }
00382 else
00383 {
00384 progMap["banner"] = progMap["title"];
00385 progMap["episode"] = progMap["subtitle"];
00386 }
00387 }
00388
00389
00390 void ScheduledRecording::loadByID(int recordID) {
00391 id->setValue(recordID);
00392 load();
00393 }
00394
00395 RecordingType ScheduledRecording::getRecordingType(void) const {
00396 return (RecordingType)(type->getValue().toInt());
00397 }
00398
00399 void ScheduledRecording::setRecordingType(RecordingType newType) {
00400 type->setValue(QString::number(newType));
00401 }
00402
00403 RecSearchType ScheduledRecording::getSearchType(void) const {
00404 return (RecSearchType)(search->intValue());
00405 }
00406
00407 void ScheduledRecording::setSearchType(RecSearchType newType) {
00408 if (type->getValue().toInt() == kOverrideRecord ||
00409 type->getValue().toInt() == kDontRecord)
00410 {
00411 VERBOSE(VB_IMPORTANT, "Attempt to set search type for "
00412 "override recording");
00413 return;
00414 }
00415 search->setValue(newType);
00416 type->clearSelections();
00417 type->addNormalSelections(!station->getValue().isEmpty(),
00418 search->intValue() == kManualSearch);
00419 }
00420
00421 int ScheduledRecording::GetAutoExpire(void) const {
00422 return(autoexpire->getValue().toInt());
00423 }
00424
00425 void ScheduledRecording::SetAutoExpire(int expire) {
00426 autoexpire->setValue(expire);
00427 }
00428
00429 int ScheduledRecording::GetTranscoder(void) const {
00430 return transcoder->getValue().toInt();
00431 }
00432
00433 int ScheduledRecording::GetAutoRunJobs(void) const {
00434 int result = 0;
00435
00436 if (autotranscode->getValue().toInt())
00437 result |= JOB_TRANSCODE;
00438 if (autocommflag->getValue().toInt())
00439 result |= JOB_COMMFLAG;
00440 if (autouserjob1->getValue().toInt())
00441 result |= JOB_USERJOB1;
00442 if (autouserjob2->getValue().toInt())
00443 result |= JOB_USERJOB2;
00444 if (autouserjob3->getValue().toInt())
00445 result |= JOB_USERJOB3;
00446 if (autouserjob4->getValue().toInt())
00447 result |= JOB_USERJOB4;
00448
00449 return result;
00450 }
00451
00452 int ScheduledRecording::GetMaxEpisodes(void) const {
00453 return(maxepisodes->getValue().toInt());
00454 }
00455
00456 bool ScheduledRecording::GetMaxNewest(void) const {
00457 return(maxnewest->getValue().toInt());
00458 }
00459
00460 void ScheduledRecording::save(void)
00461 {
00462
00463
00464
00465 save(true);
00466 }
00467
00468 void ScheduledRecording::save(bool sendSig)
00469 {
00470 if (type->isChanged() && getRecordingType() == kNotRecording)
00471 {
00472 remove();
00473 }
00474 else
00475 {
00476 ConfigurationGroup::save();
00477
00478 MSqlQuery query(MSqlQuery::InitCon());
00479 query.prepare(
00480 "UPDATE recorded "
00481 "SET recpriority = :RECPRIORITY, "
00482 "transcoder = :TRANSCODER, playgroup = :PLAYGROUP "
00483 "WHERE recordid = :RECORDID ;");
00484 query.bindValue(":RECPRIORITY", getRecPriority());
00485 query.bindValue(":TRANSCODER", transcoder->getValue().toInt());
00486 query.bindValue(":PLAYGROUP", playgroup->getValue().utf8());
00487 query.bindValue(":RECORDID", getRecordID());
00488
00489 if (!query.exec())
00490 MythContext::DBError("UPDATE recorded", query);
00491 }
00492 if (sendSig)
00493 signalChange(getRecordID());
00494 }
00495
00496 void ScheduledRecording::save(QString destination)
00497 {
00498 if (type->isChanged() && getRecordingType() == kNotRecording)
00499 {
00500 remove();
00501 }
00502 else
00503 {
00504 ConfigurationGroup::save(destination);
00505 }
00506 }
00507
00508 void ScheduledRecording::remove()
00509 {
00510 int rid = getRecordID();
00511
00512 if (!rid)
00513 return;
00514
00515 QString querystr;
00516 MSqlQuery query(MSqlQuery::InitCon());
00517 querystr = QString("DELETE FROM record WHERE recordid = %1").arg(rid);
00518 query.prepare(querystr);
00519 query.exec();
00520
00521 querystr = QString("DELETE FROM oldfind WHERE recordid = %1").arg(rid);
00522 query.prepare(querystr);
00523 query.exec();
00524 }
00525
00526 void ScheduledRecording::signalChange(int recordid)
00527 {
00528 if (gContext->IsBackend())
00529 {
00530 MythEvent me(QString("RESCHEDULE_RECORDINGS %1").arg(recordid));
00531 gContext->dispatch(me);
00532 }
00533 else
00534 {
00535 QStringList slist;
00536 slist << QString("RESCHEDULE_RECORDINGS %1").arg(recordid);
00537 if (!gContext->SendReceiveStringList(slist))
00538 VERBOSE(VB_IMPORTANT, QString("Error rescheduling id %1 "
00539 "in ScheduledRecording::signalChange")
00540 .arg(recordid));
00541 }
00542 }
00543
00544 void ScheduledRecording::doneRecording(ProgramInfo& proginfo)
00545 {
00546 proginfo.recstatus = rsRecorded;
00547
00548 QString msg = "Finished recording";
00549 QString subtitle = proginfo.subtitle.isEmpty() ? "" :
00550 QString(" \"%1\"").arg(proginfo.subtitle);
00551 QString details = QString("%1%2: channel %3")
00552 .arg(proginfo.title)
00553 .arg(subtitle)
00554 .arg(proginfo.chanid);
00555
00556 VERBOSE(VB_GENERAL, QString("%1 %2").arg(msg).arg(details).local8Bit());
00557 gContext->LogEntry("scheduler", LP_NOTICE, msg, details);
00558 }
00559
00560 void ScheduledRecording::runTitleList(void)
00561 {
00562 ProgLister *pl = NULL;
00563
00564 if (search->intValue())
00565 {
00566 if (m_pginfo)
00567 {
00568 pl = new ProgLister(plTitle, m_pginfo->title, "",
00569 gContext->GetMainWindow(), "proglist");
00570 }
00571 else
00572 {
00573 QString trimTitle = title->getValue();
00574 trimTitle.remove(QRegExp(" \\(.*\\)$"));
00575 pl = new ProgLister(plTitle, trimTitle, "",
00576 gContext->GetMainWindow(), "proglist");
00577 }
00578 }
00579 else
00580 {
00581 pl = new ProgLister(plTitle, title->getValue(), "",
00582 gContext->GetMainWindow(), "proglist");
00583 }
00584 pl->exec();
00585 delete pl;
00586 }
00587
00588 void ScheduledRecording::runRuleList(void)
00589 {
00590 ProgLister *pl = NULL;
00591
00592 if (getRecordID())
00593 {
00594 pl = new ProgLister(plRecordid,
00595 QString("%1").arg(getRecordID()), "",
00596 gContext->GetMainWindow(), "proglist");
00597 }
00598 else
00599 {
00600 pl = new ProgLister(plTitle, title->getValue(), "",
00601 gContext->GetMainWindow(), "proglist");
00602 }
00603 pl->exec();
00604 delete pl;
00605 }
00606
00607 void ScheduledRecording::runPrevList(void)
00608 {
00609 PreviousList *pb = NULL;
00610
00611 pb = new PreviousList(gContext->GetMainWindow(), "proglist",
00612 getRecordID(), title->getValue());
00613 pb->exec();
00614 delete pb;
00615 }
00616
00617 void ScheduledRecording::runShowDetails(void)
00618 {
00619 if (m_pginfo)
00620 m_pginfo->showDetails();
00621 }
00622
00623 void ScheduledRecording::fillSelections(SelectSetting* setting)
00624 {
00625 MSqlQuery result(MSqlQuery::InitCon());
00626 result.prepare("SELECT recordid FROM record");
00627 if (result.exec() && result.isActive() && result.size() > 0)
00628 {
00629 while (result.next())
00630 {
00631 int recid = result.value(0).toInt();
00632
00633 ScheduledRecording sr;
00634 sr.loadByID(recid);
00635
00636 QString label;
00637 QString weekly = "";
00638
00639 switch (sr.getRecordingType()) {
00640 case kAllRecord:
00641 label = QString("%1").arg(sr.title->getValue());
00642 break;
00643 case kFindOneRecord:
00644 label = QString("%1").arg(sr.title->getValue());
00645 break;
00646 case kFindWeeklyRecord:
00647 weekly = QDate(sr.startDate->dateValue()).toString("dddd")+"s ";
00648 case kFindDailyRecord:
00649 label = QString("%1 (after %2%3")
00650 .arg(sr.title->getValue())
00651 .arg(weekly)
00652 .arg(sr.findtime->timeValue().toString());
00653 break;
00654 case kChannelRecord:
00655 label = QString("%1 on channel %2")
00656 .arg(sr.title->getValue())
00657 .arg(sr.channel->getSelectionLabel());
00658 break;
00659 case kWeekslotRecord:
00660 weekly = QDate(sr.startDate->dateValue()).toString("dddd")+"s ";
00661 case kTimeslotRecord:
00662 label = QString("%1 on channel %2 (%3%4 - %5)")
00663 .arg(sr.title->getValue())
00664 .arg(sr.channel->getSelectionLabel())
00665 .arg(weekly)
00666 .arg(sr.startTime->timeValue().toString())
00667 .arg(sr.endTime->timeValue().toString());
00668 break;
00669 case kSingleRecord:
00670 case kOverrideRecord:
00671 case kDontRecord:
00672 label = QString("%1 on channel %2 (%3 %4 - %5)")
00673 .arg(sr.title->getValue())
00674 .arg(sr.channel->getSelectionLabel())
00675 .arg(sr.startDate->dateValue().toString())
00676 .arg(sr.startTime->timeValue().toString())
00677 .arg(sr.endTime->timeValue().toString());
00678 break;
00679 default:
00680 label = "You should not see this";
00681 }
00682
00683 setting->addSelection(label, QString::number(recid));
00684 }
00685 }
00686 }
00687
00689
00690 MythDialog *ScheduledRecordingDialog::dialogWidget(
00691 MythMainWindow *parent, const char *name)
00692 {
00693 (void) parent;
00694 (void) name;
00695
00696 #ifdef USING_FRONTEND
00697
00698 MythDialog *dlg = new RecOptDialog(schedrec, parent, name);
00699 schedrec->getRootGroup()->setDialog(dlg);
00700
00701 return dlg;
00702
00703 #else
00704
00705 #warning You must compile the frontend to use a dialogWidget.
00706
00707 VERBOSE(VB_IMPORTANT,
00708 "You must compile the frontend to use a dialogWidget.");
00709
00710 return NULL;
00711
00712 #endif
00713 }
00714
00716
00717 void ScheduledRecordingEditor::load(void)
00718 {
00719 listbox->clearSelections();
00720 ScheduledRecording::fillSelections(listbox);
00721 }
00722
00723
00724 DialogCode ScheduledRecordingEditor::exec(void)
00725 {
00726 while (ConfigurationDialog::exec() == kDialogCodeAccepted)
00727 open(listbox->getValue().toInt());
00728
00729 return kDialogCodeRejected;
00730 }
00731
00732 void ScheduledRecordingEditor::open(int id) {
00733 ScheduledRecording* sr = new ScheduledRecording();
00734
00735 if (id != 0)
00736 sr->loadByID(id);
00737
00738 if (sr->exec() == QDialog::Accepted)
00739 sr->save();
00740
00741 sr->deleteLater();
00742 }
00743
00745
00746 DialogCode ScheduledRecording::exec(bool saveOnExec, bool doLoad)
00747 {
00748 if (!dialog)
00749 dialog = new ScheduledRecordingDialog(this);
00750 return dialog->exec(saveOnExec, doLoad);
00751 }
00752
00753 void ScheduledRecording::setStart(const QDateTime& start) {
00754 startTime->setValue(start.time());
00755 startDate->setValue(start.date());
00756 }
00757
00758 void ScheduledRecording::setEnd(const QDateTime& end) {
00759 endTime->setValue(end.time());
00760 endDate->setValue(end.date());
00761 }
00762
00763 void ScheduledRecording::setEndOffset(int endminutes) {
00764 endoffset->setValue(endminutes);
00765 }
00766
00767 int ScheduledRecording::getRecPriority(void) const {
00768 return recpriority->getValue().toInt();
00769 }
00770
00771 void ScheduledRecording::setRecPriority(int newrecpriority) {
00772 recpriority->setValue(newrecpriority);
00773 }
00774
00775 void ScheduledRecording::setRecGroup(const QString& newrecgroup) {
00776 recgroup->setValue(newrecgroup);
00777 }
00778
00779 QString ScheduledRecording::GetRecGroup(void) const {
00780 return recgroup->getValue();
00781 }
00782
00783 void ScheduledRecording::setStorageGroup(const QString& newstoragegroup) {
00784 storagegroup->setValue(newstoragegroup);
00785 }
00786
00787 QString ScheduledRecording::GetStorageGroup(void) const {
00788 return storagegroup->getValue();
00789 }
00790
00791 void ScheduledRecording::setPlayGroup(const QString& newplaygroup) {
00792 playgroup->setValue(newplaygroup);
00793 }
00794
00795 QString ScheduledRecording::getProfileName(void) const {
00796 return profile->getValue();
00797 }
00798
00799 QString ScheduledRecording::getRecordTitle(void) const {
00800 return title->getValue();
00801 }
00802
00803 QString ScheduledRecording::getRecordSubTitle(void) const {
00804 return subtitle->getValue();
00805 }
00806
00807 QString ScheduledRecording::getRecordDescription(void) const {
00808 return description->getValue();
00809 }
00810
00811 void ScheduledRecording::setDefault(bool haschannel)
00812 {
00813 QDate date = QDate::currentDate();
00814 QTime time = QTime::currentTime();
00815 QDate epoch = QDate::QDate (1970, 1, 1);
00816
00817 id->setValue(0);
00818 title->setValue("");
00819 subtitle->setValue("");
00820 description->setValue("");
00821 channel->setValue("");
00822 station->setValue("");
00823 startDate->setValue(date);
00824 startTime->setValue(time);
00825 endDate->setValue(date);
00826 endTime->setValue(time);
00827 seriesid->setValue("");
00828 programid->setValue("");
00829 findday->setValue(-1);
00830 findtime->setValue(QTime::fromString("00:00:00", Qt::ISODate));
00831 findid->setValue(epoch.daysTo(date) + 719528);
00832 parentid->setValue(0);
00833 category->setValue("");
00834 search->setValue(kNoSearch);
00835
00836 if (!type)
00837 {
00838 cerr << "No type object" << endl;
00839 return;
00840 }
00841
00842 type->clearSelections();
00843 type->addNormalSelections(haschannel, search->intValue() == kManualSearch);
00844 type->setValue(kNotRecording);
00845
00846 profile->fillSelections();
00847 profile->setValue(QObject::tr("Default"));
00848
00849 dupin->setValue(kDupsInAll);
00850 dupmethod->setValue(kDupCheckSubDesc);
00851 maxepisodes->setValue(0);
00852 startoffset->setValue(gContext->GetNumSetting("DefaultStartOffset", 0));
00853 endoffset->setValue(gContext->GetNumSetting("DefaultEndOffset", 0));
00854 maxnewest->setValue(0);
00855 recpriority->setValue(0);
00856
00857 autoexpire->setValue(gContext->GetNumSetting("AutoExpireDefault", 0));
00858
00859 autotranscode->setValue(gContext->GetNumSetting("AutoTranscode", 0));
00860 transcoder->fillSelections();
00861 transcoder->setValue(gContext->GetNumSetting("DefaultTranscoder",
00862 RecordingProfile::TranscoderAutodetect));
00863 autocommflag->setValue(gContext->GetNumSetting("AutoCommercialFlag", 1));
00864 autouserjob1->setValue(gContext->GetNumSetting("AutoRunUserJob1", 0));
00865 autouserjob2->setValue(gContext->GetNumSetting("AutoRunUserJob2", 0));
00866 autouserjob3->setValue(gContext->GetNumSetting("AutoRunUserJob3", 0));
00867 autouserjob4->setValue(gContext->GetNumSetting("AutoRunUserJob4", 0));
00868
00869 recgroup->fillSelections();
00870 recgroup->setValue("Default");
00871 storagegroup->fillSelections();
00872 storagegroup->setValue("Default");
00873 playgroup->fillSelections();
00874 playgroup->setValue("Default");
00875 prefinput->fillSelections();
00876 prefinput->setValue(0);
00877
00878 inactive->setValue(0);
00879 }
00880
00881 void ScheduledRecording::setProgram(const ProgramInfo *proginfo)
00882 {
00883 m_pginfo = proginfo;
00884 if (proginfo)
00885 {
00886 title->setValue(proginfo->title);
00887 subtitle->setValue(proginfo->subtitle);
00888 description->setValue(proginfo->description);
00889 channel->setValue(proginfo->chanid);
00890 station->setValue(proginfo->chansign);
00891 startDate->setValue(proginfo->startts.date());
00892 startTime->setValue(proginfo->startts.time());
00893 endDate->setValue(proginfo->endts.date());
00894 endTime->setValue(proginfo->endts.time());
00895 seriesid->setValue(proginfo->seriesid);
00896 programid->setValue(proginfo->programid);
00897 if (findday->intValue() < 0)
00898 {
00899 findday->setValue((proginfo->startts.date().dayOfWeek() + 1) % 7);
00900 findtime->setValue(proginfo->startts.time());
00901
00902 QDate epoch = QDate::QDate (1970, 1, 1);
00903 findid->setValue(epoch.daysTo(proginfo->startts.date()) + 719528);
00904 }
00905 else
00906 {
00907 if (findid->intValue() > 0)
00908 findid->setValue(proginfo->findid);
00909 else
00910 {
00911 QDate epoch = QDate::QDate (1970, 1, 1);
00912 findid->setValue(epoch.daysTo(proginfo->startts.date()) +
00913 719528);
00914 }
00915 }
00916 category->setValue(proginfo->category);
00917
00918 fetchChannelInfo();
00919 }
00920 }
00921
00922 void ScheduledRecording::makeOverride(void)
00923 {
00924 if (type->getValue().toInt() == kOverrideRecord ||
00925 type->getValue().toInt() == kDontRecord)
00926 return;
00927
00928 id->setValue(0);
00929 type->clearSelections();
00930 type->addOverrideSelections();
00931 type->setValue(kNotRecording);
00932 inactive->setValue(0);
00933
00934 if (search->intValue() == kManualSearch)
00935 search->setChanged();
00936 else
00937 search->setValue(kNoSearch);
00938
00939 setProgram(m_pginfo);
00940
00941 parentid->setValue(m_pginfo->recordid);
00942
00943 profile->setChanged();
00944 dupin->setChanged();
00945 dupmethod->setChanged();
00946 autoexpire->setChanged();
00947 autotranscode->setChanged();
00948 autocommflag->setChanged();
00949 autouserjob1->setChanged();
00950 autouserjob2->setChanged();
00951 autouserjob3->setChanged();
00952 autouserjob4->setChanged();
00953 maxepisodes->setChanged();
00954 maxnewest->setChanged();
00955 startoffset->setChanged();
00956 endoffset->setChanged();
00957 recpriority->setChanged();
00958 recgroup->setChanged();
00959 storagegroup->setChanged();
00960 playgroup->setChanged();
00961 }
00962
00963 void
00964 ScheduledRecording::testRecording()
00965 {
00966
00967 QString ttable = "record_tmp";
00968
00969 MSqlQueryInfo dbcon = MSqlQuery::SchedCon();
00970 MSqlQuery query(dbcon);
00971 QString thequery;
00972
00973 thequery ="SELECT GET_LOCK(:LOCK, 2);";
00974 query.prepare(thequery);
00975 query.bindValue(":LOCK", "DiffSchedule");
00976 query.exec();
00977 if (query.lastError().type() != QSqlError::None)
00978 {
00979 QString msg =
00980 QString("DB Error (Obtaining lock in testRecording): \n"
00981 "Query was: %1 \nError was: %2 \n")
00982 .arg(thequery)
00983 .arg(MythContext::DBErrorMessage(query.lastError()));
00984 VERBOSE(VB_IMPORTANT, msg);
00985 return;
00986 }
00987
00988
00989 thequery = QString("DROP TABLE IF EXISTS %1;").arg(ttable);
00990 query.prepare(thequery);
00991 query.exec();
00992 if (query.lastError().type() != QSqlError::None)
00993 {
00994 QString msg =
00995 QString("DB Error (deleting old table in testRecording): \n"
00996 "Query was: %1 \nError was: %2 \n")
00997 .arg(thequery)
00998 .arg(MythContext::DBErrorMessage(query.lastError()));
00999 VERBOSE(VB_IMPORTANT, msg);
01000 return;
01001 }
01002
01003 thequery = QString("CREATE TABLE %1 SELECT * FROM record;").arg(ttable);
01004 query.prepare(thequery);
01005 query.exec();
01006 if (query.lastError().type() != QSqlError::None)
01007 {
01008 QString msg =
01009 QString("DB Error (create new table): \n"
01010 "Query was: %1 \nError was: %2 \n")
01011 .arg(thequery)
01012 .arg(MythContext::DBErrorMessage(query.lastError()));
01013 VERBOSE(VB_IMPORTANT, msg);
01014 return;
01015 }
01016
01017 bool resetID = false;
01018 if (getRecordID() == 0) {
01019 thequery = QString("SELECT MAX(recordid) FROM %1 ORDER BY recordid;")
01020 .arg(ttable);
01021 query.prepare(thequery);
01022 query.exec();
01023 if (query.isActive() && query.next())
01024 id->setValue(query.value(0).toInt() + 1);
01025 else
01026 id->setValue(100000);
01027 }
01028 save(ttable);
01029
01030 ViewScheduleDiff vsd(gContext->GetMainWindow(), "Preview Schedule Changes",
01031 ttable, getRecordID(), title->getValue());
01032
01033 thequery = "SELECT RELEASE_LOCK(:LOCK);";
01034 query.prepare(thequery);
01035 query.bindValue(":LOCK", "DiffSchedule");
01036 query.exec();
01037 if (query.lastError().type() != QSqlError::None)
01038 {
01039 QString msg =
01040 QString("DB Error (free lock): \n"
01041 "Query was: %1 \nError was: %2 \n")
01042 .arg(thequery)
01043 .arg(MythContext::DBErrorMessage(query.lastError()));
01044 VERBOSE(VB_IMPORTANT, msg);
01045 return;
01046 }
01047
01048 if (resetID)
01049 id->setValue(0);
01050
01051 vsd.exec();
01052 }
01053
01054