]> git.sesse.net Git - vlc/blob - modules/gui/qt4/components/playlist/ml_item.cpp
Qt: kill a bunch of warnings
[vlc] / modules / gui / qt4 / components / playlist / ml_item.cpp
1 /*****************************************************************************
2  * ml_item.cpp: the media library's result item
3  *****************************************************************************
4  * Copyright (C) 2008-2011 the VideoLAN Team and AUTHORS
5  * $Id$
6  *
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>
12  *
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.
17  *
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.
22  *
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  *****************************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31
32 #ifdef MEDIA_LIBRARY
33
34 #include <QDateTime>
35 #include <QUrl>
36 #include <QFileInfo>
37 #include "ml_item.hpp"
38 #include <assert.h>
39
40
41 /**
42  * @brief Compare the attribute 'meta' between medias a and b.
43  * @param a
44  * @param b
45  * @param meta
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
50  */
51 static int compareMeta( const ml_media_t *a, const ml_media_t *b,
52                         ml_select_e meta )
53 {
54 #   define scomp(c) ((a->c&&b->c&&*a->c&&*b->c) ? strcasecmp(a->c,b->c) : \
55                      (a->c&&*a->c?-1:(b->c&&*b->c?1:0)))
56 #   define icomp(c) (a->c<b->c?-1:(a->c==b->c?0:1))
57     switch( meta )
58     {
59         case ML_ALBUM: return scomp( psz_album );
60         case ML_ALBUM_ID: return icomp( i_album_id );
61         //case ML_ARTIST: return scomp( psz_artist );
62         //case ML_ARTIST_ID: return icomp( i_artist_id );
63         case ML_COVER: return scomp( psz_cover );
64         case ML_DURATION: return icomp( i_duration );
65         case ML_EXTRA: return scomp( psz_extra );
66         case ML_GENRE: return scomp( psz_genre );
67         case ML_ID: return icomp( i_id );
68         case ML_LAST_PLAYED: return icomp( i_last_played );
69         case ML_ORIGINAL_TITLE: return scomp( psz_orig_title );
70         case ML_PLAYED_COUNT: return icomp( i_played_count );
71         // case ML_ROLE: return 0;
72         case ML_SCORE: return icomp( i_score );
73         case ML_TITLE: return scomp( psz_title );
74         case ML_TRACK_NUMBER: return icomp( i_track_number );
75         case ML_TYPE: return icomp( i_type );
76         case ML_URI: return scomp( psz_uri );
77         case ML_VOTE: return icomp( i_vote );
78         case ML_YEAR: return icomp( i_year );
79         default: return 0;
80     }
81 #   undef scomp
82 #   undef icomp
83 }
84
85
86 MLItem::MLItem( const MLModel *p_model,
87                             intf_thread_t* _p_intf,
88                             ml_media_t *p_media,
89                             MLItem *p_parent )
90         : p_intf( _p_intf ), model( p_model ), children(), parentItem( p_parent )
91 {
92     if( p_media )
93         ml_gc_incref( p_media );
94     this->media = p_media;
95     p_ml = ml_Get( _p_intf );
96 }
97
98 MLItem::~MLItem()
99 {
100     // Free private data
101     if( this->media )
102         ml_gc_decref( this->media );
103     if( !children.isEmpty() )
104         clearChildren();
105 }
106
107 /**
108  * @brief recursively delete all children of this node
109  * @note must be entered after the appropriate beginRemoveRows()
110  */
111 void MLItem::clearChildren()
112 {
113     // Recursively delete all children
114     qDeleteAll( children );
115     children.clear();
116 }
117
118 MLItem* MLItem::child( int row ) const
119 {
120     if( row < 0 || row >= childCount() ) return NULL;
121     else return children.at( row );
122 }
123
124 void MLItem::addChild( MLItem *child, int row )
125 {
126     assert( child );
127     children.insert( row==-1 ? children.size() : row, child );
128 }
129
130 void MLItem::delChild( int row )
131 {
132     if( !childCount() ) return; // assert ?
133     MLItem *item =
134             children.takeAt( ( row!=-1 ) ? row : ( children.size()-1 ) );
135     assert( item );
136     delete item;
137 }
138
139 int MLItem::rowOfChild( MLItem *item ) const
140 {
141     return children.indexOf( item );
142 }
143
144 int MLItem::childCount() const
145 {
146     return children.size();
147 }
148
149 MLItem* MLItem::parent() const
150 {
151     return parentItem;
152 }
153
154 /**
155  * @brief Get a QVariant representing the data on a column
156  * @param column
157  * @return The QVariant may be formed of a int, QString
158  *         Use toString() to print it on the screen, except for pixmaps
159  */
160 QVariant MLItem::data( int column ) const
161 {
162     ml_select_e type = model->columnType( column );
163     ml_person_t *p_people = NULL, *p_person = NULL;
164     QString qsz_return;
165 #define sreturn(a) if(media->a) return qfu(media->a); break
166     switch( type )
167     {
168         case ML_ALBUM: sreturn( psz_album );
169         case ML_ALBUM_ID: return media->i_album_id;
170         case ML_ARTIST:
171             p_people = ml_GetPersonsFromMedia( p_ml, media, ML_PERSON_ARTIST );
172             p_person = p_people;
173             while( p_person )
174             {
175                 if( !EMPTY_STR( p_person->psz_name ) )
176                 {
177                     qsz_return.isEmpty() ? qsz_return = qfu( p_person->psz_name ) :
178                         qsz_return.append( "," ).append( qfu( p_person->psz_name ) );
179                 }
180                 p_person = p_person->p_next;
181             }
182             ml_FreePeople( p_people );
183             return qsz_return;
184             break;
185         case ML_COVER: sreturn( psz_cover );
186         case ML_DURATION:
187             return QTime().addSecs( media->i_duration/1000000 ).toString( "HH:mm:ss" );
188         case ML_EXTRA: sreturn( psz_extra );
189         case ML_GENRE: sreturn( psz_genre );
190         case ML_ID: return media->i_id;
191         case ML_LAST_PLAYED:
192         {
193             if( media->i_last_played > 0 )
194             {
195                 QDateTime time( QDate(1970,1,1) );
196                 return time.addSecs( qint64( media->i_last_played ) );
197             }
198             else
199                 return QString();
200         }
201         case ML_ORIGINAL_TITLE: sreturn( psz_orig_title );
202         case ML_PLAYED_COUNT: return media->i_played_count;
203         // case ML_ROLE: return qtr( "Role" );
204         case ML_SCORE: return media->i_score ? media->i_score : QVariant();
205         case ML_TITLE:
206         {
207             /* If no title, return filename */
208             if( !EMPTY_STR( media->psz_title ) )
209                 return qfu( media->psz_title );
210             else
211             {
212                 QFileInfo p_file = QFileInfo( qfu( media->psz_uri ) );
213                 return p_file.fileName().isEmpty() ? p_file.absoluteFilePath()
214                     : p_file.fileName();
215             }
216         }
217         case ML_TRACK_NUMBER: return media->i_track_number ? media->i_track_number : QVariant();
218         case ML_TYPE:
219         {
220             QString txt;
221             if( media->i_type & ML_AUDIO )
222                 txt = "Audio";
223             if( media->i_type & ML_VIDEO )
224                 txt = "Video";
225             if( media->i_type & ML_STREAM )
226             {
227                 if( txt.isEmpty() ) txt = "Stream";
228                 else txt += " stream";
229             }
230             if( media->i_type & ML_REMOVABLE )
231             {
232                 if( txt.isEmpty() ) txt = "Removable media";
233                 else txt += " (removable media)";
234             }
235             if( media->i_type & ML_NODE )
236             {
237                 if( txt.isEmpty() ) txt = "Playlist";
238                 else txt += " (Playlist)";
239             }
240             if( txt.isEmpty() )
241                 txt = qtr( "Unknown" );
242             return txt;
243         }
244         case ML_URI: sreturn( psz_uri );
245         case ML_VOTE: return media->i_vote ? media->i_vote : QVariant();
246         case ML_YEAR: return media->i_year ? media->i_year : QVariant();
247         default: return QVariant();
248     }
249 #   undef sreturn
250     return QVariant();
251 }
252
253 bool MLItem::setData( ml_select_e meta, const QVariant &data )
254 {
255 #   define setmeta(a) ml_LockMedia(media); free(media->a);                  \
256     media->a = strdup( qtu(data.toString()) ); ml_UnlockMedia( media );     \
257     goto update;
258     switch( meta )
259     {
260         /* String values */
261         case ML_ALBUM: setmeta( psz_album );
262         case ML_ARTIST: ml_DeletePersonTypeFromMedia( media, ML_PERSON_ARTIST );
263                         ml_CreateAppendPersonAdv( &media->p_people,
264                                 ML_PERSON_ARTIST, (char*)qtu(data.toString()), 0 );
265                         return ml_UpdateSimple( p_ml, ML_MEDIA, NULL, id(),
266                                 ML_PEOPLE, ML_PERSON_ARTIST, qtu( data.toString() ) ) == VLC_SUCCESS;
267         case ML_EXTRA: setmeta( psz_extra );
268         case ML_GENRE: setmeta( psz_genre );
269         case ML_ORIGINAL_TITLE: setmeta( psz_orig_title );
270         case ML_TITLE: setmeta( psz_title );
271 update:
272             return ml_UpdateSimple( p_ml, ML_MEDIA, NULL, id(),
273                                     meta, qtu( data.toString() ) ) == VLC_SUCCESS;
274
275         /* Modifiable integers */
276         case ML_TRACK_NUMBER:
277         case ML_YEAR:
278             return ml_UpdateSimple( p_ml, ML_MEDIA, NULL, id(),
279                                     meta, data.toInt() ) == VLC_SUCCESS;
280
281         // TODO case ML_VOTE:
282
283         /* Non modifiable meta */
284         default:
285             return false;
286     }
287 #   undef setmeta
288 }
289
290 int MLItem::id() const
291 {
292     return media->i_id;
293 }
294
295 ml_media_t* MLItem::getMedia() const
296 {
297     return media;
298 }
299
300 QUrl MLItem::getUri() const
301 {
302     if( !media->psz_uri ) return QUrl(); // This should be rootItem
303     QString uri = qfu( media->psz_uri );
304     if( uri.contains( "://" ) )
305         return QUrl( uri );
306     else
307         return QUrl( "file://" + uri );
308 }
309
310 bool MLItem::operator<( MLItem* item )
311 {
312      int ret = compareMeta( getMedia(), item->getMedia(), ML_ALBUM );
313      if( ret == -1 )
314          return true;
315      else return false;
316 }
317 #endif