|
MythTV
0.26-pre
|
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: */
1.7.6.1