|
MythTV
0.26-pre
|
00001 00002 // c 00003 #include <cstdlib> 00004 #include <stdlib.h> 00005 #include <unistd.h> 00006 00007 // qt 00008 #include <QDir> 00009 #include <QKeyEvent> 00010 #include <QTimer> 00011 #include <QApplication> 00012 00013 // mythtv 00014 #include <mythcontext.h> 00015 #include <mythdb.h> 00016 #include <mthread.h> 00017 #include <programinfo.h> 00018 #include <remoteutil.h> 00019 #include <mythtimer.h> 00020 #include <mythuitext.h> 00021 #include <mythuibutton.h> 00022 #include <mythuiimage.h> 00023 #include <mythuibuttonlist.h> 00024 #include <mythmainwindow.h> 00025 #include <mythprogressdialog.h> 00026 #include <mythdialogbox.h> 00027 #include <mythlogging.h> 00028 #include <mythmiscutil.h> 00029 #include <netutils.h> 00030 00031 // mytharchive 00032 #include "recordingselector.h" 00033 #include "archiveutil.h" 00034 00035 class GetRecordingListThread : public MThread 00036 { 00037 public: 00038 GetRecordingListThread(RecordingSelector *parent) : 00039 MThread("GetRecordingList"), m_parent(parent) 00040 { 00041 start(); 00042 } 00043 00044 virtual void run(void) 00045 { 00046 RunProlog(); 00047 m_parent->getRecordingList(); 00048 RunEpilog(); 00049 } 00050 00051 RecordingSelector *m_parent; 00052 }; 00053 00054 RecordingSelector::RecordingSelector( 00055 MythScreenStack *parent, QList<ArchiveItem *> *archiveList) : 00056 MythScreenType(parent, "RecordingSelector"), 00057 m_archiveList(archiveList), 00058 m_recordingList(NULL), 00059 m_recordingButtonList(NULL), 00060 m_okButton(NULL), 00061 m_cancelButton(NULL), 00062 m_categorySelector(NULL), 00063 m_titleText(NULL), 00064 m_datetimeText(NULL), 00065 m_filesizeText(NULL), 00066 m_descriptionText(NULL), 00067 m_previewImage(NULL), 00068 m_cutlistImage(NULL) 00069 { 00070 } 00071 00072 RecordingSelector::~RecordingSelector(void) 00073 { 00074 if (m_recordingList) 00075 delete m_recordingList; 00076 00077 while (!m_selectedList.isEmpty()) 00078 delete m_selectedList.takeFirst(); 00079 } 00080 00081 bool RecordingSelector::Create(void) 00082 { 00083 bool foundtheme = false; 00084 00085 // Load the theme for this screen 00086 foundtheme = LoadWindowFromXML("mytharchive-ui.xml", "recording_selector", this); 00087 00088 if (!foundtheme) 00089 return false; 00090 00091 bool err = false; 00092 UIUtilE::Assign(this, m_okButton, "ok_button", &err); 00093 UIUtilE::Assign(this, m_cancelButton, "cancel_button", &err); 00094 UIUtilE::Assign(this, m_categorySelector, "category_selector", &err); 00095 UIUtilE::Assign(this, m_recordingButtonList, "recordinglist", &err); 00096 00097 UIUtilW::Assign(this, m_titleText, "progtitle", &err); 00098 UIUtilW::Assign(this, m_datetimeText, "progdatetime", &err); 00099 UIUtilW::Assign(this, m_descriptionText, "progdescription", &err); 00100 UIUtilW::Assign(this, m_filesizeText, "filesize", &err); 00101 UIUtilW::Assign(this, m_previewImage, "preview_image", &err); 00102 UIUtilW::Assign(this, m_cutlistImage, "cutlist_image", &err); 00103 00104 if (err) 00105 { 00106 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'recording_selector'"); 00107 return false; 00108 } 00109 00110 connect(m_okButton, SIGNAL(Clicked()), this, SLOT(OKPressed())); 00111 connect(m_cancelButton, SIGNAL(Clicked()), this, SLOT(cancelPressed())); 00112 00113 new MythUIButtonListItem(m_categorySelector, tr("All Recordings")); 00114 connect(m_categorySelector, SIGNAL(itemSelected(MythUIButtonListItem *)), 00115 this, SLOT(setCategory(MythUIButtonListItem *))); 00116 00117 connect(m_recordingButtonList, SIGNAL(itemSelected(MythUIButtonListItem *)), 00118 this, SLOT(titleChanged(MythUIButtonListItem *))); 00119 connect(m_recordingButtonList, SIGNAL(itemClicked(MythUIButtonListItem *)), 00120 this, SLOT(toggleSelected(MythUIButtonListItem *))); 00121 00122 if (m_cutlistImage) 00123 m_cutlistImage->Hide(); 00124 00125 BuildFocusList(); 00126 00127 SetFocusWidget(m_recordingButtonList); 00128 00129 return true; 00130 } 00131 00132 void RecordingSelector::Init(void) 00133 { 00134 QString message = tr("Retrieving Recording List.\nPlease Wait..."); 00135 00136 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00137 00138 MythUIBusyDialog *busyPopup = new 00139 MythUIBusyDialog(message, popupStack, "recordingselectorbusydialog"); 00140 00141 if (busyPopup->Create()) 00142 popupStack->AddScreen(busyPopup, false); 00143 else 00144 { 00145 delete busyPopup; 00146 busyPopup = NULL; 00147 } 00148 00149 GetRecordingListThread *thread = new GetRecordingListThread(this); 00150 while (thread->isRunning()) 00151 { 00152 qApp->processEvents(); 00153 usleep(2000); 00154 } 00155 00156 if (!m_recordingList || m_recordingList->empty()) 00157 { 00158 ShowOkPopup(tr("Either you don't have any recordings or " 00159 "no recordings are available locally!")); 00160 if (busyPopup) 00161 busyPopup->Close(); 00162 00163 Close(); 00164 return; 00165 } 00166 00167 updateCategorySelector(); 00168 updateSelectedList(); 00169 updateRecordingList(); 00170 00171 if (busyPopup) 00172 busyPopup->Close(); 00173 } 00174 00175 bool RecordingSelector::keyPressEvent(QKeyEvent *event) 00176 { 00177 if (GetFocusWidget()->keyPressEvent(event)) 00178 return true; 00179 00180 bool handled = false; 00181 QStringList actions; 00182 handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions); 00183 00184 for (int i = 0; i < actions.size() && !handled; i++) 00185 { 00186 QString action = actions[i]; 00187 handled = true; 00188 00189 if (action == "MENU") 00190 { 00191 showMenu(); 00192 } 00193 else 00194 handled = false; 00195 } 00196 00197 if (!handled && MythScreenType::keyPressEvent(event)) 00198 handled = true; 00199 00200 return handled; 00201 } 00202 00203 void RecordingSelector::showMenu() 00204 { 00205 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00206 00207 MythDialogBox *menuPopup = new MythDialogBox(tr("Menu"), popupStack, "actionmenu"); 00208 00209 if (menuPopup->Create()) 00210 popupStack->AddScreen(menuPopup); 00211 00212 menuPopup->SetReturnEvent(this, "action"); 00213 00214 menuPopup->AddButton(tr("Clear All"), SLOT(clearAll())); 00215 menuPopup->AddButton(tr("Select All"), SLOT(selectAll())); 00216 } 00217 00218 void RecordingSelector::selectAll() 00219 { 00220 while (!m_selectedList.isEmpty()) 00221 m_selectedList.takeFirst(); 00222 m_selectedList.clear(); 00223 00224 ProgramInfo *p; 00225 vector<ProgramInfo *>::iterator i = m_recordingList->begin(); 00226 for ( ; i != m_recordingList->end(); ++i) 00227 { 00228 p = *i; 00229 m_selectedList.append(p); 00230 } 00231 00232 updateRecordingList(); 00233 } 00234 00235 void RecordingSelector::clearAll() 00236 { 00237 while (!m_selectedList.isEmpty()) 00238 m_selectedList.takeFirst(); 00239 m_selectedList.clear(); 00240 00241 updateRecordingList(); 00242 } 00243 00244 void RecordingSelector::toggleSelected(MythUIButtonListItem *item) 00245 { 00246 if (item->state() == MythUIButtonListItem:: FullChecked) 00247 { 00248 int index = m_selectedList.indexOf( 00249 qVariantValue<ProgramInfo *>(item->GetData())); 00250 if (index != -1) 00251 m_selectedList.takeAt(index); 00252 item->setChecked(MythUIButtonListItem:: NotChecked); 00253 } 00254 else 00255 { 00256 int index = m_selectedList.indexOf( 00257 qVariantValue<ProgramInfo *>(item->GetData())); 00258 if (index == -1) 00259 m_selectedList.append(qVariantValue<ProgramInfo *>(item->GetData())); 00260 00261 item->setChecked(MythUIButtonListItem::FullChecked); 00262 } 00263 } 00264 00265 void RecordingSelector::titleChanged(MythUIButtonListItem *item) 00266 { 00267 ProgramInfo *p; 00268 00269 p = qVariantValue<ProgramInfo *>(item->GetData()); 00270 00271 if (!p) 00272 return; 00273 00274 if (m_titleText) 00275 m_titleText->SetText(p->GetTitle()); 00276 00277 if (m_datetimeText) 00278 m_datetimeText->SetText(p->GetScheduledStartTime() 00279 .toString("dd MMM yy (hh:mm)")); 00280 00281 if (m_descriptionText) 00282 { 00283 m_descriptionText->SetText( 00284 ((!p->GetSubtitle().isEmpty()) ? p->GetSubtitle() + "\n" : "") + 00285 p->GetDescription()); 00286 } 00287 00288 if (m_filesizeText) 00289 { 00290 m_filesizeText->SetText(formatSize(p->GetFilesize() / 1024)); 00291 } 00292 00293 if (m_cutlistImage) 00294 { 00295 if (p->HasCutlist()) 00296 m_cutlistImage->Show(); 00297 else 00298 m_cutlistImage->Hide(); 00299 } 00300 00301 if (m_previewImage) 00302 { 00303 // try to locate a preview image 00304 if (QFile::exists(p->GetPathname() + ".png")) 00305 { 00306 m_previewImage->SetFilename(p->GetPathname() + ".png"); 00307 m_previewImage->Load(); 00308 } 00309 else 00310 { 00311 m_previewImage->SetFilename("blank.png"); 00312 m_previewImage->Load(); 00313 } 00314 } 00315 } 00316 00317 void RecordingSelector::OKPressed() 00318 { 00319 // loop though selected recordings and add them to the list 00320 ProgramInfo *p; 00321 ArchiveItem *a; 00322 00323 // remove any items that have been removed from the list 00324 QList<ArchiveItem *> tempAList; 00325 for (int x = 0; x < m_archiveList->size(); x++) 00326 { 00327 a = m_archiveList->at(x); 00328 bool found = false; 00329 00330 for (int y = 0; y < m_selectedList.size(); y++) 00331 { 00332 p = m_selectedList.at(y); 00333 if (a->type != "Recording" || a->filename == p->GetPlaybackURL(false, true)) 00334 { 00335 found = true; 00336 break; 00337 } 00338 } 00339 00340 if (!found) 00341 tempAList.append(a); 00342 } 00343 00344 for (int x = 0; x < tempAList.size(); x++) 00345 m_archiveList->removeAll(tempAList.at(x)); 00346 00347 // remove any items that are already in the list 00348 QList<ProgramInfo *> tempSList; 00349 for (int x = 0; x < m_selectedList.size(); x++) 00350 { 00351 p = m_selectedList.at(x); 00352 00353 for (int y = 0; y < m_archiveList->size(); y++) 00354 { 00355 a = m_archiveList->at(y); 00356 if (a->filename == p->GetPlaybackURL(false, true)) 00357 { 00358 tempSList.append(p); 00359 break; 00360 } 00361 } 00362 } 00363 00364 for (int x = 0; x < tempSList.size(); x++) 00365 m_selectedList.removeAll(tempSList.at(x)); 00366 00367 // add all that are left 00368 for (int x = 0; x < m_selectedList.size(); x++) 00369 { 00370 p = m_selectedList.at(x); 00371 a = new ArchiveItem; 00372 a->type = "Recording"; 00373 a->title = p->GetTitle(); 00374 a->subtitle = p->GetSubtitle(); 00375 a->description = p->GetDescription(); 00376 a->startDate = p->GetScheduledStartTime().toString("dd MMM yy"); 00377 a->startTime = p->GetScheduledStartTime().toString("(hh:mm)"); 00378 a->size = p->GetFilesize(); 00379 a->filename = p->GetPlaybackURL(false, true); 00380 a->hasCutlist = p->HasCutlist(); 00381 a->useCutlist = false; 00382 a->duration = 0; 00383 a->cutDuration = 0; 00384 a->videoWidth = 0; 00385 a->videoHeight = 0; 00386 a->fileCodec = ""; 00387 a->videoCodec = ""; 00388 a->encoderProfile = NULL; 00389 a->editedDetails = false; 00390 m_archiveList->append(a); 00391 } 00392 00393 emit haveResult(true); 00394 Close(); 00395 } 00396 00397 void RecordingSelector::cancelPressed() 00398 { 00399 emit haveResult(false); 00400 Close(); 00401 } 00402 00403 void RecordingSelector::updateRecordingList(void) 00404 { 00405 if (!m_recordingList || m_recordingList->empty()) 00406 return; 00407 00408 m_recordingButtonList->Reset(); 00409 00410 if (m_categorySelector) 00411 { 00412 ProgramInfo *p; 00413 vector<ProgramInfo *>::iterator i = m_recordingList->begin(); 00414 for ( ; i != m_recordingList->end(); ++i) 00415 { 00416 p = *i; 00417 00418 if (p->GetTitle() == m_categorySelector->GetValue() || 00419 m_categorySelector->GetValue() == tr("All Recordings")) 00420 { 00421 MythUIButtonListItem* item = new MythUIButtonListItem( 00422 m_recordingButtonList, 00423 p->GetTitle() + " ~ " + 00424 p->GetScheduledStartTime().toString("dd MMM yy (hh:mm)")); 00425 item->setCheckable(true); 00426 if (m_selectedList.indexOf((ProgramInfo *) p) != -1) 00427 { 00428 item->setChecked(MythUIButtonListItem::FullChecked); 00429 } 00430 else 00431 { 00432 item->setChecked(MythUIButtonListItem::NotChecked); 00433 } 00434 00435 QString title = p->GetTitle(); 00436 QString subtitle = p->GetSubtitle(); 00437 00438 QDateTime recstartts = p->GetScheduledStartTime(); 00439 QDateTime recendts = p->GetScheduledEndTime(); 00440 00441 QString timedate = QString("%1 - %2") 00442 .arg(MythDateTimeToString 00443 (recstartts, kDateTimeFull)) 00444 .arg(MythDateTimeToString(recendts, kTime)); 00445 00446 uint season = p->GetSeason(); 00447 uint episode = p->GetEpisode(); 00448 QString seasone, seasonx; 00449 00450 if (season && episode) 00451 { 00452 seasone = QString("s%1e%2") 00453 .arg(GetDisplaySeasonEpisode(season, 2)) 00454 .arg(GetDisplaySeasonEpisode(episode, 2)); 00455 seasonx = QString("%1x%2") 00456 .arg(GetDisplaySeasonEpisode(season, 1)) 00457 .arg(GetDisplaySeasonEpisode(episode, 2)); 00458 } 00459 00460 item->SetText(title, "title"); 00461 item->SetText(subtitle, "subtitle"); 00462 if (subtitle.isEmpty()) 00463 item->SetText(title, "titlesubtitle"); 00464 else 00465 item->SetText(title + " - \"" + subtitle + '"', 00466 "titlesubtitle"); 00467 00468 item->SetText(timedate, "timedate"); 00469 item->SetText(p->GetDescription(), "description"); 00470 item->SetText(formatSize(p->GetFilesize() / 1024), 00471 "filesize_str"); 00472 00473 item->SetText(QString::number(season), "season"); 00474 item->SetText(QString::number(episode), "episode"); 00475 item->SetText(seasonx, "00x00"); 00476 item->SetText(seasone, "s00e00"); 00477 00478 item->DisplayState(p->HasCutlist() ? "yes" : "no", "cutlist"); 00479 00480 item->SetData(qVariantFromValue(p)); 00481 } 00482 qApp->processEvents(); 00483 } 00484 } 00485 00486 m_recordingButtonList->SetItemCurrent(m_recordingButtonList->GetItemFirst()); 00487 titleChanged(m_recordingButtonList->GetItemCurrent()); 00488 } 00489 00490 void RecordingSelector::getRecordingList(void) 00491 { 00492 ProgramInfo *p; 00493 m_recordingList = RemoteGetRecordedList(-1); 00494 m_categories.clear(); 00495 00496 if (m_recordingList && !m_recordingList->empty()) 00497 { 00498 vector<ProgramInfo *>::iterator i = m_recordingList->begin(); 00499 for ( ; i != m_recordingList->end(); ++i) 00500 { 00501 p = *i; 00502 // ignore live tv and deleted recordings 00503 if (p->GetRecordingGroup() == "LiveTV" || 00504 p->GetRecordingGroup() == "Deleted") 00505 { 00506 i = m_recordingList->erase(i); 00507 --i; 00508 continue; 00509 } 00510 00511 if (m_categories.indexOf(p->GetTitle()) == -1) 00512 m_categories.append(p->GetTitle()); 00513 } 00514 } 00515 } 00516 00517 void RecordingSelector::updateCategorySelector(void) 00518 { 00519 // sort and add categories to selector 00520 m_categories.sort(); 00521 00522 if (m_categorySelector) 00523 { 00524 new MythUIButtonListItem(m_categorySelector, tr("All Recordings")); 00525 m_categorySelector->SetItemCurrent(0); 00526 00527 for (int x = 0; x < m_categories.count(); x++) 00528 { 00529 new MythUIButtonListItem(m_categorySelector, m_categories[x]); 00530 } 00531 } 00532 } 00533 00534 void RecordingSelector::setCategory(MythUIButtonListItem *item) 00535 { 00536 (void)item; 00537 updateRecordingList(); 00538 } 00539 00540 void RecordingSelector::updateSelectedList() 00541 { 00542 if (!m_recordingList) 00543 return; 00544 00545 m_selectedList.clear(); 00546 00547 ProgramInfo *p; 00548 ArchiveItem *a; 00549 for (int x = 0; x < m_archiveList->size(); x++) 00550 { 00551 a = m_archiveList->at(x); 00552 for (uint y = 0; y < m_recordingList->size(); y++) 00553 { 00554 p = m_recordingList->at(y); 00555 if (p->GetPlaybackURL(false, true) == a->filename) 00556 { 00557 if (m_selectedList.indexOf(p) == -1) 00558 m_selectedList.append(p); 00559 break; 00560 } 00561 00562 qApp->processEvents(); 00563 } 00564 } 00565 }
1.7.6.1