2 #include "videomimedata.h"
5 static const QString recentKeywordsKey = "recentKeywords";
7 ListModel::ListModel(QWidget *parent) : QAbstractListModel(parent) {
16 ListModel::~ListModel() {
20 int ListModel::rowCount(const QModelIndex &/*parent*/) const {
21 int count = videos.size();
23 // add the message item
24 if (videos.isEmpty() || !searching)
30 QVariant ListModel::data(const QModelIndex &index, int role) const {
32 int row = index.row();
34 if (row == videos.size()) {
38 boldFont.setBold(true);
42 return ItemTypeShowMore;
44 case Qt::StatusTipRole:
45 if (searching) return tr("Searching...");
46 if (canSearchMore) return tr("Show %1 More").arg(MAX_ITEMS);
47 if (videos.isEmpty()) return tr("No videos");
48 else return tr("No more videos");
49 case Qt::TextAlignmentRole:
50 return QVariant(int(Qt::AlignHCenter | Qt::AlignVCenter));
51 case Qt::ForegroundRole:
52 return palette.color(QPalette::Dark);
59 } else if (row < 0 || row >= videos.size())
62 Video *video = videos.at(row);
68 return QVariant::fromValue(QPointer<Video>(video));
70 return video == m_activeVideo;
72 case Qt::StatusTipRole:
73 return video->title();
78 if (!element.firstChildElement().text().isEmpty()) {
79 tooltip.append(QString("<b>").append(element.firstChildElement().text()).append("</b><br/>"));
81 if (!fromDate.isEmpty()) {
82 tooltip.append("<i>Pubblicato il</i> ").append(fromDate);
84 if (!toDate.isEmpty()) {
85 tooltip.append("<br/><i>Scadenza</i>: ").append(toDate);
87 tooltip.append("<br/><i>Tipo</i>: ").append(typeName)
88 .append("<br/><i>Id</i>: ").appen QFont boldFont;
89 boldFont.setBold(true);d(id);
93 // case StreamUrlRole:
94 // return video->streamUrl();
100 void ListModel::setActiveRow( int row) {
101 if ( rowExists( row ) ) {
104 m_activeVideo = videoAt(row);
106 // setStateOfRow( row, Item::Played );
108 int oldactiverow = m_activeRow;
110 if ( rowExists( oldactiverow ) )
111 emit dataChanged( createIndex( oldactiverow, 0 ), createIndex( oldactiverow, columnCount() - 1 ) );
113 emit dataChanged( createIndex( m_activeRow, 0 ), createIndex( m_activeRow, columnCount() - 1 ) );
114 emit activeRowChanged(row);
123 int ListModel::nextRow() const {
124 int nextRow = m_activeRow + 1;
125 if (rowExists(nextRow))
130 Video* ListModel::videoAt( int row ) const {
131 if ( rowExists( row ) )
132 return videos.at( row );
136 Video* ListModel::activeVideo() const {
137 return m_activeVideo;
140 void ListModel::search(SearchParams *searchParams) {
142 // delete current videos
143 while (!videos.isEmpty())
144 delete videos.takeFirst();
150 // (re)initialize the YouTubeSearch
151 if (youtubeSearch) delete youtubeSearch;
152 youtubeSearch = new YouTubeSearch();
153 connect(youtubeSearch, SIGNAL(gotVideo(Video*)), this, SLOT(addVideo(Video*)));
154 connect(youtubeSearch, SIGNAL(finished(int)), this, SLOT(searchFinished(int)));
156 this->searchParams = searchParams;
158 youtubeSearch->search(searchParams, MAX_ITEMS, skip);
162 void ListModel::searchMore(int max) {
163 if (searching) return;
165 youtubeSearch->search(searchParams, max, skip);
169 void ListModel::searchMore() {
170 searchMore(MAX_ITEMS);
173 void ListModel::searchNeeded() {
174 int remainingRows = videos.size() - m_activeRow;
175 int rowsNeeded = MAX_ITEMS - remainingRows;
177 searchMore(rowsNeeded);
180 void ListModel::abortSearch() {
181 while (!videos.isEmpty())
182 delete videos.takeFirst();
184 youtubeSearch->abort();
188 void ListModel::searchFinished(int total) {
190 canSearchMore = total > 0;
192 // update the message item
193 emit dataChanged( createIndex( MAX_ITEMS, 0 ), createIndex( MAX_ITEMS, columnCount() - 1 ) );
196 void ListModel::addVideo(Video* video) {
198 connect(video, SIGNAL(gotThumbnail()), this, SLOT(updateThumbnail()));
200 beginInsertRows(QModelIndex(), videos.size(), videos.size());
205 if (videos.size() == 1) {
210 QString query = searchParams->keywords();
212 QStringList keywords = settings.value(recentKeywordsKey).toStringList();
213 keywords.removeAll(query);
214 keywords.prepend(query);
215 while (keywords.size() > 10)
216 keywords.removeLast();
217 settings.setValue(recentKeywordsKey, keywords);
222 void ListModel::updateThumbnail() {
224 Video *video = static_cast<Video *>(sender());
226 qDebug() << "Cannot get sender";
230 int row = rowForVideo(video);
231 emit dataChanged( createIndex( row, 0 ), createIndex( row, columnCount() - 1 ) );
238 * This function does not free memory
240 bool ListModel::removeRows(int position, int rows, const QModelIndex & /*parent*/) {
241 beginRemoveRows(QModelIndex(), position, position+rows-1);
242 for (int row = 0; row < rows; ++row) {
243 videos.removeAt(position);
249 void ListModel::removeIndexes(QModelIndexList &indexes) {
250 QList<Video*> originalList(videos);
251 QList<Video*> delitems;
252 foreach (QModelIndex index, indexes) {
253 Video* video = originalList.at(index.row());
254 int idx = videos.indexOf(video);
256 beginRemoveRows(QModelIndex(), idx, idx);
257 delitems.append(video);
258 videos.removeAll(video);
263 qDeleteAll(delitems);
267 // --- Sturm und drang ---
271 Qt::DropActions ListModel::supportedDropActions() const {
272 return Qt::MoveAction;
275 Qt::ItemFlags ListModel::flags(const QModelIndex &index) const {
276 Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
278 if (index.isValid()) {
279 if (index.row() == videos.size()) {
280 // don't drag the "show 10 more" item
283 return ( defaultFlags | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled );
285 return Qt::ItemIsDropEnabled | defaultFlags;
288 QStringList ListModel::mimeTypes() const {
290 types << "application/x-minitube-video";
294 QMimeData* ListModel::mimeData( const QModelIndexList &indexes ) const {
295 VideoMimeData* mime = new VideoMimeData();
297 foreach( const QModelIndex &it, indexes ) {
299 if (row >= 0 && row < videos.size())
300 mime->addVideo( videos.at( it.row() ) );
306 bool ListModel::dropMimeData(const QMimeData *data,
307 Qt::DropAction action, int row, int column,
308 const QModelIndex &parent) {
309 if (action == Qt::IgnoreAction)
312 if (!data->hasFormat("application/x-minitube-video"))
321 else if (parent.isValid())
322 beginRow = parent.row();
324 beginRow = rowCount(QModelIndex());
326 const VideoMimeData* videoMimeData = dynamic_cast<const VideoMimeData*>( data );
327 if(!videoMimeData ) return false;
329 QList<Video*> droppedVideos = videoMimeData->videos();
330 foreach( Video *video, droppedVideos) {
333 int videoRow = videos.indexOf(video);
334 removeRows(videoRow, 1, QModelIndex());
336 // and then add them again at the new position
337 beginInsertRows(QModelIndex(), beginRow, beginRow);
338 videos.insert(beginRow, video);
343 // fix m_activeRow after all this
344 m_activeRow = videos.indexOf(m_activeVideo);
346 // let the MediaView restore the selection
347 emit needSelectionFor(droppedVideos);
353 int ListModel::rowForVideo(Video* video) {
354 return videos.indexOf(video);
357 QModelIndex ListModel::indexForVideo(Video* video) {
358 return createIndex(videos.indexOf(video), 0);
361 void ListModel::move(QModelIndexList &indexes, bool up) {
363 QList<Video*> movedVideos;
365 foreach (QModelIndex index, indexes) {
366 int row = index.row();
367 qDebug() << "index row" << row;
368 Video *video = videoAt(row);
369 movedVideos << video;
373 foreach (Video *video, movedVideos) {
375 int row = rowForVideo(video);
376 qDebug() << "video row" << row;
377 removeRows(row, 1, QModelIndex());
382 beginInsertRows(QModelIndex(), row, row);
383 videos.insert(row, video);
389 emit needSelectionFor(movedVideos);