23 #include <QtCore/QStringList>
24 #include <QtCore/QDir>
25 #include <QWriteLocker>
26 #include <QReadLocker>
29 #include <KStandardDirs>
30 #include <KConfigGroup>
36 bool isDirHidden( QDir& dir ) {
37 if ( QFileInfo( dir.path() ).isHidden() )
39 else if ( dir.cdUp() )
40 return isDirHidden( dir );
45 bool isDirHidden(
const QString& path) {
48 return isDirHidden(dir);
50 return path.contains( QLatin1String(
"/.") );
59 , m_config(
"nepomukstrigirc" )
60 , m_indexHidden(false)
66 KDirWatch* dirWatch = KDirWatch::self();
67 connect( dirWatch, SIGNAL( dirty(
const QString& ) ),
68 this, SLOT( slotConfigDirty() ) );
69 connect( dirWatch, SIGNAL( created(
const QString& ) ),
70 this, SLOT( slotConfigDirty() ) );
71 dirWatch->addFile( KStandardDirs::locateLocal(
"config", m_config.name() ) );
97 for (
int i = 0; i < m_folderCache.count(); ++i ) {
98 if ( m_folderCache[i].second )
99 fl << m_folderCache[i].first;
108 for (
int i = 0; i < m_folderCache.count(); ++i ) {
109 if ( !m_folderCache[i].second )
110 fl << m_folderCache[i].first;
118 KConfigGroup cfg = m_config.group(
"General" );
130 cfg.writeEntry(
"exclude filters", QStringList::fromSet(filters));
135 return QStringList::fromSet(filters);
141 return m_indexHidden;
148 return m_config.group(
"General" ).readEntry(
"min disk space", KIO::filesize_t( 200*1024*1024 ) );
152 void Nepomuk2::FileIndexerConfig::slotConfigDirty()
154 if( forceConfigUpdate() )
155 emit configChanged();
161 return m_config.group(
"General" ).readEntry(
"first run",
true );
167 QFileInfo fi( path );
169 return shouldFolderBeIndexed( path );
172 return( shouldFolderBeIndexed( fi.absolutePath() ) &&
173 ( !fi.isHidden() || indexHiddenFilesAndFolders() ) &&
174 shouldFileBeIndexed( fi.fileName() ) );
182 if ( folderInFolderList( path, folder ) ) {
185 if ( folder == path )
190 if ( !indexHiddenFilesAndFolders() && isDirHidden( dir ) )
198 const QStringList pathComponents = path.mid(folder.count()).split(
'/', QString::SkipEmptyParts);
199 foreach(
const QString& c, pathComponents) {
200 if(!shouldFileBeIndexed( c )) {
215 QWriteLocker lock( &m_folderCacheMutex );
216 return !m_excludeFilterRegExpCache.exactMatch( fileName );
221 QReadLocker lock( &m_mimetypeMutex );
222 return !m_excludeMimetypes.contains( mimeType );
229 return folderInFolderList( path, str );
234 QReadLocker lock( &m_folderCacheMutex );
236 const QString p = KUrl( path ).path( KUrl::RemoveTrailingSlash );
239 int i = m_folderCache.count();
241 const QString& f = m_folderCache[i].first;
242 const bool include = m_folderCache[i].second;
243 if ( p.startsWith( f ) ) {
259 bool alreadyExcluded(
const QList<QPair<QString, bool> >& folders,
const QString& f )
261 bool included =
false;
262 for (
int i = 0; i < folders.count(); ++i ) {
263 if ( f != folders[i].first &&
264 f.startsWith( KUrl( folders[i].first ).path( KUrl::AddTrailingSlash ) ) ) {
265 included = folders[i].second;
274 void insertSortFolders(
const QStringList& folders,
bool include, QList<QPair<QString, bool> >& result )
276 foreach(
const QString& f, folders ) {
278 QString path = KUrl( f ).path( KUrl::RemoveTrailingSlash );
279 while ( result.count() > pos &&
280 result[pos].first < path )
282 result.insert( pos, qMakePair( path, include ) );
291 void cleanupList( QList<QPair<QString, bool> >& result )
294 while ( i < result.count() ) {
295 if ( result[i].first.isEmpty() ||
296 (!result[i].second &&
297 alreadyExcluded( result, result[i].first ) ))
298 result.removeAt( i );
306 void Nepomuk2::FileIndexerConfig::fillIncludeFolderChanges(
const Nepomuk2::FileIndexerConfig::Entry& entry,
const QSet<QString>& include, QStringList* includeAdded, QStringList* includeRemoved)
308 QStringList added = QSet<QString>(include).subtract( entry.includes ).toList();
309 QStringList removed = QSet<QString>(entry.includes).subtract( include ).toList();
312 includeAdded->append( added );
315 includeRemoved->append( removed );
318 void Nepomuk2::FileIndexerConfig::fillExcludeFolderChanges(
const Nepomuk2::FileIndexerConfig::Entry& entry,
const QSet<QString>& exclude, QStringList* excludeAdded, QStringList* excludeRemoved)
320 QStringList added = QSet<QString>(exclude).subtract( entry.excludes ).toList();
321 QStringList removed = QSet<QString>(entry.excludes).subtract( exclude ).toList();
324 excludeAdded->append( added );
327 excludeRemoved->append( removed );
331 bool Nepomuk2::FileIndexerConfig::buildFolderCache()
333 QWriteLocker lock( &m_folderCacheMutex );
338 KConfigGroup group = m_config.group(
"General" );
339 QStringList includeFoldersPlain = group.readPathEntry(
"folders", QStringList() << QDir::homePath() );
340 QStringList excludeFoldersPlain = group.readPathEntry(
"exclude folders", QStringList() );
342 m_folderCache.clear();
343 insertSortFolders( includeFoldersPlain,
true, m_folderCache );
344 insertSortFolders( excludeFoldersPlain,
false, m_folderCache );
346 QStringList includeAdded;
347 QStringList includeRemoved;
348 QStringList excludeAdded;
349 QStringList excludeRemoved;;
351 QSet<QString> includeSet = includeFoldersPlain.toSet();
352 QSet<QString> excludeSet = excludeFoldersPlain.toSet();
354 Entry& generalEntry = m_entries[
"General" ];
355 fillIncludeFolderChanges( generalEntry, includeSet, &includeAdded, &includeRemoved );
356 fillExcludeFolderChanges( generalEntry, excludeSet, &excludeAdded, &excludeRemoved );
358 generalEntry.includes = includeSet;
359 generalEntry.excludes = excludeSet;
364 QStringList groupList = m_config.groupList();
365 foreach(
const QString& groupName, groupList ) {
366 if( !groupName.startsWith(
"Device-") )
369 KConfigGroup group = m_config.group( groupName );
370 QString mountPath = group.readEntry(
"mount path", QString() );
371 if( mountPath.isEmpty() )
374 QStringList includes = group.readPathEntry(
"folders", QStringList() );
375 QStringList excludes = group.readPathEntry(
"exclude folders", QStringList() );
377 QStringList includeFoldersPlain;
378 foreach(
const QString& path, includes )
379 includeFoldersPlain << mountPath + path;
381 QStringList excludeFoldersPlain;
382 foreach(
const QString& path, excludes )
383 excludeFoldersPlain << mountPath + path;
385 insertSortFolders( includeFoldersPlain,
true, m_folderCache );
386 insertSortFolders( excludeFoldersPlain,
false, m_folderCache );
388 QSet<QString> includeSet = includeFoldersPlain.toSet();
389 QSet<QString> excludeSet = excludeFoldersPlain.toSet();
391 Entry& cacheEntry = m_entries[ groupName ];
392 fillIncludeFolderChanges( cacheEntry, includeSet, &includeAdded, &includeRemoved );
393 fillExcludeFolderChanges( cacheEntry, excludeSet, &excludeAdded, &excludeRemoved );
395 cacheEntry.includes = includeSet;
396 cacheEntry.excludes = excludeSet;
399 cleanupList( m_folderCache );
401 bool changed =
false;
402 if( !includeAdded.isEmpty() || !includeRemoved.isEmpty() ) {
403 emit includeFolderListChanged( includeAdded, includeRemoved );
407 if( !excludeAdded.isEmpty() || !excludeRemoved.isEmpty() ) {
408 emit excludeFolderListChanged( excludeAdded, excludeRemoved );
416 bool Nepomuk2::FileIndexerConfig::buildExcludeFilterRegExpCache()
418 QWriteLocker lock( &m_folderCacheMutex );
419 QStringList newFilters = excludeFilters();
420 m_excludeFilterRegExpCache.rebuildCacheFromFilterList( newFilters );
422 QSet<QString> newFilterSet = newFilters.toSet();
423 if( m_prevFileFilters != newFilterSet ) {
424 m_prevFileFilters = newFilterSet;
425 emit fileExcludeFiltersChanged();
432 bool Nepomuk2::FileIndexerConfig::buildMimeTypeCache()
434 QWriteLocker lock( &m_mimetypeMutex );
435 QStringList newMimeExcludes = m_config.group(
"General" ).readPathEntry(
"exclude mimetypes", QStringList() );
437 QSet<QString> newMimeExcludeSet = newMimeExcludes.toSet();
438 if( m_excludeMimetypes != newMimeExcludeSet ) {
439 m_excludeMimetypes = newMimeExcludeSet;
440 emit mimeTypeFiltersChanged();
450 m_config.reparseConfiguration();
451 bool changed =
false;
453 changed = buildFolderCache() || changed;
454 changed = buildExcludeFilterRegExpCache() || changed;
455 changed = buildMimeTypeCache() || changed;
457 bool hidden = m_config.group(
"General" ).readEntry(
"index hidden folders",
false );
458 if( hidden != m_indexHidden ) {
459 m_indexHidden = hidden;
468 m_config.group(
"General" ).writeEntry(
"first run", isInitialRun );
473 return m_config.group(
"General" ).readEntry(
"disable initial update",
true );
478 return m_config.group(
"General" ).readEntry(
"disable suspend on powersave",
false );
483 return m_config.group(
"General" ).readEntry(
"debug mode",
false );
487 #include "fileindexerconfig.moc"
bool shouldFolderBeIndexed(const QString &path) const
Check if the folder at path should be indexed.
bool shouldMimeTypeBeIndexed(const QString &mimeType) const
Checks if mimeType should be indexed.
QStringList excludeFilters() const
FileIndexerConfig(QObject *parent=0)
Create a new file indexr config.
NEPOMUKCOMMON_EXPORT int defaultExcludeFilterListVersion()
bool isDebugModeEnabled() const
Check if the debug mode is enabled.
QStringList includeFolders() const
The folders to search for files to analyze.
Active config class which emits signals if the config was changed, for example if the KCM saved the c...
bool folderInFolderList(const QString &path)
Returns true if the folder is in the list indexed directories and not in the list of exclude director...
bool shouldFileBeIndexed(const QString &fileName) const
Check fileName for all exclude filters.
QStringList excludeFolders() const
The folders that should be excluded.
bool shouldBeIndexed(const QString &path) const
Check if path should be indexed taking into account the includeFolders(), the excludeFolders(), and the excludeFilters().
QList< QPair< QString, bool > > folders() const
A cleaned up list of all include and exclude folders with their respective include/exclude flag sorte...
bool indexHiddenFilesAndFolders() const
KIO::filesize_t minDiskSpace() const
The minimal available disk space.
bool initialUpdateDisabled() const
A "hidden" config option which allows to disable the initial update of all indexed folders...
NEPOMUKCOMMON_EXPORT QStringList defaultExcludeFilterList()
bool isInitialRun() const
true the first time the service is run (or after manually tampering with the config.
void setInitialRun(bool isInitialRun)
Should be called once the initial indexing is done, ie.
static FileIndexerConfig * self()
Get the first created instance of FileIndexerConfig.
bool suspendOnPowerSaveDisabled() const
A "hidden" config option which allows to disable the feature where the file indexing is suspended whe...
bool forceConfigUpdate()
Reread the config from disk and update the configuration cache.