]> git.sesse.net Git - vlc/blob - modules/gui/qt4/components/playlist/playlist_item.cpp
meta-data handling cleanup
[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 #include "sorting.h"
40
41 /*************************************************************************
42  * Playlist item implementation
43  *************************************************************************/
44
45 /*
46    Playlist item is just a wrapper, an abstraction of the playlist_item
47    in order to be managed by PLModel
48
49    PLItem have a parent, and id and a input Id
50 */
51
52
53 void PLItem::init( int _i_id, int _i_input_id, PLItem *parent, PLModel *m )
54 {
55     parentItem = parent;          /* Can be NULL, but only for the rootItem */
56     i_id       = _i_id;           /* Playlist item specific id */
57     i_input_id = _i_input_id;     /* Identifier of the input */
58     model      = m;               /* PLModel (QAbsmodel) */
59     i_type     = -1;              /* Item type - Avoid segfault */
60     b_current  = false;           /* Is the item the current Item or not */
61
62     assert( model );              /* We need a model */
63
64     /* No parent, should be the 2 main ones */
65     if( parentItem == NULL )
66     {
67         if( model->i_depth == DEPTH_SEL )  /* Selector Panel */
68         {
69             item_col_strings.append( "" );
70         }
71         else
72         {
73             QSettings settings( "vlc", "vlc-qt-interface" );
74             i_showflags = settings.value( "qt-pl-showflags", 39 ).toInt();
75             if( i_showflags < 1)
76                 i_showflags = 39; //reasonable default to show something;
77             updateColumnHeaders();
78         }
79     }
80     else
81     {
82         i_showflags = parentItem->i_showflags;
83         //Add empty string and update() handles data appending
84         item_col_strings.append( "" );
85     }
86 }
87
88 /*
89    Constructors
90    Call the above function init
91    So far the first constructor isn't used...
92    */
93 PLItem::PLItem( int _i_id, int _i_input_id, PLItem *parent, PLModel *m )
94 {
95     init( _i_id, _i_input_id, parent, m );
96 }
97
98 PLItem::PLItem( playlist_item_t * p_item, PLItem *parent, PLModel *m )
99 {
100     init( p_item->i_id, p_item->p_input->i_id, parent, m );
101 }
102
103 PLItem::~PLItem()
104 {
105     qDeleteAll( children );
106     children.clear();
107 }
108
109 /* Column manager */
110 void PLItem::updateColumnHeaders()
111 {
112     item_col_strings.clear();
113
114     assert( i_showflags < COLUMN_END );
115
116     for( uint32_t i_index=1; i_index < COLUMN_END; i_index <<= 1 )
117     {
118         if( i_showflags & i_index )
119             item_col_strings.append( psz_column_title( i_index ) );
120     }
121 }
122
123 /* So far signal is always true.
124    Using signal false would not call PLModel... Why ?
125  */
126 void PLItem::insertChild( PLItem *item, int i_pos, bool signal )
127 {
128     if( signal )
129         model->beginInsertRows( model->index( this , 0 ), i_pos, i_pos );
130     children.insert( i_pos, item );
131     if( signal )
132         model->endInsertRows();
133 }
134
135 void PLItem::remove( PLItem *removed )
136 {
137     if( model->i_depth == DEPTH_SEL || parentItem )
138     {
139         int i_index = parentItem->children.indexOf( removed );
140         model->beginRemoveRows( model->index( parentItem, 0 ),
141                                 i_index, i_index );
142         parentItem->children.removeAt( i_index );
143         model->endRemoveRows();
144     }
145 }
146
147 /* This function is used to get one's parent's row number in the model */
148 int PLItem::row() const
149 {
150     if( parentItem )
151         return parentItem->children.indexOf( const_cast<PLItem*>(this) );
152        // We don't ever inherit PLItem, yet, but it might come :D
153     return 0;
154 }
155
156 /* update the PL Item, get the good names and so on */
157 /* This function may not be the best way to do it
158    It destroys everything and gets everything again instead of just
159    building the necessary columns.
160    This does extra work if you re-display the same column. Slower...
161    On the other hand, this way saves memory.
162    There must be a more clever way.
163    */
164 void PLItem::update( playlist_item_t *p_item, bool iscurrent )
165 {
166     char psz_duration[MSTRTIME_MAX_SIZE];
167     char *psz_meta;
168
169     assert( p_item->p_input->i_id == i_input_id );
170
171     /* Useful for the model */
172     i_type = p_item->p_input->i_type;
173     b_current = iscurrent;
174
175     item_col_strings.clear();
176
177     if( model->i_depth == 1 )  /* Selector Panel */
178     {
179         item_col_strings.append( qfu( p_item->p_input->psz_name ) );
180         return;
181     }
182
183     assert( parentItem->i_showflags < COLUMN_END );
184
185     for( uint32_t i_index=1; i_index < COLUMN_END; i_index <<= 1 )
186     {
187         if( parentItem->i_showflags & i_index )
188         {
189             char *psz = psz_column_meta( p_item->p_input, i_index );
190             item_col_strings.append( psz );
191             free( psz );
192         }
193     }
194 }