File 4_7_BRANCH.diff of Package kdebase4-runtime
--- a/BRANCH_STATUS
+++ b/BRANCH_STATUS
@@ -0,0 +1,2 @@
+current HEAD: 3bb47ee3b3326105e8fe5b1be6c9ca059dfff626
+git diff v4.7.2..origin/KDE/4.7
diff --git a/activitymanager/kactivitymanagerd.desktop b/activitymanager/kactivitymanagerd.desktop
index 6218dd5..d6d197f 100644
--- a/activitymanager/kactivitymanagerd.desktop
+++ b/activitymanager/kactivitymanagerd.desktop
@@ -78,7 +78,7 @@ Comment[bg]=Ядро за управление на дейности
Comment[bs]=Pozadina za upravljanje aktivnostima
Comment[ca]=Dorsal de gestió d'activitats
Comment[ca@valencia]=Dorsal de gestió d'activitats
-Comment[cs]=Backend pro správu aktivit
+Comment[cs]=Podpůrná vrstva pro správu aktivit
Comment[da]=Motor til aktivitetshåndtering
Comment[de]=Backend zur Aktivitätenverwaltung
Comment[el]=Σύστημα διαχείρισης δραστηριότητας
diff --git a/kioslave/thumbnail/cursorthumbnail.desktop b/kioslave/thumbnail/cursorthumbnail.desktop
index 1f50bf6..094d688 100644
--- a/kioslave/thumbnail/cursorthumbnail.desktop
+++ b/kioslave/thumbnail/cursorthumbnail.desktop
@@ -81,7 +81,7 @@ Name[te]=ములుకు దస్త్రాలు
Name[tg]=Файлҳои курсор
Name[th]=แฟ้มเคอร์เซอร์ต่างๆ
Name[tr]=İmleç Dosyaları
-Name[ug]=نۇر بەلگە ھۆججەتلەر
+Name[ug]=نۇربەلگە ھۆججەتلەر
Name[uk]=Файли курсорів
Name[uz]=Kursor fayllari
Name[uz@cyrillic]=Курсор файллари
diff --git a/knotify/hardwarenotifications.notifyrc b/knotify/hardwarenotifications.notifyrc
index d6589e3..f8f0e6c 100644
--- a/knotify/hardwarenotifications.notifyrc
+++ b/knotify/hardwarenotifications.notifyrc
@@ -188,7 +188,7 @@ Name[ta]=கருவி நோட்டம்
Name[tg]=Извещение о новых устройствах
Name[th]=แจ้งให้ทราบถึงอุปกรณ์
Name[tr]=Aygıt Bildirici
-Name[ug]=ئۈسكىنە ئۇقتۇرۇشى
+Name[ug]=ئۈسكۈنە ئۇقتۇرۇشى
Name[uk]=Сповіщення про пристрої
Name[wa]=Notifiaedje d' éndjin
Name[x-test]=xxDevice Notifierxx
@@ -241,7 +241,7 @@ Comment[sr@latin]=Plasma izveštavač o uređajima je prisutan
Comment[sv]=Plasma enhetsunderrättelser är tillgänglig
Comment[th]=แสดงตัวแจ้งเกี่ยวกับอุปกรณ์บนพลาสมาอยู่
Comment[tr]=Plasma aygıt bildiricisi mevcut
-Comment[ug]=پىلازما ئۈسكىنىسىنىڭ بىلدۈرگۈسى مەۋجۇت
+Comment[ug]=پىلازما ئۈسكۈنىسىنىڭ بىلدۈرگۈسى مەۋجۇت
Comment[uk]=Сповіщувач Плазми про пристрої увімкнено
Comment[x-test]=xxThe Plasma device notifier is presentxx
Comment[zh_CN]=显示 Plasma 设备通知
@@ -424,7 +424,7 @@ Name[sr@latin]=Uređaj se može bezbedno ukloniti
Name[sv]=Enheten kan urkopplas säkert
Name[th]=สามารถถอดอุปกรณ์ได้อย่างปลอดภัย
Name[tr]=Aygıt güvenli bir şekilde kaldırılabilir
-Name[ug]=ئۈسكىنىنى ھازىر بىخەتەر چىقىرىشقا بولىدۇ
+Name[ug]=ئۈسكۈنىنى ھازىر بىخەتەر چىقىرىشقا بولىدۇ
Name[uk]=Пристрій можна безпечно від’єднувати
Name[x-test]=xxThe device can be safely removedxx
Name[zh_CN]=可以安全的移除设备了
@@ -475,7 +475,7 @@ Comment[sr@latin]=Upravo demontirani uređaj može se sada bezbedno ukloniti.
Comment[sv]=Enheten som precis har avmonterats kan nu urkopplas säkert.
Comment[th]=อุปกรณ์ที่เพิ่งยกเลิกการเมานท์สามารถถอดออกได้อย่างปลอดภัย
Comment[tr]=Çıkarılan aygıt güvenli bir şekilde kaldırılabilir
-Comment[ug]=ھازىر ئېگەرسىزلىگەن ئۈسكىنىنى بىخەتەر چىقىرىشقا بولىدۇ
+Comment[ug]=ھازىر ئېگەرسىزلىگەن ئۈسكۈنىنى بىخەتەر چىقىرىشقا بولىدۇ
Comment[uk]=Пристрій, який щойно було демонтовано можна безпечно від’єднувати.
Comment[x-test]=xxThe device which has been just unmounted is now safe to remove.xx
Comment[zh_CN]=已经卸载了设备,可以安全移除了。
diff --git a/knotify/notifybypopup.cpp b/knotify/notifybypopup.cpp
index 3b93c24..213421c 100644
--- a/knotify/notifybypopup.cpp
+++ b/knotify/notifybypopup.cpp
@@ -68,6 +68,10 @@ NotifyByPopup::NotifyByPopup(QObject *parent)
watcher->addWatchedService(dbusServiceName);
connect(watcher, SIGNAL(serviceOwnerChanged(const QString&, const QString&, const QString&)),
SLOT(slotServiceOwnerChanged(const QString&, const QString&, const QString&)));
+#ifdef Q_WS_WIN
+ if(!m_dbusServiceExists)
+ QDBusConnection::sessionBus().interface()->startService("org.freedesktop.Notifications");
+#endif
}
diff --git a/kurifilter-plugins/ikws/ikwsopts.cpp b/kurifilter-plugins/ikws/ikwsopts.cpp
index ceea753..7aa3004 100644
--- a/kurifilter-plugins/ikws/ikwsopts.cpp
+++ b/kurifilter-plugins/ikws/ikwsopts.cpp
@@ -25,6 +25,7 @@
#include "searchprovider.h"
#include "searchproviderdlg.h"
+#include <KDE/KDebug>
#include <KDE/KStandardDirs>
#include <KDE/KServiceTypeTrader>
#include <KDE/KBuildSycocaProgressDialog>
@@ -102,8 +103,7 @@ QVariant ProvidersModel::data(const QModelIndex& index, int role) const
void ProvidersModel::setProviders(const QList<SearchProvider*>& providers, const QStringList& favoriteEngines)
{
m_providers = providers;
- m_favoriteEngines = QSet<QString>::fromList(favoriteEngines);
- reset();
+ setFavoriteProviders(favoriteEngines);
}
void ProvidersModel::setFavoriteProviders(const QStringList& favoriteEngines)
@@ -148,7 +148,7 @@ void ProvidersModel::deleteProvider(SearchProvider* p)
void ProvidersModel::addProvider(SearchProvider* p)
{
beginInsertRows(QModelIndex(), m_providers.size(), m_providers.size());
- m_providers.append(p);
+ m_providers.append(p);
endInsertRows();
emit dataModified();
}
@@ -276,7 +276,7 @@ void FilterOptions::load()
Q_FOREACH(const KService::Ptr &service, services)
{
- SearchProvider* provider=new SearchProvider(service);
+ SearchProvider* provider = new SearchProvider(service);
if (defaultSearchEngine == provider->desktopEntryName())
defaultProviderIndex = providers.size();
providers.append(provider);
@@ -318,58 +318,26 @@ void FilterOptions::save()
group.writeEntry("FavoriteSearchEngines", m_providersModel->favoriteEngines());
group.writeEntry("UseSelectedProvidersOnly", m_dlg.cbUseSelectedShortcutsOnly->isChecked());
- QList<SearchProvider*> providers = m_providersModel->providers();
- QString path = KGlobal::mainComponent().dirs()->saveLocation("services", "searchproviders/");
int changedProviderCount = 0;
+ QList<SearchProvider*> providers = m_providersModel->providers();
+ const QString path = KGlobal::mainComponent().dirs()->saveLocation("services", "searchproviders/");
+
Q_FOREACH(SearchProvider* provider, providers)
{
if (!provider->isDirty())
continue;
- changedProviderCount++;
-
- QString name = provider->desktopEntryName();
- if (name.isEmpty())
- {
- // New provider
- // Take the longest search shortcut as filename,
- // if such a file already exists, append a number and increase it
- // until the name is unique
- Q_FOREACH(const QString& key, provider->keys())
- {
- if (key.length() > name.length())
- name = key.toLower();
- }
- for (int suffix = 0; ; ++suffix)
- {
- QString located, check = name;
- if (suffix)
- check += QString().setNum(suffix);
- if ((located = KStandardDirs::locate("services", "searchproviders/" + check + ".desktop")).isEmpty())
- {
- name = check;
- break;
- }
- else if (located.startsWith(path))
- {
- // If it's a deleted (hidden) entry, overwrite it
- if (KService(located).isDeleted())
- break;
- }
- }
- }
+ changedProviderCount++;
- KConfig _service(path + name + ".desktop", KConfig::SimpleConfig );
+ KConfig _service(path + provider->desktopEntryName() + ".desktop", KConfig::SimpleConfig );
KConfigGroup service(&_service, "Desktop Entry");
- service.writeEntry("Type", "Service");
- service.writeEntry("ServiceTypes", "SearchProvider");
- service.writeEntry("Name", provider->name());
- service.writeEntry("Query", provider->query());
- service.writeEntry("Keys", provider->keys());
- service.writeEntry("Charset", provider->charset());
-
- // we might be overwriting a hidden entry
- service.writeEntry("Hidden", false);
+ service.writeEntry("Type", "Service");
+ service.writeEntry("ServiceTypes", "SearchProvider");
+ service.writeEntry("Name", provider->name());
+ service.writeEntry("Query", provider->query());
+ service.writeEntry("Keys", provider->keys());
+ service.writeEntry("Charset", provider->charset());
+ service.writeEntry("Hidden", false); // we might be overwriting a hidden entry
}
Q_FOREACH(const QString& providerName, m_deletedProviders)
@@ -381,6 +349,7 @@ void FilterOptions::save()
continue;
changedProviderCount++;
+
if (matches.size() == 1 && matches.first().startsWith(path))
{
// If only the local copy existed, unlink it
@@ -388,6 +357,7 @@ void FilterOptions::save()
QFile::remove(matches.first());
continue;
}
+
KConfig _service(path + providerName + ".desktop", KConfig::SimpleConfig );
KConfigGroup service(&_service, "Desktop Entry");
service.writeEntry("Type", "Service");
diff --git a/kurifilter-plugins/ikws/kuriikwsfilter.cpp b/kurifilter-plugins/ikws/kuriikwsfilter.cpp
index a95f1f3..0a343ac 100644
--- a/kurifilter-plugins/ikws/kuriikwsfilter.cpp
+++ b/kurifilter-plugins/ikws/kuriikwsfilter.cpp
@@ -46,7 +46,7 @@ KAutoWebSearch::KAutoWebSearch(QObject *parent, const QVariantList&)
:KUriFilterPlugin( "kuriikwsfilter", parent )
{
KGlobal::locale()->insertCatalog("kurifilter");
- QDBusConnection::sessionBus().connect(QString(), QString(), "org.kde.KUriFilterPlugin",
+ QDBusConnection::sessionBus().connect(QString(), "/", "org.kde.KUriFilterPlugin",
"configure", this, SLOT(configure()));
}
diff --git a/kurifilter-plugins/ikws/kurisearchfilter.cpp b/kurifilter-plugins/ikws/kurisearchfilter.cpp
index 33bffcf..17b6660 100644
--- a/kurifilter-plugins/ikws/kurisearchfilter.cpp
+++ b/kurifilter-plugins/ikws/kurisearchfilter.cpp
@@ -39,7 +39,7 @@ KUriSearchFilter::KUriSearchFilter(QObject *parent, const QVariantList &)
:KUriFilterPlugin( "kurisearchfilter", parent )
{
KGlobal::locale()->insertCatalog("kurifilter");
- QDBusConnection::sessionBus().connect(QString(), QString(), "org.kde.KUriFilterPlugin",
+ QDBusConnection::sessionBus().connect(QString(), "/", "org.kde.KUriFilterPlugin",
"configure", this, SLOT(configure()));
}
diff --git a/kurifilter-plugins/ikws/searchprovider.cpp b/kurifilter-plugins/ikws/searchprovider.cpp
index 5b66ebd..5ea3608 100644
--- a/kurifilter-plugins/ikws/searchprovider.cpp
+++ b/kurifilter-plugins/ikws/searchprovider.cpp
@@ -18,6 +18,8 @@
#include "searchprovider.h"
+#include <krandom.h>
+#include <kstandarddirs.h>
#include <kservicetypetrader.h>
SearchProvider::SearchProvider(const KService::Ptr service)
@@ -52,7 +54,47 @@ void SearchProvider::setKeys(const QStringList &keys)
if (KUriFilterSearchProvider::keys() == keys)
return;
- KUriFilterSearchProvider::setKeys(keys);
+ KUriFilterSearchProvider::setKeys(keys);
+
+ QString name = desktopEntryName();
+ if (!name.isEmpty())
+ return;
+
+ // New provider. Set the desktopEntryName.
+ // Take the longest search shortcut as filename,
+ // if such a file already exists, append a number and increase it
+ // until the name is unique
+ Q_FOREACH(const QString& key, keys)
+ {
+ if (key.length() > name.length())
+ name = key.toLower();
+ }
+
+ const QString path (KGlobal::mainComponent().dirs()->saveLocation("services", "searchproviders/"));
+ bool firstRun = true;
+
+ while (true)
+ {
+ QString check(name);
+
+ if (!firstRun)
+ check += KRandom::randomString(4);
+
+ const QString located = KStandardDirs::locate("services", "searchproviders/" + check + ".desktop");
+ if (located.isEmpty())
+ {
+ name = check;
+ break;
+ }
+ else if (located.startsWith(path))
+ {
+ // If it's a deleted (hidden) entry, overwrite it
+ if (KService(located).isDeleted())
+ break;
+ }
+ }
+
+ setDesktopEntryName(name);
}
void SearchProvider::setCharset(const QString &charset)
diff --git a/kurifilter-plugins/ikws/searchproviders/call.desktop b/kurifilter-plugins/ikws/searchproviders/call.desktop
index 54edd61..4a2fc0b 100644
--- a/kurifilter-plugins/ikws/searchproviders/call.desktop
+++ b/kurifilter-plugins/ikws/searchproviders/call.desktop
@@ -90,94 +90,6 @@ Name[wa]=Båzes di dnêyes des indicatifs di houcaedje (avions) QRZ.com
Name[x-test]=xxQRZ.com Callsign Databasexx
Name[zh_CN]=QRZ.com Callsign 数据库
Name[zh_TW]=QRZ.com Callsign 資料庫
-Query=http://www.qrz.com/database?callsign=\\{@}
-Query[af]=http://www.qrz.com/database?callsign=\\{@}
-Query[ar]=http://www.qrz.com/database?callsign=\\{@}
-Query[as]=http://www.qrz.com/database?callsign=\\{@}
-Query[ast]=http://www.qrz.com/database?callsign=\\{@}
-Query[be]=http://www.qrz.com/database?callsign=\\{@}
-Query[be@latin]=http://www.qrz.com/database?callsign=\\{@}
-Query[bg]=http://www.qrz.com/database?callsign=\\{@}
-Query[bn]=http://www.qrz.com/database?callsign=\\{@}
-Query[bn_IN]=http://www.qrz.com/database?callsign=\\{@}
-Query[br]=http://www.qrz.com/database?callsign=\\{@}
-Query[bs]=http://www.qrz.com/database?callsign=\\{@}
-Query[ca]=http://www.qrz.com/database?callsign=\\{@}
-Query[ca@valencia]=http://www.qrz.com/database?callsign=\\{@}
-Query[cs]=http://www.qrz.com/database?callsign=\\{@}
-Query[csb]=http://www.qrz.com/database?callsign=\\{@}
-Query[da]=http://www.qrz.com/database?callsign=\\{@}
-Query[de]=http://www.qrz.com/database?callsign=\\{@}
-Query[el]=http://www.qrz.com/database?callsign=\\{@}
-Query[en_GB]=http://www.qrz.com/database?callsign=\\{@}
-Query[eo]=http://www.qrz.com/database?callsign=\\{@}
-Query[es]=http://www.qrz.com/database?callsign=\\{@}
-Query[et]=http://www.qrz.com/database?callsign=\\{@}
-Query[eu]=http://www.qrz.com/database?callsign=\\{@}
-Query[fi]=http://www.qrz.com/database?callsign=\\{@}
-Query[fr]=http://www.qrz.com/database?callsign=\\{@}
-Query[fy]=http://www.qrz.com/database?callsign=\\{@}
-Query[ga]=http://www.qrz.com/database?callsign=\\{@}
-Query[gl]=http://www.qrz.com/database?callsign=\\{@}
-Query[gu]=http://www.qrz.com/database?callsign=\\{@}
-Query[he]=http://www.qrz.com/database?callsign=\\{@}
-Query[hi]=http://www.qrz.com/database?callsign=\\{@}
-Query[hne]=http://www.qrz.com/database?callsign=\\{@}
-Query[hr]=http://www.qrz.com/database?callsign=\\{@}
-Query[hsb]=http://www.qrz.com/database?callsign=\\{@}
-Query[hu]=http://www.qrz.com/database?callsign=\\{@}
-Query[ia]=http://www.qrz.com/database?callsign=\\{@}
-Query[id]=http://www.qrz.com/database?callsign=\\{@}
-Query[is]=http://www.qrz.com/database?callsign=\\{@}
-Query[it]=http://www.qrz.com/database?callsign=\\{@}
-Query[ja]=http://www.qrz.com/database?callsign=\\{@}
-Query[ka]=http://www.qrz.com/database?callsign=\\{@}
-Query[kk]=http://www.qrz.com/database?callsign=\\{@}
-Query[km]=http://www.qrz.com/database?callsign=\\{@}
-Query[kn]=http://www.qrz.com/database?callsign=\\{@}
-Query[ko]=http://www.qrz.com/database?callsign=\\{@}
-Query[ku]=http://www.qrz.com/database?callsign=\\{@}
-Query[lt]=http://www.qrz.com/database?callsign=\\{@}
-Query[lv]=http://www.qrz.com/database?callsign=\\{@}
-Query[mai]=http://www.qrz.com/database?callsign=\\{@}
-Query[ml]=http://www.qrz.com/database?callsign=\\{@}
-Query[mr]=http://www.qrz.com/database?callsign=\\{@}
-Query[ms]=http://www.qrz.com/database?callsign=\\{@}
-Query[nb]=http://www.qrz.com/database?callsign=\\{@}
-Query[nds]=http://www.qrz.com/database?callsign=\\{@}
-Query[ne]=http://www.qrz.com/database?callsign=\\{@}
-Query[nl]=http://www.qrz.com/database?callsign=\\{@}
-Query[nn]=http://www.qrz.com/database?callsign=\\{@}
-Query[oc]=http://www.qrz.com/database?callsign=\\{@}
-Query[or]=http://www.qrz.com/database?callsign=\\{@}
-Query[pa]=http://www.qrz.com/database?callsign=\\{@}
-Query[pl]=http://www.qrz.com/database?callsign=\\{@}
-Query[pt]=http://www.qrz.com/database?callsign=\\{@}
-Query[pt_BR]=http://www.qrz.com/database?callsign=\\{@}
-Query[ro]=http://www.qrz.com/database?callsign=\\{@}
-Query[ru]=http://www.qrz.com/database?callsign=\\{@}
-Query[se]=http://www.qrz.com/database?callsign=\\{@}
-Query[si]=http://www.qrz.com/database?callsign=\\{@}
-Query[sk]=http://www.qrz.com/database?callsign=\\{@}
-Query[sl]=http://www.qrz.com/database?callsign=\\{@}
-Query[sr]=http://www.qrz.com/database?callsign=\\{@}
-Query[sr@ijekavian]=http://www.qrz.com/database?callsign=\\{@}
-Query[sr@ijekavianlatin]=http://www.qrz.com/database?callsign=\\{@}
-Query[sr@latin]=http://www.qrz.com/database?callsign=\\{@}
-Query[sv]=http://www.qrz.com/database?callsign=\\{@}
-Query[ta]=http://www.qrz.com/database?callsign=\\{@}
-Query[te]=http://www.qrz.com/database?callsign=\\{@}
-Query[tg]=http://www.qrz.com/database?callsign=\\{@}
-Query[th]=http://www.qrz.com/database?callsign=\\{@}
-Query[tr]=http://www.qrz.com/database?callsign=\\{@}
-Query[ug]=http://www.qrz.com/database?callsign=\\{@}
-Query[uk]=http://www.qrz.com/database?callsign=\\{@}
-Query[uz]=http://www.qrz.com/database?callsign=\\{@}
-Query[uz@cyrillic]=http://www.qrz.com/database?callsign=\\{@}
-Query[vi]=http://www.qrz.com/database?callsign=\\{@}
-Query[wa]=http://www.qrz.com/database?callsign=\\{@}
-Query[x-test]=xxhttp://www.qrz.com/database?callsign=\\{@}xx
-Query[zh_CN]=http://www.qrz.com/database?callsign=\\{@}
-Query[zh_TW]=http://www.qrz.com/database?callsign=\\{@}
+Query=http://www.qrz.com/db/\\{@}
X-KDE-ServiceTypes=SearchProvider
Type=Service
diff --git a/kurifilter-plugins/shorturi/kshorturifilter.cpp b/kurifilter-plugins/shorturi/kshorturifilter.cpp
index a7e23ec..802b325 100644
--- a/kurifilter-plugins/shorturi/kshorturifilter.cpp
+++ b/kurifilter-plugins/shorturi/kshorturifilter.cpp
@@ -96,7 +96,7 @@ static QString removeArgs( const QString& _cmd )
KShortUriFilter::KShortUriFilter( QObject *parent, const QVariantList & /*args*/ )
:KUriFilterPlugin( "kshorturifilter", parent )
{
- QDBusConnection::sessionBus().connect(QString(), QString(), "org.kde.KUriFilterPlugin",
+ QDBusConnection::sessionBus().connect(QString(), "/", "org.kde.KUriFilterPlugin",
"configure", this, SLOT(configure()));
configure();
}
diff --git a/nepomuk/common/fileexcludefilters.cpp b/nepomuk/common/fileexcludefilters.cpp
index 2172b52..079332a 100644
--- a/nepomuk/common/fileexcludefilters.cpp
+++ b/nepomuk/common/fileexcludefilters.cpp
@@ -59,11 +59,14 @@ namespace {
"litmain.sh",
"*.orig",
".histfile.*",
+ ".xsession-errors*",
// end of list
0
};
+ const int s_defaultFileExcludeFiltersVersion = 2;
+
const char* s_defaultFolderExcludeFilters[] = {
"po",
@@ -85,6 +88,8 @@ namespace {
// end of list
0
};
+
+ const int s_defaultFolderExcludeFiltersVersion = 1;
}
@@ -97,3 +102,8 @@ QStringList Nepomuk::defaultExcludeFilterList()
l << QLatin1String( s_defaultFolderExcludeFilters[i] );
return l;
}
+
+int Nepomuk::defaultExcludeFilterListVersion()
+{
+ return qMax(s_defaultFileExcludeFiltersVersion, s_defaultFolderExcludeFiltersVersion);
+}
diff --git a/nepomuk/common/fileexcludefilters.h b/nepomuk/common/fileexcludefilters.h
index 91eb088..311c0fe 100644
--- a/nepomuk/common/fileexcludefilters.h
+++ b/nepomuk/common/fileexcludefilters.h
@@ -31,6 +31,12 @@ namespace Nepomuk {
* user configurable exclude filters in the strigi service.
*/
NEPOMUKCOMMON_EXPORT QStringList defaultExcludeFilterList();
+
+ /**
+ * \return The version of the default exclude filter list.
+ * This is increased whenever the list changes.
+ */
+ NEPOMUKCOMMON_EXPORT int defaultExcludeFilterListVersion();
}
#endif
diff --git a/nepomuk/common/removablemediacache.cpp b/nepomuk/common/removablemediacache.cpp
index 54afdc2..dbb31c8 100644
--- a/nepomuk/common/removablemediacache.cpp
+++ b/nepomuk/common/removablemediacache.cpp
@@ -254,8 +254,8 @@ QString Nepomuk::RemovableMediaCache::Entry::constructLocalPath( const KUrl& fil
QString path( sa->filePath() );
if ( path.endsWith( QLatin1String( "/" ) ) )
path.truncate( path.length()-1 );
-
- return path + filexUrl.url().mid(m_urlPrefix.count());
+ // We use QUrl::toString instead of KUrl::url to resolve any encoded chars
+ return path + QUrl(filexUrl).toString().mid(m_urlPrefix.count());
}
}
diff --git a/nepomuk/services/filewatch/CMakeLists.txt b/nepomuk/services/filewatch/CMakeLists.txt
index d480b3c..3cda68b 100644
--- a/nepomuk/services/filewatch/CMakeLists.txt
+++ b/nepomuk/services/filewatch/CMakeLists.txt
@@ -20,6 +20,7 @@ set(SRCS
invalidfileresourcecleaner.cpp
../strigi/strigiserviceconfig.cpp
removabledeviceindexnotification.cpp
+ activefilequeue.cpp
)
qt4_add_dbus_interface(SRCS ../../interfaces/org.kde.nepomuk.Strigi.xml strigiserviceinterface)
diff --git a/nepomuk/services/filewatch/activefilequeue.cpp b/nepomuk/services/filewatch/activefilequeue.cpp
new file mode 100644
index 0000000..8bb54ed
--- /dev/null
+++ b/nepomuk/services/filewatch/activefilequeue.cpp
@@ -0,0 +1,130 @@
+/*
+ This file is part of the Nepomuk KDE project.
+ Copyright (C) 2011 Sebastian Trueg <trueg@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "activefilequeue.h"
+
+#include <QtCore/QQueue>
+#include <QtCore/QTimer>
+
+
+namespace {
+ class Entry {
+ public:
+ Entry(const KUrl& url, int c);
+ bool operator==(const Entry& other) const;
+
+ /// The file url
+ KUrl url;
+ /// The seconds left in this entry
+ int cnt;
+ };
+
+ Entry::Entry(const KUrl &u, int c)
+ : url(u),
+ cnt(c)
+ {
+ }
+
+ bool Entry::operator==(const Entry &other) const
+ {
+ // we ignore the counter since we need this for the search in queueUrl only
+ return url == other.url;
+ }
+}
+
+Q_DECLARE_TYPEINFO(Entry, Q_MOVABLE_TYPE);
+
+
+class ActiveFileQueue::Private
+{
+public:
+ QQueue<Entry> m_queue;
+ QTimer m_queueTimer;
+ int m_timeout;
+};
+
+
+ActiveFileQueue::ActiveFileQueue(QObject *parent)
+ : QObject(parent),
+ d(new Private())
+{
+ // we default to 5 seconds
+ d->m_timeout = 5;
+
+ // setup the timer
+ connect(&d->m_queueTimer, SIGNAL(timeout()),
+ this, SLOT(slotTimer()));
+
+ // we check in 1 sec intervals
+ d->m_queueTimer.setInterval(1000);
+}
+
+ActiveFileQueue::~ActiveFileQueue()
+{
+ delete d;
+}
+
+void ActiveFileQueue::enqueueUrl(const KUrl &url)
+{
+ Entry defaultEntry(url, d->m_timeout);
+ QQueue<Entry>::iterator it = qFind(d->m_queue.begin(), d->m_queue.end(), defaultEntry);
+ if(it == d->m_queue.end()) {
+ // if this is a new url add it with the default timeout
+ d->m_queue.enqueue(defaultEntry);
+ }
+ else {
+ // If the url is already in the queue update its timestamp
+ it->cnt = d->m_timeout;
+ }
+
+ // make sure the timer is running
+ if(!d->m_queueTimer.isActive()) {
+ d->m_queueTimer.start();
+ }
+}
+
+void ActiveFileQueue::setTimeout(int seconds)
+{
+ d->m_timeout = seconds;
+}
+
+void ActiveFileQueue::slotTimer()
+{
+ // we run through the queue, decrease each counter and emit each entry which has a count of 0
+ QQueue<Entry>::iterator it = d->m_queue.begin();
+ while(it != d->m_queue.end()) {
+ it->cnt--;
+ if(it->cnt == 0) {
+ emit urlTimeout(it->url);
+ it = d->m_queue.erase(it);
+ }
+ else {
+ ++it;
+ }
+ }
+
+ // stop the timer in case we have nothing left to do
+ if(d->m_queue.isEmpty()) {
+ d->m_queueTimer.stop();
+ }
+}
+
+#include "activefilequeue.moc"
diff --git a/nepomuk/services/filewatch/activefilequeue.h b/nepomuk/services/filewatch/activefilequeue.h
new file mode 100644
index 0000000..19d4813
--- /dev/null
+++ b/nepomuk/services/filewatch/activefilequeue.h
@@ -0,0 +1,71 @@
+/*
+ This file is part of the Nepomuk KDE project.
+ Copyright (C) 2011 Sebastian Trueg <trueg@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ACTIVEFILEQUEUE_H
+#define ACTIVEFILEQUEUE_H
+
+#include <QtCore/QObject>
+
+#include <KUrl>
+
+/**
+ * The active file queue maintains a queue of file paths
+ * with a timestamp. It will signal the timout of a file after
+ * a given time. As soon as a file is queued again its timestamp
+ * will be reset and the timing restarts.
+ *
+ * This allows to "compress" file modification events of downloads
+ * and the like into a single event resulting in a smoother
+ * experience for the user.
+ *
+ * \author Sebastian Trueg <trueg@ĸde.org>
+ */
+class ActiveFileQueue : public QObject
+{
+ Q_OBJECT
+
+public:
+ ActiveFileQueue(QObject *parent = 0);
+ ~ActiveFileQueue();
+
+signals:
+ void urlTimeout(const KUrl& url);
+
+public slots:
+ void enqueueUrl(const KUrl& url);
+
+ /**
+ * Set the timeout in seconds. Be aware that the timeout
+ * will not be exact. For internal reasons the queue tries
+ * to roughly match the configured timeout. It only guarantees
+ * that the timeout will be between \p seconds and \p seconds+1.
+ */
+ void setTimeout(int seconds);
+
+private slots:
+ void slotTimer();
+
+private:
+ class Private;
+ Private* const d;
+};
+
+#endif // ACTIVEFILEQUEUE_H
diff --git a/nepomuk/services/filewatch/metadatamover.cpp b/nepomuk/services/filewatch/metadatamover.cpp
index 8db2ecf..eb4f357 100644
--- a/nepomuk/services/filewatch/metadatamover.cpp
+++ b/nepomuk/services/filewatch/metadatamover.cpp
@@ -213,7 +213,7 @@ void Nepomuk::MetadataMover::updateMetadata( const KUrl& from, const KUrl& to )
// If we have no metadata yet we need to tell strigi (if running) so it can
// create the metadata in case the target folder is configured to be indexed.
//
- emit movedWithoutData( to.directory( KUrl::IgnoreTrailingSlash ) );
+ emit movedWithoutData( to.path() );
}
}
diff --git a/nepomuk/services/filewatch/nepomukfilewatch.cpp b/nepomuk/services/filewatch/nepomukfilewatch.cpp
index fad7d0d..33e1e92 100644
--- a/nepomuk/services/filewatch/nepomukfilewatch.cpp
+++ b/nepomuk/services/filewatch/nepomukfilewatch.cpp
@@ -24,6 +24,7 @@
#include "removabledeviceindexnotification.h"
#include "removablemediacache.h"
#include "../strigi/strigiserviceconfig.h"
+#include "activefilequeue.h"
#ifdef BUILD_KINOTIFY
#include "kinotify.h"
@@ -98,10 +99,12 @@ namespace {
if( Nepomuk::StrigiServiceConfig::self()->shouldFolderBeIndexed( path ) ) {
modes |= KInotify::EventCreate;
modes |= KInotify::EventModify;
+ modes |= KInotify::EventCloseWrite;
}
else {
modes &= (~KInotify::EventCreate);
modes &= (~KInotify::EventModify);
+ modes &= (~KInotify::EventCloseWrite);
}
return true;
@@ -113,6 +116,10 @@ namespace {
Nepomuk::FileWatch::FileWatch( QObject* parent, const QList<QVariant>& )
: Service( parent )
{
+ // Create the configuration instance singleton (for thread-safety)
+ // ==============================================================
+ (void)new StrigiServiceConfig(this);
+
// the list of default exclude filters we use here differs from those
// that can be configured for the strigi service
// the default list should only contain files and folders that users are
@@ -129,6 +136,10 @@ Nepomuk::FileWatch::FileWatch( QObject* parent, const QList<QVariant>& )
Qt::QueuedConnection );
m_metadataMover->start();
+ m_fileModificationQueue = new ActiveFileQueue(this);
+ connect(m_fileModificationQueue, SIGNAL(urlTimeout(KUrl)),
+ this, SLOT(slotActiveFileQueueTimeout(KUrl)));
+
#ifdef BUILD_KINOTIFY
// monitor the file system for changes (restricted by the inotify limit)
m_dirWatch = new IgnoringKInotify( m_pathExcludeRegExpCache, this );
@@ -141,6 +152,8 @@ Nepomuk::FileWatch::FileWatch( QObject* parent, const QList<QVariant>& )
this, SLOT( slotFileCreated( QString ) ) );
connect( m_dirWatch, SIGNAL( modified( QString ) ),
this, SLOT( slotFileModified( QString ) ) );
+ connect( m_dirWatch, SIGNAL( closedWrite( QString ) ),
+ this, SLOT( slotFileClosedAfterWrite( QString ) ) );
connect( m_dirWatch, SIGNAL( watchUserLimitReached() ),
this, SLOT( slotInotifyWatchUserLimitReached() ) );
@@ -185,7 +198,7 @@ void Nepomuk::FileWatch::watchFolder( const QString& path )
#ifdef BUILD_KINOTIFY
if ( m_dirWatch && !m_dirWatch->watchingPath( path ) )
m_dirWatch->addWatch( path,
- KInotify::WatchEvents( KInotify::EventMove|KInotify::EventDelete|KInotify::EventDeleteSelf|KInotify::EventCreate|KInotify::EventModify ),
+ KInotify::WatchEvents( KInotify::EventMove|KInotify::EventDelete|KInotify::EventDeleteSelf|KInotify::EventCreate|KInotify::EventModify|KInotify::EventCloseWrite ),
KInotify::WatchFlags() );
#endif
}
@@ -193,7 +206,7 @@ void Nepomuk::FileWatch::watchFolder( const QString& path )
void Nepomuk::FileWatch::slotFileMoved( const QString& urlFrom, const QString& urlTo )
{
- if( !ignorePath( urlFrom ) ) {
+ if( !ignorePath( urlFrom ) || !ignorePath( urlTo ) ) {
KUrl from( urlFrom );
KUrl to( urlTo );
@@ -233,20 +246,36 @@ void Nepomuk::FileWatch::slotFileDeleted( const QString& urlString, bool isDir )
void Nepomuk::FileWatch::slotFileCreated( const QString& path )
{
- kDebug() << path;
- updateFileViaStrigi( path );
+ if( StrigiServiceConfig::self()->shouldBeIndexed(path) ) {
+ // we only cache the file and wait until it has been closed, ie. the writing has been finished
+ m_modifiedFilesCache.insert(path);
+ }
}
void Nepomuk::FileWatch::slotFileModified( const QString& path )
{
- updateFileViaStrigi( path );
+ if( StrigiServiceConfig::self()->shouldBeIndexed(path) ) {
+ // we only cache the file and wait until it has been closed, ie. the writing has been finished
+ m_modifiedFilesCache.insert(path);
+ }
}
+void Nepomuk::FileWatch::slotFileClosedAfterWrite( const QString& path )
+{
+ // we only need to update the file if it has actually been modified
+ QSet<KUrl>::iterator it = m_modifiedFilesCache.find(path);
+ if(it != m_modifiedFilesCache.end()) {
+ // we do not tell the file indexer right away but wait a short while in case the file is modified very often (irc logs for example)
+ m_fileModificationQueue->enqueueUrl( path );
+ m_modifiedFilesCache.erase(it);
+ }
+}
+
void Nepomuk::FileWatch::slotMovedWithoutData( const QString& path )
{
- updateFolderViaStrigi( path );
+ updateFileViaStrigi( path );
}
@@ -378,4 +407,9 @@ void Nepomuk::FileWatch::slotDeviceMounted(const Nepomuk::RemovableMediaCache::E
watchFolder(entry->mountPath());
}
+void Nepomuk::FileWatch::slotActiveFileQueueTimeout(const KUrl &url)
+{
+ updateFileViaStrigi(url.toLocalFile());
+}
+
#include "nepomukfilewatch.moc"
diff --git a/nepomuk/services/filewatch/nepomukfilewatch.h b/nepomuk/services/filewatch/nepomukfilewatch.h
index 3e61b91..a85c349 100644
--- a/nepomuk/services/filewatch/nepomukfilewatch.h
+++ b/nepomuk/services/filewatch/nepomukfilewatch.h
@@ -37,6 +37,7 @@ namespace Soprano {
class KInotify;
class KUrl;
class RegExpCache;
+class ActiveFileQueue;
namespace Nepomuk {
@@ -72,6 +73,7 @@ namespace Nepomuk {
void slotFilesDeleted( const QStringList& path );
void slotFileCreated( const QString& );
void slotFileModified( const QString& );
+ void slotFileClosedAfterWrite( const QString& );
void slotMovedWithoutData( const QString& );
void connectToKDirWatch();
#ifdef BUILD_KINOTIFY
@@ -91,6 +93,8 @@ namespace Nepomuk {
*/
void slotDeviceMounted( const Nepomuk::RemovableMediaCache::Entry* );
+ void slotActiveFileQueueTimeout(const KUrl& url);
+
private:
/**
* Adds watches for all mounted removable media.
@@ -112,6 +116,12 @@ namespace Nepomuk {
RegExpCache* m_pathExcludeRegExpCache;
RemovableMediaCache* m_removableMediaCache;
+
+ /// stores all the file URLs that have been modified but not closed yet
+ QSet<KUrl> m_modifiedFilesCache;
+
+ /// queue used to "compress" constant file modifications like downloads
+ ActiveFileQueue* m_fileModificationQueue;
};
}
diff --git a/nepomuk/services/filewatch/test/CMakeLists.txt b/nepomuk/services/filewatch/test/CMakeLists.txt
index ab30228..9d518a3 100644
--- a/nepomuk/services/filewatch/test/CMakeLists.txt
+++ b/nepomuk/services/filewatch/test/CMakeLists.txt
@@ -10,3 +10,10 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
${KDE4_KDECORE_LIBS}
)
endif(CMAKE_SYSTEM_NAME MATCHES "Linux")
+
+set(activefilequeuetest_SRC activefilequeuetest.cpp ../activefilequeue.cpp)
+kde4_add_unit_test(activefilequeuetest TESTNAME nepomuk-activefilequeuetest NOGUI ${activefilequeuetest_SRC})
+target_link_libraries(activefilequeuetest
+ ${QT_QTTEST_LIBRARY}
+ ${KDE4_KDECORE_LIBS}
+)
diff --git a/nepomuk/services/filewatch/test/activefilequeuetest.cpp b/nepomuk/services/filewatch/test/activefilequeuetest.cpp
new file mode 100644
index 0000000..0445e8f
--- /dev/null
+++ b/nepomuk/services/filewatch/test/activefilequeuetest.cpp
@@ -0,0 +1,100 @@
+/*
+ This file is part of the Nepomuk KDE project.
+ Copyright (C) 2011 Sebastian Trueg <trueg@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "activefilequeuetest.h"
+#include "../activefilequeue.h"
+
+#include <QtTest>
+#include <qtest_kde.h>
+
+
+namespace {
+ void loopWait(int msecs) {
+ QEventLoop loop;
+ QTimer::singleShot(msecs, &loop, SLOT(quit()));
+ loop.exec();
+ }
+}
+
+ActiveFileQueueTest::ActiveFileQueueTest()
+{
+ qRegisterMetaType<KUrl>();
+}
+
+void ActiveFileQueueTest::testTimeout()
+{
+ KUrl myUrl("/tmp");
+
+ // enqueue one url and then make sure it is not emitted before the timeout
+ ActiveFileQueue queue;
+ queue.setTimeout(3);
+ queue.enqueueUrl(myUrl);
+
+ QSignalSpy spy( &queue, SIGNAL(urlTimeout(KUrl)) );
+
+ // wait for 1 seconds
+ loopWait(1000);
+
+ // the signal should not have been emitted yet
+ QVERIFY(spy.isEmpty());
+
+ // wait another 2 seconds
+ loopWait(2000);
+
+ // now the signal should have been emitted
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().first().value<KUrl>(), myUrl);
+}
+
+void ActiveFileQueueTest::testRequeue()
+{
+ KUrl myUrl("/tmp");
+
+ // enqueue one url and then make sure it is not emitted before the timeout
+ ActiveFileQueue queue;
+ queue.setTimeout(3);
+ queue.enqueueUrl(myUrl);
+
+ QSignalSpy spy( &queue, SIGNAL(urlTimeout(KUrl)) );
+
+ // wait for 2 seconds
+ loopWait(1000);
+
+ // re-queue the url
+ queue.enqueueUrl(myUrl);
+
+ // wait another 2 seconds
+ loopWait(2000);
+
+ // the signal should not have been emitted yet
+ QVERIFY(spy.isEmpty());
+
+ // wait another 2 seconds
+ loopWait(2000);
+
+ // now the signal should have been emitted
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().first().value<KUrl>(), myUrl);
+}
+
+QTEST_MAIN(ActiveFileQueueTest)
+
+#include "activefilequeuetest.moc"
diff --git a/nepomuk/services/filewatch/test/activefilequeuetest.h b/nepomuk/services/filewatch/test/activefilequeuetest.h
new file mode 100644
index 0000000..34610be
--- /dev/null
+++ b/nepomuk/services/filewatch/test/activefilequeuetest.h
@@ -0,0 +1,39 @@
+/*
+ This file is part of the Nepomuk KDE project.
+ Copyright (C) 2011 Sebastian Trueg <trueg@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ACTIVEFILEQUEUETEST_H
+#define ACTIVEFILEQUEUETEST_H
+
+#include <QObject>
+
+class ActiveFileQueueTest : public QObject
+{
+ Q_OBJECT
+
+public:
+ ActiveFileQueueTest();
+
+private slots:
+ void testTimeout();
+ void testRequeue();
+};
+
+#endif // ACTIVEFILEQUEUETEST_H
diff --git a/nepomuk/services/storage/datamanagementmodel.cpp b/nepomuk/services/storage/datamanagementmodel.cpp
index af653f9..fe68e29 100644
--- a/nepomuk/services/storage/datamanagementmodel.cpp
+++ b/nepomuk/services/storage/datamanagementmodel.cpp
@@ -1063,17 +1063,18 @@ void Nepomuk::DataManagementModel::removeDataByApplication(const QList<QUrl> &re
//
// Gather the resources that we actually change, ie. those which have non-metadata props in the removed graphs
//
- Soprano::QueryResultIterator mResIt
- = executeQuery(QString::fromLatin1("select ?r where { graph ?g { ?r ?p ?o . FILTER(?r in (%1)) . FILTER(%2) . } . FILTER(?g in (%3)) . }")
- .arg(resourcesToN3(resolvedResources).join(QLatin1String(",")),
- createResourceMetadataPropertyFilter(QLatin1String("?p"), true),
- resourcesToN3(graphsToRemove).join(QLatin1String(","))),
- Soprano::Query::QueryLanguageSparql);
- while(mResIt.next()) {
- modifiedResources.insert(mResIt[0].uri());
+ if( !graphsToRemove.isEmpty() ) {
+ Soprano::QueryResultIterator mResIt
+ = executeQuery(QString::fromLatin1("select ?r where { graph ?g { ?r ?p ?o . FILTER(?r in (%1)) . FILTER(%2) . } . FILTER(?g in (%3)) . }")
+ .arg(resourcesToN3(resolvedResources).join(QLatin1String(",")),
+ createResourceMetadataPropertyFilter(QLatin1String("?p"), true),
+ resourcesToN3(graphsToRemove).join(QLatin1String(","))),
+ Soprano::Query::QueryLanguageSparql);
+ while(mResIt.next()) {
+ modifiedResources.insert(mResIt[0].uri());
+ }
}
-
//
// Remove the actual data. This has to be done using removeAllStatements. Otherwise the crappy inferencer cannot follow the changes.
//
diff --git a/nepomuk/services/storage/datamanagementmodel.h b/nepomuk/services/storage/datamanagementmodel.h
index 9722157..67fcbeb 100644
--- a/nepomuk/services/storage/datamanagementmodel.h
+++ b/nepomuk/services/storage/datamanagementmodel.h
@@ -156,7 +156,7 @@ public Q_SLOTS:
const QString& app,
Nepomuk::StoreIdentificationMode identificationMode = Nepomuk::IdentifyNew,
Nepomuk::StoreResourcesFlags flags = Nepomuk::NoStoreResourcesFlags,
- const QHash<QUrl, QVariant>& additionalMetadata = QHash<QUrl, QVariant>() );
+ const QHash<QUrl, QVariant>& additionalMetadata = (QHash<QUrl, QVariant>()));
/**
* Merges two resources into one. Properties from \p resource1
@@ -188,7 +188,7 @@ public Q_SLOTS:
const QString& userSerialization = QString(),
Nepomuk::StoreIdentificationMode identificationMode = Nepomuk::IdentifyNew,
Nepomuk::StoreResourcesFlags flags = Nepomuk::NoStoreResourcesFlags,
- const QHash<QUrl, QVariant>& additionalMetadata = QHash<QUrl, QVariant>());
+ const QHash<QUrl, QVariant>& additionalMetadata = (QHash<QUrl, QVariant>()));
/**
* Describe a set of resources, i.e. retrieve all their properties.
@@ -200,7 +200,7 @@ public Q_SLOTS:
//@}
private:
- QUrl createGraph(const QString& app = QString(), const QHash<QUrl, QVariant>& additionalMetadata = QHash<QUrl, QVariant>());
+ QUrl createGraph(const QString& app = QString(), const QHash<QUrl, QVariant>& additionalMetadata = (QHash<QUrl, QVariant>()));
QUrl createGraph(const QString& app, const QMultiHash<QUrl, Soprano::Node>& additionalMetadata);
/**
diff --git a/nepomuk/services/storage/repository.cpp b/nepomuk/services/storage/repository.cpp
index 128c3d6..b9b2051 100644
--- a/nepomuk/services/storage/repository.cpp
+++ b/nepomuk/services/storage/repository.cpp
@@ -62,6 +62,9 @@ Nepomuk::Repository::Repository( const QString& name )
m_model( 0 ),
m_inferencer( 0 ),
m_removableStorageModel( 0 ),
+ m_dataManagementModel( 0 ),
+ m_dataManagementAdaptor( 0 ),
+ m_nrlModel( 0 ),
m_backend( 0 ),
m_modelCopyJob( 0 ),
m_oldStorageBackend( 0 )
diff --git a/nepomuk/services/storage/test/removablemediamodeltest.cpp b/nepomuk/services/storage/test/removablemediamodeltest.cpp
index 8bf3ab1..3a4abee 100644
--- a/nepomuk/services/storage/test/removablemediamodeltest.cpp
+++ b/nepomuk/services/storage/test/removablemediamodeltest.cpp
@@ -122,6 +122,14 @@ void RemovableMediaModelTest::testConvertFileUrlsInStatement_data()
const Statement convertableFileObjectWithNieUrl4_original(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("file:///media/nfs"));
const Statement convertableFileObjectWithNieUrl4_converted(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("nfs://thehost/solid-path"));
QTest::newRow("convertableFileUrlInObjectWithNieUrl4") << convertableFileObjectWithNieUrl4_original << convertableFileObjectWithNieUrl4_converted;
+
+ const Statement convertableFileObjectWithNieUrl5_original(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("file:///media/XO-Y4/file with spaces.txt"));
+ const Statement convertableFileObjectWithNieUrl5_converted(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("filex://xyz-123/file with spaces.txt"));
+ QTest::newRow("convertableFileUrlInObjectWithNieUrl5") << convertableFileObjectWithNieUrl5_original << convertableFileObjectWithNieUrl5_converted;
+
+ const Statement convertableFileObjectWithNieUrl6_original(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("file:///media/whatever with spaces/file with spaces.txt"));
+ const Statement convertableFileObjectWithNieUrl6_converted(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("filex://whatever/file with spaces.txt"));
+ QTest::newRow("convertableFileUrlInObjectWithNieUrl6") << convertableFileObjectWithNieUrl6_original << convertableFileObjectWithNieUrl6_converted;
}
@@ -180,6 +188,12 @@ void RemovableMediaModelTest::testConvertFilxUrl_data()
const Node convertFilex2(QUrl("filex://xyz-123"));
QTest::newRow("convertFilex2") << convertFilex2 << Node(QUrl("file:///media/XO-Y4"));
+ const Node convertFilex3(QUrl("filex://xyz-123/hello world"));
+ QTest::newRow("convertFilex3") << convertFilex3 << Node(QUrl("file:///media/XO-Y4/hello world"));
+
+ const Node convertFilex4(QUrl("filex://whatever/hello world"));
+ QTest::newRow("convertFilex4") << convertFilex4 << Node(QUrl("file:///media/whatever with spaces/hello world"));
+
const Node convertnfs(QUrl("nfs://thehost/solid-path"));
QTest::newRow("convertnfs") << convertnfs << Node(QUrl("file:///media/nfs"));
}
@@ -224,6 +238,14 @@ void RemovableMediaModelTest::testConvertFilxUrls_data()
const Statement convertableFilexObjectWithNieUrl4_original(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("nfs://thehost/solid-path"));
const Statement convertableFilexObjectWithNieUrl4_converted(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("file:///media/nfs"));
QTest::newRow("convertableFileUrlInObjectWithNieUrl4") << convertableFilexObjectWithNieUrl4_original << convertableFilexObjectWithNieUrl4_converted;
+
+ const Statement convertableFilexObjectWithNieUrl5_original(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("filex://xyz-123/file with spaces.txt"));
+ const Statement convertableFilexObjectWithNieUrl5_converted(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("file:///media/XO-Y4/file with spaces.txt"));
+ QTest::newRow("convertableFileUrlInObjectWithNieUrl5") << convertableFilexObjectWithNieUrl5_original << convertableFilexObjectWithNieUrl5_converted;
+
+ const Statement convertableFileObjectWithNieUrl6_original(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("filex://whatever/file with spaces.txt"));
+ const Statement convertableFileObjectWithNieUrl6_converted(QUrl("nepomuk:/res/xyz"), NIE::url(), QUrl("file:///media/whatever with spaces/file with spaces.txt"));
+ QTest::newRow("convertableFileUrlInObjectWithNieUrl6") << convertableFileObjectWithNieUrl6_original << convertableFileObjectWithNieUrl6_converted;
}
void RemovableMediaModelTest::testConvertFilxUrls()
diff --git a/nepomuk/services/storage/test/solid/fakecomputer.xml b/nepomuk/services/storage/test/solid/fakecomputer.xml
index e3fcfb8..67b374f 100644
--- a/nepomuk/services/storage/test/solid/fakecomputer.xml
+++ b/nepomuk/services/storage/test/solid/fakecomputer.xml
@@ -437,6 +437,69 @@
<property key="size">993284096</property>
</device>
+ <!-- USB Device -->
+ <device udi="/org/kde/solid/fakehw/usb_device_whatever">
+ <property key="name">Acme whatever</property>
+ <property key="parent">/org/kde/solid/fakehw/usb_device_whatever</property>
+ </device>
+ <!-- Mass Storage Interface -->
+ <device udi="/org/kde/solid/fakehw/usb_device_whatever_if0">
+ <property key="name">USB Mass Storage Inferface</property>
+ <property key="parent">/org/kde/solid/fakehw/usb_device_whatever</property>
+ </device>
+ <!-- SCSI Adapter -->
+ <device udi="/org/kde/solid/fakehw/usb_device_whatever_if0_scsi_host">
+ <property key="name">SCSI Host Adapter</property>
+ <property key="parent">/org/kde/solid/fakehw/usb_device_whatever_if0</property>
+ </device>
+ <!-- SCSI Device -->
+ <device udi="/org/kde/solid/fakehw/usb_device_whatever_if0_scsi_host_scsi_device_lun0">
+ <property key="name">SCSI Device</property>
+ <property key="parent">/org/kde/solid/fakehw/usb_device_whatever_if0_scsi_host</property>
+ </device>
+ <!-- We finally find the storage device, which is a portable media player... -->
+ <device udi="/org/kde/solid/fakehw/storage_serial_whatever">
+ <property key="name">whatever</property>
+ <property key="vendor">Acme Electronics</property>
+ <property key="interfaces">StorageDrive,Block,PortableMediaPlayer</property>
+ <property key="parent">/org/kde/solid/fakehw/usb_device_whatever_if0_scsi_host_scsi_device_lun0</property>
+
+ <property key="minor">0</property>
+ <property key="major">8</property>
+ <property key="device">/dev/sdb</property>
+
+ <property key="bus">usb</property>
+ <property key="driveType">disk</property>
+ <property key="isRemovable">true</property>
+ <property key="isEjectRequired">true</property>
+ <property key="isHotpluggable">true</property>
+ <property key="isMediaCheckEnabled">true</property>
+ <property key="product">whatever</property>
+
+ <property key="accessMethod">MassStorage</property>
+ <property key="outputFormats">audio/x-mp3</property>
+ <property key="inputFormats">audio/x-wav,audio/x-mp3,audio/vorbis</property>
+ <property key="playlistFormats">audio/x-mpegurl</property>
+ </device>
+ <!-- ... with a partition since it's a USB Mass Storage device -->
+ <device udi="/org/kde/solid/fakehw/volume_part1_whatever">
+ <property key="name">StorageVolume (vfat)</property>
+ <property key="interfaces">Block,StorageVolume,StorageAccess</property>
+ <property key="parent">/org/kde/solid/fakehw/storage_serial_whatever</property>
+ <property key="uuid">whatever</property>
+
+ <property key="minor">1</property>
+ <property key="major">8</property>
+ <property key="device">/dev/sdb1</property>
+
+ <property key="isIgnored">false</property>
+ <property key="isMounted">true</property>
+ <property key="mountPoint">/media/whatever with spaces</property>
+ <property key="usage">filesystem</property>
+ <property key="fsType">vfat</property>
+ <property key="size">993284096</property>
+ </device>
+
<!-- Second USB Controller -->
diff --git a/nepomuk/services/strigi/eventmonitor.cpp b/nepomuk/services/strigi/eventmonitor.cpp
index 621cb25..7c72c96 100644
--- a/nepomuk/services/strigi/eventmonitor.cpp
+++ b/nepomuk/services/strigi/eventmonitor.cpp
@@ -98,6 +98,7 @@ void Nepomuk::EventMonitor::slotPowerManagementStatusChanged( bool conserveResou
sendEvent( "indexingResumed", i18n("Resuming indexing of files for fast searching."), "battery-charging" );
}
else if ( conserveResources &&
+ !StrigiServiceConfig::self()->suspendOnPowerSaveDisabled() &&
!m_indexScheduler->isSuspended() ) {
kDebug() << "Pausing indexer due to power management";
m_wasIndexingWhenPaused = m_indexScheduler->isIndexing();
diff --git a/nepomuk/services/strigi/indexscheduler.cpp b/nepomuk/services/strigi/indexscheduler.cpp
index 323169e..ba4ab55 100644
--- a/nepomuk/services/strigi/indexscheduler.cpp
+++ b/nepomuk/services/strigi/indexscheduler.cpp
@@ -173,10 +173,6 @@ Nepomuk::IndexScheduler::IndexScheduler( QObject* parent )
connect( StrigiServiceConfig::self(), SIGNAL( configChanged() ),
this, SLOT( slotConfigChanged() ) );
-
- // start the initial indexing
- queueAllFoldersForUpdate();
- callDoIndexing();
}
@@ -342,6 +338,8 @@ void Nepomuk::IndexScheduler::doIndexing()
m_currentMutex.unlock();
setIndexingStarted( false );
+
+ emit indexingDone();
}
}
diff --git a/nepomuk/services/strigi/indexscheduler.h b/nepomuk/services/strigi/indexscheduler.h
index 53db1ab..2b328e6 100644
--- a/nepomuk/services/strigi/indexscheduler.h
+++ b/nepomuk/services/strigi/indexscheduler.h
@@ -171,6 +171,9 @@ namespace Nepomuk {
void indexingFile( const QString & );
void indexingSuspended( bool suspended );
+ /// emitted once the indexing is done and the queue is empty
+ void indexingDone();
+
private Q_SLOTS:
void slotConfigChanged();
void slotCleaningDone();
diff --git a/nepomuk/services/strigi/nepomukindexer.cpp b/nepomuk/services/strigi/nepomukindexer.cpp
index d796983..ff981e6 100644
--- a/nepomuk/services/strigi/nepomukindexer.cpp
+++ b/nepomuk/services/strigi/nepomukindexer.cpp
@@ -30,41 +30,56 @@
#include <KStandardDirs>
#include <QtCore/QFileInfo>
+#include <QtCore/QTimer>
-Nepomuk::Indexer::Indexer(const KUrl& localUrl, QObject* parent)
- : KJob(parent),
- m_url( localUrl ),
- m_exitCode( -1 )
-{
-}
-
Nepomuk::Indexer::Indexer(const QFileInfo& info, QObject* parent)
: KJob(parent),
m_url( info.absoluteFilePath() ),
m_exitCode( -1 )
{
+ // setup the timer used to kill the indexer process if it seems to get stuck
+ m_processTimer = new QTimer(this);
+ m_processTimer->setSingleShot(true);
+ connect(m_processTimer, SIGNAL(timeout()),
+ this, SLOT(slotProcessTimerTimeout()));
}
void Nepomuk::Indexer::start()
{
+ // setup the external process which does the actual indexing
const QString exe = KStandardDirs::findExe(QLatin1String("nepomukindexer"));
m_process = new KProcess( this );
m_process->setProgram( exe, QStringList() << m_url.toLocalFile() );
+ // start the process
kDebug() << "Running" << exe << m_url.toLocalFile();
-
connect( m_process, SIGNAL(finished(int)), this, SLOT(slotIndexedFile(int)) );
m_process->start();
+
+ // start the timer which will kill the process if it does not terminate after 5 minutes
+ m_processTimer->start(5*60*1000);
}
void Nepomuk::Indexer::slotIndexedFile(int exitCode)
{
+ // stop the timer since there is no need to kill the process anymore
+ m_processTimer->stop();
+
kDebug() << "Indexing of " << m_url.toLocalFile() << "finished with exit code" << exitCode;
m_exitCode = exitCode;
emitResult();
}
+void Nepomuk::Indexer::slotProcessTimerTimeout()
+{
+ kDebug() << "Killing the indexer process which seems stuck for" << m_url;
+ m_process->disconnect(this);
+ m_process->kill();
+ m_process->waitForFinished();
+ emitResult();
+}
+
#include "nepomukindexer.moc"
diff --git a/nepomuk/services/strigi/nepomukindexer.h b/nepomuk/services/strigi/nepomukindexer.h
index 5b14787..3188eef 100644
--- a/nepomuk/services/strigi/nepomukindexer.h
+++ b/nepomuk/services/strigi/nepomukindexer.h
@@ -27,6 +27,7 @@
class KProcess;
class QFileInfo;
+class QTimer;
namespace Nepomuk {
@@ -53,7 +54,6 @@ namespace Nepomuk {
public:
Indexer( const QFileInfo& info, QObject* parent = 0 );
- Indexer( const KUrl& localUrl, QObject* parent = 0 );
KUrl url() const { return m_url; }
@@ -74,11 +74,13 @@ namespace Nepomuk {
private slots:
void slotIndexedFile(int exitCode);
+ void slotProcessTimerTimeout();
private:
KUrl m_url;
KProcess* m_process;
int m_exitCode;
+ QTimer* m_processTimer;
};
}
diff --git a/nepomuk/services/strigi/strigiservice.cpp b/nepomuk/services/strigi/strigiservice.cpp
index 0189679..0880381 100644
--- a/nepomuk/services/strigi/strigiservice.cpp
+++ b/nepomuk/services/strigi/strigiservice.cpp
@@ -38,6 +38,10 @@
Nepomuk::StrigiService::StrigiService( QObject* parent, const QList<QVariant>& )
: Service( parent )
{
+ // Create the configuration instance singleton (for thread-safety)
+ // ==============================================================
+ (void)new StrigiServiceConfig(this);
+
// setup the actual index scheduler including strigi stuff
// ==============================================================
m_schedulingThread = new QThread( this );
@@ -61,6 +65,8 @@ Nepomuk::StrigiService::StrigiService( QObject* parent, const QList<QVariant>& )
this, SIGNAL( statusStringChanged() ) );
connect( m_indexScheduler, SIGNAL( indexingStopped() ),
this, SIGNAL( statusStringChanged() ) );
+ connect( m_indexScheduler, SIGNAL( indexingDone() ),
+ this, SLOT( slotIndexingDone() ) );
connect( m_indexScheduler, SIGNAL( indexingFolder(QString) ),
this, SIGNAL( statusStringChanged() ) );
connect( m_indexScheduler, SIGNAL( indexingFile(QString) ),
@@ -72,6 +78,12 @@ Nepomuk::StrigiService::StrigiService( QObject* parent, const QList<QVariant>& )
// this is done for KDE startup - to not slow that down too much
m_indexScheduler->setIndexingSpeed( IndexScheduler::SnailPace );
+ // start initial indexing honoring the hidden config option to disable it
+ if(StrigiServiceConfig::self()->isInitialRun() ||
+ !StrigiServiceConfig::self()->initialUpdateDisabled()) {
+ m_indexScheduler->updateAll();
+ }
+
// delayed init for the rest which uses IO and CPU
// FIXME: do not use a random delay value but wait for KDE to be started completely (using the session manager)
QTimer::singleShot( 2*60*1000, this, SLOT( finishInitialization() ) );
@@ -126,6 +138,12 @@ void Nepomuk::StrigiService::slotIdleTimerResume()
}
+void Nepomuk::StrigiService::slotIndexingDone()
+{
+ StrigiServiceConfig::self()->setInitialRun(true);
+}
+
+
void Nepomuk::StrigiService::updateWatches()
{
org::kde::nepomuk::FileWatch filewatch( "org.kde.nepomuk.services.nepomukfilewatch",
diff --git a/nepomuk/services/strigi/strigiservice.h b/nepomuk/services/strigi/strigiservice.h
index 2eb7eac..acca179 100644
--- a/nepomuk/services/strigi/strigiservice.h
+++ b/nepomuk/services/strigi/strigiservice.h
@@ -97,6 +97,7 @@ namespace Nepomuk {
void updateWatches();
void slotIdleTimeoutReached();
void slotIdleTimerResume();
+ void slotIndexingDone();
private:
void updateStrigiConfig();
diff --git a/nepomuk/services/strigi/strigiserviceconfig.cpp b/nepomuk/services/strigi/strigiserviceconfig.cpp
index 4a71cf9..0fc5fa2 100644
--- a/nepomuk/services/strigi/strigiserviceconfig.cpp
+++ b/nepomuk/services/strigi/strigiserviceconfig.cpp
@@ -25,12 +25,36 @@
#include <KDirWatch>
#include <KStandardDirs>
#include <KConfigGroup>
+#include <KDebug>
-Nepomuk::StrigiServiceConfig::StrigiServiceConfig()
- : QObject(),
+namespace {
+ /// recursively check if a folder is hidden
+ bool isDirHidden( QDir& dir ) {
+ if ( QFileInfo( dir.path() ).isHidden() )
+ return true;
+ else if ( dir.cdUp() )
+ return isDirHidden( dir );
+ else
+ return false;
+ }
+
+ bool isDirHidden(const QString& path) {
+ QDir dir(path);
+ return isDirHidden(dir);
+ }
+}
+
+Nepomuk::StrigiServiceConfig* Nepomuk::StrigiServiceConfig::s_self = 0;
+
+Nepomuk::StrigiServiceConfig::StrigiServiceConfig(QObject* parent)
+ : QObject(parent),
m_config( "nepomukstrigirc" )
{
+ if(!s_self) {
+ s_self = this;
+ }
+
KDirWatch* dirWatch = KDirWatch::self();
connect( dirWatch, SIGNAL( dirty( const QString& ) ),
this, SLOT( slotConfigDirty() ) );
@@ -45,14 +69,12 @@ Nepomuk::StrigiServiceConfig::StrigiServiceConfig()
Nepomuk::StrigiServiceConfig::~StrigiServiceConfig()
{
- m_config.group( "General" ).writeEntry( "first run", false );
}
Nepomuk::StrigiServiceConfig* Nepomuk::StrigiServiceConfig::self()
{
- K_GLOBAL_STATIC( StrigiServiceConfig, _self );
- return _self;
+ return s_self;
}
@@ -86,7 +108,24 @@ QStringList Nepomuk::StrigiServiceConfig::excludeFolders() const
QStringList Nepomuk::StrigiServiceConfig::excludeFilters() const
{
- return m_config.group( "General" ).readEntry( "exclude filters", defaultExcludeFilterList() );
+ KConfigGroup cfg = m_config.group( "General" );
+
+ // read configured exclude filters
+ QSet<QString> filters = cfg.readEntry( "exclude filters", defaultExcludeFilterList() ).toSet();
+
+ // make sure we always keep the latest default exclude filters
+ // TODO: there is one problem here. What if the user removed some of the default filters?
+ if(cfg.readEntry("exclude filters version", 0) < defaultExcludeFilterListVersion()) {
+ filters += defaultExcludeFilterList().toSet();
+
+ // write the config directly since the KCM does not have support for the version yet
+ // TODO: make this class public and use it in the KCM
+ cfg.writeEntry("exclude filters", QStringList::fromSet(filters));
+ cfg.writeEntry("exclude filters version", defaultExcludeFilterListVersion());
+ }
+
+ // remove duplicates
+ return QStringList::fromSet(filters);
}
@@ -132,18 +171,6 @@ bool Nepomuk::StrigiServiceConfig::shouldBeIndexed( const QString& path ) const
}
-namespace {
- /// recursively check if a folder is hidden
- bool isDirHidden( QDir& dir ) {
- if ( QFileInfo( dir.path() ).isHidden() )
- return true;
- else if ( dir.cdUp() )
- return isDirHidden( dir );
- else
- return false;
- }
-}
-
bool Nepomuk::StrigiServiceConfig::shouldFolderBeIndexed( const QString& path ) const
{
bool exact = false;
@@ -202,15 +229,19 @@ bool Nepomuk::StrigiServiceConfig::folderInFolderList( const QString& path, bool
namespace {
/**
* Returns true if the specified folder f would already be included or excluded using the list
- * folders
+ * folders. Hidden folders are a special case because of the index hidden files setting.
+ * We always keep hidden folders in the list if they are forced to be indexed.
*/
bool alreadyInList( const QList<QPair<QString, bool> >& folders, const QString& f, bool include )
{
bool included = false;
+ const bool hidden = isDirHidden(f);
for ( int i = 0; i < folders.count(); ++i ) {
if ( f != folders[i].first &&
- f.startsWith( KUrl( folders[i].first ).path( KUrl::AddTrailingSlash ) ) )
+ f.startsWith( KUrl( folders[i].first ).path( KUrl::AddTrailingSlash ) ) &&
+ !hidden ) {
included = folders[i].second;
+ }
}
return included == include;
}
@@ -269,4 +300,19 @@ void Nepomuk::StrigiServiceConfig::buildExcludeFilterRegExpCache()
m_excludeFilterRegExpCache.rebuildCacheFromFilterList( excludeFilters() );
}
+void Nepomuk::StrigiServiceConfig::setInitialRun(bool isInitialRun)
+{
+ m_config.group( "General" ).writeEntry( "first run", isInitialRun );
+}
+
+bool Nepomuk::StrigiServiceConfig::initialUpdateDisabled() const
+{
+ return m_config.group( "General" ).readEntry( "disable initial update", false );
+}
+
+bool Nepomuk::StrigiServiceConfig::suspendOnPowerSaveDisabled() const
+{
+ return m_config.group( "General" ).readEntry( "disable suspend on powersave", false );
+}
+
#include "strigiserviceconfig.moc"
diff --git a/nepomuk/services/strigi/strigiserviceconfig.h b/nepomuk/services/strigi/strigiserviceconfig.h
index 03d827f..88a1153 100644
--- a/nepomuk/services/strigi/strigiserviceconfig.h
+++ b/nepomuk/services/strigi/strigiserviceconfig.h
@@ -39,7 +39,16 @@ namespace Nepomuk {
Q_OBJECT
public:
+ /**
+ * Create a new file indexr config. The first instance to be
+ * created will be accessible via self().
+ */
+ StrigiServiceConfig(QObject* parent = 0);
~StrigiServiceConfig();
+
+ /**
+ * Get the first created instance of StrigiServiceConfig
+ */
static StrigiServiceConfig* self();
/**
@@ -77,6 +86,25 @@ namespace Nepomuk {
bool isInitialRun() const;
/**
+ * A "hidden" config option which allows to disable the initial
+ * update of all indexed folders.
+ *
+ * This should be used in combination with isInitialRun() to make
+ * sure all folders are at least indexed once.
+ */
+ bool initialUpdateDisabled() const;
+
+ /**
+ * A "hidden" config option which allows to disable the feature
+ * where the file indexing is suspended when in powersave mode.
+ * This is especially useful for mobile devices which always run
+ * on battery.
+ *
+ * At some point this should be a finer grained configuration.
+ */
+ bool suspendOnPowerSaveDisabled() const;
+
+ /**
* Check if \p path should be indexed taking into account
* the includeFolders(), the excludeFolders(), and the
* excludeFilters().
@@ -114,12 +142,17 @@ namespace Nepomuk {
Q_SIGNALS:
void configChanged();
+ public Q_SLOTS:
+ /**
+ * Should be called once the initial indexing is done, ie. all folders
+ * have been indexed.
+ */
+ void setInitialRun(bool isInitialRun);
+
private Q_SLOTS:
void slotConfigDirty();
private:
- StrigiServiceConfig();
-
/**
* Check if \p path is in the list of folders to be indexed taking
* include and exclude folders into account.
@@ -130,7 +163,7 @@ namespace Nepomuk {
void buildFolderCache();
void buildExcludeFilterRegExpCache();
- KConfig m_config;
+ mutable KConfig m_config;
/// Caching cleaned up list (no duplicates, no useless entries, etc.)
QList<QPair<QString, bool> > m_folderCache;
@@ -140,6 +173,8 @@ namespace Nepomuk {
RegExpCache m_excludeFilterRegExpCache;
mutable QMutex m_folderCacheMutex;
+
+ static StrigiServiceConfig* s_self;
};
}
diff --git a/nepomuk/servicestub/main.cpp b/nepomuk/servicestub/main.cpp
index e0d754c..40cad5b 100644
--- a/nepomuk/servicestub/main.cpp
+++ b/nepomuk/servicestub/main.cpp
@@ -38,6 +38,8 @@
#include "priority.h"
namespace {
+ Nepomuk::ServiceControl* s_control = 0;
+
#ifndef Q_OS_WIN
void signalHandler( int signal )
{
@@ -45,6 +47,7 @@ namespace {
case SIGHUP:
case SIGQUIT:
case SIGINT:
+ delete s_control;
QCoreApplication::exit( 0 );
}
}
@@ -157,12 +160,12 @@ int main( int argc, char** argv )
// register the service control
// ====================================
- Nepomuk::ServiceControl* control = new Nepomuk::ServiceControl( serviceName, service, &app );
+ s_control = new Nepomuk::ServiceControl( serviceName, service, &app );
// start the service (queued since we need an event loop)
// ====================================
- QTimer::singleShot( 0, control, SLOT( start() ) );
+ QTimer::singleShot( 0, s_control, SLOT( start() ) );
return app.exec();
}
diff --git a/phonon/kcm/xine/kcm_phononxine.desktop b/phonon/kcm/xine/kcm_phononxine.desktop
index 757ab6b..ace5892 100644
--- a/phonon/kcm/xine/kcm_phononxine.desktop
+++ b/phonon/kcm/xine/kcm_phononxine.desktop
@@ -98,7 +98,7 @@ Comment[bn_IN]=Xine ব্যাক-এন্ডের কনফিগারে
Comment[bs]=Postava pozadine Ksin
Comment[ca]=Configuració del dorsal del Xine
Comment[ca@valencia]=Configuració del dorsal del Xine
-Comment[cs]=Nastavení backendu Xine
+Comment[cs]=Nastavení podpůrné vrstvy Xine
Comment[csb]=Kònfigùracëjô czérownika Xine
Comment[da]=Konfiguration af Xine-motor
Comment[de]=Xine-Treiber-Einrichtung
diff --git a/phonon/platform_kde/phononbackend.desktop b/phonon/platform_kde/phononbackend.desktop
index 1c1e2c9..5df5d13 100644
--- a/phonon/platform_kde/phononbackend.desktop
+++ b/phonon/platform_kde/phononbackend.desktop
@@ -11,7 +11,7 @@ Name[bn_IN]=KDE মাল্টিমিডিয়া ব্যাক-এন্
Name[bs]=KDE‑ova multimedijska pozadina
Name[ca]=Dorsal multimèdia del KDE
Name[ca@valencia]=Dorsal multimèdia del KDE
-Name[cs]=Multimediální backend KDE
+Name[cs]=Multimediální podpůrná vrstva KDE
Name[csb]=Òbsłużënk mùltimediów
Name[da]=KDE multimedie-backend
Name[de]=KDE-Multimedia-Unterstützung
/space/work/OBS/kdf/kdebase4-runtime