]> git.sesse.net Git - vlc/blob - modules/gui/qt4/components/playlist/playlist_item.cpp
Move the track id from the last column to the first one in the playlist dialog and...
[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_TRACKID:
119                 item_col_strings.append( qtr( VLC_META_TRACKID ) );
120                 break;
121             case VLC_META_ENGINE_ARTIST:
122                 item_col_strings.append( qtr( VLC_META_ARTIST ) );
123                 break;
124             case VLC_META_ENGINE_TITLE:
125                 item_col_strings.append( qtr( VLC_META_TITLE ) );
126                 break;
127             case VLC_META_ENGINE_DESCRIPTION:
128                 item_col_strings.append( qtr( VLC_META_DESCRIPTION ) );
129                 break;
130             case VLC_META_ENGINE_DURATION:
131                 item_col_strings.append( qtr( "Duration" ) );
132                 break;
133             case VLC_META_ENGINE_GENRE:
134                 item_col_strings.append( qtr( VLC_META_GENRE ) );
135                 break;
136             case VLC_META_ENGINE_COLLECTION:
137                 item_col_strings.append( qtr( VLC_META_COLLECTION ) );
138                 break;
139             case VLC_META_ENGINE_SEQ_NUM:
140                 item_col_strings.append( qtr( VLC_META_SEQ_NUM ) );
141                 break;
142             default:
143                 break;
144             }
145         }
146     }
147 }
148
149 /* So far signal is always true.
150    Using signal false would not call PLModel... Why ?
151  */
152 void PLItem::insertChild( PLItem *item, int i_pos, bool signal )
153 {
154     if( signal )
155         model->beginInsertRows( model->index( this , 0 ), i_pos, i_pos );
156     children.insert( i_pos, item );
157     if( signal )
158         model->endInsertRows();
159 }
160
161 void PLItem::remove( PLItem *removed )
162 {
163     if( model->i_depth == DEPTH_SEL || parentItem )
164     {
165         int i_index = parentItem->children.indexOf( removed );
166         model->beginRemoveRows( model->index( parentItem, 0 ),
167                                 i_index, i_index );
168         parentItem->children.removeAt( i_index );
169         model->endRemoveRows();
170     }
171 }
172
173 /* This function is used to get one's parent's row number in the model */
174 int PLItem::row() const
175 {
176     if( parentItem )
177         return parentItem->children.indexOf( const_cast<PLItem*>(this) );
178        // We don't ever inherit PLItem, yet, but it might come :D
179     return 0;
180 }
181
182 /* update the PL Item, get the good names and so on */
183 /* This function may not be the best way to do it
184    It destroys everything and gets everything again instead of just
185    building the necessary columns.
186    This does extra work if you re-display the same column. Slower...
187    On the other hand, this way saves memory.
188    There must be a more clever way.
189    */
190 void PLItem::update( playlist_item_t *p_item, bool iscurrent )
191 {
192     char psz_duration[MSTRTIME_MAX_SIZE];
193     char *psz_meta;
194
195     assert( p_item->p_input->i_id == i_input_id );
196
197     /* Useful for the model */
198     i_type = p_item->p_input->i_type;
199     b_current = iscurrent;
200
201     item_col_strings.clear();
202
203     if( model->i_depth == 1 )  /* Selector Panel */
204     {
205         item_col_strings.append( qfu( p_item->p_input->psz_name ) );
206         return;
207     }
208
209 #define ADD_META( item, meta ) \
210     psz_meta = input_item_Get ## meta ( item->p_input ); \
211     item_col_strings.append( qfu( psz_meta ) ); \
212     free( psz_meta );
213
214     for( int i_index=1; i_index <= VLC_META_ENGINE_ART_URL; i_index *= 2 )
215     {
216         if( parentItem->i_showflags & i_index )
217         {
218             switch( i_index )
219             {
220             case VLC_META_ENGINE_ARTIST:
221                 ADD_META( p_item, Artist );
222                 break;
223             case VLC_META_ENGINE_TITLE:
224                 char *psz_title;
225                 psz_title = input_item_GetTitle( p_item->p_input );
226                 if( psz_title )
227                 {
228                     ADD_META( p_item, Title );
229                     free( psz_title );
230                 }
231                 else
232                 {
233                     psz_title = input_item_GetName( p_item->p_input );
234                     if( psz_title )
235                     {
236                         item_col_strings.append( qfu( psz_title ) );
237                     }
238                     free( psz_title );
239                 }
240                 break;
241             case VLC_META_ENGINE_DESCRIPTION:
242                 ADD_META( p_item, Description );
243                 break;
244             case VLC_META_ENGINE_DURATION:
245                 secstotimestr( psz_duration,
246                     input_item_GetDuration( p_item->p_input ) / 1000000 );
247                 item_col_strings.append( QString( psz_duration ) );
248                 break;
249             case VLC_META_ENGINE_GENRE:
250                 ADD_META( p_item, Genre );
251                 break;
252             case VLC_META_ENGINE_COLLECTION:
253                 ADD_META( p_item, Album );
254                 break;
255             case VLC_META_ENGINE_SEQ_NUM:
256                 ADD_META( p_item, TrackNum );
257                 break;
258             case VLC_META_ENGINE_TRACKID:
259                 item_col_strings.append( QString::number( p_item->i_id ) );
260                 break;
261             default:
262                 break;
263             }
264         }
265     }
266 #undef ADD_META
267 }
268