1 /***************************************************************************
5 copyright : (C) 2003 Scott Wheeler <wheeler@kde.org>
6 : (C) 2004 Max Howell <max.howell@methylblue.com>
7 : (C) 2004 Mark Kretschmann <markey@web.de>
8 ***************************************************************************/
10 /***************************************************************************
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
17 ***************************************************************************/
19 #include "directorylist.h"
21 #include "amarokconfig.h"
22 #include "mountpointmanager.h"
34 CollectionSetup
* CollectionSetup::s_instance
;
37 CollectionSetup::CollectionSetup( QWidget
*parent
)
40 setObjectName( "CollectionSetup" );
44 "These folders will be scanned for "
45 "media to make up your collection:"), this ))->setAlignment( Qt::AlignJustify
);
47 m_view
= new QFixedListView( this );
48 m_recursive
= new QCheckBox( i18n("&Scan folders recursively"), this );
49 m_monitor
= new QCheckBox( i18n("&Watch folders for changes"), this );
51 m_recursive
->setToolTip( i18n( "If selected, Amarok will read all subfolders." ) );
52 m_monitor
->setToolTip( i18n( "If selected, folders will automatically get rescanned when the content is modified, e.g. when a new file was added." ) );
55 //we have to detect if this is the actual first run and not get the collectionFolders in that case
56 //there won't be any anyway and accessing them creates a Sqlite database, even if the user wants to
57 //use another database
59 if( !Amarok::config().readEntry( "First Run", true ) )
60 m_dirs
= MountPointManager::instance()->collectionFolders();
62 m_recursive
->setChecked( AmarokConfig::scanRecursively() );
63 m_monitor
->setChecked( AmarokConfig::monitorChanges() );
65 m_view
->addColumn( QString() );
66 m_view
->setRootIsDecorated( true );
67 m_view
->setSizePolicy( QSizePolicy::Expanding
, QSizePolicy::Expanding
);
68 m_view
->setResizeMode( Q3ListView::LastColumn
);
70 reinterpret_cast<QWidget
*>(m_view
->header())->hide();
71 new CollectionFolder::Item( m_view
);
78 CollectionSetup::writeConfig()
80 //If we are in recursive mode then we don't need to store the names of the
81 //subdirectories of the selected directories
84 for ( QStringList::iterator it
=m_dirs
.begin(); it
!=m_dirs
.end(); ++it
)
86 QStringList::iterator jt
=m_dirs
.begin();
87 while ( jt
!=m_dirs
.end() )
94 //Note: all directories except "/" lack a trailing '/'.
95 //If (*jt) is a subdirectory of (*it) it is redundant.
96 //As all directories are subdirectories of "/", if "/" is selected, we
97 //can delete everything else.
98 if ( ( *jt
).startsWith( *it
+ '/' ) || *it
=="/" )
99 jt
= m_dirs
.erase( jt
);
106 MountPointManager::instance()->setCollectionFolders( m_dirs
);
107 AmarokConfig::setScanRecursively( recursive() );
108 AmarokConfig::setMonitorChanges( monitor() );
112 //////////////////////////////////////////////////////////////////////////////////////////
114 //////////////////////////////////////////////////////////////////////////////////////////
116 namespace CollectionFolder
{
118 Item::Item( Q3ListView
*parent
)
119 : Q3CheckListItem( parent
, "/", Q3CheckListItem::CheckBox
)
123 , m_fullyDisabled( false )
125 m_lister
.setDelayedMimeTypes( true );
126 //Since we create the "/" checklistitem here, we need to enable it if needed
127 if ( CollectionSetup::instance()->m_dirs
.contains( "/" ) )
128 static_cast<Q3CheckListItem
*>( this )->setOn(true);
129 m_lister
.setDirOnlyMode( true );
130 connect( &m_lister
, SIGNAL(newItems( const KFileItemList
& )), SLOT(newItems( const KFileItemList
& )) );
136 Item::Item( Q3ListViewItem
*parent
, const KUrl
&url
, bool full_disable
/* default=false */ )
137 : Q3CheckListItem( parent
, url
.fileName(), Q3CheckListItem::CheckBox
)
141 , m_fullyDisabled( full_disable
)
143 m_lister
.setDelayedMimeTypes( true );
144 m_lister
.setDirOnlyMode( true );
145 setExpandable( true );
146 connect( &m_lister
, SIGNAL(newItems( const KFileItemList
& )), SLOT(newItems( const KFileItemList
& )) );
147 connect( &m_lister
, SIGNAL(completed()), SLOT(completed()) );
148 connect( &m_lister
, SIGNAL(canceled()), SLOT(completed()) );
153 Item::fullPath() const
157 for( const Q3ListViewItem
*item
= this; item
!= listView()->firstChild(); item
= item
->parent() )
159 path
.prepend( item
->text( 0 ) );
168 Item::setOpen( bool b
)
172 m_lister
.openUrl( m_url
, KDirLister::Keep
);
176 Q3ListViewItem::setOpen( b
);
181 Item::stateChange( bool b
)
183 QStringList
&cs_m_dirs
= CollectionSetup::instance()->m_dirs
;
185 if ( isFullyDisabled() )
188 if( CollectionSetup::instance()->recursive() )
189 for( Q3ListViewItem
*item
= firstChild(); item
; item
= item
->nextSibling() )
190 if ( dynamic_cast<Item
*>( item
) && !dynamic_cast<Item
*>( item
)->isFullyDisabled() )
191 static_cast<Q3CheckListItem
*>(item
)->Q3CheckListItem::setOn( b
);
193 //If it is disabled, allow us to change its appearance (above code) but not add it
194 //to the list of folders (code below)
198 // Update folder list
199 QStringList::Iterator it
= cs_m_dirs
.find( m_url
.path() );
201 if ( it
== cs_m_dirs
.end() )
202 cs_m_dirs
<< m_url
.path();
204 // Deselect subdirectories if we are in recursive mode as they are redundant
205 if ( CollectionSetup::instance()->recursive() )
207 QStringList::Iterator diriter
= cs_m_dirs
.begin();
208 while ( diriter
!= cs_m_dirs
.end() )
210 // Since the dir "/" starts with '/', we need a hack to stop it removing
211 // itself (it being the only path with a trailing '/')
212 if ( (*diriter
).startsWith( m_url
.path( KUrl::AddTrailingSlash
) ) && *diriter
!= "/" )
213 diriter
= cs_m_dirs
.erase(diriter
);
220 //Deselect item and recurse through children but only deselect children if they
221 //do not exist unless we are in recursive mode (where no children should be
222 //selected if the parent is being unselected)
223 //Note this does not do anything to the checkboxes, but they should be doing
224 //the same thing as we are (hopefully)
225 //Note: all paths lack a trailing '/' except for "/", which must be handled as a
227 if ( it
!= cs_m_dirs
.end() )
228 cs_m_dirs
.erase( it
);
229 QStringList::Iterator diriter
= cs_m_dirs
.begin();
230 while ( diriter
!= cs_m_dirs
.end() )
232 if ( (*diriter
).startsWith( m_url
.path( KUrl::AddTrailingSlash
) ) ) //path(1) adds a trailing '/'
234 if ( CollectionSetup::instance()->recursive() ||
235 !QFile::exists( *diriter
) )
237 diriter
= cs_m_dirs
.erase(diriter
);
247 // Redraw parent items
248 listView()->triggerUpdate();
256 Q3CheckListItem::activate();
261 Item::newItems( const KFileItemList
&list
) //SLOT
263 for( KFileItemList::const_iterator it
= list
.begin(); it
!= list
.end(); ++it
)
265 //Fully disable (always appears off and grayed-out) if it is "/proc", "/sys" or
266 //"/dev" or one of their children. This is because we will never scan them, so we
267 //might as well show that.
268 //These match up with the skipped dirs in CollectionScanner::readDir.
269 bool fully_disable
=false;
271 if ( this->m_url
.fileName().isEmpty() && ( (*it
).url().fileName()=="proc"
272 || (*it
).url().fileName()=="dev" || (*it
).url().fileName()=="sys" ) )
277 Item
*item
= new Item( this, (*it
).url() , fully_disable
|| this->isFullyDisabled() );
279 if ( !item
->isFullyDisabled() )
281 if( CollectionSetup::instance()->recursive() && isOn() ||
282 CollectionSetup::instance()->m_dirs
.contains( item
->fullPath() ) )
288 item
->setPixmap( 0, (*it
).pixmap( KIconLoader::SizeSmall
) );
294 Item::paintCell( QPainter
* p
, const QColorGroup
& cg
, int column
, int width
, int align
)
297 QStringList
&cs_m_dirs
= CollectionSetup::instance()->m_dirs
;
299 // Figure out if a child folder is activated
300 for ( QStringList::const_iterator iter
= cs_m_dirs
.begin(); iter
!= cs_m_dirs
.end();
302 if ( ( *iter
).startsWith( m_url
.path( KUrl::AddTrailingSlash
) ) )
303 if ( *iter
!= "/" ) // "/" should not match as a child of "/"
306 // Use a different color if this folder has an activated child folder
307 const QFont f
= p
->font();
308 QColorGroup _cg
= cg
;
311 _cg
.setColor( QColorGroup::Text
, listView()->colorGroup().link() );
312 QFont font
= p
->font();
313 font
.setBold( !font
.bold() );
317 Q3CheckListItem::paintCell( p
, isDisabled() ? listView()->palette().disabled() : _cg
, column
, width
, align
);
321 } //namespace Collection
323 #include "directorylist.moc"