1 /*****************************************************************************
2 * ml_item.cpp: the media library's result item
3 *****************************************************************************
4 * Copyright (C) 2008-2011 the VideoLAN Team and AUTHORS
7 * Authors: Antoine Lejeune <phytos@videolan.org>
8 * Jean-Philippe André <jpeg@videolan.org>
9 * Rémi Duraffort <ivoire@videolan.org>
10 * Adrien Maglo <magsoft@videolan.org>
11 * Srikanth Raju <srikiraju#gmail#com>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
37 #include "ml_item.hpp"
42 * @brief Compare the attribute 'meta' between medias a and b.
46 * @note If a->meta < b->meta, return -1
47 * If a->meta == b->meta, return 0
48 * If a->meta > b->meta, return +1
49 * @note If a->meta == NULL and b->meta != NULL (strings), then b>a
51 static int compareMeta( ml_media_t *a, ml_media_t *b, ml_select_e meta )
54 # define scomp(c) i_ret = ((a->c&&b->c&&*a->c&&*b->c) ?\
55 strcasecmp(a->c,b->c) : \
56 (a->c&&*a->c?-1:(b->c&&*b->c?1:0))); break;
57 # define icomp(c) i_ret = (a->c<b->c?-1:(a->c==b->c?0:1)); break;
58 if ( a == b ) return 0;
59 vlc_mutex_lock( &a->lock );
60 vlc_mutex_lock( &b->lock );
63 case ML_ALBUM: scomp( psz_album );
64 case ML_ALBUM_ID: icomp( i_album_id );
65 //case ML_ARTIST: scomp( psz_artist );
66 //case ML_ARTIST_ID: icomp( i_artist_id );
67 case ML_COVER: scomp( psz_cover );
68 case ML_DURATION: icomp( i_duration );
69 case ML_EXTRA: scomp( psz_extra );
70 case ML_GENRE: scomp( psz_genre );
71 case ML_ID: icomp( i_id );
72 case ML_LAST_PLAYED: icomp( i_last_played );
73 case ML_ORIGINAL_TITLE: scomp( psz_orig_title );
74 case ML_PLAYED_COUNT: icomp( i_played_count );
76 case ML_SCORE: icomp( i_score );
77 case ML_TITLE: scomp( psz_title );
78 case ML_TRACK_NUMBER: icomp( i_track_number );
79 case ML_TYPE: icomp( i_type );
80 case ML_URI: scomp( psz_uri );
81 case ML_VOTE: icomp( i_vote );
82 case ML_YEAR: icomp( i_year );
88 vlc_mutex_unlock( &a->lock );
89 vlc_mutex_unlock( &b->lock );
94 MLItem::MLItem( intf_thread_t* _p_intf,
98 parentItem = p_parent;
100 ml_gc_incref( p_media );
102 p_ml = ml_Get( _p_intf );
109 ml_gc_decref( this->media );
110 if( !children.isEmpty() )
114 AbstractPLItem* MLItem::child( int row ) const
116 if( row < 0 || row >= childCount() ) return NULL;
117 else return children.at( row );
120 input_item_t* MLItem::inputItem()
122 return ml_CreateInputItem( p_ml, id( MLMEDIA_ID ) );
126 * @brief Get a QVariant representing the data on a column
128 * @return The QVariant may be formed of a int, QString
129 * Use toString() to print it on the screen, except for pixmaps
131 QVariant MLItem::data( ml_select_e columntype ) const
133 ml_person_t *p_people = NULL, *p_person = NULL;
137 #define sget(a) if(media->a) ret = qfu(media->a);
138 #define iget(a) if(media->a) ret = QVariant(media->a);
140 vlc_mutex_lock( &media->lock );
151 vlc_mutex_unlock( &media->lock );
152 p_people = ml_GetPersonsFromMedia( p_ml, media, ML_PERSON_ARTIST );
153 vlc_mutex_lock( &media->lock );
157 if( !EMPTY_STR( p_person->psz_name ) )
159 temp.isEmpty() ? temp = qfu( p_person->psz_name ) :
160 temp.append( "," ).append( qfu( p_person->psz_name ) );
162 p_person = p_person->p_next;
164 ml_FreePeople( p_people );
171 if ( media->i_duration )
172 ret = QTime().addSecs( media->i_duration/1000000 ).toString( "HH:mm:ss" );
184 if( media->i_last_played > 0 )
186 QDateTime time( QDate(1970,1,1) );
187 ret = time.addSecs( qint64( media->i_last_played ) );
190 case ML_ORIGINAL_TITLE:
191 sget( psz_orig_title );
193 case ML_PLAYED_COUNT:
194 iget( i_played_count );
196 // case ML_ROLE: return qtr( "Role" );
198 if ( media->i_score ) iget( i_score );
201 temp = qfu( media->psz_title );
202 /* If no title, return filename */
205 vlc_mutex_unlock( &media->lock );
207 vlc_mutex_lock( &media->lock );
208 if ( uri.scheme() != "file" )
209 ret = QUrl::fromPercentEncoding( uri.toString().toUtf8() );
211 QFileInfo p_file( uri.toLocalFile() );
212 ret = p_file.fileName().isEmpty() ? p_file.absoluteFilePath()
218 case ML_TRACK_NUMBER:
219 if ( media->i_track_number ) iget( i_track_number );
222 if( media->i_type & ML_AUDIO )
224 if( media->i_type & ML_VIDEO )
226 if( media->i_type & ML_STREAM )
228 if( temp.isEmpty() ) temp = "Stream";
229 else temp += " stream";
231 if( media->i_type & ML_REMOVABLE )
233 if( temp.isEmpty() ) temp = "Removable media";
234 else temp += " (removable media)";
236 if( media->i_type & ML_NODE )
238 if( temp.isEmpty() ) temp = "Playlist";
239 else temp += " (Playlist)";
242 temp = qtr( "Unknown" );
249 if ( media->i_vote ) iget( i_vote );
252 if ( media->i_year ) iget( i_year );
258 vlc_mutex_unlock( &media->lock );
265 bool MLItem::setData( ml_select_e meta, const QVariant &data )
267 # define setmeta(a) ml_LockMedia(media); free(media->a); \
268 media->a = strdup( qtu(data.toString()) ); ml_UnlockMedia( media ); \
273 case ML_ALBUM: setmeta( psz_album );
274 case ML_ARTIST: ml_DeletePersonTypeFromMedia( media, ML_PERSON_ARTIST );
275 ml_CreateAppendPersonAdv( &media->p_people,
276 ML_PERSON_ARTIST, (char*)qtu(data.toString()), 0 );
277 return ml_UpdateSimple( p_ml, ML_MEDIA, NULL, id( MLMEDIA_ID ),
278 ML_PEOPLE, ML_PERSON_ARTIST, qtu( data.toString() ) ) == VLC_SUCCESS;
279 case ML_EXTRA: setmeta( psz_extra );
280 case ML_GENRE: setmeta( psz_genre );
281 case ML_ORIGINAL_TITLE: setmeta( psz_orig_title );
282 case ML_TITLE: setmeta( psz_title );
284 Q_ASSERT( qtu( data.toString() ) );
285 return ml_UpdateSimple( p_ml, ML_MEDIA, NULL, id( MLMEDIA_ID ),
286 meta, qtu( data.toString() ) ) == VLC_SUCCESS;
288 /* Modifiable integers */
289 case ML_TRACK_NUMBER:
291 return ml_UpdateSimple( p_ml, ML_MEDIA, NULL, id( MLMEDIA_ID ),
292 meta, data.toInt() ) == VLC_SUCCESS;
294 // TODO case ML_VOTE:
296 /* Non modifiable meta */
303 int MLItem::id( int type )
308 return inputItem()->i_id;
318 ml_media_t* MLItem::getMedia() const
323 QUrl MLItem::getURI() const
326 vlc_mutex_lock( &media->lock );
327 uri = qfu( media->psz_uri );
328 vlc_mutex_unlock( &media->lock );
329 if ( uri.isEmpty() ) return QUrl(); // This should be rootItem
331 QUrl url = QUrl::fromEncoded( uri.toUtf8(), QUrl::TolerantMode );
332 if ( url.scheme().isEmpty() ) url.setScheme( "file" );
336 QString MLItem::getTitle() const
339 vlc_mutex_lock( &media->lock );
340 title = QString( media->psz_title );
341 vlc_mutex_unlock( &media->lock );
345 bool MLItem::operator<( MLItem* item )
347 int ret = compareMeta( getMedia(), item->getMedia(), ML_ALBUM );