00001
00002 #include "customedit.h"
00003
00004
00005 #include <QSqlError>
00006
00007
00008 #include "mythdb.h"
00009
00010
00011 #include "mythcorecontext.h"
00012
00013
00014 #include "mythuibuttonlist.h"
00015 #include "mythuitextedit.h"
00016 #include "mythuibutton.h"
00017 #include "mythdialogbox.h"
00018
00019
00020 #include "recordingrule.h"
00021
00022
00023 #include "scheduleeditor.h"
00024 #include "proglist.h"
00025
00026 CustomEdit::CustomEdit(MythScreenStack *parent, ProgramInfo *pginfo)
00027 : MythScreenType(parent, "CustomEdit")
00028 {
00029 if (pginfo)
00030 m_pginfo = new ProgramInfo(*pginfo);
00031 else
00032 m_pginfo = new ProgramInfo();
00033
00034 m_baseTitle = m_pginfo->GetTitle();
00035 m_baseTitle.remove(QRegExp(" \\(.*\\)$"));
00036
00037 m_maxex = 0;
00038 m_evaluate = true;
00039 m_seSuffix = QString(" (%1)").arg(tr("stored search"));
00040 m_exSuffix = QString(" (%1)").arg(tr("stored example"));
00041
00042 gCoreContext->addListener(this);
00043 }
00044
00045 CustomEdit::~CustomEdit(void)
00046 {
00047 delete m_pginfo;
00048
00049 gCoreContext->removeListener(this);
00050 }
00051
00052 bool CustomEdit::Create()
00053 {
00054 if (!LoadWindowFromXML("schedule-ui.xml", "customedit", this))
00055 return false;
00056
00057 bool err = false;
00058 UIUtilE::Assign(this, m_ruleList, "rules", &err);
00059 UIUtilE::Assign(this, m_clauseList, "clauses", &err);
00060
00061 UIUtilE::Assign(this, m_titleEdit, "title", &err);
00062 UIUtilE::Assign(this, m_subtitleEdit, "subtitle", &err);
00063 UIUtilE::Assign(this, m_descriptionEdit, "description", &err);
00064 UIUtilE::Assign(this, m_clauseText, "clausetext", &err);
00065 UIUtilE::Assign(this, m_testButton, "test", &err);
00066 UIUtilE::Assign(this, m_recordButton, "record", &err);
00067 UIUtilE::Assign(this, m_storeButton, "store", &err);
00068 UIUtilE::Assign(this, m_cancelButton, "cancel", &err);
00069
00070 if (err)
00071 {
00072 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'customedit'");
00073 return false;
00074 }
00075
00076 connect(m_ruleList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00077 SLOT(ruleChanged(MythUIButtonListItem *)));
00078 connect(m_titleEdit, SIGNAL(valueChanged(void)), this,
00079 SLOT(textChanged(void)));
00080 m_titleEdit->SetMaxLength(128);
00081 m_subtitleEdit->SetMaxLength(128);
00082 connect(m_descriptionEdit, SIGNAL(valueChanged(void)), this,
00083 SLOT(textChanged(void)));
00084 m_descriptionEdit->SetMaxLength(0);
00085
00086 connect(m_clauseList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00087 SLOT(clauseChanged(MythUIButtonListItem *)));
00088 connect(m_clauseList, SIGNAL(itemClicked(MythUIButtonListItem *)),
00089 SLOT(clauseClicked(MythUIButtonListItem *)));
00090
00091 connect(m_testButton, SIGNAL(Clicked()), SLOT(testClicked()));
00092 connect(m_recordButton, SIGNAL(Clicked()), SLOT(recordClicked()));
00093 connect(m_storeButton, SIGNAL(Clicked()), SLOT(storeClicked()));
00094 connect(m_cancelButton, SIGNAL(Clicked()), SLOT(Close()));
00095
00096 loadData();
00097 BuildFocusList();
00098
00099 return true;
00100 }
00101
00102
00103 void CustomEdit::loadData(void)
00104 {
00105 CustomRuleInfo rule;
00106
00107
00108 rule.recordid = '0';
00109 rule.title = m_baseTitle;
00110 if (!m_baseTitle.isEmpty())
00111 {
00112 QString quoteTitle = m_baseTitle;
00113 quoteTitle.replace("\'","\'\'");
00114 rule.description = QString("program.title = '%1' ").arg(quoteTitle);
00115 }
00116
00117 new MythUIButtonListItem(m_ruleList, tr("<New rule>"),
00118 qVariantFromValue(rule));
00119
00120 MSqlQuery result(MSqlQuery::InitCon());
00121 result.prepare("SELECT recordid, title, subtitle, description "
00122 "FROM record WHERE search = :SEARCH ORDER BY title;");
00123 result.bindValue(":SEARCH", kPowerSearch);
00124
00125 if (result.exec())
00126 {
00127 while (result.next())
00128 {
00129 QString trimTitle = result.value(1).toString();
00130 trimTitle.remove(QRegExp(" \\(.*\\)$"));
00131
00132 rule.recordid = result.value(0).toString();
00133 rule.title = trimTitle;
00134 rule.subtitle = result.value(2).toString();
00135 rule.description = result.value(3).toString();
00136
00137 MythUIButtonListItem *item =
00138 new MythUIButtonListItem(m_ruleList, rule.title,
00139 qVariantFromValue(rule));
00140
00141 if (trimTitle == m_baseTitle ||
00142 result.value(0).toUInt() == m_pginfo->GetRecordingRuleID())
00143 m_ruleList->SetItemCurrent(item);
00144 }
00145 }
00146 else
00147 MythDB::DBError("Get power search rules query", result);
00148
00149 loadClauses();
00150
00151 textChanged();
00152 }
00153
00154 QString CustomEdit::evaluate(QString clause)
00155 {
00156 int s0=0;
00157 int e0=0;
00158
00159 while (1) {
00160 s0 = clause.indexOf (QRegExp("\\{[A-Z]+\\}"), e0);
00161
00162 if (s0 < 0)
00163 break;
00164
00165 e0 = clause.indexOf ("}", s0);
00166
00167 QString mid = clause.mid(s0 + 1, e0 - s0 - 1);
00168 QString repl = "";
00169
00170 if (!mid.compare("TITLE")) {
00171 repl = m_pginfo->GetTitle();
00172 repl.replace("\'","\'\'");
00173 } else if (!mid.compare("SUBTITLE")) {
00174 repl = m_pginfo->GetSubtitle();
00175 repl.replace("\'","\'\'");
00176 } else if (!mid.compare("DESCR")) {
00177 repl = m_pginfo->GetDescription();
00178 repl.replace("\'","\'\'");
00179 } else if (!mid.compare("SERIESID")) {
00180 repl = QString("%1").arg(m_pginfo->GetSeriesID());
00181 } else if (!mid.compare("PROGID")) {
00182 repl = m_pginfo->GetProgramID();
00183 } else if (!mid.compare("SEASON")) {
00184 repl = QString::number(m_pginfo->GetSeason());
00185 } else if (!mid.compare("EPISODE")) {
00186 repl = QString::number(m_pginfo->GetEpisode());
00187 } else if (!mid.compare("CATEGORY")) {
00188 repl = m_pginfo->GetCategory();
00189 } else if (!mid.compare("CHANID")) {
00190 repl = QString("%1").arg(m_pginfo->GetChanID());
00191 } else if (!mid.compare("CHANNUM")) {
00192 repl = m_pginfo->GetChanNum();
00193 } else if (!mid.compare("SCHEDID")) {
00194 repl = m_pginfo->GetChannelSchedulingID();
00195 } else if (!mid.compare("CHANNAME")) {
00196 repl = m_pginfo->GetChannelName();
00197 } else if (!mid.compare("DAYNAME")) {
00198 repl = m_pginfo->GetScheduledStartTime().toString("dddd");
00199 } else if (!mid.compare("STARTDATE")) {
00200 repl = m_pginfo->GetScheduledStartTime().toString("yyyy-mm-dd hh:mm:ss");
00201 } else if (!mid.compare("ENDDATE")) {
00202 repl = m_pginfo->GetScheduledEndTime().toString("yyyy-mm-dd hh:mm:ss");
00203 } else if (!mid.compare("STARTTIME")) {
00204 repl = m_pginfo->GetScheduledStartTime().toString("hh:mm");
00205 } else if (!mid.compare("ENDTIME")) {
00206 repl = m_pginfo->GetScheduledEndTime().toString("hh:mm");
00207 } else if (!mid.compare("STARTSEC")) {
00208 QDateTime date = m_pginfo->GetScheduledStartTime();
00209 QDateTime midnight = QDateTime(date.date());
00210 repl = QString("%1").arg(midnight.secsTo(date));
00211 } else if (!mid.compare("ENDSEC")) {
00212 QDateTime date = m_pginfo->GetScheduledEndTime();
00213 QDateTime midnight = QDateTime(date.date());
00214 repl = QString("%1").arg(midnight.secsTo(date));
00215 }
00216
00217 clause.replace(s0, e0 - s0 + 1, repl);
00218 }
00219 return clause;
00220 }
00221
00222 void CustomEdit::loadClauses()
00223 {
00224 CustomRuleInfo rule;
00225
00226 rule.title = tr("Match an exact title");
00227 if (!m_baseTitle.isEmpty())
00228 rule.description = QString("program.title = '{TITLE}' ");
00229 else
00230 rule.description = "program.title = 'Nova' ";
00231 new MythUIButtonListItem(m_clauseList, rule.title,
00232 qVariantFromValue(rule));
00233
00234 if (!m_pginfo->GetSeriesID().isEmpty())
00235 {
00236 rule.title = tr("Match this series");
00237 rule.subtitle.clear();
00238 rule.description = QString("program.seriesid = '{SERIESID}' ");
00239 new MythUIButtonListItem(m_clauseList, rule.title,
00240 qVariantFromValue(rule));
00241 }
00242
00243 rule.title = tr("Match words in the title");
00244 rule.subtitle.clear();
00245 if (!m_pginfo->GetTitle().isEmpty())
00246 rule.description = QString("program.title LIKE '%{TITLE}%' ");
00247 else
00248 rule.description = "program.title LIKE 'CSI: %' ";
00249 new MythUIButtonListItem(m_clauseList, rule.title,
00250 qVariantFromValue(rule));
00251
00252 rule.title = tr("Match words in the subtitle");
00253 rule.subtitle.clear();
00254 if (!m_pginfo->GetSubtitle().isEmpty())
00255 rule.description = QString("program.subtitle LIKE '%{SUBTITLE}%' ");
00256 else
00257 rule.description = "program.subtitle LIKE '%Las Vegas%' ";
00258 new MythUIButtonListItem(m_clauseList, rule.title,
00259 qVariantFromValue(rule));
00260
00261 if (!m_pginfo->GetProgramID().isEmpty())
00262 {
00263 rule.title = tr("Match this episode");
00264 rule.subtitle.clear();
00265 rule.description = QString("program.programid = '{PROGID}' ");
00266 }
00267 else if (!m_pginfo->GetSubtitle().isEmpty())
00268 {
00269 rule.title = tr("Match this episode");
00270 rule.subtitle.clear();
00271 rule.description = QString("program.subtitle = '{SUBTITLE}' \n"
00272 "AND program.description = '{DESCR}' ");
00273 }
00274 else
00275 {
00276 rule.title = tr("Match an exact episode");
00277 rule.subtitle.clear();
00278 rule.description = QString("program.title = 'Seinfeld' \n"
00279 "AND program.subtitle = 'The Soup' ");
00280 }
00281 new MythUIButtonListItem(m_clauseList, rule.title,
00282 qVariantFromValue(rule));
00283
00284 rule.title = tr("Match in any descriptive field");
00285 rule.subtitle.clear();
00286 rule.description = QString("(program.title LIKE '%Japan%' \n"
00287 " OR program.subtitle LIKE '%Japan%' \n"
00288 " OR program.description LIKE '%Japan%') ");
00289 new MythUIButtonListItem(m_clauseList, rule.title,
00290 qVariantFromValue(rule));
00291
00292 rule.title = tr("New episodes only");
00293 rule.subtitle.clear();
00294 rule.description = "program.previouslyshown = 0 ";
00295 new MythUIButtonListItem(m_clauseList, rule.title,
00296 qVariantFromValue(rule));
00297
00298 rule.title = tr("Exclude unidentified episodes");
00299 rule.subtitle.clear();
00300 rule.description = "program.generic = 0 ";
00301 new MythUIButtonListItem(m_clauseList, rule.title,
00302 qVariantFromValue(rule));
00303
00304 rule.title = tr("First showing of each episode");
00305 rule.subtitle.clear();
00306 rule.description = "program.first > 0 ";
00307 new MythUIButtonListItem(m_clauseList, rule.title,
00308 qVariantFromValue(rule));
00309
00310 rule.title = tr("Last showing of each episode");
00311 rule.subtitle.clear();
00312 rule.description = "program.last > 0 ";
00313 new MythUIButtonListItem(m_clauseList, rule.title,
00314 qVariantFromValue(rule));
00315
00316 rule.title = tr("Anytime on a specific day of the week");
00317 rule.subtitle.clear();
00318 rule.description = QString("DAYNAME(program.starttime) = '{DAYNAME}' ");
00319 new MythUIButtonListItem(m_clauseList, rule.title,
00320 qVariantFromValue(rule));
00321
00322 rule.title = tr("Only on weekdays (Monday through Friday)");
00323 rule.subtitle.clear();
00324 rule.description = "WEEKDAY(program.starttime) < 5 ";
00325 new MythUIButtonListItem(m_clauseList, rule.title,
00326 qVariantFromValue(rule));
00327
00328 rule.title = tr("Only on weekends");
00329 rule.subtitle.clear();
00330 rule.description = "WEEKDAY(program.starttime) >= 5 ";
00331 new MythUIButtonListItem(m_clauseList, rule.title,
00332 qVariantFromValue(rule));
00333
00334 rule.title = tr("Only in primetime");
00335 rule.subtitle.clear();
00336 rule.description = QString("HOUR(program.starttime) >= 19 \n"
00337 "AND HOUR(program.starttime) < 23 ");
00338 new MythUIButtonListItem(m_clauseList, rule.title,
00339 qVariantFromValue(rule));
00340
00341 rule.title = tr("Not in primetime");
00342 rule.subtitle.clear();
00343 rule.description = QString("(HOUR(program.starttime) < 19 \n"
00344 " OR HOUR(program.starttime) >= 23) ");
00345 new MythUIButtonListItem(m_clauseList, rule.title,
00346 qVariantFromValue(rule));
00347
00348 rule.title = tr("Only on a specific station");
00349 rule.subtitle.clear();
00350 if (!m_pginfo->GetChannelSchedulingID().isEmpty())
00351 rule.description = QString("channel.callsign = '{SCHEDID}' ");
00352 else
00353 rule.description = "channel.callsign = 'ESPN' ";
00354 new MythUIButtonListItem(m_clauseList, rule.title,
00355 qVariantFromValue(rule));
00356
00357 rule.title = tr("Exclude one station");
00358 rule.subtitle.clear();
00359 rule.description = "channel.callsign != 'GOLF' ";
00360 new MythUIButtonListItem(m_clauseList, rule.title,
00361 qVariantFromValue(rule));
00362
00363 rule.title = tr("Match related callsigns");
00364 rule.subtitle.clear();
00365 rule.description = "channel.callsign LIKE 'HBO%' ";
00366 new MythUIButtonListItem(m_clauseList, rule.title,
00367 qVariantFromValue(rule));
00368
00369 rule.title = tr("Only channels from the Favorites group");
00370 rule.subtitle = ", channelgroup cg, channelgroupnames cgn";
00371 rule.description = "cgn.name = 'Favorites' \n"
00372 "AND cg.grpid = cgn.grpid \n"
00373 "AND program.chanid = cg.chanid ";
00374 new MythUIButtonListItem(m_clauseList, rule.title,
00375 qVariantFromValue(rule));
00376
00377 rule.title = tr("Only channels from a specific video source");
00378 rule.subtitle.clear();
00379 rule.description = "channel.sourceid = 2 ";
00380 new MythUIButtonListItem(m_clauseList, rule.title,
00381 qVariantFromValue(rule));
00382
00383 rule.title = tr("Only channels marked as commercial free");
00384 rule.subtitle.clear();
00385 rule.description = QString("channel.commmethod = %1 ")
00386 .arg(COMM_DETECT_COMMFREE);
00387 new MythUIButtonListItem(m_clauseList, rule.title,
00388 qVariantFromValue(rule));
00389
00390 rule.title = tr("Only shows marked as HDTV");
00391 rule.subtitle.clear();
00392 rule.description = "program.hdtv > 0 ";
00393 new MythUIButtonListItem(m_clauseList, rule.title,
00394 qVariantFromValue(rule));
00395
00396 rule.title = tr("Only shows marked as widescreen");
00397 rule.subtitle.clear();
00398 rule.description = "FIND_IN_SET('WIDESCREEN', program.videoprop) > 0 ";
00399 new MythUIButtonListItem(m_clauseList, rule.title,
00400 qVariantFromValue(rule));
00401
00402 rule.title = tr("Exclude H.264 encoded streams (EIT only)");
00403 rule.subtitle.clear();
00404 rule.description = "FIND_IN_SET('AVC', program.videoprop) = 0 ";
00405 new MythUIButtonListItem(m_clauseList, rule.title,
00406 qVariantFromValue(rule));
00407
00408 rule.title = tr("Only shows with in-vision signing");
00409 rule.subtitle.clear();
00410 rule.description = "FIND_IN_SET('SIGNED', program.subtitletypes) > 0 ";
00411 new MythUIButtonListItem(m_clauseList, rule.title,
00412 qVariantFromValue(rule));
00413
00414 rule.title = tr("Only shows with in-vision subtitles");
00415 rule.subtitle.clear();
00416 rule.description = "FIND_IN_SET('ONSCREEN', program.subtitletypes) > 0 ";
00417 new MythUIButtonListItem(m_clauseList, rule.title,
00418 qVariantFromValue(rule));
00419
00420 rule.title = tr("Limit by category");
00421 rule.subtitle.clear();
00422 if (!m_pginfo->GetCategory().isEmpty())
00423 rule.description = QString("program.category = '{CATEGORY}' ");
00424 else
00425 rule.description = "program.category = 'Reality' ";
00426 new MythUIButtonListItem(m_clauseList, rule.title,
00427 qVariantFromValue(rule));
00428
00429 rule.title = tr("All matches for a genre (Data Direct)");
00430 rule.subtitle = "LEFT JOIN programgenres ON "
00431 "program.chanid = programgenres.chanid AND "
00432 "program.starttime = programgenres.starttime ";
00433 if (!m_pginfo->GetCategory().isEmpty())
00434 rule.description = QString("programgenres.genre = '{CATEGORY}' ");
00435 else
00436 rule.description = "programgenres.genre = 'Reality' ";
00437 new MythUIButtonListItem(m_clauseList, rule.title,
00438 qVariantFromValue(rule));
00439
00440 rule.title = tr("Limit by MPAA or VCHIP rating (Data Direct)");
00441 rule.subtitle = "LEFT JOIN programrating ON "
00442 "program.chanid = programrating.chanid AND "
00443 "program.starttime = programrating.starttime ";
00444 rule.description = "(programrating.rating = 'G' OR programrating.rating "
00445 "LIKE 'TV-Y%') ";
00446 new MythUIButtonListItem(m_clauseList, rule.title,
00447 qVariantFromValue(rule));
00448
00449 rule.title = QString(tr("Category type") +
00450 " ('movie', 'series', 'sports' " + tr("or") + " 'tvshow')");
00451 rule.subtitle.clear();
00452 rule.description = "program.category_type = 'sports' ";
00453 new MythUIButtonListItem(m_clauseList, rule.title,
00454 qVariantFromValue(rule));
00455
00456 rule.title = tr("Limit movies by the year of release");
00457 rule.subtitle.clear();
00458 rule.description = "program.category_type = 'movie' AND "
00459 "program.airdate >= 2000 ";
00460 new MythUIButtonListItem(m_clauseList, rule.title,
00461 qVariantFromValue(rule));
00462
00463 rule.title = tr("Minimum star rating (0.0 to 1.0 for movies only)");
00464 rule.subtitle.clear();
00465 rule.description = "program.stars >= 0.75 ";
00466 new MythUIButtonListItem(m_clauseList, rule.title,
00467 qVariantFromValue(rule));
00468
00469 rule.title = tr("Person named in the credits (Data Direct)");
00470 rule.subtitle = ", people, credits";
00471 rule.description = "people.name = 'Tom Hanks' \n"
00472 "AND credits.person = people.person \n"
00473 "AND program.chanid = credits.chanid \n"
00474 "AND program.starttime = credits.starttime ";
00475 new MythUIButtonListItem(m_clauseList, rule.title,
00476 qVariantFromValue(rule));
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 rule.title = tr("Re-record SDTV in HDTV (disable duplicate matching)");
00491 rule.subtitle = ", recordedprogram rp1 LEFT OUTER JOIN recordedprogram rp2"
00492 " ON rp1.programid = rp2.programid AND rp2.hdtv = 1";
00493 rule.description = "program.programid = rp1.programid \n"
00494 "AND rp1.hdtv = 0 \n"
00495 "AND program.hdtv = 1 \n"
00496 "AND rp2.starttime IS NULL ";
00497 new MythUIButtonListItem(m_clauseList, rule.title,
00498 qVariantFromValue(rule));
00499
00500 rule.title = tr("Multiple sports teams (complete example)");
00501 rule.subtitle.clear();
00502 rule.description = "program.title = 'NBA Basketball' \n"
00503 "AND program.subtitle REGEXP '(Miami|Cavaliers|Lakers)' \n"
00504 "AND program.first > 0 \n";
00505 new MythUIButtonListItem(m_clauseList, rule.title,
00506 qVariantFromValue(rule));
00507
00508 rule.title = tr("Sci-fi B-movies (complete example)");
00509 rule.subtitle.clear();
00510 rule.description = "program.category_type='movie' \n"
00511 "AND program.category='Science fiction' \n"
00512 "AND program.stars <= 0.5 AND program.airdate < 1970 ";
00513 new MythUIButtonListItem(m_clauseList, rule.title,
00514 qVariantFromValue(rule));
00515
00516 rule.title =
00517 tr("SportsCenter Overnight (complete example - use FindDaily)");
00518 rule.subtitle.clear();
00519 rule.description = "program.title = 'SportsCenter' \n"
00520 "AND HOUR(program.starttime) >= 2 \n"
00521 "AND HOUR(program.starttime) <= 6 ";
00522 new MythUIButtonListItem(m_clauseList, rule.title,
00523 qVariantFromValue(rule));
00524
00525 rule.title = tr("Movie of the Week (complete example - use FindWeekly)");
00526 rule.subtitle.clear();
00527 rule.description = "program.category_type='movie' \n"
00528 "AND program.stars >= 1.0 AND program.airdate >= 1965 \n"
00529 "AND DAYNAME(program.starttime) = 'Friday' \n"
00530 "AND HOUR(program.starttime) >= 12 ";
00531 new MythUIButtonListItem(m_clauseList, rule.title,
00532 qVariantFromValue(rule));
00533
00534 rule.title = tr("First Episodes (complete example for Data Direct)");
00535 rule.subtitle.clear();
00536 rule.description = "program.first > 0 \n"
00537 "AND program.programid LIKE 'EP%0001' \n"
00538 "AND program.originalairdate = DATE(program.starttime) ";
00539 new MythUIButtonListItem(m_clauseList, rule.title,
00540 qVariantFromValue(rule));
00541
00542 m_maxex = m_clauseList->GetCount();
00543
00544 MSqlQuery result(MSqlQuery::InitCon());
00545 result.prepare("SELECT rulename,fromclause,whereclause,search "
00546 "FROM customexample;");
00547
00548 if (result.exec())
00549 {
00550 while (result.next())
00551 {
00552 QString str = result.value(0).toString();
00553
00554 if (result.value(3).toInt() > 0)
00555 str += m_seSuffix;
00556 else
00557 str += m_exSuffix;
00558
00559 rule.title = str;
00560 rule.subtitle = result.value(1).toString();
00561 rule.description = result.value(2).toString();
00562 new MythUIButtonListItem(m_clauseList, rule.title,
00563 qVariantFromValue(rule));
00564 }
00565 }
00566 }
00567
00568 void CustomEdit::ruleChanged(MythUIButtonListItem *item)
00569 {
00570 if (!item)
00571 return;
00572
00573 CustomRuleInfo rule = qVariantValue<CustomRuleInfo>(item->GetData());
00574
00575 m_titleEdit->SetText(rule.title);
00576 m_descriptionEdit->SetText(rule.description);
00577 m_subtitleEdit->SetText(rule.subtitle);
00578
00579 textChanged();
00580 }
00581
00582 void CustomEdit::textChanged(void)
00583 {
00584 bool hastitle = !m_titleEdit->GetText().isEmpty();
00585 bool hasdesc = !m_descriptionEdit->GetText().isEmpty();
00586
00587 m_testButton->SetEnabled(hasdesc);
00588 m_recordButton->SetEnabled(hastitle && hasdesc);
00589 m_storeButton->SetEnabled(m_clauseList->GetCurrentPos() >= m_maxex ||
00590 (hastitle && hasdesc));
00591 }
00592
00593 void CustomEdit::clauseChanged(MythUIButtonListItem *item)
00594 {
00595 if (!item)
00596 return;
00597
00598 CustomRuleInfo rule = qVariantValue<CustomRuleInfo>(item->GetData());
00599
00600 QString msg = (m_evaluate) ? evaluate(rule.description) : rule.description;
00601 msg.replace('\n', ' ');
00602 msg.replace(QRegExp(" [ ]*"), " ");
00603 msg = QString("\"%1\"").arg(msg);
00604 m_clauseText->SetText(msg);
00605
00606 bool hastitle = !m_titleEdit->GetText().isEmpty();
00607 bool hasdesc = !m_descriptionEdit->GetText().isEmpty();
00608
00609 m_storeButton->SetEnabled(m_clauseList->GetCurrentPos() >= m_maxex ||
00610 (hastitle && hasdesc));
00611 }
00612
00613 void CustomEdit::clauseClicked(MythUIButtonListItem *item)
00614 {
00615 if (!item)
00616 return;
00617
00618 CustomRuleInfo rule = qVariantValue<CustomRuleInfo>(item->GetData());
00619
00620 QString clause;
00621 QString desc = m_descriptionEdit->GetText();
00622
00623 if (desc.contains(QRegExp("\\S")))
00624 clause = "AND ";
00625 clause += (m_evaluate) ? evaluate(rule.description) : rule.description;
00626
00627 m_descriptionEdit->SetText(desc.append(clause));
00628
00629 QString sub = m_subtitleEdit->GetText();
00630 m_subtitleEdit->SetText(sub.append(rule.subtitle));
00631 }
00632
00633 void CustomEdit::testClicked(void)
00634 {
00635 if (!checkSyntax())
00636 {
00637 return;
00638 }
00639
00640 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00641 ProgLister *pl = new ProgLister(mainStack, plSQLSearch,
00642 evaluate(m_descriptionEdit->GetText()),
00643 m_subtitleEdit->GetText());
00644 if (pl->Create())
00645 {
00646 mainStack->AddScreen(pl);
00647 }
00648 else
00649 delete pl;
00650 }
00651
00652 void CustomEdit::recordClicked(void)
00653 {
00654 if (!checkSyntax())
00655 return;
00656
00657 RecordingRule *record = new RecordingRule();
00658
00659 MythUIButtonListItem* item = m_ruleList->GetItemCurrent();
00660 CustomRuleInfo rule = qVariantValue<CustomRuleInfo>(item->GetData());
00661
00662 int cur_recid = rule.recordid.toInt();
00663 if (cur_recid > 0)
00664 {
00665 record->ModifyPowerSearchByID(cur_recid, m_titleEdit->GetText(),
00666 evaluate(m_descriptionEdit->GetText()),
00667 m_subtitleEdit->GetText());
00668 }
00669 else
00670 {
00671 record->LoadBySearch(kPowerSearch, m_titleEdit->GetText(),
00672 evaluate(m_descriptionEdit->GetText()),
00673 m_subtitleEdit->GetText());
00674 }
00675
00676 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00677 ScheduleEditor *schededit = new ScheduleEditor(mainStack, record);
00678 if (schededit->Create())
00679 {
00680 mainStack->AddScreen(schededit);
00681 connect(schededit, SIGNAL(ruleSaved(int)), SLOT(scheduleCreated(int)));
00682 }
00683 else
00684 delete schededit;
00685 }
00686
00687 void CustomEdit::scheduleCreated(int ruleID)
00688 {
00689 if (ruleID > 0)
00690 Close();
00691 }
00692
00693 void CustomEdit::storeClicked(void)
00694 {
00695 bool exampleExists = false;
00696
00697 MSqlQuery query(MSqlQuery::InitCon());
00698 query.prepare("SELECT rulename,whereclause FROM customexample "
00699 "WHERE rulename = :RULE;");
00700 query.bindValue(":RULE", m_titleEdit->GetText());
00701
00702 if (query.exec() && query.next())
00703 exampleExists = true;
00704
00705 QString msg = QString("%1: %2\n\n").arg(tr("Current Example"))
00706 .arg(m_titleEdit->GetText());
00707
00708 if (m_subtitleEdit->GetText().length())
00709 msg += m_subtitleEdit->GetText() + "\n\n";
00710
00711 msg += m_descriptionEdit->GetText();
00712
00713 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00714 MythDialogBox *storediag = new MythDialogBox(msg, mainStack,
00715 "storePopup", true);
00716
00717 storediag->SetReturnEvent(this, "storeruledialog");
00718 if (storediag->Create())
00719 {
00720 if (!m_titleEdit->GetText().isEmpty())
00721 {
00722 QString str;
00723
00724 if (exampleExists)
00725 str = tr("Replace as a search");
00726 else
00727 str = tr("Store as a search");
00728 storediag->AddButton(str);
00729
00730 if (exampleExists)
00731 str = tr("Replace as an example");
00732 else
00733 str = tr("Store as an example");
00734 storediag->AddButton(str);
00735 }
00736
00737 if (m_clauseList->GetCurrentPos() >= m_maxex)
00738 {
00739 MythUIButtonListItem* item = m_clauseList->GetItemCurrent();
00740 QString str = QString("%1 \"%2\"").arg(tr("Delete"))
00741 .arg(item->GetText());
00742 storediag->AddButton(str);
00743 }
00744 mainStack->AddScreen(storediag);
00745 }
00746 else
00747 delete storediag;
00748 }
00749
00750
00751 bool CustomEdit::checkSyntax(void)
00752 {
00753 bool ret = false;
00754 QString msg;
00755
00756 QString desc = evaluate(m_descriptionEdit->GetText());
00757 QString from = m_subtitleEdit->GetText();
00758 if (desc.contains(QRegExp("^\\s*AND\\s", Qt::CaseInsensitive)))
00759 {
00760 msg = tr("Power Search rules no longer require a leading \"AND\".");
00761 }
00762 else if (desc.contains(';'))
00763 {
00764 msg = tr("Power Search rules cannot include semicolon ( ; ) ");
00765 msg += tr("statement terminators.");
00766 }
00767 else
00768 {
00769 MSqlQuery query(MSqlQuery::InitCon());
00770 query.prepare(QString("SELECT NULL FROM (program,channel) "
00771 "%1 WHERE\n%2").arg(from).arg(desc));
00772
00773 if (query.exec())
00774 {
00775 ret = true;
00776 }
00777 else
00778 {
00779 msg = tr("An error was found when checking") + ":\n\n";
00780 msg += query.executedQuery();
00781 msg += "\n\n" + tr("The database error was") + ":\n";
00782 msg += query.lastError().databaseText();
00783 }
00784 }
00785
00786 if (!msg.isEmpty())
00787 {
00788 MythScreenStack *popupStack = GetMythMainWindow()->
00789 GetStack("popup stack");
00790 MythConfirmationDialog *checkSyntaxPopup =
00791 new MythConfirmationDialog(popupStack, msg, false);
00792
00793 if (checkSyntaxPopup->Create())
00794 {
00795 checkSyntaxPopup->SetReturnEvent(this, "checkSyntaxPopup");
00796 popupStack->AddScreen(checkSyntaxPopup);
00797 }
00798 else
00799 {
00800 delete checkSyntaxPopup;
00801 }
00802 ret = false;
00803 }
00804 return ret;
00805 }
00806
00807 void CustomEdit::storeRule(bool is_search, bool is_new)
00808 {
00809 CustomRuleInfo rule;
00810 rule.recordid = '0';
00811 rule.title = m_titleEdit->GetText();
00812 rule.subtitle = m_subtitleEdit->GetText();
00813 rule.description = m_descriptionEdit->GetText();
00814
00815 MSqlQuery query(MSqlQuery::InitCon());
00816 query.prepare("REPLACE INTO customexample "
00817 "(rulename,fromclause,whereclause,search) "
00818 "VALUES(:RULE,:FROMC,:WHEREC,:SEARCH);");
00819 query.bindValue(":RULE", rule.title);
00820 query.bindValue(":FROMC", rule.subtitle);
00821 query.bindValue(":WHEREC", rule.description);
00822 query.bindValue(":SEARCH", is_search);
00823
00824 if (is_search)
00825 rule.title += m_seSuffix;
00826 else
00827 rule.title += m_exSuffix;
00828
00829 if (!query.exec())
00830 MythDB::DBError("Store custom example", query);
00831 else if (is_new)
00832 {
00833 new MythUIButtonListItem(m_clauseList, rule.title,
00834 qVariantFromValue(rule));
00835 }
00836 else
00837 {
00838
00839
00840
00841 for (int i = m_maxex; i < m_clauseList->GetCount(); i++)
00842 {
00843 MythUIButtonListItem* item = m_clauseList->GetItemAt(i);
00844 QString removedStr = item->GetText().remove(m_seSuffix)
00845 .remove(m_exSuffix);
00846 if (m_titleEdit->GetText() == removedStr)
00847 {
00848 item->SetData(qVariantFromValue(rule));
00849 clauseChanged(item);
00850 break;
00851 }
00852 }
00853 }
00854
00855
00856 }
00857
00858 void CustomEdit::deleteRule(void)
00859 {
00860 MythUIButtonListItem* item = m_clauseList->GetItemCurrent();
00861 if (!item || m_clauseList->GetCurrentPos() < m_maxex)
00862 return;
00863
00864 MSqlQuery query(MSqlQuery::InitCon());
00865 query.prepare("DELETE FROM customexample "
00866 "WHERE rulename = :RULE;");
00867 query.bindValue(":RULE", item->GetText().remove(m_seSuffix)
00868 .remove(m_exSuffix));
00869
00870 if (!query.exec())
00871 MythDB::DBError("Delete custom example", query);
00872 else
00873 {
00874 m_clauseList->RemoveItem(item);
00875 }
00876 }
00877
00878 void CustomEdit::customEvent(QEvent *event)
00879 {
00880 if (event->type() == DialogCompletionEvent::kEventType)
00881 {
00882 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00883
00884 QString resultid = dce->GetId();
00885 QString resulttext = dce->GetResultText();
00886
00887 if (resultid == "storeruledialog")
00888 {
00889 if (resulttext.startsWith(tr("Delete")))
00890 {
00891 deleteRule();
00892 }
00893 else if (!resulttext.isEmpty())
00894 {
00895 storeRule(resulttext.contains(tr("as a search")),
00896 !resulttext.startsWith(tr("Replace")));
00897 }
00898 }
00899 }
00900 }
00901
00902 bool CustomEdit::keyPressEvent(QKeyEvent *event)
00903 {
00904 if (GetFocusWidget()->keyPressEvent(event))
00905 return true;
00906
00907 bool handled = false;
00908 QStringList actions;
00909 handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", event, actions);
00910
00911 for (int i = 0; i < actions.size() && !handled; i++)
00912 {
00913 QString action = actions[i];
00914 handled = true;
00915
00916 if (action == "DELETE")
00917 {
00918 if (GetFocusWidget() == m_clauseList)
00919 deleteRule();
00920
00921
00922 }
00923 else if (action == "EDIT")
00924 {
00925
00926 m_evaluate = !m_evaluate;
00927 MythUIButtonListItem* item = m_clauseList->GetItemCurrent();
00928 clauseChanged(item);
00929 } else
00930 handled = false;
00931 }
00932
00933 if (!handled && MythScreenType::keyPressEvent(event))
00934 handled = true;
00935
00936 return handled;
00937 }
00938