MythTV  0.26-pre
statusbox.cpp
Go to the documentation of this file.
00001 
00002 #include "statusbox.h"
00003 
00004 using namespace std;
00005 
00006 #include <QRegExp>
00007 #include <QHostAddress>
00008 
00009 #include "mythcorecontext.h"
00010 #include "filesysteminfo.h"
00011 #include "mythdb.h"
00012 #include "mythlogging.h"
00013 #include "mythversion.h"
00014 #include "mythmiscutil.h"
00015 
00016 #include "config.h"
00017 #include "remoteutil.h"
00018 #include "tv.h"
00019 #include "jobqueue.h"
00020 #include "cardutil.h"
00021 #include "recordinginfo.h"
00022 
00023 #include "mythuihelper.h"
00024 #include "mythuibuttonlist.h"
00025 #include "mythuitext.h"
00026 #include "mythuistatetype.h"
00027 #include "mythdialogbox.h"
00028 
00029 struct LogLine {
00030     QString line;
00031     QString detail;
00032     QString help;
00033     QString helpdetail;
00034     QString data;
00035     QString state;
00036 };
00037 
00038 
00048 StatusBox::StatusBox(MythScreenStack *parent)
00049           : MythScreenType(parent, "StatusBox")
00050 {
00051     m_minLevel = gCoreContext->GetNumSetting("LogDefaultView",5);
00052 
00053     m_iconState = NULL;
00054     m_categoryList = m_logList = NULL;
00055     m_helpText = NULL;
00056     m_justHelpText = NULL;
00057 
00058     QStringList strlist;
00059     strlist << "QUERY_IS_ACTIVE_BACKEND";
00060     strlist << gCoreContext->GetHostName();
00061 
00062     gCoreContext->SendReceiveStringList(strlist);
00063 
00064     if (QString(strlist[0]) == "TRUE")
00065         m_isBackendActive = true;
00066     else
00067         m_isBackendActive = false;
00068 
00069     m_popupStack = GetMythMainWindow()->GetStack("popup stack");
00070 }
00071 
00072 StatusBox::~StatusBox(void)
00073 {
00074     if (m_logList)
00075         gCoreContext->SaveSetting("StatusBoxItemCurrent",
00076                                   m_logList->GetCurrentPos());
00077 }
00078 
00079 bool StatusBox::Create()
00080 {
00081     if (!LoadWindowFromXML("status-ui.xml", "status", this))
00082         return false;
00083 
00084     m_categoryList = dynamic_cast<MythUIButtonList *>(GetChild("category"));
00085     m_logList = dynamic_cast<MythUIButtonList *>(GetChild("log"));
00086 
00087     m_iconState = dynamic_cast<MythUIStateType *>(GetChild("icon"));
00088     m_helpText = dynamic_cast<MythUIText *>(GetChild("helptext"));
00089     m_justHelpText = dynamic_cast<MythUIText *>(GetChild("justhelptext"));
00090 
00091     if (!m_categoryList || !m_logList || (!m_helpText && !m_justHelpText))
00092     {
00093         LOG(VB_GENERAL, LOG_ERR, "StatusBox, theme is missing "
00094                                  "required elements");
00095         return false;
00096     }
00097 
00098     connect(m_categoryList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00099             SLOT(updateLogList(MythUIButtonListItem *)));
00100     connect(m_logList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00101             SLOT(setHelpText(MythUIButtonListItem *)));
00102     connect(m_logList, SIGNAL(itemClicked(MythUIButtonListItem *)),
00103             SLOT(clicked(MythUIButtonListItem *)));
00104 
00105     BuildFocusList();
00106     return true;
00107 }
00108 
00109 void StatusBox::Init()
00110 {
00111     MythUIButtonListItem *item;
00112 
00113     item = new MythUIButtonListItem(m_categoryList, tr("Listings Status"),
00114                             qVariantFromValue((void*)SLOT(doListingsStatus())));
00115     item->DisplayState("listings", "icon");
00116 
00117     item = new MythUIButtonListItem(m_categoryList, tr("Schedule Status"),
00118                             qVariantFromValue((void*)SLOT(doScheduleStatus())));
00119     item->DisplayState("schedule", "icon");
00120 
00121     item = new MythUIButtonListItem(m_categoryList, tr("Tuner Status"),
00122                             qVariantFromValue((void*)SLOT(doTunerStatus())));
00123     item->DisplayState("tuner", "icon");
00124 
00125     item = new MythUIButtonListItem(m_categoryList, tr("Job Queue"),
00126                             qVariantFromValue((void*)SLOT(doJobQueueStatus())));
00127     item->DisplayState("jobqueue", "icon");
00128 
00129     item = new MythUIButtonListItem(m_categoryList, tr("Machine Status"),
00130                             qVariantFromValue((void*)SLOT(doMachineStatus())));
00131     item->DisplayState("machine", "icon");
00132 
00133     item = new MythUIButtonListItem(m_categoryList, tr("AutoExpire List"),
00134                             qVariantFromValue((void*)SLOT(doAutoExpireList())));
00135     item->DisplayState("autoexpire", "icon");
00136 
00137     int itemCurrent = gCoreContext->GetNumSetting("StatusBoxItemCurrent", 0);
00138     m_categoryList->SetItemCurrent(itemCurrent);
00139 }
00140 
00141 MythUIButtonListItem* StatusBox::AddLogLine(const QString & line,
00142                                             const QString & help,
00143                                             const QString & detail,
00144                                             const QString & helpdetail,
00145                                             const QString & state,
00146                                             const QString & data)
00147 {
00148     LogLine logline;
00149     logline.line = line;
00150 
00151     if (detail.isEmpty())
00152         logline.detail = line;
00153     else
00154         logline.detail = detail;
00155 
00156     if (help.isEmpty())
00157         logline.help = logline.detail;
00158     else
00159         logline.help = help;
00160 
00161     if (helpdetail.isEmpty())
00162         logline.helpdetail = logline.detail;
00163     else
00164         logline.helpdetail = helpdetail;
00165 
00166     logline.state = state;
00167     logline.data = data;
00168 
00169     MythUIButtonListItem *item = new MythUIButtonListItem(m_logList, line,
00170                                                 qVariantFromValue(logline));
00171     if (logline.state.isEmpty())
00172         logline.state = "normal";
00173 
00174     item->SetFontState(logline.state);
00175     item->DisplayState(logline.state, "status");
00176     item->SetText(logline.detail, "detail");
00177 
00178     return item;
00179 }
00180 
00181 bool StatusBox::keyPressEvent(QKeyEvent *event)
00182 {
00183     if (GetFocusWidget()->keyPressEvent(event))
00184         return true;
00185 
00186     bool handled = false;
00187     QStringList actions;
00188     handled = GetMythMainWindow()->TranslateKeyPress("Status", event, actions);
00189 
00190     for (int i = 0; i < actions.size() && !handled; ++i)
00191     {
00192         QString action = actions[i];
00193         handled = true;
00194 
00195         QRegExp logNumberKeys( "^[12345678]$" );
00196 
00197         MythUIButtonListItem* currentButton = m_categoryList->GetItemCurrent();
00198         QString currentItem;
00199         if (currentButton)
00200             currentItem = currentButton->GetText();
00201 
00202         handled = true;
00203 
00204         if (action == "MENU")
00205         {
00206             if (currentItem == tr("Log Entries"))
00207             {
00208                 QString message = tr("Acknowledge all log entries at "
00209                                      "this priority level or lower?");
00210 
00211                 MythConfirmationDialog *confirmPopup =
00212                         new MythConfirmationDialog(m_popupStack, message);
00213 
00214                 confirmPopup->SetReturnEvent(this, "LogAckAll");
00215 
00216                 if (confirmPopup->Create())
00217                     m_popupStack->AddScreen(confirmPopup, false);
00218             }
00219         }
00220         else if ((currentItem == tr("Log Entries")) &&
00221                  (logNumberKeys.indexIn(action) == 0))
00222         {
00223             m_minLevel = action.toInt();
00224             if (m_helpText)
00225                 m_helpText->SetText(tr("Setting priority level to %1")
00226                                     .arg(m_minLevel));
00227             if (m_justHelpText)
00228                 m_justHelpText->SetText(tr("Setting priority level to %1")
00229                                         .arg(m_minLevel));
00230             doLogEntries();
00231         }
00232         else
00233             handled = false;
00234     }
00235 
00236     if (!handled && MythScreenType::keyPressEvent(event))
00237         handled = true;
00238 
00239     return handled;
00240 }
00241 
00242 void StatusBox::setHelpText(MythUIButtonListItem *item)
00243 {
00244     if (!item || GetFocusWidget() != m_logList)
00245         return;
00246 
00247     LogLine logline = qVariantValue<LogLine>(item->GetData());
00248     if (m_helpText)
00249         m_helpText->SetText(logline.helpdetail);
00250     if (m_justHelpText)
00251         m_justHelpText->SetText(logline.help);
00252 }
00253 
00254 void StatusBox::updateLogList(MythUIButtonListItem *item)
00255 {
00256     if (!item)
00257         return;
00258 
00259     disconnect(this, SIGNAL(updateLog()),0,0);
00260 
00261     const char *slot = (const char *)qVariantValue<void*>(item->GetData());
00262 
00263     connect(this, SIGNAL(updateLog()), slot);
00264     emit updateLog();
00265 }
00266 
00267 void StatusBox::clicked(MythUIButtonListItem *item)
00268 {
00269     if (!item)
00270         return;
00271 
00272     LogLine logline = qVariantValue<LogLine>(item->GetData());
00273 
00274     MythUIButtonListItem *currentButton = m_categoryList->GetItemCurrent();
00275     QString currentItem;
00276     if (currentButton)
00277         currentItem = currentButton->GetText();
00278 
00279     // FIXME: Comparisons against strings here is not great, changing names
00280     //        breaks everything and it's inefficient
00281     if (currentItem == tr("Log Entries"))
00282     {
00283         QString message = tr("Acknowledge this log entry?");
00284 
00285         MythConfirmationDialog *confirmPopup =
00286                 new MythConfirmationDialog(m_popupStack, message);
00287 
00288         confirmPopup->SetReturnEvent(this, "LogAck");
00289         confirmPopup->SetData(logline.data);
00290 
00291         if (confirmPopup->Create())
00292             m_popupStack->AddScreen(confirmPopup, false);
00293     }
00294     else if (currentItem == tr("Job Queue"))
00295     {
00296         QStringList msgs;
00297         int jobStatus;
00298 
00299         jobStatus = JobQueue::GetJobStatus(logline.data.toInt());
00300 
00301         if (jobStatus == JOB_QUEUED)
00302         {
00303             QString message = tr("Delete Job?");
00304 
00305             MythConfirmationDialog *confirmPopup =
00306                     new MythConfirmationDialog(m_popupStack, message);
00307 
00308             confirmPopup->SetReturnEvent(this, "JobDelete");
00309             confirmPopup->SetData(logline.data);
00310 
00311             if (confirmPopup->Create())
00312                 m_popupStack->AddScreen(confirmPopup, false);
00313         }
00314         else if ((jobStatus == JOB_PENDING) ||
00315                 (jobStatus == JOB_STARTING) ||
00316                 (jobStatus == JOB_RUNNING)  ||
00317                 (jobStatus == JOB_PAUSED))
00318         {
00319             QString label = tr("Job Queue Actions:");
00320 
00321             MythDialogBox *menuPopup = new MythDialogBox(label, m_popupStack,
00322                                                             "statusboxpopup");
00323 
00324             if (menuPopup->Create())
00325                 m_popupStack->AddScreen(menuPopup, false);
00326 
00327             menuPopup->SetReturnEvent(this, "JobModify");
00328 
00329             QVariant data = qVariantFromValue(logline.data);
00330 
00331             if (jobStatus == JOB_PAUSED)
00332                 menuPopup->AddButton(tr("Resume"), data);
00333             else
00334                 menuPopup->AddButton(tr("Pause"), data);
00335             menuPopup->AddButton(tr("Stop"), data);
00336             menuPopup->AddButton(tr("No Change"), data);
00337         }
00338         else if (jobStatus & JOB_DONE)
00339         {
00340             QString message = tr("Requeue Job?");
00341 
00342             MythConfirmationDialog *confirmPopup =
00343                     new MythConfirmationDialog(m_popupStack, message);
00344 
00345             confirmPopup->SetReturnEvent(this, "JobRequeue");
00346             confirmPopup->SetData(logline.data);
00347 
00348             if (confirmPopup->Create())
00349                 m_popupStack->AddScreen(confirmPopup, false);
00350         }
00351     }
00352     else if (currentItem == tr("AutoExpire List"))
00353     {
00354         ProgramInfo* rec = m_expList[m_logList->GetCurrentPos()];
00355 
00356         if (rec)
00357         {
00358             QString label = tr("AutoExpire Actions:");
00359 
00360             MythDialogBox *menuPopup = new MythDialogBox(label, m_popupStack,
00361                                                             "statusboxpopup");
00362 
00363             if (menuPopup->Create())
00364                 m_popupStack->AddScreen(menuPopup, false);
00365 
00366             menuPopup->SetReturnEvent(this, "AutoExpireManage");
00367 
00368             menuPopup->AddButton(tr("Delete Now"), qVariantFromValue(rec));
00369             if ((rec)->GetRecordingGroup() == "LiveTV")
00370             {
00371                 menuPopup->AddButton(tr("Move to Default group"),
00372                                                        qVariantFromValue(rec));
00373             }
00374             else if ((rec)->GetRecordingGroup() == "Deleted")
00375                 menuPopup->AddButton(tr("Undelete"), qVariantFromValue(rec));
00376             else
00377                 menuPopup->AddButton(tr("Disable AutoExpire"),
00378                                                         qVariantFromValue(rec));
00379             menuPopup->AddButton(tr("No Change"), qVariantFromValue(rec));
00380 
00381         }
00382     }
00383 }
00384 
00385 void StatusBox::customEvent(QEvent *event)
00386 {
00387     if (event->type() == DialogCompletionEvent::kEventType)
00388     {
00389         DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00390 
00391         QString resultid  = dce->GetId();
00392         int     buttonnum = dce->GetResult();
00393 
00394         if (resultid == "LogAck")
00395         {
00396             if (buttonnum == 1)
00397             {
00398                 QString sql = dce->GetData().toString();
00399                 MSqlQuery query(MSqlQuery::InitCon());
00400                 query.prepare("UPDATE mythlog SET acknowledged = 1 "
00401                             "WHERE logid = :LOGID ;");
00402                 query.bindValue(":LOGID", sql);
00403                 if (!query.exec())
00404                     MythDB::DBError("StatusBox::customEvent -- LogAck", query);
00405                 m_logList->RemoveItem(m_logList->GetItemCurrent());
00406             }
00407         }
00408         else if (resultid == "LogAckAll")
00409         {
00410             if (buttonnum == 1)
00411             {
00412                 MSqlQuery query(MSqlQuery::InitCon());
00413                 query.prepare("UPDATE mythlog SET acknowledged = 1 "
00414                                 "WHERE priority <= :PRIORITY ;");
00415                 query.bindValue(":PRIORITY", m_minLevel);
00416                 if (!query.exec())
00417                     MythDB::DBError("StatusBox::customEvent -- LogAckAll",
00418                                     query);
00419                 doLogEntries();
00420             }
00421         }
00422         else if (resultid == "JobDelete")
00423         {
00424             if (buttonnum == 1)
00425             {
00426                 int jobID = dce->GetData().toInt();
00427                 JobQueue::DeleteJob(jobID);
00428 
00429                 m_logList->RemoveItem(m_logList->GetItemCurrent());
00430             }
00431         }
00432         else if (resultid == "JobRequeue")
00433         {
00434             if (buttonnum == 1)
00435             {
00436                 int jobID = dce->GetData().toInt();
00437                 JobQueue::ChangeJobStatus(jobID, JOB_QUEUED);
00438                 doJobQueueStatus();
00439             }
00440         }
00441         else if (resultid == "JobModify")
00442         {
00443             int jobID = dce->GetData().toInt();
00444             if (buttonnum == 0)
00445             {
00446                 if (JobQueue::GetJobStatus(jobID) == JOB_PAUSED)
00447                     JobQueue::ResumeJob(jobID);
00448                 else
00449                     JobQueue::PauseJob(jobID);
00450             }
00451             else if (buttonnum == 1)
00452             {
00453                 JobQueue::StopJob(jobID);
00454             }
00455 
00456             doJobQueueStatus();
00457         }
00458         else if (resultid == "AutoExpireManage")
00459         {
00460             ProgramInfo* rec = qVariantValue<ProgramInfo*>(dce->GetData());
00461 
00462             // button 2 is "No Change"
00463             if (!rec || buttonnum == 2)
00464                 return;
00465 
00466             // button 1 is "Delete Now"
00467             if ((buttonnum == 0) && rec->QueryIsDeleteCandidate())
00468             {
00469                 if (!RemoteDeleteRecording(
00470                     rec->GetChanID(), rec->GetRecordingStartTime(),
00471                     false, false))
00472                 {
00473                     LOG(VB_GENERAL, LOG_ERR, QString("Failed to delete recording: %1").arg(rec->GetTitle()));
00474                     return;
00475                 }
00476             }
00477             // button 1 is "Move To Default Group" or "UnDelete" or "Disable AutoExpire"
00478             else if (buttonnum == 1)
00479             {
00480                 if ((rec)->GetRecordingGroup() == "Deleted")
00481                 {
00482                     RemoteUndeleteRecording(
00483                         rec->GetChanID(), rec->GetRecordingStartTime());
00484                 }
00485                 else
00486                 {
00487                     rec->SaveAutoExpire(kDisableAutoExpire);
00488 
00489                     if ((rec)->GetRecordingGroup() == "LiveTV")
00490                     {
00491                         RecordingInfo ri(*rec);
00492                         ri.ApplyRecordRecGroupChange("Default");
00493                         *rec = ri;
00494                     }
00495                 }
00496             }
00497 
00498             // remove the changed recording from the expire list
00499             delete m_expList[m_logList->GetCurrentPos()];
00500             m_expList.erase(m_expList.begin() + m_logList->GetCurrentPos());
00501 
00502             int pos = m_logList->GetCurrentPos();
00503             int topPos = m_logList->GetTopItemPos();
00504             doAutoExpireList(false);
00505             m_logList->SetItemCurrent(pos, topPos);
00506         }
00507 
00508     }
00509 }
00510 
00511 void StatusBox::doListingsStatus()
00512 {
00513     if (m_iconState)
00514         m_iconState->DisplayState("listings");
00515     m_logList->Reset();
00516 
00517     QString helpmsg(tr("Listings Status shows the latest "
00518                        "status information from "
00519                        "mythfilldatabase"));
00520     if (m_helpText)
00521         m_helpText->SetText(helpmsg);
00522     if (m_justHelpText)
00523         m_justHelpText->SetText(helpmsg);
00524 
00525     QDateTime mfdLastRunStart, mfdLastRunEnd, mfdNextRunStart;
00526     QString mfdLastRunStatus;
00527     QString querytext, DataDirectMessage;
00528     int DaysOfData;
00529     QDateTime qdtNow, GuideDataThrough;
00530 
00531     qdtNow = QDateTime::currentDateTime();
00532 
00533     MSqlQuery query(MSqlQuery::InitCon());
00534     query.prepare("SELECT max(endtime) FROM program WHERE manualid=0;");
00535 
00536     if (query.exec() && query.next())
00537         GuideDataThrough = QDateTime::fromString(query.value(0).toString(),
00538                                                  Qt::ISODate);
00539 
00540     QString tmp = gCoreContext->GetSetting("mythfilldatabaseLastRunStart");
00541     mfdLastRunStart = QDateTime::fromString(tmp, Qt::ISODate);
00542     tmp = gCoreContext->GetSetting("mythfilldatabaseLastRunEnd");
00543     mfdLastRunEnd = QDateTime::fromString(tmp, Qt::ISODate);
00544     tmp = gCoreContext->GetSetting("MythFillSuggestedRunTime");
00545     mfdNextRunStart = QDateTime::fromString(tmp, Qt::ISODate);
00546 
00547     mfdLastRunStatus = gCoreContext->GetSetting("mythfilldatabaseLastRunStatus");
00548     DataDirectMessage = gCoreContext->GetSetting("DataDirectMessage");
00549 
00550     AddLogLine(tr("Mythfrontend version: %1 (%2)").arg(MYTH_SOURCE_PATH)
00551                .arg(MYTH_SOURCE_VERSION), helpmsg);
00552     AddLogLine(tr("Last mythfilldatabase guide update:"), helpmsg);
00553     tmp = tr("Started:   %1").arg(MythDateTimeToString(mfdLastRunStart,
00554                                                     kDateTimeFull | kSimplify));
00555     AddLogLine(tmp, helpmsg);
00556 
00557     if (mfdLastRunEnd >= mfdLastRunStart)
00558     {
00559         tmp =
00560             tr("Finished: %1").arg(MythDateTimeToString(mfdLastRunEnd,
00561                                                     kDateTimeFull | kSimplify));
00562         AddLogLine(tmp, helpmsg);
00563     }
00564 
00565     AddLogLine(tr("Result: %1").arg(mfdLastRunStatus), helpmsg);
00566 
00567 
00568     if (mfdNextRunStart >= mfdLastRunStart)
00569     {
00570         tmp = tr("Suggested Next: %1").arg(MythDateTimeToString(mfdNextRunStart,
00571                                                     kDateTimeFull | kSimplify));
00572         AddLogLine(tmp, helpmsg);
00573     }
00574 
00575     DaysOfData = qdtNow.daysTo(GuideDataThrough);
00576 
00577     if (GuideDataThrough.isNull())
00578     {
00579         AddLogLine(tr("There's no guide data available!"), helpmsg,
00580                    "", "warning");
00581         AddLogLine(tr("Have you run mythfilldatabase?"), helpmsg,
00582                    "", "warning");
00583     }
00584     else
00585     {
00586         AddLogLine(tr("There is guide data until %1")
00587                    .arg(MythDateTimeToString(GuideDataThrough,
00588                                              kDateTimeFull | kSimplify)), helpmsg);
00589 
00590         AddLogLine(QString("(%1).").arg(tr("%n day(s)", "", DaysOfData)),
00591                    helpmsg);
00592     }
00593 
00594     if (DaysOfData <= 3)
00595         AddLogLine(tr("WARNING: is mythfilldatabase running?"), helpmsg,
00596                    "", "", "warning");
00597 
00598     if (!DataDirectMessage.isEmpty())
00599     {
00600         AddLogLine(tr("DataDirect Status: "), helpmsg);
00601         AddLogLine(DataDirectMessage, helpmsg);
00602     }
00603 
00604 }
00605 
00606 void StatusBox::doScheduleStatus()
00607 {
00608     if (m_iconState)
00609         m_iconState->DisplayState("schedule");
00610     m_logList->Reset();
00611 
00612     QString helpmsg(tr("Schedule Status shows current statistics "
00613                        "from the scheduler."));
00614     if (m_helpText)
00615         m_helpText->SetText(helpmsg);
00616     if (m_justHelpText)
00617         m_justHelpText->SetText(helpmsg);
00618 
00619     MSqlQuery query(MSqlQuery::InitCon());
00620 
00621     query.prepare("SELECT COUNT(*) FROM record WHERE search = 0");
00622     if (query.exec() && query.next())
00623     {
00624         QString rules = tr("%n standard rule(s) (is) defined", "",
00625                             query.value(0).toInt());
00626         AddLogLine(rules, helpmsg);
00627     }
00628     else
00629     {
00630         MythDB::DBError("StatusBox::doScheduleStatus()", query);
00631         return;
00632     }
00633 
00634     query.prepare("SELECT COUNT(*) FROM record WHERE search > 0");
00635     if (query.exec() && query.next())
00636     {
00637         QString rules = tr("%n search rule(s) are defined", "",
00638                             query.value(0).toInt());
00639         AddLogLine(rules, helpmsg);
00640     }
00641     else
00642     {
00643         MythDB::DBError("StatusBox::doScheduleStatus()", query);
00644         return;
00645     }
00646 
00647     QMap<RecStatusType, int> statusMatch;
00648     QMap<RecStatusType, QString> statusText;
00649     QMap<int, int> sourceMatch;
00650     QMap<int, QString> sourceText;
00651     QMap<int, int> inputMatch;
00652     QMap<int, QString> inputText;
00653     QString tmpstr;
00654     int maxSource = 0;
00655     int maxInput = 0;
00656     int lowerpriority = 0;
00657     int hdflag = 0;
00658 
00659     query.prepare("SELECT MAX(sourceid) FROM videosource");
00660     if (query.exec())
00661     {
00662         if (query.next())
00663             maxSource = query.value(0).toInt();
00664     }
00665 
00666     query.prepare("SELECT sourceid,name FROM videosource");
00667     if (query.exec())
00668     {
00669         while (query.next())
00670             sourceText[query.value(0).toInt()] = query.value(1).toString();
00671     }
00672 
00673     query.prepare("SELECT MAX(cardinputid) FROM cardinput");
00674     if (query.exec())
00675     {
00676         if (query.next())
00677             maxInput = query.value(0).toInt();
00678     }
00679 
00680     query.prepare("SELECT cardinputid,cardid,inputname,displayname "
00681                   "FROM cardinput");
00682     if (query.exec())
00683     {
00684         while (query.next())
00685         {
00686             if (!query.value(3).toString().isEmpty())
00687                 inputText[query.value(0).toInt()] = query.value(3).toString();
00688             else
00689                 inputText[query.value(0).toInt()] = QString("%1: %2")
00690                                               .arg(query.value(1).toInt())
00691                                               .arg(query.value(2).toString());
00692         }
00693     }
00694 
00695     ProgramList schedList;
00696     LoadFromScheduler(schedList);
00697 
00698     tmpstr = tr("%n matching showing(s)", "", schedList.size());
00699     AddLogLine(tmpstr, helpmsg);
00700 
00701     ProgramList::const_iterator it = schedList.begin();
00702     for (; it != schedList.end(); ++it)
00703     {
00704         const ProgramInfo *s = *it;
00705         const RecStatusType recstatus = s->GetRecordingStatus();
00706 
00707         if (statusMatch[recstatus] < 1)
00708         {
00709             statusText[recstatus] = toString(
00710                 recstatus, s->GetRecordingRuleType());
00711         }
00712 
00713         ++statusMatch[recstatus];
00714 
00715         if (recstatus == rsWillRecord || recstatus == rsRecording)
00716         {
00717             ++sourceMatch[s->GetSourceID()];
00718             ++inputMatch[s->GetInputID()];
00719             if (s->GetRecordingPriority2() < 0)
00720                 ++lowerpriority;
00721             if (s->GetVideoProperties() & VID_HDTV)
00722                 ++hdflag;
00723         }
00724     }
00725 
00726 #define ADD_STATUS_LOG_LINE(rtype, fstate)                      \
00727     do {                                                        \
00728         if (statusMatch[rtype] > 0)                             \
00729         {                                                       \
00730             tmpstr = QString("%1 %2").arg(statusMatch[rtype])   \
00731                                      .arg(statusText[rtype]);   \
00732             AddLogLine(tmpstr, helpmsg, tmpstr, tmpstr, fstate);\
00733         }                                                       \
00734     } while (0)
00735     ADD_STATUS_LOG_LINE(rsRecording, "");
00736     ADD_STATUS_LOG_LINE(rsWillRecord, "");
00737     ADD_STATUS_LOG_LINE(rsConflict, "error");
00738     ADD_STATUS_LOG_LINE(rsTooManyRecordings, "warning");
00739     ADD_STATUS_LOG_LINE(rsLowDiskSpace, "warning");
00740     ADD_STATUS_LOG_LINE(rsLaterShowing, "warning");
00741     ADD_STATUS_LOG_LINE(rsNotListed, "warning");
00742 
00743     QString willrec = statusText[rsWillRecord];
00744 
00745     if (lowerpriority > 0)
00746     {
00747         tmpstr = QString("%1 %2 %3").arg(lowerpriority).arg(willrec)
00748                                     .arg(tr("with lower priority"));
00749         AddLogLine(tmpstr, helpmsg, tmpstr, tmpstr, "warning");
00750     }
00751     if (hdflag > 0)
00752     {
00753         tmpstr = QString("%1 %2 %3").arg(hdflag).arg(willrec)
00754                                     .arg(tr("marked as HDTV"));
00755         AddLogLine(tmpstr, helpmsg);
00756     }
00757     int i;
00758     for (i = 1; i <= maxSource; ++i)
00759     {
00760         if (sourceMatch[i] > 0)
00761         {
00762             tmpstr = QString("%1 %2 %3 %4 \"%5\"")
00763                              .arg(sourceMatch[i]).arg(willrec)
00764                              .arg(tr("from source")).arg(i).arg(sourceText[i]);
00765             AddLogLine(tmpstr, helpmsg);
00766         }
00767     }
00768     for (i = 1; i <= maxInput; ++i)
00769     {
00770         if (inputMatch[i] > 0)
00771         {
00772             tmpstr = QString("%1 %2 %3 %4 \"%5\"")
00773                              .arg(inputMatch[i]).arg(willrec)
00774                              .arg(tr("on input")).arg(i).arg(inputText[i]);
00775             AddLogLine(tmpstr, helpmsg);
00776         }
00777     }
00778 }
00779 
00780 void StatusBox::doTunerStatus()
00781 {
00782     if (m_iconState)
00783         m_iconState->DisplayState("tuner");
00784     m_logList->Reset();
00785 
00786     QString helpmsg(tr("Tuner Status shows the current information "
00787                        "about the state of backend tuner cards"));
00788     if (m_helpText)
00789         m_helpText->SetText(helpmsg);
00790     if (m_justHelpText)
00791         m_justHelpText->SetText(helpmsg);
00792 
00793     MSqlQuery query(MSqlQuery::InitCon());
00794     query.prepare(
00795         "SELECT cardid, cardtype, videodevice "
00796         "FROM capturecard ORDER BY cardid");
00797 
00798     if (!query.exec() || !query.isActive())
00799     {
00800         MythDB::DBError("StatusBox::doTunerStatus()", query);
00801         return;
00802     }
00803 
00804     while (query.next())
00805     {
00806         int cardid = query.value(0).toInt();
00807 
00808         QString cmd = QString("QUERY_REMOTEENCODER %1").arg(cardid);
00809         QStringList strlist( cmd );
00810         strlist << "GET_STATE";
00811 
00812         gCoreContext->SendReceiveStringList(strlist);
00813         int state = strlist[0].toInt();
00814 
00815         QString status;
00816         QString fontstate;
00817         if (state == kState_Error)
00818         {
00819             strlist.clear();
00820             strlist << QString("QUERY_REMOTEENCODER %1").arg(cardid);
00821             strlist << "GET_SLEEPSTATUS";
00822 
00823             gCoreContext->SendReceiveStringList(strlist);
00824             state = strlist[0].toInt();
00825 
00826             if (state == -1)
00827                 status = tr("has an error");
00828             else if (state == sStatus_Undefined)
00829                 status = tr("is unavailable");
00830             else
00831                 status = tr("is asleep");
00832 
00833             fontstate = "warning";
00834         }
00835         else if (state == kState_WatchingLiveTV)
00836             status = tr("is watching Live TV");
00837         else if (state == kState_RecordingOnly ||
00838                  state == kState_WatchingRecording)
00839             status = tr("is recording");
00840         else
00841             status = tr("is not recording");
00842 
00843         QString tun = tr("Tuner %1 %2 %3");
00844         QString devlabel = CardUtil::GetDeviceLabel(
00845             query.value(1).toString(), query.value(2).toString());
00846 
00847         QString shorttuner = tun.arg(cardid).arg("").arg(status);
00848         QString longtuner = tun.arg(cardid).arg(devlabel).arg(status);
00849 
00850         if (state == kState_RecordingOnly ||
00851             state == kState_WatchingRecording)
00852         {
00853             strlist = QStringList( QString("QUERY_RECORDER %1").arg(cardid));
00854             strlist << "GET_RECORDING";
00855             gCoreContext->SendReceiveStringList(strlist);
00856             ProgramInfo pginfo(strlist);
00857             if (pginfo.GetChanID())
00858             {
00859                 status += ' ' + pginfo.GetTitle();
00860                 status += "\n";
00861                 status += pginfo.GetSubtitle();
00862                 longtuner = tun.arg(cardid).arg(devlabel).arg(status);
00863             }
00864         }
00865 
00866         AddLogLine(shorttuner, helpmsg, longtuner, longtuner, fontstate);
00867     }
00868 }
00869 
00870 void StatusBox::doLogEntries(void)
00871 {
00872     if (m_iconState)
00873         m_iconState->DisplayState("log");
00874     m_logList->Reset();
00875 
00876     QString helpmsg(tr("Log Entries shows any unread log entries "
00877                        "from the system if you have logging enabled"));
00878     if (m_helpText)
00879         m_helpText->SetText(helpmsg);
00880     if (m_justHelpText)
00881         m_justHelpText->SetText(helpmsg);
00882 
00883     MSqlQuery query(MSqlQuery::InitCon());
00884     query.prepare("SELECT logid, module, priority, logdate, host, "
00885                   "message, details "
00886                   "FROM mythlog WHERE acknowledged = 0 "
00887                   "AND priority <= :PRIORITY ORDER BY logdate DESC;");
00888     query.bindValue(":PRIORITY", m_minLevel);
00889 
00890     if (query.exec())
00891     {
00892         QString line;
00893         QString detail;
00894         while (query.next())
00895         {
00896             line = QString("%1").arg(query.value(5).toString());
00897 
00898             detail = tr("On %1 from %2.%3\n%4\n")
00899                         .arg(MythDateTimeToString(query.value(3).toDateTime(),
00900                                                     kDateTimeShort))
00901                         .arg(query.value(4).toString())
00902                         .arg(query.value(1).toString())
00903                         .arg(query.value(5).toString());
00904 
00905             QString tmp = query.value(6).toString();
00906             if (!tmp.isEmpty())
00907                 detail.append(tmp);
00908             else
00909                 detail.append(tr("No further details"));
00910 
00911             AddLogLine(line, helpmsg, detail, detail,
00912                        "", query.value(0).toString());
00913         }
00914 
00915         if (query.size() == 0)
00916         {
00917             AddLogLine(tr("No items found at priority level %1 or lower.")
00918                        .arg(m_minLevel), helpmsg);
00919             AddLogLine(tr("Use 1-8 to change priority level."), helpmsg);
00920         }
00921     }
00922 }
00923 
00924 void StatusBox::doJobQueueStatus()
00925 {
00926     if (m_iconState)
00927         m_iconState->DisplayState("jobqueue");
00928     m_logList->Reset();
00929 
00930     QString helpmsg(tr("Job Queue shows any jobs currently in "
00931                        "MythTV's Job Queue such as a commercial "
00932                        "detection job."));
00933     if (m_helpText)
00934         m_helpText->SetText(helpmsg);
00935     if (m_justHelpText)
00936         m_justHelpText->SetText(helpmsg);
00937 
00938     QMap<int, JobQueueEntry> jobs;
00939     QMap<int, JobQueueEntry>::Iterator it;
00940 
00941     JobQueue::GetJobsInQueue(jobs,
00942                              JOB_LIST_NOT_DONE | JOB_LIST_ERROR |
00943                              JOB_LIST_RECENT);
00944 
00945     if (jobs.size())
00946     {
00947         QString detail;
00948         QString line;
00949 
00950         for (it = jobs.begin(); it != jobs.end(); ++it)
00951         {
00952             ProgramInfo pginfo((*it).chanid, (*it).recstartts);
00953 
00954             if (!pginfo.GetChanID())
00955                 continue;
00956 
00957             detail = QString("%1\n%2 %3 @ %4\n%5 %6     %7 %8")
00958                 .arg(pginfo.GetTitle())
00959                 .arg(pginfo.GetChannelName())
00960                 .arg(pginfo.GetChanNum())
00961                 .arg(MythDateTimeToString(pginfo.GetRecordingStartTime(),
00962                                           kDateTimeFull | kSimplify))
00963                 .arg(tr("Job:"))
00964                 .arg(JobQueue::JobText((*it).type))
00965                 .arg(tr("Status: "))
00966                 .arg(JobQueue::StatusText((*it).status));
00967 
00968             if ((*it).status != JOB_QUEUED)
00969                 detail += " (" + (*it).hostname + ')';
00970 
00971             if ((*it).schedruntime > QDateTime::currentDateTime())
00972                 detail += '\n' + tr("Scheduled Run Time:") + ' ' +
00973                     MythDateTimeToString((*it).schedruntime,
00974                                          kDateTimeFull | kSimplify);
00975             else
00976                 detail += '\n' + (*it).comment;
00977 
00978             line = QString("%1 @ %2").arg(pginfo.GetTitle())
00979                                           .arg(MythDateTimeToString(
00980                                               pginfo.GetRecordingStartTime(),
00981                                               kDateTimeFull | kSimplify));
00982 
00983             QString font;
00984             if ((*it).status == JOB_ERRORED)
00985                 font = "error";
00986             else if ((*it).status == JOB_ABORTED)
00987                 font = "warning";
00988 
00989             AddLogLine(line, helpmsg, detail, detail, font,
00990                        QString("%1").arg((*it).id));
00991         }
00992     }
00993     else
00994         AddLogLine(tr("Job Queue is currently empty."), helpmsg);
00995 
00996 }
00997 
00998 // Some helper routines for doMachineStatus() that format the output strings
00999 
01007 static const QString sm_str(long long sizeKB, int prec=1)
01008 {
01009     if (sizeKB>1024*1024*1024) // Terabytes
01010     {
01011         double sizeGB = sizeKB/(1024*1024*1024.0);
01012         return QString(QObject::tr("%1 TB")).arg(sizeGB, 0, 'f', (sizeGB>10)?0:prec);
01013     }
01014     else if (sizeKB>1024*1024) // Gigabytes
01015     {
01016         double sizeGB = sizeKB/(1024*1024.0);
01017         return QString(QObject::tr("%1 GB")).arg(sizeGB, 0, 'f', (sizeGB>10)?0:prec);
01018     }
01019     else if (sizeKB>1024) // Megabytes
01020     {
01021         double sizeMB = sizeKB/1024.0;
01022         return QString(QObject::tr("%1 MB")).arg(sizeMB, 0, 'f', (sizeMB>10)?0:prec);
01023     }
01024     // Kilobytes
01025     return QString(QObject::tr("%1 KB")).arg(sizeKB);
01026 }
01027 
01028 static const QString usage_str_kb(long long total,
01029                                   long long used,
01030                                   long long free)
01031 {
01032     QString ret = QObject::tr("Unknown");
01033     if (total > 0.0 && free > 0.0)
01034     {
01035         double percent = (100.0*free)/total;
01036         ret = StatusBox::tr("%1 total, %2 used, %3 (or %4%) free.")
01037             .arg(sm_str(total)).arg(sm_str(used))
01038             .arg(sm_str(free)).arg(percent, 0, 'f', (percent >= 10.0) ? 0 : 2);
01039     }
01040     return ret;
01041 }
01042 
01043 static const QString usage_str_mb(float total, float used, float free)
01044 {
01045     return usage_str_kb((long long)(total*1024), (long long)(used*1024),
01046                         (long long)(free*1024));
01047 }
01048 
01049 static void disk_usage_with_rec_time_kb(QStringList& out, long long total,
01050                                         long long used, long long free,
01051                                         const recprof2bps_t& prof2bps)
01052 {
01053     const QString tail = StatusBox::tr(", using your %1 rate of %2 kb/s");
01054 
01055     out<<usage_str_kb(total, used, free);
01056     if (free<0)
01057         return;
01058 
01059     recprof2bps_t::const_iterator it = prof2bps.begin();
01060     for (; it != prof2bps.end(); ++it)
01061     {
01062         const QString pro =
01063                 tail.arg(it.key()).arg((int)((float)(*it) / 1024.0));
01064 
01065         long long bytesPerMin = ((*it) >> 1) * 15;
01066         uint minLeft = ((free<<5)/bytesPerMin)<<5;
01067         minLeft = (minLeft/15)*15;
01068         uint hoursLeft = minLeft/60;
01069         QString hourstring = StatusBox::tr("%n hour(s)", "", hoursLeft);
01070         QString minstring = StatusBox::tr("%n minute(s)", "", minLeft%60);
01071         QString remainstring = StatusBox::tr("%1 remaining", "time");
01072         if (minLeft%60 == 0)
01073             out<<remainstring.arg(hourstring) + pro;
01074         else if (minLeft > 60)
01075             out<<StatusBox::tr("%1 and %2 remaining", "time").arg(hourstring)
01076                                                    .arg(minstring) + pro;
01077         else
01078             out<<remainstring.arg(minstring) + pro;
01079     }
01080 }
01081 
01082 static const QString uptimeStr(time_t uptime)
01083 {
01084     int     days, hours, min, secs;
01085     QString str;
01086 
01087     str = QString("   " + StatusBox::tr("Uptime") + ": ");
01088 
01089     if (uptime == 0)
01090         return str + "unknown";
01091 
01092     days = uptime/(60*60*24);
01093     uptime -= days*60*60*24;
01094     hours = uptime/(60*60);
01095     uptime -= hours*60*60;
01096     min  = uptime/60;
01097     secs = uptime%60;
01098 
01099     if (days > 0)
01100     {
01101         char    buff[6];
01102         QString dayLabel = StatusBox::tr("%n day(s)", "", days);
01103 
01104         sprintf(buff, "%d:%02d", hours, min);
01105 
01106         return str + QString("%1, %2").arg(dayLabel).arg(buff);
01107     }
01108     else
01109     {
01110         char  buff[9];
01111 
01112         sprintf(buff, "%d:%02d:%02d", hours, min, secs);
01113 
01114         return str + QString( buff );
01115     }
01116 }
01117 
01121 void StatusBox::getActualRecordedBPS(QString hostnames)
01122 {
01123     recordingProfilesBPS.clear();
01124 
01125     QString querystr;
01126     MSqlQuery query(MSqlQuery::InitCon());
01127 
01128     querystr =
01129         "SELECT sum(filesize) * 8 / "
01130             "sum(((unix_timestamp(endtime) - unix_timestamp(starttime)))) "
01131             "AS avg_bitrate "
01132         "FROM recorded WHERE hostname in (%1) "
01133             "AND (unix_timestamp(endtime) - unix_timestamp(starttime)) > 300;";
01134 
01135     query.prepare(querystr.arg(hostnames));
01136 
01137     if (query.exec() && query.next() &&
01138         query.value(0).toDouble() > 0)
01139     {
01140         QString rateStr = tr("average", "average rate");
01141 
01142         // Don't user a tr() directly here as the Qt tools will
01143         // not be able to extract the string for translation.
01144         recordingProfilesBPS[rateStr] =
01145             (int)(query.value(0).toDouble());
01146     }
01147 
01148     querystr =
01149         "SELECT max(filesize * 8 / "
01150             "(unix_timestamp(endtime) - unix_timestamp(starttime))) "
01151             "AS max_bitrate "
01152         "FROM recorded WHERE hostname in (%1) "
01153             "AND (unix_timestamp(endtime) - unix_timestamp(starttime)) > 300;";
01154 
01155     query.prepare(querystr.arg(hostnames));
01156 
01157     if (query.exec() && query.next() &&
01158         query.value(0).toDouble() > 0)
01159     {
01160         QString rateStr = tr("maximum", "maximum rate");
01161 
01162         // Don't user a tr() directly here as the Qt tools will
01163         // not be able to extract the string for translation.
01164         recordingProfilesBPS[rateStr] =
01165             (int)(query.value(0).toDouble());
01166     }
01167 }
01168 
01177 void StatusBox::doMachineStatus()
01178 {
01179     if (m_iconState)
01180         m_iconState->DisplayState("machine");
01181     m_logList->Reset();
01182     QString machineStr = tr("Machine Status shows some operating system "
01183                             "statistics of this machine");
01184     if (!m_isBackendActive)
01185         machineStr.append(" " + tr("and the MythTV server"));
01186 
01187     if (m_helpText)
01188         m_helpText->SetText(machineStr);
01189     if (m_justHelpText)
01190         m_justHelpText->SetText(machineStr);
01191 
01192     int           totalM, usedM, freeM;    // Physical memory
01193     int           totalS, usedS, freeS;    // Virtual  memory (swap)
01194     time_t        uptime;
01195 
01196     QString line;
01197     if (m_isBackendActive)
01198         line = tr("System:");
01199     else
01200         line = tr("This machine:");
01201     AddLogLine(line, machineStr);
01202 
01203     // uptime
01204     if (!getUptime(uptime))
01205         uptime = 0;
01206     line = uptimeStr(uptime);
01207 
01208     // weighted average loads
01209     line.append(".   " + tr("Load") + ": ");
01210 
01211 #ifdef _WIN32
01212     line.append(tr("unknown") + " - getloadavg() " + tr("failed"));
01213 #else // if !_WIN32
01214     double loads[3];
01215     if (getloadavg(loads,3) == -1)
01216         line.append(tr("unknown") + " - getloadavg() " + tr("failed"));
01217     else
01218     {
01219         char buff[30];
01220 
01221         sprintf(buff, "%0.2lf, %0.2lf, %0.2lf", loads[0], loads[1], loads[2]);
01222         line.append(QString(buff));
01223     }
01224 #endif // _WIN32
01225 
01226     AddLogLine(line, machineStr);
01227 
01228     // memory usage
01229     if (getMemStats(totalM, freeM, totalS, freeS))
01230     {
01231         usedM = totalM - freeM;
01232         if (totalM > 0)
01233         {
01234             line = "   " + tr("RAM") + ": " + usage_str_mb(totalM, usedM, freeM);
01235             AddLogLine(line, machineStr);
01236         }
01237         usedS = totalS - freeS;
01238         if (totalS > 0)
01239         {
01240             line = "   " + tr("Swap") +
01241                                   ": "  + usage_str_mb(totalS, usedS, freeS);
01242             AddLogLine(line, machineStr);
01243         }
01244     }
01245 
01246     if (!m_isBackendActive)
01247     {
01248         line = tr("MythTV server") + ':';
01249         AddLogLine(line, machineStr);
01250 
01251         // uptime
01252         if (!RemoteGetUptime(uptime))
01253             uptime = 0;
01254         line = uptimeStr(uptime);
01255 
01256         // weighted average loads
01257         line.append(".   " + tr("Load") + ": ");
01258         float loads[3];
01259         if (RemoteGetLoad(loads))
01260         {
01261             char buff[30];
01262 
01263             sprintf(buff, "%0.2f, %0.2f, %0.2f", loads[0], loads[1], loads[2]);
01264             line.append(QString(buff));
01265         }
01266         else
01267             line.append(tr("unknown"));
01268 
01269         AddLogLine(line, machineStr);
01270 
01271         // memory usage
01272         if (RemoteGetMemStats(totalM, freeM, totalS, freeS))
01273         {
01274             usedM = totalM - freeM;
01275             if (totalM > 0)
01276             {
01277                 line = "   " + tr("RAM") +
01278                                      ": "  + usage_str_mb(totalM, usedM, freeM);
01279                 AddLogLine(line, machineStr);
01280             }
01281 
01282             usedS = totalS - freeS;
01283             if (totalS > 0)
01284             {
01285                 line = "   " + tr("Swap") +
01286                                      ": "  + usage_str_mb(totalS, usedS, freeS);
01287                 AddLogLine(line, machineStr);
01288             }
01289         }
01290     }
01291 
01292     // get free disk space
01293     QString hostnames;
01294 
01295     QList<FileSystemInfo> fsInfos = FileSystemInfo::RemoteGetInfo();
01296     for (int i = 0; i < fsInfos.size(); ++i)
01297     {
01298         // For a single-directory installation just display the totals
01299         if ((fsInfos.size() == 2) && (i == 0) &&
01300             (fsInfos[i].getPath() != "TotalDiskSpace") &&
01301             (fsInfos[i+1].getPath() == "TotalDiskSpace"))
01302             i++;
01303 
01304         hostnames = QString("\"%1\"").arg(fsInfos[i].getHostname());
01305         hostnames.replace(' ', "");
01306         hostnames.replace(',', "\",\"");
01307 
01308         getActualRecordedBPS(hostnames);
01309 
01310         QStringList list;
01311         disk_usage_with_rec_time_kb(list,
01312             fsInfos[i].getTotalSpace(), fsInfos[i].getUsedSpace(),
01313             fsInfos[i].getTotalSpace() - fsInfos[i].getUsedSpace(),
01314             recordingProfilesBPS);
01315 
01316         if (fsInfos[i].getPath() == "TotalDiskSpace")
01317         {
01318             line = tr("Total Disk Space:");
01319             AddLogLine(line, machineStr);
01320         }
01321         else
01322         {
01323             line = tr("MythTV Drive #%1:").arg(fsInfos[i].getFSysID());
01324             AddLogLine(line, machineStr);
01325 
01326             QStringList tokens = fsInfos[i].getPath().split(',');
01327 
01328             if (tokens.size() > 1)
01329             {
01330                 AddLogLine(QString("   ") + tr("Directories:"), machineStr);
01331 
01332                 int curToken = 0;
01333                 while (curToken < tokens.size())
01334                     AddLogLine(QString("      ") +
01335                                tokens[curToken++], machineStr);
01336             }
01337             else
01338             {
01339                 AddLogLine(QString("   " ) + tr("Directory:") + ' ' +
01340                            fsInfos[i].getPath(), machineStr);
01341             }
01342         }
01343 
01344         QStringList::iterator it = list.begin();
01345         for (;it != list.end(); ++it)
01346         {
01347             line = QString("   ") + (*it);
01348             AddLogLine(line, machineStr);
01349         }
01350     }
01351 
01352 }
01353 
01357 void StatusBox::doAutoExpireList(bool updateExpList)
01358 {
01359     if (m_iconState)
01360         m_iconState->DisplayState("autoexpire");
01361     m_logList->Reset();
01362 
01363     QString helpmsg(tr("The AutoExpire List shows all recordings "
01364                        "which may be expired and the order of "
01365                        "their expiration. Recordings at the top "
01366                        "of the list will be expired first."));
01367     if (m_helpText)
01368         m_helpText->SetText(helpmsg);
01369     if (m_justHelpText)
01370         m_justHelpText->SetText(helpmsg);
01371 
01372     ProgramInfo*          pginfo;
01373     QString               contentLine;
01374     QString               detailInfo;
01375     QString               staticInfo;
01376     long long             totalSize(0);
01377     long long             liveTVSize(0);
01378     int                   liveTVCount(0);
01379     long long             deletedGroupSize(0);
01380     int                   deletedGroupCount(0);
01381 
01382     vector<ProgramInfo *>::iterator it;
01383 
01384     if (updateExpList)
01385     {
01386         for (it = m_expList.begin(); it != m_expList.end(); ++it)
01387             delete *it;
01388         m_expList.clear();
01389 
01390         RemoteGetAllExpiringRecordings(m_expList);
01391     }
01392 
01393     for (it = m_expList.begin(); it != m_expList.end(); ++it)
01394     {
01395         pginfo = *it;
01396 
01397         totalSize += pginfo->GetFilesize();
01398         if (pginfo->GetRecordingGroup() == "LiveTV")
01399         {
01400             liveTVSize += pginfo->GetFilesize();
01401             liveTVCount++;
01402         }
01403         else if (pginfo->GetRecordingGroup() == "Deleted")
01404         {
01405             deletedGroupSize += pginfo->GetFilesize();
01406             deletedGroupCount++;
01407         }
01408     }
01409 
01410     staticInfo = tr("%n recording(s) consuming %1 (is) allowed to expire\n", "",
01411                      m_expList.size()).arg(sm_str(totalSize / 1024));
01412 
01413     if (liveTVCount)
01414         staticInfo += tr("%n (is) LiveTV and consume(s) %1\n", "", liveTVCount)
01415                             .arg(sm_str(liveTVSize / 1024));
01416 
01417     if (deletedGroupCount)
01418         staticInfo += tr("%n (is) Deleted and consume(s) %1\n", "",
01419                         deletedGroupCount)
01420                         .arg(sm_str(deletedGroupSize / 1024));
01421 
01422     for (it = m_expList.begin(); it != m_expList.end(); ++it)
01423     {
01424         pginfo = *it;
01425         QDateTime starttime = pginfo->GetRecordingStartTime();
01426         QDateTime endtime = pginfo->GetRecordingEndTime();
01427         contentLine =
01428             MythDateTimeToString(starttime, kDateFull | kSimplify) + " - ";
01429 
01430         contentLine +=
01431             "(" + ProgramInfo::i18n(pginfo->GetRecordingGroup()) + ") ";
01432 
01433         contentLine += pginfo->GetTitle() +
01434             " (" + sm_str(pginfo->GetFilesize() / 1024) + ")";
01435 
01436         detailInfo =
01437             MythDateTimeToString(starttime, kDateTimeFull | kSimplify) + " - " +
01438             MythDateTimeToString(endtime, kDateTimeFull | kSimplify);
01439 
01440         detailInfo += " (" + sm_str(pginfo->GetFilesize() / 1024) + ")";
01441 
01442         detailInfo += " (" + ProgramInfo::i18n(pginfo->GetRecordingGroup()) + ")";
01443 
01444         detailInfo += "\n" + pginfo->toString(ProgramInfo::kTitleSubtitle, " - ");
01445 
01446         AddLogLine(contentLine, staticInfo, detailInfo,
01447                    staticInfo + detailInfo);
01448     }
01449 }
01450 
01451 Q_DECLARE_METATYPE(LogLine)
01452 
01453 /* vim: set expandtab tabstop=4 shiftwidth=4: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends