]> git.sesse.net Git - vlc/blob - modules/gui/qt4/components/playlist/playlist_item.cpp
71f3fd04bd479af39088cb4a3ad98c97058bac71
[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 <QSettings>
36
37 #include "sorting.h"
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, QSettings *settings )
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             i_showflags = 0;
68             item_col_strings.append( "" );
69         }
70         else
71         {
72             i_showflags = settings->value( "qt-pl-showflags", COLUMN_DEFAULT ).toInt();
73             if( i_showflags < 1)
74                 i_showflags = COLUMN_DEFAULT; /* reasonable default to show something; */
75             else if ( i_showflags >= COLUMN_END )
76                 i_showflags = COLUMN_END - 1; /* show everything */
77
78             updateColumnHeaders();
79         }
80     }
81     else
82     {
83         i_showflags = parentItem->i_showflags;
84         //Add empty string and update() handles data appending
85         item_col_strings.append( "" );
86     }
87 }
88
89 /*
90    Constructors
91    Call the above function init
92    So far the first constructor isn't used...
93    */
94 PLItem::PLItem( int _i_id, int _i_input_id, PLItem *parent, PLModel *m )
95 {
96     init( _i_id, _i_input_id, parent, m, NULL );
97 }
98
99 PLItem::PLItem( playlist_item_t * p_item, PLItem *parent, PLModel *m )
100 {
101     init( p_item->i_id, p_item->p_input->i_id, parent, m, NULL );
102 }
103
104 PLItem::PLItem( playlist_item_t * p_item, QSettings *settings, PLModel *m )
105 {
106     init( p_item->i_id, p_item->p_input->i_id, NULL, m, settings );
107 }
108
109 PLItem::~PLItem()
110 {
111     qDeleteAll( children );
112     children.clear();
113 }
114
115 /* Column manager */
116 void PLItem::updateColumnHeaders()
117 {
118     item_col_strings.clear();
119
120     assert( i_showflags < COLUMN_END );
121
122     for( uint32_t i_index=1; i_index < COLUMN_END; i_index <<= 1 )
123     {
124         if( i_showflags & i_index )
125             item_col_strings.append( qfu( psz_column_title( i_index ) ) );
126     }
127 }
128
129 /* So far signal is always true.
130    Using signal false would not call PLModel... Why ?
131  */
132 void PLItem::insertChild( PLItem *item, int i_pos, bool signal )
133 {
134     if( signal )
135         model->beginInsertRows( model->index( this , 0 ), i_pos, i_pos );
136     children.insert( i_pos, item );
137     if( signal )
138         model->endInsertRows();
139 }
140
141 void PLItem::remove( PLItem *removed )
142 {
143     if( model->i_depth == DEPTH_SEL || parentItem )
144     {
145         int i_index = parentItem->children.indexOf( removed );
146         model->beginRemoveRows( model->index( parentItem, 0 ),
147                                 i_index, i_index );
148         parentItem->children.removeAt( i_index );
149         model->endRemoveRows();
150     }
151 }
152
153 /* This function is used to get one's parent's row number in the model */
154 int PLItem::row() const
155 {
156     if( parentItem )
157         return parentItem->children.indexOf( const_cast<PLItem*>(this) );
158        // We don't ever inherit PLItem, yet, but it might come :D
159     return 0;
160 }
161
162 /* update the PL Item, get the good names and so on */
163 /* This function may not be the best way to do it
164    It destroys everything and gets everything again instead of just
165    building the necessary columns.
166    This does extra work if you re-display the same column. Slower...
167    On the other hand, this way saves memory.
168    There must be a more clever way.
169    */
170 void PLItem::update( playlist_item_t *p_item, bool iscurrent )
171 {
172     char psz_duration[MSTRTIME_MAX_SIZE];
173     char *psz_meta;
174
175     assert( p_item->p_input->i_id == i_input_id );
176
177     /* Useful for the model */
178     i_type = p_item->p_input->i_type;
179     b_current = iscurrent;
180
181     item_col_strings.clear();
182
183     if( model->i_depth == 1 )  /* Selector Panel */
184     {
185         item_col_strings.append( qfu( p_item->p_input->psz_name ) );
186         return;
187     }
188
189     i_showflags = parentItem ? parentItem->i_showflags : i_showflags;
190
191     /* Meta: ID */
192     if( i_showflags & COLUMN_NUMBER )
193     {
194         QModelIndex idx = model->index( this, 0 );
195         item_col_strings.append( QString::number( idx.row() + 1 ) );
196     }
197     /* Other meta informations */
198     for( uint32_t i_index=2; i_index < COLUMN_END; i_index <<= 1 )
199     {
200         if( i_showflags & i_index )
201         {
202             char *psz = psz_column_meta( p_item->p_input, i_index );
203             item_col_strings.append( qfu( psz ) );
204             free( psz );
205         }
206     }
207 }
208