namespace The {
NetworkAccess* http();
-QMap<QString, QAction*>* globalActions();
+QHash<QString, QAction*>* globalActions();
QMap<QString, QMenu*>* globalMenus();
QNetworkAccessManager* networkAccessManager();
}
searchParams->keywords().startsWith("https://")) {
QString videoId = YTSearch::videoIdFromUrl(searchParams->keywords());
if (!videoId.isEmpty()) {
- qDebug() << "single video";
YTSingleVideoSource *singleVideoSource = new YTSingleVideoSource(this);
singleVideoSource->setVideoId(videoId);
setVideoSource(singleVideoSource);
SearchParams *searchParams = getSearchParams();
bool isChannel = searchParams && !searchParams->author().isEmpty();
playlistView->setClickableAuthors(!isChannel);
+
+ The::globalActions()->value("related-videos")->setEnabled(true);
}
void MediaView::searchAgain() {
}
}
+Video* MediaView::getCurrentVideo() {
+ Video *currentVideo = 0;
+ if (downloadItem)
+ currentVideo = downloadItem->getVideo();
+ return currentVideo;
+}
+
void MediaView::activeRowChanged(int row) {
if (reallyStopped) return;
Video *video = playlistModel->videoAt(row);
if (!video) return;
- // Do not stop/start playing if the first video result is the current video
- if (row == 0 && !history.isEmpty()) {
- Video *currentVideo = 0;
- if (downloadItem && downloadItem->getVideo())
- currentVideo = downloadItem->getVideo();
- if (currentVideo && playlistModel->videoAt(row)->webpage() == currentVideo->webpage()) {
- The::globalActions()->value("related-videos")->setEnabled(false);
- return;
- }
- }
-
errorTimer->stop();
videoAreaWidget->showLoading(video);
The::globalActions()->value("related-videos")->setEnabled(true);
// see you in gotStreamUrl...
-
}
void MediaView::gotStreamUrl(QUrl streamUrl) {
}
void MediaView::playbackFinished() {
- qDebug() << __PRETTY_FUNCTION__ << mediaObject->currentTime();
- // qDebug() << "finished" << mediaObject->currentTime() << mediaObject->totalTime();
+ const int totalTime = mediaObject->totalTime();
+ const int currentTime = mediaObject->currentTime();
+ qDebug() << __PRETTY_FUNCTION__ << mediaObject->currentTime() << totalTime;
// add 10 secs for imprecise Phonon backends (VLC, Xine)
- if (mediaObject->currentTime() + 10000 < mediaObject->totalTime()) {
- // mediaObject->seek(mediaObject->currentTime());
+ if (currentTime > 0 && currentTime + 10000 < totalTime) {
+ // mediaObject->seek(currentTime);
QTimer::singleShot(500, this, SLOT(playbackResume()));
} else {
QAction* stopAfterThisAction = The::globalActions()->value("stopafterthis");
YTSingleVideoSource *singleVideoSource = new YTSingleVideoSource();
singleVideoSource->setVideoId(video->id());
setVideoSource(singleVideoSource);
+ The::globalActions()->value("related-videos")->setEnabled(false);
}
void MediaView::shareViaTwitter() {
#include "ytsearch.h"
#include "video.h"
#include "searchparams.h"
+#include "mediaview.h"
static const int maxItems = 10;
static const QString recentKeywordsKey = "recentKeywords";
videoSource = 0;
searching = false;
canSearchMore = true;
+ firstSearch = false;
m_activeVideo = 0;
m_activeRow = -1;
skip = 1;
max = 0;
-
hoveredRow = -1;
authorHovered = false;
authorPressed = false;
return QVariant();
}
-void PlaylistModel::setActiveRow( int row) {
+void PlaylistModel::setActiveRow(int row, bool notify) {
if ( rowExists( row ) ) {
m_activeRow = row;
emit dataChanged( createIndex( oldactiverow, 0 ), createIndex( oldactiverow, columnCount() - 1 ) );
emit dataChanged( createIndex( m_activeRow, 0 ), createIndex( m_activeRow, columnCount() - 1 ) );
- emit activeRowChanged(row);
+ if (notify) emit activeRowChanged(row);
} else {
m_activeRow = -1;
reset();
this->videoSource = videoSource;
- connect(videoSource, SIGNAL(gotVideo(Video*)),
- SLOT(addVideo(Video*)), Qt::UniqueConnection);
+ connect(videoSource, SIGNAL(gotVideos(QList<Video*>)),
+ SLOT(addVideos(QList<Video*>)), Qt::UniqueConnection);
connect(videoSource, SIGNAL(finished(int)),
SLOT(searchFinished(int)), Qt::UniqueConnection);
connect(videoSource, SIGNAL(error(QString)),
void PlaylistModel::searchMore(int max) {
if (searching) return;
searching = true;
+ firstSearch = skip == 1;
this->max = max;
errorMessage.clear();
videoSource->loadVideos(max, skip);
if (!videoSource->getSuggestions().isEmpty())
emit haveSuggestions(videoSource->getSuggestions());
+
+ if (firstSearch && !videos.isEmpty())
+ handleFirstVideo(videos.first());
}
void PlaylistModel::searchError(QString message) {
emit dataChanged( createIndex( maxItems, 0 ), createIndex( maxItems, columnCount() - 1 ) );
}
-void PlaylistModel::addVideo(Video* video) {
-
- connect(video, SIGNAL(gotThumbnail()), SLOT(updateThumbnail()), Qt::UniqueConnection);
- video->loadThumbnail();
+void PlaylistModel::addVideos(QList<Video*> newVideos) {
+ if (newVideos.isEmpty()) return;
+
+ bool isFirstVideo = videos.isEmpty();
- beginInsertRows(QModelIndex(), videos.size(), videos.size());
- videos << video;
+ beginInsertRows(QModelIndex(), videos.size(), videos.size() + newVideos.size() - 1);
+ videos.append(newVideos);
endInsertRows();
-
- // first result!
- if (videos.size() == 1) {
- // manualplay
+ foreach (Video* video, newVideos) {
+ connect(video, SIGNAL(gotThumbnail()),
+ SLOT(updateThumbnail()), Qt::UniqueConnection);
+ video->loadThumbnail();
+ }
+
+ // if (isFirstVideo) handleFirstVideo(newVideos.first());
+}
+
+void PlaylistModel::handleFirstVideo(Video *video) {
+
+ int currentVideoRow = rowForCloneVideo(MediaView::instance()->getCurrentVideo());
+ if (currentVideoRow != -1) setActiveRow(currentVideoRow, false);
+ else {
QSettings settings;
if (!settings.value("manualplay", false).toBool())
setActiveRow(0);
+ }
- if (videoSource->metaObject()->className() == QLatin1String("YTSearch")) {
-
- static const int maxRecentElements = 10;
-
- YTSearch *search = dynamic_cast<YTSearch *>(videoSource);
- SearchParams *searchParams = search->getSearchParams();
-
- // save keyword
- QString query = searchParams->keywords();
- if (!query.isEmpty() && !searchParams->isTransient()) {
- if (query.startsWith("http://")) {
- // Save the video title
- query += "|" + videos.first()->title();
- }
- QStringList keywords = settings.value(recentKeywordsKey).toStringList();
- keywords.removeAll(query);
- keywords.prepend(query);
- while (keywords.size() > maxRecentElements)
- keywords.removeLast();
- settings.setValue(recentKeywordsKey, keywords);
- }
+ QSettings settings;
+ if (!settings.value("manualplay", false).toBool()) {
+ int newActiveRow = rowForCloneVideo(MediaView::instance()->getCurrentVideo());
+ if (newActiveRow != -1) setActiveRow(newActiveRow, false);
+ else setActiveRow(0);
+ }
- // save channel
- QString channel = searchParams->author();
- if (!channel.isEmpty() && !searchParams->isTransient()) {
- if (!video->authorUri().isEmpty())
- channel = video->authorUri() + "|" + video->author();
- QStringList channels = settings.value(recentChannelsKey).toStringList();
- channels.removeAll(channel);
- channels.prepend(channel);
- while (channels.size() > maxRecentElements)
- channels.removeLast();
- settings.setValue(recentChannelsKey, channels);
+ if (videoSource->metaObject()->className() == QLatin1String("YTSearch")) {
+
+ static const int maxRecentElements = 10;
+
+ YTSearch *search = dynamic_cast<YTSearch *>(videoSource);
+ SearchParams *searchParams = search->getSearchParams();
+
+ // save keyword
+ QString query = searchParams->keywords();
+ if (!query.isEmpty() && !searchParams->isTransient()) {
+ if (query.startsWith("http://")) {
+ // Save the video title
+ query += "|" + videos.first()->title();
}
+ QStringList keywords = settings.value(recentKeywordsKey).toStringList();
+ keywords.removeAll(query);
+ keywords.prepend(query);
+ while (keywords.size() > maxRecentElements)
+ keywords.removeLast();
+ settings.setValue(recentKeywordsKey, keywords);
}
+ // save channel
+ QString channel = searchParams->author();
+ if (!channel.isEmpty() && !searchParams->isTransient()) {
+ QString value;
+ if (!video->authorUri().isEmpty() && video->authorUri() != video->author())
+ value = video->authorUri() + "|" + video->author();
+ else value = video->author();
+ QStringList channels = settings.value(recentChannelsKey).toStringList();
+ channels.removeAll(value);
+ channels.removeAll(channel);
+ channels.prepend(value);
+ while (channels.size() > maxRecentElements)
+ channels.removeLast();
+ settings.setValue(recentChannelsKey, channels);
+ }
}
-
}
void PlaylistModel::updateThumbnail() {
Qt::DropActions PlaylistModel::supportedDropActions() const {
- return Qt::MoveAction;
+ return Qt::CopyAction;
+}
+
+Qt::DropActions PlaylistModel::supportedDragActions() const {
+ return Qt::CopyAction;
}
Qt::ItemFlags PlaylistModel::flags(const QModelIndex &index) const {
- if (index.isValid())
+ if (index.isValid()) {
if (index.row() == videos.size()) {
// don't drag the "show 10 more" item
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
} else return (Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
+ }
return Qt::ItemIsDropEnabled;
}
}
+int PlaylistModel::rowForCloneVideo(Video *video) const {
+ if (!video) return -1;
+ for (int i = 0; i < videos.size(); ++i) {
+ Video *v = videos.at(i);
+ if (v->id() == video->id()) return i;
+ }
+ return -1;
+}
+
int PlaylistModel::rowForVideo(Video* video) {
return videos.indexOf(video);
}
Qt::ItemFlags flags(const QModelIndex &index) const;
QStringList mimeTypes() const;
Qt::DropActions supportedDropActions() const;
+ Qt::DropActions supportedDragActions() const;
QMimeData* mimeData( const QModelIndexList &indexes ) const;
bool dropMimeData(const QMimeData *data,
Qt::DropAction action, int row, int column,
const QModelIndex &parent);
- void setActiveRow( int row );
+ void setActiveRow(int row , bool notify = true);
bool rowExists( int row ) const { return (( row >= 0 ) && ( row < videos.size() ) ); }
int activeRow() const { return m_activeRow; } // returns -1 if there is no active row
int nextRow() const;
Video* videoAt( int row ) const;
Video* activeVideo() const;
- bool hasVideo(Video *video) const { return videos.contains(video); }
+ int rowForCloneVideo(Video *video) const;
VideoSource* getVideoSource() { return videoSource; }
void setVideoSource(VideoSource *videoSource);
public slots:
void searchMore();
void searchNeeded();
- void addVideo(Video* video);
+ void addVideos(QList<Video*> newVideos);
void searchFinished(int total);
void searchError(QString message);
void updateThumbnail();
void haveSuggestions(const QStringList &suggestions);
private:
+ void handleFirstVideo(Video* video);
void searchMore(int max);
VideoSource *videoSource;
bool searching;
bool canSearchMore;
+ bool firstSearch;
QList<Video*> videos;
int skip;