MythTV  0.26-pre
videoselector.cpp
Go to the documentation of this file.
00001 // c
00002 #include <cstdlib>
00003 #include <stdlib.h>
00004 #include <unistd.h>
00005 
00006 // qt
00007 #include <QDir>
00008 #include <QTimer>
00009 
00010 // mythtv
00011 #include <mythcontext.h>
00012 #include <dialogbox.h>
00013 #include <mythdb.h>
00014 #include <mythuitext.h>
00015 #include <mythuibutton.h>
00016 #include <mythuiimage.h>
00017 #include <mythuibuttonlist.h>
00018 #include <mythmainwindow.h>
00019 #include <mythdialogbox.h>
00020 
00021 // mytharchive
00022 #include "videoselector.h"
00023 #include "archiveutil.h"
00024 
00025 using namespace std;
00026 
00027 VideoSelector::VideoSelector(MythScreenStack *parent, QList<ArchiveItem *> *archiveList)
00028               :MythScreenType(parent, "VideoSelector")
00029 {
00030     m_archiveList = archiveList;
00031     m_currentParentalLevel = ParentalLevel::plNone;
00032     m_videoList = NULL;
00033 
00034     m_parentalLevelChecker = new ParentalLevelChangeChecker();
00035     connect(m_parentalLevelChecker, SIGNAL(SigResultReady(bool, ParentalLevel::Level)),
00036             this, SLOT(parentalLevelChanged(bool, ParentalLevel::Level)));
00037 }
00038 
00039 VideoSelector::~VideoSelector(void)
00040 {
00041     if (m_videoList)
00042         delete m_videoList;
00043 
00044     while (!m_selectedList.isEmpty())
00045          delete m_selectedList.takeFirst();
00046     m_selectedList.clear();
00047 
00048     delete m_parentalLevelChecker;
00049 }
00050 
00051 bool VideoSelector::Create(void)
00052 {
00053     bool foundtheme = false;
00054 
00055     // Load the theme for this screen
00056     foundtheme = LoadWindowFromXML("mytharchive-ui.xml", "video_selector", this);
00057 
00058     if (!foundtheme)
00059         return false;
00060 
00061     bool err = false;
00062     UIUtilE::Assign(this, m_okButton, "ok_button", &err);
00063     UIUtilE::Assign(this, m_cancelButton, "cancel_button", &err);
00064     UIUtilE::Assign(this, m_categorySelector, "category_selector", &err);
00065     UIUtilE::Assign(this, m_videoButtonList, "videolist", &err);
00066     UIUtilE::Assign(this, m_titleText, "videotitle", &err);
00067     UIUtilE::Assign(this, m_plotText, "videoplot", &err);
00068     UIUtilE::Assign(this, m_filesizeText, "filesize", &err);
00069     UIUtilE::Assign(this, m_coverImage, "cover_image", &err);
00070     UIUtilE::Assign(this, m_warningText, "warning_text", &err);
00071     UIUtilE::Assign(this, m_plText, "parentallevel_text", &err);
00072 
00073     if (err)
00074     {
00075         LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'video_selector'");
00076         return false;
00077     }
00078 
00079     connect(m_okButton, SIGNAL(Clicked()), SLOT(OKPressed()));
00080     connect(m_cancelButton, SIGNAL(Clicked()), SLOT(cancelPressed()));
00081 
00082     connect(m_categorySelector, SIGNAL(itemSelected(MythUIButtonListItem *)),
00083             SLOT(setCategory(MythUIButtonListItem *)));
00084 
00085     getVideoList();
00086     connect(m_videoButtonList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00087             SLOT(titleChanged(MythUIButtonListItem *)));
00088     connect(m_videoButtonList, SIGNAL(itemClicked(MythUIButtonListItem *)),
00089             SLOT(toggleSelected(MythUIButtonListItem *)));
00090 
00091     BuildFocusList();
00092 
00093     SetFocusWidget(m_videoButtonList);
00094 
00095     setParentalLevel(ParentalLevel::plLowest);
00096 
00097     updateSelectedList();
00098     updateVideoList();
00099 
00100     return true;
00101 }
00102 
00103 bool VideoSelector::keyPressEvent(QKeyEvent *event)
00104 {
00105     if (GetFocusWidget()->keyPressEvent(event))
00106         return true;
00107 
00108     bool handled = false;
00109     QStringList actions;
00110     handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
00111 
00112     for (int i = 0; i < actions.size() && !handled; i++)
00113     {
00114         QString action = actions[i];
00115         handled = true;
00116 
00117         if (action == "MENU")
00118         {
00119             showMenu();
00120         }
00121         else if (action == "1")
00122         {
00123             setParentalLevel(ParentalLevel::plLowest);
00124         }
00125         else if (action == "2")
00126         {
00127             setParentalLevel(ParentalLevel::plLow);
00128         }
00129         else if (action == "3")
00130         {
00131             setParentalLevel(ParentalLevel::plMedium);
00132         }
00133         else if (action == "4")
00134         {
00135             setParentalLevel(ParentalLevel::plHigh);
00136         }
00137         else
00138             handled = false;
00139     }
00140 
00141     if (!handled && MythScreenType::keyPressEvent(event))
00142         handled = true;
00143 
00144     return handled;
00145 }
00146 
00147 void VideoSelector::showMenu()
00148 {
00149     MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00150 
00151     MythDialogBox *menuPopup = new MythDialogBox(tr("Menu"), popupStack, "actionmenu");
00152 
00153     if (menuPopup->Create())
00154         popupStack->AddScreen(menuPopup);
00155 
00156     menuPopup->SetReturnEvent(this, "action");
00157 
00158     menuPopup->AddButton(tr("Clear All"), SLOT(clearAll()));
00159     menuPopup->AddButton(tr("Select All"), SLOT(selectAll()));
00160 }
00161 
00162 void VideoSelector::selectAll()
00163 {
00164     while (!m_selectedList.isEmpty())
00165          m_selectedList.takeFirst();
00166     m_selectedList.clear();
00167 
00168     VideoInfo *v;
00169     vector<VideoInfo *>::iterator i = m_videoList->begin();
00170     for ( ; i != m_videoList->end(); ++i)
00171     {
00172         v = *i;
00173         m_selectedList.append(v);
00174     }
00175 
00176     updateVideoList();
00177 }
00178 
00179 void VideoSelector::clearAll()
00180 {
00181     while (!m_selectedList.isEmpty())
00182          m_selectedList.takeFirst();
00183     m_selectedList.clear();
00184 
00185     updateVideoList();
00186 }
00187 
00188 void VideoSelector::toggleSelected(MythUIButtonListItem *item)
00189 {
00190     if (item->state() == MythUIButtonListItem::FullChecked)
00191     {
00192         int index = m_selectedList.indexOf(
00193                                 qVariantValue<VideoInfo *>(item->GetData()));
00194         if (index != -1)
00195             m_selectedList.takeAt(index);
00196         item->setChecked(MythUIButtonListItem::NotChecked);
00197     }
00198     else
00199     {
00200         int index = m_selectedList.indexOf(
00201                                 qVariantValue<VideoInfo *>(item->GetData()));
00202         if (index == -1)
00203             m_selectedList.append(qVariantValue<VideoInfo *>(item->GetData()));
00204 
00205         item->setChecked(MythUIButtonListItem::FullChecked);
00206     }
00207 }
00208 
00209 void VideoSelector::titleChanged(MythUIButtonListItem *item)
00210 {
00211     VideoInfo *v;
00212 
00213     v = qVariantValue<VideoInfo *>(item->GetData());
00214 
00215     if (!v)
00216         return;
00217 
00218     if (m_titleText)
00219         m_titleText->SetText(v->title);
00220 
00221     if (m_plotText)
00222         m_plotText->SetText(v->plot);
00223 
00224     if (m_coverImage)
00225     {
00226         if (v->coverfile != "" && v->coverfile != "No Cover")
00227         {
00228             m_coverImage->SetFilename(v->coverfile);
00229             m_coverImage->Load();
00230         }
00231         else
00232         {
00233             m_coverImage->SetFilename("blank.png");
00234             m_coverImage->Load();
00235         }
00236     }
00237 
00238     if (m_filesizeText)
00239     {
00240         if (v->size == 0)
00241         {
00242             QFile file(v->filename);
00243             if (file.exists())
00244                 v->size = (uint64_t)file.size();
00245             else
00246                 LOG(VB_GENERAL, LOG_ERR,
00247                     QString("VideoSelector: Cannot find file: %1")
00248                         .arg(v->filename));
00249         }
00250 
00251         m_filesizeText->SetText(formatSize(v->size / 1024));
00252     }
00253 }
00254 
00255 void VideoSelector::OKPressed()
00256 {
00257     // loop though selected videos and add them to the list
00258     VideoInfo *v;
00259     ArchiveItem *a;
00260 
00261     // remove any items that have been removed from the list
00262     QList<ArchiveItem *> tempAList;
00263     for (int x = 0; x < m_archiveList->size(); x++)
00264     {
00265         a = m_archiveList->at(x);
00266         bool found = false;
00267 
00268         for (int y = 0; y < m_selectedList.size(); y++)
00269         {
00270             v = m_selectedList.at(y);
00271             if (a->type != "Video" || a->filename == v->filename)
00272             {
00273                 found = true;
00274                 break;
00275             }
00276         }
00277 
00278         if (!found)
00279             tempAList.append(a);
00280     }
00281 
00282     for (int x = 0; x < tempAList.size(); x++)
00283         m_archiveList->removeAll(tempAList.at(x));
00284 
00285     // remove any items that are already in the list
00286     QList<VideoInfo *> tempSList;
00287     for (int x = 0; x < m_selectedList.size(); x++)
00288     {
00289         v = m_selectedList.at(x);
00290 
00291         for (int y = 0; y < m_archiveList->size(); y++)
00292         {
00293             a = m_archiveList->at(y);
00294             if (a->filename == v->filename)
00295             {
00296                 tempSList.append(v);
00297                 break;
00298             }
00299         }
00300     }
00301 
00302     for (int x = 0; x < tempSList.size(); x++)
00303         m_selectedList.removeAll(tempSList.at(x));
00304 
00305     // add all that are left
00306     for (int x = 0; x < m_selectedList.size(); x++)
00307     {
00308         v = m_selectedList.at(x);
00309         a = new ArchiveItem;
00310         a->type = "Video";
00311         a->title = v->title;
00312         a->subtitle = "";
00313         a->description = v->plot;
00314         a->startDate = "";
00315         a->startTime = "";
00316         a->size = v->size;
00317         a->filename = v->filename;
00318         a->hasCutlist = false;
00319         a->useCutlist = false;
00320         a->duration = 0;
00321         a->cutDuration = 0;
00322         a->videoWidth = 0;
00323         a->videoHeight = 0;
00324         a->fileCodec = "";
00325         a->videoCodec = "";
00326         a->encoderProfile = NULL;
00327         a->editedDetails = false;
00328         m_archiveList->append(a);
00329     }
00330 
00331     emit haveResult(true);
00332     Close();
00333 }
00334 
00335 void VideoSelector::cancelPressed()
00336 {
00337     emit haveResult(false);
00338     Close();
00339 }
00340 
00341 void VideoSelector::updateVideoList(void)
00342 {
00343     if (!m_videoList)
00344         return;
00345 
00346     m_videoButtonList->Reset();
00347 
00348     if (m_categorySelector)
00349     {
00350         VideoInfo *v;
00351         vector<VideoInfo *>::iterator i = m_videoList->begin();
00352         for ( ; i != m_videoList->end(); ++i)
00353         {
00354             v = *i;
00355 
00356             if (v->category == m_categorySelector->GetValue() ||
00357                 m_categorySelector->GetValue() == tr("All Videos"))
00358             {
00359                 if (v->parentalLevel <= m_currentParentalLevel)
00360                 {
00361                     MythUIButtonListItem* item = new MythUIButtonListItem(
00362                             m_videoButtonList, v->title);
00363                     item->setCheckable(true);
00364                     if (m_selectedList.indexOf((VideoInfo *) v) != -1)
00365                     {
00366                         item->setChecked(MythUIButtonListItem::FullChecked);
00367                     }
00368                     else
00369                     {
00370                         item->setChecked(MythUIButtonListItem::NotChecked);
00371                     }
00372 
00373                     item->SetData(qVariantFromValue(v));
00374                 }
00375             }
00376         }
00377     }
00378 
00379     if (m_videoButtonList->GetCount() > 0)
00380     {
00381         m_videoButtonList->SetItemCurrent(m_videoButtonList->GetItemFirst());
00382         titleChanged(m_videoButtonList->GetItemCurrent());
00383         m_warningText->Hide();
00384     }
00385     else
00386     {
00387         m_warningText->Show();
00388         m_titleText->Reset();
00389         m_plotText->Reset();
00390         m_coverImage->SetFilename("blank.png");
00391         m_coverImage->Load();
00392         m_filesizeText->Reset();
00393     }
00394 }
00395 
00396 vector<VideoInfo *> *VideoSelector::getVideoListFromDB(void)
00397 {
00398     // get a list of category's
00399     typedef QMap<int, QString> CategoryMap;
00400     CategoryMap categoryMap;
00401     MSqlQuery query(MSqlQuery::InitCon());
00402     query.prepare("SELECT intid, category FROM videocategory");
00403 
00404     if (query.exec())
00405     {
00406         while (query.next())
00407         {
00408             int id = query.value(0).toInt();
00409             QString category = query.value(1).toString();
00410             categoryMap.insert(id, category);
00411         }
00412     }
00413 
00414     vector<VideoInfo*> *videoList = new vector<VideoInfo*>;
00415 
00416     query.prepare("SELECT intid, title, plot, length, filename, coverfile, "
00417                   "category, showlevel, subtitle, season, episode "
00418                   "FROM videometadata ORDER BY title,season,episode");
00419 
00420     if (query.exec() && query.size())
00421     {
00422         QString artist, genre, episode;
00423         while (query.next())
00424         {
00425             VideoInfo *info = new VideoInfo;
00426 
00427             info->id = query.value(0).toInt();
00428             if (query.value(9).toInt() > 0)
00429             {
00430                 episode = query.value(10).toString();
00431                 if (episode.size() < 2)
00432                         episode.prepend("0");
00433                     info->title = QString("%1 %2x%3 - %4")
00434                                 .arg(query.value(1).toString())
00435                                 .arg(query.value(9).toString())
00436                                 .arg(episode)
00437                                 .arg(query.value(8).toString());
00438             }
00439             else
00440                 info->title = query.value(1).toString();
00441 
00442             info->plot = query.value(2).toString();
00443             info->size = 0; //query.value(3).toInt();
00444             info->filename = query.value(4).toString();
00445             info->coverfile = query.value(5).toString();
00446             info->category = categoryMap[query.value(6).toInt()];
00447             info->parentalLevel = query.value(7).toInt();
00448             if (info->category.isEmpty())
00449                 info->category = "(None)";
00450             videoList->push_back(info);
00451         }
00452     }
00453     else
00454     {
00455         LOG(VB_GENERAL, LOG_ERR, "VideoSelector: Failed to get any video's");
00456         return NULL;
00457     }
00458 
00459     return videoList;
00460 }
00461 
00462 void VideoSelector::getVideoList(void)
00463 {
00464     VideoInfo *v;
00465     m_videoList = getVideoListFromDB();
00466     QStringList categories;
00467 
00468     if (m_videoList && !m_videoList->empty())
00469     {
00470         vector<VideoInfo *>::iterator i = m_videoList->begin();
00471         for ( ; i != m_videoList->end(); ++i)
00472         {
00473             v = *i;
00474 
00475             if (categories.indexOf(v->category) == -1)
00476                 categories.append(v->category);
00477         }
00478     }
00479     else
00480     {
00481         QTimer::singleShot(100, this, SLOT(cancelPressed()));
00482         return;
00483     }
00484 
00485     // sort and add categories to selector
00486     categories.sort();
00487 
00488     if (m_categorySelector)
00489     {
00490         new MythUIButtonListItem(m_categorySelector, tr("All Videos"));
00491         m_categorySelector->SetItemCurrent(0);
00492 
00493         for (int x = 0; x < categories.count(); x++)
00494         {
00495             new MythUIButtonListItem(m_categorySelector, categories[x]);
00496         }
00497     }
00498 
00499     setCategory(0);
00500 }
00501 
00502 void VideoSelector::setCategory(MythUIButtonListItem *item)
00503 {
00504     (void)item;
00505     updateVideoList();
00506 }
00507 
00508 void VideoSelector::updateSelectedList()
00509 {
00510     if (!m_videoList)
00511         return;
00512 
00513     m_selectedList.clear();
00514 
00515     ArchiveItem *a;
00516     VideoInfo *v;
00517     for (int x = 0; x < m_archiveList->size(); x++)
00518     {
00519         a = m_archiveList->at(x);
00520         for (uint y = 0; y < m_videoList->size(); y++)
00521         {
00522             v = m_videoList->at(y);
00523             if (v->filename == a->filename)
00524             {
00525                 if (m_selectedList.indexOf(v) == -1)
00526                     m_selectedList.append(v);
00527                 break;
00528             }
00529         }
00530     }
00531 }
00532 
00533 void VideoSelector::setParentalLevel(ParentalLevel::Level level)
00534 {
00535     m_parentalLevelChecker->Check(m_currentParentalLevel, level);
00536 }
00537 
00538 void VideoSelector::parentalLevelChanged(bool passwordValid, ParentalLevel::Level newLevel)
00539 {
00540     if (passwordValid)
00541     {
00542         m_currentParentalLevel = newLevel;
00543         updateVideoList();
00544         m_plText->SetText(QString::number(newLevel));
00545     }
00546     else
00547         ShowOkPopup(tr("You need to enter a valid password for this parental level"));
00548 }
00549 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends