2 #include "playlist/PrettyItemDelegate.h"
3 #include "networkaccess.h"
4 #include "videowidget.h"
5 #include "minisplitter.h"
8 QMap<QString, QAction*>* globalActions();
9 QMap<QString, QMenu*>* globalMenus();
10 QNetworkAccessManager* networkAccessManager();
13 MediaView::MediaView(QWidget *parent) : QWidget(parent) {
15 QBoxLayout *layout = new QHBoxLayout();
18 splitter = new MiniSplitter(this);
19 splitter->setChildrenCollapsible(false);
20 // splitter->setBackgroundRole(QPalette::Text);
21 // splitter->setAutoFillBackground(true);
23 sortBar = new THBlackBar(this);
24 mostRelevantAction = new THAction(tr("Most relevant"), this);
25 connect(mostRelevantAction, SIGNAL(triggered()), this, SLOT(searchMostRelevant()), Qt::QueuedConnection);
26 sortBar->addAction(mostRelevantAction);
27 mostRecentAction = new THAction(tr("Most recent"), this);
28 connect(mostRecentAction, SIGNAL(triggered()), this, SLOT(searchMostRecent()), Qt::QueuedConnection);
29 sortBar->addAction(mostRecentAction);
30 mostViewedAction = new THAction(tr("Most viewed"), this);
31 connect(mostViewedAction, SIGNAL(triggered()), this, SLOT(searchMostViewed()), Qt::QueuedConnection);
32 sortBar->addAction(mostViewedAction);
34 listView = new QListView(this);
35 listView->setItemDelegate(new Playlist::PrettyItemDelegate(this));
36 listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
39 listView->setDragEnabled(true);
40 listView->setAcceptDrops(true);
41 listView->setDropIndicatorShown(true);
42 listView->setDragDropMode(QAbstractItemView::InternalMove);
45 listView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
46 listView->setFrameShape( QFrame::NoFrame );
47 listView->setAttribute(Qt::WA_MacShowFocusRect, false);
48 listView->setMinimumSize(320,240);
50 // respond to the user doubleclicking a playlist item
51 connect(listView, SIGNAL(activated(const QModelIndex &)), this, SLOT(itemActivated(const QModelIndex &)));
53 listModel = new ListModel(this);
54 connect(listModel, SIGNAL(activeRowChanged(int)), this, SLOT(activeRowChanged(int)));
55 // needed to restore the selection after dragndrop
56 connect(listModel, SIGNAL(needSelectionFor(QList<Video*>)), this, SLOT(selectVideos(QList<Video*>)));
57 listView->setModel(listModel);
59 connect(listView->selectionModel(),
60 SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & )),
61 this, SLOT(selectionChanged ( const QItemSelection & , const QItemSelection & )));
63 playlistWidget = new PlaylistWidget(this, sortBar, listView);
65 splitter->addWidget(playlistWidget);
67 videoWidget = new VideoWidget(this);
68 videoWidget->setMinimumSize(320,240);
69 splitter->addWidget(videoWidget);
70 // expand video by default
71 // splitter->setStretchFactor (1, 2);
73 layout->addWidget(splitter);
77 MediaView::~MediaView() {
81 void MediaView::initialize() {
82 connect(videoWidget, SIGNAL(doubleClicked()), The::globalActions()->value("fullscreen"), SLOT(trigger()));
83 videoWidget->setContextMenuPolicy(Qt::CustomContextMenu);
84 connect(videoWidget, SIGNAL(customContextMenuRequested(QPoint)),
85 this, SLOT(showVideoContextMenu(QPoint)));
88 void MediaView::setMediaObject(Phonon::MediaObject *mediaObject) {
89 this->mediaObject = mediaObject;
90 Phonon::createPath(this->mediaObject, videoWidget);
91 // connect(mediaObject, SIGNAL(aboutToFinish()), this, SLOT(aboutToFinish()));
92 connect(mediaObject, SIGNAL(finished()), this, SLOT(skip()));
93 connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
94 this, SLOT(stateChanged(Phonon::State, Phonon::State)));
95 connect(mediaObject, SIGNAL(currentSourceChanged(Phonon::MediaSource)),
96 this, SLOT(currentSourceChanged(Phonon::MediaSource)));
97 // connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
100 void MediaView::search(SearchParams *searchParams) {
101 this->searchParams = searchParams;
103 // this implies that the enum and the bar action order is the same
104 sortBar->setCheckedAction(searchParams->sortBy()-1);
106 listModel->search(searchParams);
107 listView->setFocus();
110 void MediaView::disappear() {
114 void MediaView::stateChanged(Phonon::State newState, Phonon::State /* oldState */)
118 case Phonon::ErrorState:
119 qDebug() << "Phonon error:" << mediaObject->errorString() << mediaObject->errorType();
120 // recover from errors by skipping to the next video
124 case Phonon::PlayingState:
128 case Phonon::StoppedState:
130 // Play() has already been called when setting the source
131 // but Phonon on Linux needs a little more help to start playback
135 case Phonon::PausedState:
139 case Phonon::BufferingState:
143 case Phonon::LoadingState:
152 void MediaView::pause() {
153 switch( mediaObject->state() ) {
154 case Phonon::PlayingState:
155 mediaObject->pause();
163 void MediaView::fullscreen() {
166 splitterState = splitter->saveState();
167 videoWidget->setParent(0);
168 videoWidget->showFullScreen();
170 videoWidget->setFullScreen(!videoWidget->isFullScreen());
175 void MediaView::exitFullscreen() {
178 videoWidget->setParent(this);
179 splitter->addWidget(videoWidget);
180 videoWidget->showNormal();
181 splitter->restoreState(splitterState);
183 videoWidget->setFullScreen(false);
188 void MediaView::stop() {
189 listModel->abortSearch();
191 mediaObject->clear();
194 void MediaView::activeRowChanged(int row) {
195 Video *video = listModel->videoAt(row);
197 QUrl streamUrl = video->streamUrl();
198 // qDebug() << "setCurrentSource" << streamUrl.toString();
201 mediaObject->setCurrentSource(streamUrl);
204 // ensure we always have 10 videos ahead
205 listModel->searchNeeded();
207 // ensure active item is visible
208 QModelIndex index = listModel->index(row, 0, QModelIndex());
209 listView->scrollTo(index, QAbstractItemView::EnsureVisible);
212 void MediaView::itemActivated(const QModelIndex &index) {
213 if (listModel->rowExists(index.row()))
214 listModel->setActiveRow(index.row());
215 // the user doucleclicked on the "Search More" item
216 else listModel->searchMore();
219 void MediaView::aboutToFinish() {
221 int nextRow = listModel->nextRow();
222 if (nextRow == -1) return;
223 Video* video = listModel->videoAt(nextRow);
224 QUrl streamUrl = video->streamUrl();
225 qDebug() << "Enqueing" << streamUrl;
226 mediaObject->enqueue(streamUrl);
230 void MediaView::currentSourceChanged(const Phonon::MediaSource source) {
231 qDebug() << "Source changed:" << source.url();
234 void MediaView::skip() {
235 int nextRow = listModel->nextRow();
236 if (nextRow == -1) return;
237 listModel->setActiveRow(nextRow);
240 void MediaView::openWebPage() {
241 Video* video = listModel->activeVideo();
243 mediaObject->pause();
244 QDesktopServices::openUrl(video->webpage());
247 void MediaView::removeSelected() {
248 if (!listView->selectionModel()->hasSelection()) return;
249 QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
250 listModel->removeIndexes(indexes);
253 void MediaView::selectVideos(QList<Video*> videos) {
254 foreach (Video *video, videos) {
255 QModelIndex index = listModel->indexForVideo(video);
256 listView->selectionModel()->select(index, QItemSelectionModel::Select);
257 listView->scrollTo(index, QAbstractItemView::EnsureVisible);
261 void MediaView::selectionChanged(const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/) {
262 const bool gotSelection = listView->selectionModel()->hasSelection();
263 The::globalActions()->value("remove")->setEnabled(gotSelection);
264 The::globalActions()->value("moveUp")->setEnabled(gotSelection);
265 The::globalActions()->value("moveDown")->setEnabled(gotSelection);
268 void MediaView::moveUpSelected() {
269 if (!listView->selectionModel()->hasSelection()) return;
270 QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
271 listModel->move(indexes, true);
274 void MediaView::moveDownSelected() {
275 if (!listView->selectionModel()->hasSelection()) return;
276 QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
277 listModel->move(indexes, false);
280 void MediaView::showVideoContextMenu(QPoint point) {
281 The::globalMenus()->value("video")->popup(videoWidget->mapToGlobal(point));
284 void MediaView::searchMostRelevant() {
285 searchParams->setSortBy(SearchParams::SortByRelevance);
286 search(searchParams);
289 void MediaView::searchMostRecent() {
290 searchParams->setSortBy(SearchParams::SortByNewest);
291 search(searchParams);
294 void MediaView::searchMostViewed() {
295 searchParams->setSortBy(SearchParams::SortByViewCount);
296 search(searchParams);