]> git.sesse.net Git - vlc/blob - modules/gui/qt4/components/playlist/playlist_item.cpp
701f60dd51ce3288b8ebd7e7292db1c39f521cd0
[vlc] / modules / gui / qt4 / components / playlist / playlist_item.cpp
1 /*****************************************************************************
2  * playlist_item.cpp : Manage playlist item
3  ****************************************************************************
4  * Copyright (C) 2006-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include <assert.h>
29
30 #include "qt4.hpp"
31 #include "components/playlist/playlist_model.hpp"
32 #include <vlc_intf_strings.h>
33
34 #include "pixmaps/type_unknown.xpm"
35
36 /*************************************************************************
37  * Playlist item implementation
38  *************************************************************************/
39
40 /*
41    Playlist item is just a wrapper, an abstraction of the playlist_item
42    in order to be managed by PLModel
43
44    PLItem have a parent, and id and a input Id
45 */
46
47
48 void PLItem::init( int _i_id, int _i_input_id, PLItem *parent, PLModel *m )
49 {
50     parentItem = parent;          /* Can be NULL, but only for the rootItem */
51     i_id       = _i_id;           /* Playlist item specific id */
52     i_input_id = _i_input_id;     /* Identifier of the input */
53     model      = m;               /* PLModel (QAbsmodel) */
54     i_type     = -1;              /* Item type - Avoid segfault */
55     b_current  = false;           /* Is the item the current Item or not */
56
57     assert( model );              /* We need a model */
58
59     /* No parent, should be the 2 main ones */
60     if( parentItem == NULL )
61     {
62         if( model->i_depth == DEPTH_SEL )  /* Selector Panel */
63         {
64             item_col_strings.append( "" );
65         }
66         else
67         {
68             i_showflags = config_GetInt( model->p_intf, "qt-pl-showflags" );
69             updateColumnHeaders();
70         }
71     }
72     else
73     {
74         i_showflags = parentItem->i_showflags;
75         //Add empty string and update() handles data appending
76         item_col_strings.append( "" );
77     }
78 }
79
80 /*
81    Constructors
82    Call the above function init
83    So far the first constructor isn't used...
84    */
85 PLItem::PLItem( int _i_id, int _i_input_id, PLItem *parent, PLModel *m )
86 {
87     init( _i_id, _i_input_id, parent, m );
88 }
89
90 PLItem::PLItem( playlist_item_t * p_item, PLItem *parent, PLModel *m )
91 {
92     init( p_item->i_id, p_item->p_input->i_id, parent, m );
93 }
94
95 PLItem::~PLItem()
96 {
97     qDeleteAll( children );
98     children.clear();
99 }
100
101 /* Column manager */
102 void PLItem::updateColumnHeaders()
103 {
104     item_col_strings.clear();
105
106     for( int i_index=1; i_index <= VLC_META_ENGINE_ART_URL; i_index *= 2 )
107     {
108         if( i_showflags & i_index )
109         {
110             switch( i_index )
111             {
112             case VLC_META_ENGINE_ARTIST:
113                 item_col_strings.append( qtr( VLC_META_ARTIST ) );
114                 break;
115             case VLC_META_ENGINE_TITLE:
116                 item_col_strings.append( qtr( VLC_META_TITLE ) );
117                 break;
118             case VLC_META_ENGINE_DESCRIPTION:
119                 item_col_strings.append( qtr( VLC_META_DESCRIPTION ) );
120                 break;
121             case VLC_META_ENGINE_DURATION:
122                 item_col_strings.append( qtr( "Duration" ) );
123                 break;
124             case VLC_META_ENGINE_GENRE:
125                 item_col_strings.append( qtr( VLC_META_GENRE ) );
126                 break;
127             case VLC_META_ENGINE_COLLECTION:
128                 item_col_strings.append( qtr( VLC_META_COLLECTION ) );
129                 break;
130             case VLC_META_ENGINE_SEQ_NUM:
131                 item_col_strings.append( qtr( VLC_META_SEQ_NUM ) );
132                 break;
133             case VLC_META_ENGINE_RATING:
134                 item_col_strings.append( qtr( VLC_META_RATING ) );
135                 break;
136             default:
137                 break;
138             }
139         }
140     }
141 }
142
143 /* So far signal is always true.
144    Using signal false would not call PLModel... Why ?
145  */
146 void PLItem::insertChild( PLItem *item, int i_pos, bool signal )
147 {
148     if( signal )
149         model->beginInsertRows( model->index( this , 0 ), i_pos, i_pos );
150     children.insert( i_pos, item );
151     if( signal )
152         model->endInsertRows();
153 }
154
155 void PLItem::remove( PLItem *removed )
156 {
157     if( model->i_depth == DEPTH_SEL || parentItem )
158     {
159         int i_index = parentItem->children.indexOf( removed );
160         model->beginRemoveRows( model->index( parentItem, 0 ),
161                                 i_index, i_index );
162         parentItem->children.removeAt( i_index );
163         model->endRemoveRows();
164     }
165 }
166
167 /* This function is used to get one's parent's row number in the model */
168 int PLItem::row() const
169 {
170     if( parentItem )
171         return parentItem->children.indexOf( const_cast<PLItem*>(this) );
172        // We don't ever inherit PLItem, yet, but it might come :D
173     return 0;
174 }
175
176 /* update the PL Item, get the good names and so on */
177 /* This function may not be the best way to do it
178    It destroys everything and gets everything again instead of just
179    building the necessary columns.
180    This does extra work if you re-display the same column. Slower...
181    On the other hand, this way saves memory.
182    There must be a more clever way.
183    */
184 void PLItem::update( playlist_item_t *p_item, bool iscurrent )
185 {
186     char psz_duration[MSTRTIME_MAX_SIZE];
187     char *psz_meta;
188
189     assert( p_item->p_input->i_id == i_input_id );
190
191     /* Useful for the model */
192     i_type = p_item->p_input->i_type;
193     b_current = iscurrent;
194
195     item_col_strings.clear();
196
197     if( model->i_depth == 1 )  /* Selector Panel */
198     {
199         item_col_strings.append( qfu( p_item->p_input->psz_name ) );
200         return;
201     }
202
203 #define ADD_META( item, meta ) \
204     psz_meta = input_item_Get ## meta ( item->p_input ); \
205     item_col_strings.append( qfu( psz_meta ) ); \
206     free( psz_meta );
207
208     for( int i_index=1; i_index <= VLC_META_ENGINE_ART_URL; i_index *= 2 )
209     {
210         if( parentItem->i_showflags & i_index )
211         {
212             switch( i_index )
213             {
214             case VLC_META_ENGINE_ARTIST:
215                 ADD_META( p_item, Artist );
216                 break;
217             case VLC_META_ENGINE_TITLE:
218                 char *psz_title;
219                 psz_title = input_item_GetTitle( p_item->p_input );
220                 if( psz_title )
221                 {
222                     ADD_META( p_item, Title );
223                     free( psz_title );
224                 }
225                 else
226                 {
227                     psz_title = input_item_GetName( p_item->p_input );
228                     if( psz_title )
229                     {
230                         item_col_strings.append( qfu( psz_title ) );
231                     }
232                     free( psz_title );
233                 }
234                 break;
235             case VLC_META_ENGINE_DESCRIPTION:
236                 ADD_META( p_item, Description );
237                 break;
238             case VLC_META_ENGINE_DURATION:
239                 secstotimestr( psz_duration,
240                     input_item_GetDuration( p_item->p_input ) / 1000000 );
241                 item_col_strings.append( QString( psz_duration ) );
242                 break;
243             case VLC_META_ENGINE_GENRE:
244                 ADD_META( p_item, Genre );
245                 break;
246             case VLC_META_ENGINE_COLLECTION:
247                 ADD_META( p_item, Album );
248                 break;
249             case VLC_META_ENGINE_SEQ_NUM:
250                 ADD_META( p_item, TrackNum );
251                 break;
252             case VLC_META_ENGINE_RATING:
253                 ADD_META( p_item, Rating );
254             default:
255                 break;
256             }
257         }
258     }
259 #undef ADD_META
260 }
261