Qt4: store input_item_t* in plitem and handle metadata in model
[vlc.git] / 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( playlist_item_t *_playlist_item, PLItem *parent, PLModel *m, QSettings *settings )
52 {
53     parentItem = parent;          /* Can be NULL, but only for the rootItem */
54     i_id       = _playlist_item->i_id;           /* Playlist item specific id */
55     i_input_id = _playlist_item->p_input->i_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     b_is_node  = _playlist_item->i_children > 1;
60     p_input    = _playlist_item->p_input;
61     vlc_gc_incref( p_input );
62
63     assert( model );              /* We need a model */
64
65     /* No parent, should be the 2 main ones */
66     if( parentItem == NULL )
67     {
68         if( model->i_depth == DEPTH_SEL )  /* Selector Panel */
69         {
70             i_showflags = 0;
71         }
72         else
73         {
74             i_showflags = settings->value( "qt-pl-showflags", COLUMN_DEFAULT ).toInt();
75             if( i_showflags < 1)
76                 i_showflags = COLUMN_DEFAULT; /* reasonable default to show something; */
77             else if ( i_showflags >= COLUMN_END )
78                 i_showflags = COLUMN_END - 1; /* show everything */
79
80             updateColumnHeaders();
81         }
82     }
83     else
84     {
85         i_showflags = parentItem->i_showflags;
86         //Add empty string and update() handles data appending
87     }
88 }
89
90 /*
91    Constructors
92    Call the above function init
93    So far the first constructor isn't used...
94    */
95 PLItem::PLItem( playlist_item_t *p_item, PLItem *parent, PLModel *m )
96 {
97     init( p_item, parent, m, NULL );
98 }
99
100 PLItem::PLItem( playlist_item_t * p_item, QSettings *settings, PLModel *m )
101 {
102     init( p_item, NULL, m, settings );
103 }
104
105 PLItem::~PLItem()
106 {
107     qDeleteAll( children );
108     children.clear();
109 }
110
111 /* Column manager */
112 void PLItem::updateColumnHeaders()
113 {
114     assert( i_showflags < COLUMN_END );
115 }
116
117 /* So far signal is always true.
118    Using signal false would not call PLModel... Why ?
119  */
120 void PLItem::insertChild( PLItem *item, int i_pos, bool signal )
121 {
122     if( signal )
123         model->beginInsertRows( model->index( this , 0 ), i_pos, i_pos );
124     children.insert( i_pos, item );
125     if( signal )
126         model->endInsertRows();
127 }
128
129 void PLItem::remove( PLItem *removed )
130 {
131     if( model->i_depth == DEPTH_SEL || parentItem )
132     {
133         int i_index = parentItem->children.indexOf( removed );
134         model->beginRemoveRows( model->index( parentItem, 0 ),
135                                 i_index, i_index );
136         parentItem->children.removeAt( i_index );
137         model->endRemoveRows();
138     }
139 }
140
141 /* This function is used to get one's parent's row number in the model */
142 int PLItem::row() const
143 {
144     if( parentItem )
145         return parentItem->children.indexOf( const_cast<PLItem*>(this) );
146        // We don't ever inherit PLItem, yet, but it might come :D
147     return 0;
148 }
149
150 /* update the PL Item, get the good names and so on */
151 /* This function may not be the best way to do it
152    It destroys everything and gets everything again instead of just
153    building the necessary columns.
154    This does extra work if you re-display the same column. Slower...
155    On the other hand, this way saves memory.
156    There must be a more clever way.
157    */
158 void PLItem::update( playlist_item_t *p_item, bool iscurrent )
159 {
160     assert( p_item->p_input->i_id == i_input_id );
161
162     /* Useful for the model */
163     i_type = p_item->p_input->i_type;
164     b_current = iscurrent;
165     b_is_node = p_item->i_children > -1;
166
167     i_showflags = parentItem ? parentItem->i_showflags : i_showflags;
168 }
169