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