00001 #include <qpixmap.h>
00002 #include <unistd.h>
00003 #include <algorithm>
00004
00005 #include <mythtv/mythcontext.h>
00006 #include <mythtv/xmlparse.h>
00007
00008 #include "metadata.h"
00009 #include "videobrowser.h"
00010
00011 #include "videofilter.h"
00012 #include "videolist.h"
00013 #include "videoutils.h"
00014 #include "imagecache.h"
00015 #include "parentalcontrols.h"
00016
00017 namespace
00018 {
00019 int limit_upper(int value, int max)
00020 {
00021 return std::min(value, max);
00022 }
00023 };
00024
00025 VideoBrowser::VideoBrowser(MythMainWindow *lparent, const QString &lname,
00026 VideoList *video_list) :
00027 VideoDialog(DLG_BROWSER, lparent, "browser", lname, video_list),
00028 inData(0), m_state(0)
00029 {
00030 setFlatList(true);
00031
00032 setFileBrowser(gContext->GetNumSetting("VideoBrowserNoDB", 0));
00033 loadWindow(xmldata);
00034 bgTransBackup.reset(gContext->LoadScalePixmap("trans-backup.png"));
00035
00036 if (!bgTransBackup.get())
00037 bgTransBackup.reset(new QPixmap());
00038
00039 setNoErase();
00040
00041 fetchVideos();
00042 updateBackground();
00043 }
00044
00045 VideoBrowser::~VideoBrowser()
00046 {
00047 }
00048
00049 void VideoBrowser::slotParentalLevelChanged()
00050 {
00051 LayerSet *container = theme->GetSet("browsing");
00052 if (container)
00053 {
00054 checkedSetText(container, "pl_value",
00055 QString::number(currentParentalLevel->GetLevel()));
00056 }
00057 }
00058
00059 void VideoBrowser::keyPressEvent(QKeyEvent *e)
00060 {
00061 bool handled = false;
00062 QStringList actions;
00063
00064 gContext->GetMainWindow()->TranslateKeyPress("Video", e, actions);
00065 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00066 {
00067 QString action = actions[i];
00068 handled = true;
00069
00070 if ((action == "SELECT" || action == "PLAY") && curitem)
00071 playVideo(curitem);
00072 else if (action == "INFO")
00073 doMenu(true);
00074 else if (action == "DOWN")
00075 jumpSelection(1);
00076 else if (action == "UP")
00077 jumpSelection(-1);
00078 else if (action == "PAGEDOWN")
00079 jumpSelection(limit_upper(m_video_list->count() / 5, 25));
00080 else if (action == "PAGEUP")
00081 jumpSelection(-limit_upper(m_video_list->count() / 5, 25));
00082 else if (action == "LEFT")
00083 cursorLeft();
00084 else if (action == "RIGHT")
00085 cursorRight();
00086 else if (action == "HOME")
00087 jumpToSelection(0);
00088 else if (action == "END")
00089 jumpToSelection(m_video_list->count() - 1);
00090 else if (action == "INCPARENT")
00091 shiftParental(1);
00092 else if (action == "DECPARENT")
00093 shiftParental(-1);
00094 else if (action == "1" || action == "2" ||
00095 action == "3" || action == "4")
00096 setParentalLevel(ParentalLevel(action.toInt()));
00097 else if (action == "FILTER")
00098 slotDoFilter();
00099 else if (action == "MENU")
00100 doMenu(false);
00101 else
00102 handled = false;
00103 }
00104
00105 if (!handled)
00106 {
00107 gContext->GetMainWindow()->TranslateKeyPress("TV Frontend", e, actions);
00108
00109 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00110 {
00111 QString action = actions[i];
00112 if (action == "PLAYBACK")
00113 {
00114 handled = true;
00115 slotWatchVideo();
00116 }
00117 }
00118 }
00119
00120 if (!handled)
00121 MythDialog::keyPressEvent(e);
00122 }
00123
00124 void VideoBrowser::doMenu(bool info)
00125 {
00126 if (createPopup())
00127 {
00128 QButton *focusButton = NULL;
00129 if (info)
00130 {
00131 focusButton = popup->addButton(tr("Watch This Video"), this,
00132 SLOT(slotWatchVideo()));
00133 popup->addButton(tr("View Full Plot"), this, SLOT(slotViewPlot()));
00134 popup->addButton(tr("View Cast"), this, SLOT(slotViewCast()));
00135 }
00136 else
00137 {
00138 focusButton = popup->addButton(tr("Filter Display"), this,
00139 SLOT(slotDoFilter()));
00140 AddPopupViews();
00141 }
00142
00143 popup->addButton(tr("Cancel"), this, SLOT(slotDoCancel()));
00144
00145 popup->ShowPopup(this, SLOT(slotDoCancel()));
00146
00147 if (focusButton)
00148 focusButton->setFocus();
00149 }
00150 }
00151
00152 void VideoBrowser::fetchVideos()
00153 {
00154 VideoDialog::fetchVideos();
00155
00156 SetCurrentItem(0);
00157 update(infoRect);
00158 update(browsingRect);
00159 repaint();
00160 }
00161
00162 void VideoBrowser::paintEvent(QPaintEvent *e)
00163 {
00164 QRect r = e->rect();
00165 QPainter p(this);
00166 if (m_state == 0)
00167 {
00168 if (r.intersects(infoRect) && allowPaint == true)
00169 {
00170 updateInfo(&p);
00171 }
00172 if (r.intersects(browsingRect) && allowPaint == true)
00173 {
00174 updateBrowsing(&p);
00175 }
00176 }
00177 else if (m_state > 0)
00178 {
00179 allowPaint = false;
00180 updatePlayWait(&p);
00181 }
00182 }
00183
00184 void VideoBrowser::updatePlayWait(QPainter *p)
00185 {
00186 if (m_state < 4)
00187 {
00188 LayerSet *container = theme->GetSet("playwait");
00189 if (container)
00190 {
00191 QRect area = container->GetAreaRect();
00192 if (area.isValid())
00193 {
00194 QPixmap pix(area.size());
00195 pix.fill(this, area.topLeft());
00196 QPainter tmp(&pix);
00197
00198 for (int i = 0; i < 4; ++i)
00199 container->Draw(&tmp, i, 0);
00200
00201 tmp.end();
00202
00203 p->drawPixmap(area.topLeft(), pix);
00204 }
00205 else
00206 {
00207 VERBOSE(VB_IMPORTANT,
00208 QObject::tr("Theme Error: browser/playwait "
00209 "has an invalid area."));
00210 }
00211 }
00212
00213 m_state++;
00214 update(fullRect);
00215 }
00216 else if (m_state == 4)
00217 {
00218 allowPaint = true;
00219 update(fullRect);
00220 }
00221 }
00222
00223 void VideoBrowser::SetCurrentItem(unsigned int index)
00224 {
00225 curitem = NULL;
00226
00227 unsigned int list_count = m_video_list->count();
00228
00229 if (list_count == 0)
00230 return;
00231
00232 inData = QMIN(list_count - 1, index);
00233 curitem = m_video_list->getVideoListMetadata(inData);
00234 }
00235
00236 void VideoBrowser::updateBrowsing(QPainter *p)
00237 {
00238 QRect pr = browsingRect;
00239 QPixmap pix(pr.size());
00240 pix.fill(this, pr.topLeft());
00241 QPainter tmp(&pix);
00242 unsigned int list_count = m_video_list->count();
00243
00244 QString vidnum;
00245 if (list_count > 0)
00246 vidnum = QString(tr("%1 of %2")).arg(inData + 1).arg(list_count);
00247 else
00248 vidnum = tr("No Videos");
00249
00250 LayerSet *container = theme->GetSet("browsing");
00251 if (container)
00252 {
00253 checkedSetText(container, "currentvideo", vidnum);
00254
00255 checkedSetText(container, "pl_value",
00256 QString::number(currentParentalLevel->GetLevel()));
00257
00258 for (int i = 1; i < 9; ++i)
00259 container->Draw(&tmp, i, 0);
00260 }
00261 tmp.end();
00262 p->drawPixmap(pr.topLeft(), pix);
00263 }
00264
00265 void VideoBrowser::updateInfo(QPainter *p)
00266 {
00267 if (m_video_list->count() > 0 && curitem)
00268 {
00269 LayerSet *container = theme->GetSet("info");
00270 if (container)
00271 {
00272 QRect pr = infoRect;
00273 QPixmap pix(pr.size());
00274 pix.fill(this, pr.topLeft());
00275 QPainter tmp(&pix);
00276
00277 checkedSetText(container, "title", curitem->Title());
00278 checkedSetText(container, "filename", curitem->Filename());
00279 checkedSetText(container, "video_player",
00280 Metadata::getPlayer(curitem));
00281
00282 QString coverfile = curitem->CoverFile();
00283 UIImageType *itype = (UIImageType *)container->GetType("coverart");
00284 if (itype)
00285 {
00286 if (isDefaultCoverFile(coverfile))
00287 {
00288 if (itype->isShown())
00289 itype->hide();
00290 }
00291 else
00292 {
00293 QSize img_size = itype->GetSize(true);
00294 const QPixmap *img =
00295 ImageCache::getImageCache().load(coverfile,
00296 img_size.width(),
00297 img_size.height(),
00298 QImage::ScaleFree);
00299 if (img)
00300 {
00301 if (itype->GetImage().serialNumber() !=
00302 img->serialNumber())
00303 {
00304 itype->SetImage(*img);
00305 }
00306 if (itype->isHidden())
00307 itype->show();
00308 }
00309 else
00310 {
00311 if (itype->isShown())
00312 itype->hide();
00313 }
00314 }
00315 }
00316
00317 checkedSetText(container, "director", curitem->Director());
00318 checkedSetText(container, "plot", curitem->Plot());
00319 checkedSetText(container, "cast", GetCast(*curitem));
00320 checkedSetText(container, "rating",
00321 getDisplayRating(curitem->Rating()));
00322 checkedSetText(container, "inetref", curitem->InetRef());
00323 checkedSetText(container, "year", getDisplayYear(curitem->Year()));
00324 checkedSetText(container, "userrating",
00325 getDisplayUserRating(curitem->UserRating()));
00326 checkedSetText(container, "length",
00327 getDisplayLength(curitem->Length()));
00328 checkedSetText(container, "coverfile", coverfile);
00329 checkedSetText(container, "child_id",
00330 QString::number(curitem->ChildID()));
00331 checkedSetText(container, "browseable",
00332 getDisplayBrowse(curitem->Browse()));
00333 checkedSetText(container, "category", curitem->Category());
00334 checkedSetText(container, "level",
00335 QString::number(curitem->ShowLevel()));
00336
00337 for (int i = 1; i < 9; ++i)
00338 container->Draw(&tmp, i, 0);
00339
00340 tmp.end();
00341 p->drawPixmap(pr.topLeft(), pix);
00342 }
00343 }
00344 else
00345 {
00346 LayerSet *norec = theme->GetSet("novideos_info");
00347 if (norec)
00348 {
00349 QRect pr = norec->GetAreaRect();
00350 if (pr.isValid())
00351 {
00352 QPixmap pix(pr.size());
00353 pix.fill(this, pr.topLeft());
00354 QPainter tmp(&pix);
00355
00356 for (int i = 1; i <= 9; ++i)
00357 {
00358 norec->Draw(&tmp, i, 0);
00359 }
00360
00361 tmp.end();
00362
00363 p->drawPixmap(pr.topLeft(), pix);
00364 }
00365 else
00366 {
00367 VERBOSE(VB_IMPORTANT,
00368 QObject::tr("Theme Error: browser/novideos_info "
00369 "has an invalid area."));
00370 }
00371 }
00372 }
00373 }
00374
00375 void VideoBrowser::jumpToSelection(int index)
00376 {
00377 SetCurrentItem(index);
00378 update(infoRect);
00379 update(browsingRect);
00380 }
00381
00382 void VideoBrowser::jumpSelection(int amount)
00383 {
00384 unsigned int list_count = m_video_list->count();
00385
00386 if (list_count == 0)
00387 return;
00388
00389 int index;
00390
00391 if (amount >= 0 || inData >= (unsigned int)-amount)
00392 index = (inData + amount) % list_count;
00393 else
00394 index = list_count + amount + inData;
00395
00396 jumpToSelection(index);
00397 }
00398
00399 void VideoBrowser::cursorLeft()
00400 {
00401 exitWin();
00402 }
00403
00404 void VideoBrowser::cursorRight()
00405 {
00406 doMenu();
00407 }
00408
00409 void VideoBrowser::parseContainer(QDomElement &element)
00410 {
00411 QRect area;
00412 QString container_name;
00413 int context;
00414 theme->parseContainer(element, container_name, context, area);
00415
00416 container_name = container_name.lower();
00417 if (container_name == "info")
00418 infoRect = area;
00419 if (container_name == "browsing")
00420 browsingRect = area;
00421 }