Qt: correctly display the right treeView columns
[vlc.git] / modules / gui / qt4 / components / playlist / ml_item.cpp
blob3dd7db944caeb7d83685bfd15904e70f9819e93e
1 /*****************************************************************************
2 * ml_item.cpp: the media library's result item
3 *****************************************************************************
4 * Copyright (C) 2008-2011 the VideoLAN Team and AUTHORS
5 * $Id$
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 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
32 #ifdef MEDIA_LIBRARY
34 #include <QDateTime>
35 #include <QUrl>
36 #include <QFileInfo>
37 #include "ml_item.hpp"
38 #include <assert.h>
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
51 static int compareMeta( const ml_media_t *a, const ml_media_t *b,
52 ml_select_e meta )
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 )
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;
81 # undef scomp
82 # undef icomp
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 )
92 if( p_media )
93 ml_gc_incref( p_media );
94 this->media = p_media;
95 p_ml = ml_Get( _p_intf );
98 MLItem::~MLItem()
100 // Free private data
101 if( this->media )
102 ml_gc_decref( this->media );
103 if( !children.isEmpty() )
104 clearChildren();
108 * @brief recursively delete all children of this node
109 * @note must be entered after the appropriate beginRemoveRows()
111 void MLItem::clearChildren()
113 // Recursively delete all children
114 qDeleteAll( children );
115 children.clear();
118 MLItem* MLItem::child( int row ) const
120 if( row < 0 || row >= childCount() ) return NULL;
121 else return children.at( row );
124 void MLItem::addChild( MLItem *child, int row )
126 assert( child );
127 children.insert( row==-1 ? children.count() : row, child );
130 void MLItem::delChild( int row )
132 if( !childCount() ) return; // assert ?
133 MLItem *item =
134 children.takeAt( ( row!=-1 ) ? row : ( children.count()-1 ) );
135 assert( item );
136 delete item;
139 int MLItem::rowOfChild( MLItem *item ) const
141 return children.indexOf( item );
144 int MLItem::childCount() const
146 return children.count();
149 MLItem* MLItem::parent() const
151 return parentItem;
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
160 QVariant MLItem::data( int column ) const
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 )
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 )
175 if( !EMPTY_STR( p_person->psz_name ) )
177 qsz_return.isEmpty() ? qsz_return = qfu( p_person->psz_name ) :
178 qsz_return.append( "," ).append( qfu( p_person->psz_name ) );
180 p_person = p_person->p_next;
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:
193 if( media->i_last_played > 0 )
195 QDateTime time( QDate(1970,1,1) );
196 return time.addSecs( qint64( media->i_last_played ) );
198 else
199 return QString();
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:
207 /* If no title, return filename */
208 if( !EMPTY_STR( media->psz_title ) )
209 return qfu( media->psz_title );
210 else
212 QFileInfo p_file = QFileInfo( qfu( media->psz_uri ) );
213 return p_file.fileName().isEmpty() ? p_file.absoluteFilePath()
214 : p_file.fileName();
217 case ML_TRACK_NUMBER: return media->i_track_number ? media->i_track_number : QVariant();
218 case ML_TYPE:
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 )
227 if( txt.isEmpty() ) txt = "Stream";
228 else txt += " stream";
230 if( media->i_type & ML_REMOVABLE )
232 if( txt.isEmpty() ) txt = "Removable media";
233 else txt += " (removable media)";
235 if( media->i_type & ML_NODE )
237 if( txt.isEmpty() ) txt = "Playlist";
238 else txt += " (Playlist)";
240 if( txt.isEmpty() )
241 txt = qtr( "Unknown" );
242 return txt;
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();
249 # undef sreturn
250 return QVariant();
253 bool MLItem::setData( ml_select_e meta, const QVariant &data )
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 )
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;
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;
281 // TODO case ML_VOTE:
283 /* Non modifiable meta */
284 default:
285 return false;
287 # undef setmeta
290 int MLItem::id() const
292 return media->i_id;
295 ml_media_t* MLItem::getMedia() const
297 return media;
300 QUrl MLItem::getUri() const
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 );
310 bool MLItem::operator<( MLItem* item )
312 int ret = compareMeta( getMedia(), item->getMedia(), ML_ALBUM );
313 if( ret == -1 )
314 return true;
315 else return false;
317 #endif