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
00280
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
00463 if (!rec || buttonnum == 2)
00464 return;
00465
00466
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
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
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
00999
01007 static const QString sm_str(long long sizeKB, int prec=1)
01008 {
01009 if (sizeKB>1024*1024*1024)
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)
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)
01020 {
01021 double sizeMB = sizeKB/1024.0;
01022 return QString(QObject::tr("%1 MB")).arg(sizeMB, 0, 'f', (sizeMB>10)?0:prec);
01023 }
01024
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
01143
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
01163
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;
01193 int totalS, usedS, freeS;
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
01204 if (!getUptime(uptime))
01205 uptime = 0;
01206 line = uptimeStr(uptime);
01207
01208
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
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
01252 if (!RemoteGetUptime(uptime))
01253 uptime = 0;
01254 line = uptimeStr(uptime);
01255
01256
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
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
01293 QString hostnames;
01294
01295 QList<FileSystemInfo> fsInfos = FileSystemInfo::RemoteGetInfo();
01296 for (int i = 0; i < fsInfos.size(); ++i)
01297 {
01298
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