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