add more spacing
[personal-kdebase.git] / runtime / nepomuk / kcm / folderselectionmodel.cpp
blobca7247fd4458cc08a040c4df4779c034048427ed
1 /* This file is part of the KDE Project
2 Copyright (c) 2008 Sebastian Trueg <trueg@kde.org>
4 Based on CollectionSetup.cpp from the Amarok project
5 (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 (C) 2008 Seb Ruiz <ruiz@kde.org>
9 (C) 2008 Sebastian Trueg <trueg@kde.org>
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public
13 License version 2 as published by the Free Software Foundation.
15 This library 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 GNU
18 Library General Public License for more details.
20 You should have received a copy of the GNU Library General Public License
21 along with this library; see the file COPYING.LIB. If not, write to
22 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 Boston, MA 02110-1301, USA.
26 #include "folderselectionmodel.h"
28 #include <QtCore/QDir>
29 #include <QtCore/QFileInfo>
30 #include <QtGui/QColor>
31 #include <QtGui/QBrush>
32 #include <QtGui/QPalette>
34 #include <KDebug>
35 #include <KIcon>
36 #include <KLocale>
39 FolderSelectionModel::FolderSelectionModel( QObject* parent )
40 : QFileSystemModel( parent )
42 setFilter( QDir::AllDirs | QDir::NoDotAndDotDot );
46 FolderSelectionModel::~FolderSelectionModel()
51 Qt::ItemFlags FolderSelectionModel::flags( const QModelIndex &index ) const
53 Qt::ItemFlags flags = QFileSystemModel::flags( index );
54 flags |= Qt::ItemIsUserCheckable;
55 if( isForbiddenPath( filePath( index ) ) )
56 flags ^= Qt::ItemIsEnabled; //disabled!
57 return flags;
61 QVariant FolderSelectionModel::data( const QModelIndex& index, int role ) const
63 if( index.isValid() && index.column() == 0 ) {
64 if( role == Qt::CheckStateRole ) {
65 const IncludeState state = includeState( index );
66 switch( state ) {
67 case StateNone:
68 case StateExclude:
69 case StateExcludeInherited:
70 return Qt::Unchecked;
71 case StateInclude:
72 case StateIncludeInherited:
73 return Qt::Checked;
76 else if( role == IncludeStateRole ) {
77 return includeState( index );
79 else if( role == Qt::ForegroundRole ) {
80 IncludeState state = includeState( index );
81 QBrush brush = QFileSystemModel::data( index, role ).value<QBrush>();
82 switch( state ) {
83 case StateInclude:
84 case StateIncludeInherited:
85 // brush = QPalette().brush( QPalette::Disabled, QPalette::Foreground );
86 break;
87 case StateNone:
88 case StateExclude:
89 case StateExcludeInherited:
90 brush = QPalette().brush( QPalette::Disabled, QPalette::Foreground );
91 break;
93 return QVariant::fromValue( brush );
95 else if ( role == Qt::ToolTipRole ) {
96 IncludeState state = includeState( index );
97 if ( state == StateInclude || state == StateIncludeInherited ) {
98 return i18nc( "@info:tooltip %1 is the path of the folder in a listview",
99 "<filename>%1</filename><nl/>(will be indexed for desktop search)", filePath( index ) );
101 else {
102 return i18nc( "@info:tooltip %1 is the path of the folder in a listview",
103 "<filename>%1</filename><nl/> (will <emphasis>not</emphasis> be indexed for desktop search)", filePath( index ) );
106 else if ( role == Qt::DecorationRole ) {
107 if ( filePath( index ) == QDir::homePath() ) {
108 return KIcon( "user-home" );
113 return QFileSystemModel::data( index, role );
117 bool FolderSelectionModel::setData( const QModelIndex& index, const QVariant& value, int role )
119 if( index.isValid() && index.column() == 0 && role == Qt::CheckStateRole ) {
120 const QString path = filePath( index );
121 const IncludeState state = includeState( path );
123 // here we ignore the check value, we treat it as a toggle
124 // This is due to our using the Qt checking system in a virtual way
125 if( state == StateInclude ||
126 state == StateIncludeInherited ) {
127 excludePath( path );
128 return true;
130 else {
131 includePath( path );
132 return true;
134 return false;
137 return QFileSystemModel::setData( index, value, role );
141 namespace {
142 void removeSubDirs( const QString& path, QSet<QString>& set ) {
143 QSet<QString>::iterator it = set.begin();
144 while( it != set.end() ) {
145 if( it->startsWith( path ) )
146 it = set.erase( it );
147 else
148 ++it;
152 QModelIndex findLastLeaf( const QModelIndex& index, FolderSelectionModel* model ) {
153 int rows = model->rowCount( index );
154 if( rows > 0 ) {
155 return findLastLeaf( model->index( rows-1, 0, index ), model );
157 else {
158 return index;
163 void FolderSelectionModel::includePath( const QString& path )
165 if( !m_included.contains( path ) ) {
166 // remove all subdirs
167 removeSubDirs( path, m_included );
168 removeSubDirs( path, m_excluded );
169 m_excluded.remove( path );
171 // only really include if the parent is not already included
172 if( includeState( path ) != StateIncludeInherited ) {
173 m_included.insert( path );
175 emit dataChanged( index( path ), findLastLeaf( index( path ), this ) );
180 void FolderSelectionModel::excludePath( const QString& path )
182 if( !m_excluded.contains( path ) ) {
183 // remove all subdirs
184 removeSubDirs( path, m_included );
185 removeSubDirs( path, m_excluded );
186 m_included.remove( path );
188 // only really exclude the path if a parent is included
189 if( includeState( path ) == StateIncludeInherited ) {
190 m_excluded.insert( path );
192 emit dataChanged( index( path ), findLastLeaf( index( path ), this ) );
197 void FolderSelectionModel::setFolders( const QStringList& includeDirs, const QStringList& excludeDirs )
199 m_included = QSet<QString>::fromList( includeDirs );
200 m_excluded = QSet<QString>::fromList( excludeDirs );
201 reset();
205 QStringList FolderSelectionModel::includeFolders() const
207 return m_included.toList();
211 QStringList FolderSelectionModel::excludeFolders() const
213 return m_excluded.toList();
217 inline bool FolderSelectionModel::isForbiddenPath( const QString& path ) const
219 // we need the trailing slash otherwise we could forbid "/dev-music" for example
220 QString _path = path.endsWith( "/" ) ? path : path + "/";
221 QFileInfo fi( _path );
222 return( _path.startsWith( "/proc/" ) ||
223 _path.startsWith( "/dev/" ) ||
224 _path.startsWith( "/sys/" ) ||
225 !fi.isReadable() ||
226 !fi.isExecutable() );
230 FolderSelectionModel::IncludeState FolderSelectionModel::includeState( const QModelIndex& index ) const
232 return includeState( filePath( index ) );
236 FolderSelectionModel::IncludeState FolderSelectionModel::includeState( const QString& path ) const
238 if( m_included.contains( path ) ) {
239 return StateInclude;
241 else if( m_excluded.contains( path ) ) {
242 return StateExclude;
244 else {
245 QString parent = path.section( QDir::separator(), 0, -2, QString::SectionSkipEmpty|QString::SectionIncludeLeadingSep );
246 if( parent.isEmpty() ) {
247 return StateNone;
249 else {
250 IncludeState state = includeState( parent );
251 if( state == StateNone )
252 return StateNone;
253 else if( state == StateInclude || state == StateIncludeInherited )
254 return StateIncludeInherited;
255 else
256 return StateExcludeInherited;
261 #include "folderselectionmodel.moc"