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