]> git.sur5r.net Git - minitube/blob - src/MediaView.cpp
Initial import
[minitube] / src / MediaView.cpp
1 #include "MediaView.h"
2 #include "playlist/PrettyItemDelegate.h"
3 #include "networkaccess.h"
4 #include "videowidget.h"
5 #include "minisplitter.h"
6
7 namespace The {
8     QMap<QString, QAction*>* globalActions();
9     QMap<QString, QMenu*>* globalMenus();
10     QNetworkAccessManager* networkAccessManager();
11 }
12
13 MediaView::MediaView(QWidget *parent) : QWidget(parent) {
14
15     QBoxLayout *layout = new QHBoxLayout();
16     layout->setMargin(0);
17
18     splitter = new MiniSplitter(this);
19     splitter->setChildrenCollapsible(false);
20     // splitter->setBackgroundRole(QPalette::Text);
21     // splitter->setAutoFillBackground(true);
22
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);
33
34     listView = new QListView(this);
35     listView->setItemDelegate(new Playlist::PrettyItemDelegate(this));
36     listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
37
38     // dragndrop
39     listView->setDragEnabled(true);
40     listView->setAcceptDrops(true);
41     listView->setDropIndicatorShown(true);
42     listView->setDragDropMode(QAbstractItemView::InternalMove);
43
44     // cosmetics
45     listView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
46     listView->setFrameShape( QFrame::NoFrame );
47     listView->setAttribute(Qt::WA_MacShowFocusRect, false);
48     listView->setMinimumSize(320,240);
49
50     // respond to the user doubleclicking a playlist item
51     connect(listView, SIGNAL(activated(const QModelIndex &)), this, SLOT(itemActivated(const QModelIndex &)));
52
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);
58
59     connect(listView->selectionModel(),
60             SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & )),
61             this, SLOT(selectionChanged ( const QItemSelection & , const QItemSelection & )));
62
63     playlistWidget = new PlaylistWidget(this, sortBar, listView);
64
65     splitter->addWidget(playlistWidget);
66
67     videoWidget = new VideoWidget(this);
68     videoWidget->setMinimumSize(320,240);
69     splitter->addWidget(videoWidget);
70     // expand video by default
71     // splitter->setStretchFactor (1, 2);
72
73     layout->addWidget(splitter);
74     setLayout(layout);
75 }
76
77 MediaView::~MediaView() {
78
79 }
80
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)));
86 }
87
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)));
98 }
99
100 void MediaView::search(SearchParams *searchParams) {
101     this->searchParams = searchParams;
102
103     // this implies that the enum and the bar action order is the same
104     sortBar->setCheckedAction(searchParams->sortBy()-1);
105
106     listModel->search(searchParams);
107     listView->setFocus();
108 }
109
110 void MediaView::disappear() {
111
112 }
113
114 void MediaView::stateChanged(Phonon::State newState, Phonon::State /* oldState */)
115 {
116     switch (newState) {
117
118          case Phonon::ErrorState:
119         qDebug() << "Phonon error:" << mediaObject->errorString() << mediaObject->errorType();
120         // recover from errors by skipping to the next video
121         skip();
122         break;
123
124          case Phonon::PlayingState:
125         qDebug("playing");
126         break;
127
128          case Phonon::StoppedState:
129         qDebug("stopped");
130         // Play() has already been called when setting the source
131         // but Phonon on Linux needs a little more help to start playback
132         mediaObject->play();
133         break;
134
135          case Phonon::PausedState:
136         qDebug("paused");
137         break;
138
139          case Phonon::BufferingState:
140         qDebug("buffering");
141         break;
142
143          case Phonon::LoadingState:
144         qDebug("loading");
145         break;
146
147          default:
148         ;
149     }
150 }
151
152 void MediaView::pause() {
153     switch( mediaObject->state() ) {
154     case Phonon::PlayingState:
155         mediaObject->pause();
156         break;
157     default:
158         mediaObject->play();
159         break;
160     }
161 }
162
163 void MediaView::fullscreen() {
164
165 #ifdef Q_WS_MAC
166     splitterState = splitter->saveState();
167     videoWidget->setParent(0);
168     videoWidget->showFullScreen();
169 #else
170     videoWidget->setFullScreen(!videoWidget->isFullScreen());
171 #endif
172
173 }
174
175 void MediaView::exitFullscreen() {
176
177 #ifdef Q_WS_MAC
178     videoWidget->setParent(this);
179     splitter->addWidget(videoWidget);
180     videoWidget->showNormal();
181     splitter->restoreState(splitterState);
182 #else
183     videoWidget->setFullScreen(false);
184 #endif
185
186 }
187
188 void MediaView::stop() {
189     listModel->abortSearch();
190     mediaObject->stop();
191     mediaObject->clear();
192 }
193
194 void MediaView::activeRowChanged(int row) {
195     Video *video = listModel->videoAt(row);
196     if (!video) return;
197     QUrl streamUrl = video->streamUrl();
198     // qDebug() << "setCurrentSource" << streamUrl.toString();
199
200     // go!
201     mediaObject->setCurrentSource(streamUrl);
202     mediaObject->play();
203
204     // ensure we always have 10 videos ahead
205     listModel->searchNeeded();
206
207     // ensure active item is visible
208     QModelIndex index = listModel->index(row, 0, QModelIndex());
209     listView->scrollTo(index, QAbstractItemView::EnsureVisible);
210 }
211
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();
217 }
218
219 void MediaView::aboutToFinish() {
220     /*
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);
227     */
228 }
229
230 void MediaView::currentSourceChanged(const Phonon::MediaSource source) {
231     qDebug() << "Source changed:" << source.url();
232 }
233
234 void MediaView::skip() {
235     int nextRow = listModel->nextRow();
236     if (nextRow == -1) return;
237     listModel->setActiveRow(nextRow);
238 }
239
240 void MediaView::openWebPage() {
241     Video* video = listModel->activeVideo();
242     if (!video) return;
243     mediaObject->pause();
244     QDesktopServices::openUrl(video->webpage());
245 }
246
247 void MediaView::removeSelected() {
248     if (!listView->selectionModel()->hasSelection()) return;
249     QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
250     listModel->removeIndexes(indexes);
251 }
252
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);
258     }
259 }
260
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);
266 }
267
268 void MediaView::moveUpSelected() {
269     if (!listView->selectionModel()->hasSelection()) return;
270     QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
271     listModel->move(indexes, true);
272 }
273
274 void MediaView::moveDownSelected() {
275     if (!listView->selectionModel()->hasSelection()) return;
276     QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
277     listModel->move(indexes, false);
278 }
279
280 void MediaView::showVideoContextMenu(QPoint point) {
281     The::globalMenus()->value("video")->popup(videoWidget->mapToGlobal(point));
282 }
283
284 void MediaView::searchMostRelevant() {
285     searchParams->setSortBy(SearchParams::SortByRelevance);
286     search(searchParams);
287 }
288
289 void MediaView::searchMostRecent() {
290     searchParams->setSortBy(SearchParams::SortByNewest);
291     search(searchParams);
292 }
293
294 void MediaView::searchMostViewed() {
295     searchParams->setSortBy(SearchParams::SortByViewCount);
296     search(searchParams);
297 }