Qt4- Playlist Model. Save the showColumn flags in the configuration ONLY during distr...
[vlc.git] / 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 main one */
60     if( parentItem == NULL )
61     {
62         i_showflags = model->shownFlags();
63         updateColumnHeaders();
64     }
65     else
66     {
67         i_showflags = parentItem->i_showflags;
68         //Add empty string and update() handles data appending
69         item_col_strings.append( "" );
70     }
71     msg_Dbg( model->p_intf, "PLItem created of type: %i", model->i_depth );
72 }
73
74 /*
75    Constructors
76    Call the above function init
77    So far the first constructor isn't used...
78    */
79 PLItem::PLItem( int _i_id, int _i_input_id, PLItem *parent, PLModel *m )
80 {
81     init( _i_id, _i_input_id, parent, m );
82 }
83
84 PLItem::PLItem( playlist_item_t * p_item, PLItem *parent, PLModel *m )
85 {
86     init( p_item->i_id, p_item->p_input->i_id, parent, m );
87 }
88
89 PLItem::~PLItem()
90 {
91     qDeleteAll( children );
92     children.clear();
93 }
94
95 /* Column manager */
96 void PLItem::updateColumnHeaders()
97 {
98     item_col_strings.clear();
99
100     if( model->i_depth == DEPTH_SEL )  /* Selector Panel */
101     {
102         item_col_strings.append( "" );
103         return;
104     }
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     i_type = p_item->p_input->i_type;
192     b_current = iscurrent;
193
194     item_col_strings.clear();
195
196     if( model->i_depth == 1 )  /* Selector Panel */
197     {
198         item_col_strings.append( qfu( p_item->p_input->psz_name ) );
199         return;
200     }
201
202 #define ADD_META( item, meta ) \
203     psz_meta = input_item_Get ## meta ( item->p_input ); \
204     item_col_strings.append( qfu( psz_meta ) ); \
205     free( psz_meta );
206
207     for( int i_index=1; i_index <= VLC_META_ENGINE_ART_URL; i_index *= 2 )
208     {
209         if( parentItem->i_showflags & i_index )
210         {
211             switch( i_index )
212             {
213             case VLC_META_ENGINE_ARTIST:
214                 ADD_META( p_item, Artist );
215                 break;
216             case VLC_META_ENGINE_TITLE:
217                 char *psz_title;
218                 psz_title = input_item_GetTitle( p_item->p_input );
219                 if( psz_title )
220                 {
221                     ADD_META( p_item, Title );
222                     free( psz_title );
223                 }
224                 else
225                 {
226                     psz_title = input_item_GetName( p_item->p_input );
227                     if( psz_title )
228                     {
229                         item_col_strings.append( qfu( psz_title ) );
230                     }
231                     free( psz_title );
232                 }
233                 break;
234             case VLC_META_ENGINE_DESCRIPTION:
235                 ADD_META( p_item, Description );
236                 break;
237             case VLC_META_ENGINE_DURATION:
238                 secstotimestr( psz_duration,
239                     input_item_GetDuration( p_item->p_input ) / 1000000 );
240                 item_col_strings.append( QString( psz_duration ) );
241                 break;
242             case VLC_META_ENGINE_GENRE:
243                 ADD_META( p_item, Genre );
244                 break;
245             case VLC_META_ENGINE_COLLECTION:
246                 ADD_META( p_item, Album );
247                 break;
248             case VLC_META_ENGINE_SEQ_NUM:
249                 ADD_META( p_item, TrackNum );
250                 break;
251             case VLC_META_ENGINE_RATING:
252                 ADD_META( p_item, Rating );
253             default:
254                 break;
255             }
256         }
257
258     }
259 #undef ADD_META
260 }
261