MythTV  0.26-pre
viewschedulediff.cpp
Go to the documentation of this file.
00001 // myth
00002 #include "mythcorecontext.h"
00003 #include "mythlogging.h"
00004 #include "remoteutil.h"
00005 #include "recordinginfo.h"
00006 
00007 //mythui
00008 #include "mythuitext.h"
00009 #include "mythuibuttonlist.h"
00010 #include "mythmainwindow.h"
00011 #include "mythdialogbox.h"
00012 
00013 //mythtv
00014 #include "scheduledrecording.h"
00015 #include "tv.h"
00016 
00017 //mythfrontend
00018 #include "viewschedulediff.h"
00019 
00020 ViewScheduleDiff::ViewScheduleDiff(MythScreenStack *parent, QString altTable,
00021                                    int recordidDiff, QString title)
00022         : MythScreenType(parent, "ViewScheduleDiff"),
00023             m_inEvent(false), m_inFill(false),
00024             m_altTable(altTable), m_title(title),
00025             m_conflictList(NULL), m_titleText(NULL),
00026             m_noChangesText(NULL), m_recordid(recordidDiff)
00027 {
00028 }
00029 
00030 ViewScheduleDiff::~ViewScheduleDiff()
00031 {
00032 }
00033 
00034 bool ViewScheduleDiff::Create()
00035 {
00036     if (!LoadWindowFromXML("schedule-ui.xml", "schedulediff", this))
00037         return false;
00038 
00039     bool err = false;
00040     UIUtilE::Assign(this, m_conflictList, "conflictlist", &err);
00041 
00042     UIUtilW::Assign(this, m_titleText, "titletext");
00043     UIUtilW::Assign(this, m_noChangesText, "nochanges");
00044 
00045     if (err)
00046     {
00047         LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'schedulediff'");
00048         return false;
00049     }
00050 
00051     connect(m_conflictList, SIGNAL(itemSelected(MythUIButtonListItem*)),
00052             SLOT(updateInfo(MythUIButtonListItem*)));
00053     connect(m_conflictList, SIGNAL(itemClicked(MythUIButtonListItem*)),
00054             SLOT(showStatus(MythUIButtonListItem*)));
00055 
00056     if (m_titleText)
00057         m_titleText->SetText(m_title);
00058 
00059     BuildFocusList();
00060     LoadInBackground();
00061 
00062     return true;
00063 }
00064 
00065 void ViewScheduleDiff::Load(void)
00066 {
00067     fillList();
00068 }
00069 
00070 void ViewScheduleDiff::Init()
00071 {
00072     updateUIList();
00073 }
00074 
00075 bool ViewScheduleDiff::keyPressEvent(QKeyEvent *e)
00076 {
00077     if (m_inEvent)
00078         return true;
00079 
00080     m_inEvent = true;
00081 
00082     bool handled = false;
00083     QStringList actions;
00084 
00085     handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", e, actions);
00086 
00087     if (!handled && MythScreenType::keyPressEvent(e))
00088         handled = true;
00089 
00090     m_inEvent = false;
00091 
00092     return handled;
00093 }
00094 
00095 void ViewScheduleDiff::showStatus(MythUIButtonListItem *item)
00096 {
00097     ProgramInfo *pi = CurrentProgram();
00098     if (!pi)
00099         return;
00100 
00101     QString timeFormat = gCoreContext->GetSetting("TimeFormat", "h:mm AP");
00102 
00103     QString message = pi->toString(ProgramInfo::kTitleSubtitle, " - ");
00104     message += "\n\n";
00105     message += toDescription(pi->GetRecordingStatus(),
00106                              pi->GetRecordingRuleType(),
00107                              pi->GetRecordingStartTime());
00108 
00109     if (pi->GetRecordingStatus() == rsConflict ||
00110         pi->GetRecordingStatus() == rsLaterShowing)
00111     {
00112         message += " " + QObject::tr("The following programs will be recorded "
00113                                      "instead:") + "\n\n";
00114 
00115         ProgramList::const_iterator it = m_recListAfter.begin();
00116         for (; it != m_recListAfter.end(); ++it)
00117         {
00118             const ProgramInfo *pa = *it;
00119             if (pa->GetRecordingStartTime() >= pi->GetRecordingEndTime())
00120                 break;
00121             if (pa->GetRecordingEndTime() > pi->GetRecordingStartTime() &&
00122                 (pa->GetRecordingStatus() == rsWillRecord ||
00123                  pa->GetRecordingStatus() == rsRecording))
00124             {
00125                 message += QString("%1 - %2  %3\n")
00126                     .arg(pa->GetRecordingStartTime().toString(timeFormat))
00127                     .arg(pa->GetRecordingEndTime().toString(timeFormat))
00128                     .arg(pa->toString(ProgramInfo::kTitleSubtitle, " - "));
00129             }
00130         }
00131     }
00132 
00133     QString title = QObject::tr("Program Status");
00134     MythScreenStack *mainStack = GetMythMainWindow()->GetStack("main stack");
00135     MythDialogBox   *dlg = new MythDialogBox(title, message, mainStack,
00136                                              "statusdialog", true);
00137 
00138     if (dlg->Create())
00139     {
00140         dlg->AddButton(QObject::tr("OK"));
00141         mainStack->AddScreen(dlg);
00142     }
00143     else
00144         delete dlg;
00145 }
00146 
00147 static int comp_recstart(const ProgramInfo *a, const ProgramInfo *b)
00148 {
00149     if (a->GetRecordingStartTime() != b->GetRecordingStartTime())
00150     {
00151         if (a->GetRecordingStartTime() > b->GetRecordingStartTime())
00152             return 1;
00153         else
00154             return -1;
00155     }
00156     if (a->GetRecordingEndTime() != b->GetRecordingEndTime())
00157     {
00158         if (a->GetRecordingEndTime() > b->GetRecordingEndTime())
00159             return 1;
00160         else
00161             return -1;
00162     }
00163     if (a->GetChannelSchedulingID() != b->GetChannelSchedulingID())
00164     {
00165         if (a->GetChannelSchedulingID() < b->GetChannelSchedulingID())
00166             return 1;
00167         else
00168             return -1;
00169     }
00170     if (a->GetRecordingPriority() != b->GetRecordingPriority() &&
00171         (a->GetRecordingStatus() == rsWillRecord ||
00172          b->GetRecordingStatus() == rsWillRecord))
00173     {
00174         if (a->GetRecordingPriority() < b->GetRecordingPriority())
00175             return 1;
00176         else
00177             return -1;
00178     }
00179     return 0;
00180 }
00181 
00182 static bool comp_recstart_less_than(const ProgramInfo *a, const ProgramInfo *b)
00183 {
00184     return comp_recstart(a,b) < 0;
00185 }
00186 
00187 void ViewScheduleDiff::fillList(void)
00188 {
00189     m_inFill = true;
00190 
00191     QString callsign;
00192     QDateTime startts, recstartts;
00193     bool dummy;
00194 
00195     LoadFromScheduler(m_recListBefore, dummy);
00196     LoadFromScheduler(m_recListAfter,  dummy, m_altTable, m_recordid);
00197 
00198     std::stable_sort(m_recListBefore.begin(), m_recListBefore.end(),
00199                      comp_recstart_less_than);
00200     std::stable_sort(m_recListAfter.begin(), m_recListAfter.end(),
00201                      comp_recstart_less_than);
00202 
00203     QDateTime now = QDateTime::currentDateTime();
00204 
00205     ProgramList::iterator it = m_recListBefore.begin();
00206     while (it != m_recListBefore.end())
00207     {
00208         if ((*it)->GetRecordingEndTime() >= now ||
00209             (*it)->GetScheduledEndTime() >= now)
00210         {
00211             ++it;
00212         }
00213         else
00214         {
00215             it = m_recListBefore.erase(it);
00216         }
00217     }
00218 
00219     it = m_recListAfter.begin();
00220     while (it != m_recListAfter.end())
00221     {
00222         if ((*it)->GetRecordingEndTime() >= now ||
00223             (*it)->GetScheduledEndTime() >= now)
00224         {
00225             ++it;
00226         }
00227         else
00228         {
00229             it = m_recListAfter.erase(it);
00230         }
00231     }
00232 
00233     ProgramList::iterator pb = m_recListBefore.begin();
00234     ProgramList::iterator pa = m_recListAfter.begin();
00235     ProgramStruct s;
00236 
00237     m_recList.clear();
00238     while (pa != m_recListAfter.end() || pb != m_recListBefore.end())
00239     {
00240         s.before = (pb != m_recListBefore.end()) ? *pb : NULL;
00241         s.after  = (pa != m_recListAfter.end())  ? *pa : NULL;
00242 
00243         if (pa == m_recListAfter.end())
00244         {
00245             ++pb;
00246         }
00247         else if (pb == m_recListBefore.end())
00248         {
00249             ++pa;
00250         }
00251         else
00252         {
00253             switch (comp_recstart(*pb, *pa))
00254             {
00255                 case 0:
00256                     ++pb;
00257                     ++pa;
00258                     break;
00259                 case -1: // pb BEFORE pa
00260                     ++pb;
00261                     s.after = NULL;
00262                     break;
00263                 case 1: // pa BEFORE pb
00264                     s.before = NULL;
00265                     ++pa;
00266                     break;
00267             }
00268         }
00269 
00270         if (s.before && s.after &&
00271             (s.before->GetCardID() == s.after->GetCardID()) &&
00272             (s.before->GetRecordingStatus() == s.after->GetRecordingStatus()))
00273         {
00274             continue;
00275         }
00276 
00277         m_recList.push_back(s);
00278     }
00279 
00280     m_inFill = false;
00281 }
00282 
00283 void ViewScheduleDiff::updateUIList(void)
00284 {
00285     for (uint i = 0; i < m_recList.size(); i++)
00286     {
00287         class ProgramStruct s = m_recList[i];
00288         class ProgramInfo *pginfo = s.after;
00289         if (!pginfo)
00290             pginfo = s.before;
00291 
00292         MythUIButtonListItem *item = new MythUIButtonListItem(
00293             m_conflictList, "", qVariantFromValue(pginfo));
00294 
00295         InfoMap infoMap;
00296         pginfo->ToMap(infoMap);
00297 
00298         QString state = toUIState(pginfo->GetRecordingStatus());
00299 
00300         item->DisplayState(state, "status");
00301         item->SetTextFromMap(infoMap, state);
00302 
00303         if (s.before)
00304             item->SetText(toString(s.before->GetRecordingStatus(),
00305                                    s.before->GetCardID()), "statusbefore",
00306                           state);
00307         else
00308             item->SetText("-", "statusbefore");
00309 
00310         if (s.after)
00311             item->SetText(toString(s.after->GetRecordingStatus(),
00312                                    s.after->GetCardID()), "statusafter",
00313                           state);
00314         else
00315             item->SetText("-", "statusafter");
00316     }
00317 
00318     if (m_noChangesText)
00319     {
00320         if (m_recList.empty())
00321             m_noChangesText->Show();
00322         else
00323             m_noChangesText->Hide();
00324     }
00325 }
00326 
00327 void ViewScheduleDiff::updateInfo(MythUIButtonListItem *item)
00328 {
00329     if (!item)
00330         return;
00331 
00332     ProgramInfo *pginfo = qVariantValue<ProgramInfo*> (item->GetData());
00333     if (pginfo)
00334     {
00335         InfoMap infoMap;
00336         pginfo->ToMap(infoMap);
00337         SetTextFromMap(infoMap);
00338     }
00339 }
00340 
00341 ProgramInfo *ViewScheduleDiff::CurrentProgram()
00342 {
00343     int pos = m_conflictList->GetCurrentPos();
00344     if (pos >= (int)m_recList.size())
00345         return NULL;
00346 
00347     ProgramStruct s = m_recList[pos];
00348 
00349     if (s.after)
00350         return s.after;
00351     else
00352         return s.before;
00353 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends