diff --git a/applications/settings/modules/time/helper.cpp b/applications/settings/modules/time/helper.cpp index 30e978bd..4e6cb80d 100644 --- a/applications/settings/modules/time/helper.cpp +++ b/applications/settings/modules/time/helper.cpp @@ -1,168 +1,168 @@ /* * tzone.cpp * * Copyright (C) 1998 Luca Montecchiani * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ /* A helper that's run using KAuth and does the system modifications. */ #include "helper.h" #include "config.h" #include #include #include #include #include #include #include #include #include #include int ClockHelper::ntp( const QStringList& ntpServers, bool ntpEnabled, const QString& ntpUtility ) { int ret = 0; // write to the system config file QFile config_file(KDE_CONFDIR "/kcmclockrc"); if(!config_file.exists()) { config_file.open(QIODevice::WriteOnly); config_file.close(); config_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther); } KConfig _config(config_file.fileName(), KConfig::SimpleConfig); KConfigGroup config(&_config, "NTP"); config.writeEntry("servers", ntpServers ); config.writeEntry("enabled", ntpEnabled ); if ( ntpEnabled && !ntpUtility.isEmpty() ) { // NTP Time setting QString timeServer = ntpServers.first(); if( timeServer.indexOf( QRegExp(".*\\(.*\\)$") ) != -1 ) { - timeServer.replace( QRegExp(".*\\("), "" ); - timeServer.replace( QRegExp("\\).*"), "" ); + timeServer.replace( QRegExp(".*\\("), '' ); + timeServer.replace( QRegExp("\\).*"), '' ); // Would this be better?: s/^.*\(([^)]*)\).*$/\1/ } KProcess proc; proc << ntpUtility << timeServer; if ( proc.execute() != 0 ) { ret |= NTPError; } } else if( ntpEnabled ) { ret |= NTPError; } return ret; } int ClockHelper::date( const QString& newdate, const QString& olddate ) { struct timeval tv; tv.tv_sec = newdate.toULong() - olddate.toULong() + time(0); tv.tv_usec = 0; #ifndef Q_OS_WIN32 if (settimeofday(&tv, 0)) { return DateError; } #else return DateError; #endif if (!KStandardDirs::findExe("hwclock").isEmpty()) { KProcess::execute("hwclock", QStringList() << "--systohc"); } return 0; } // on non-Solaris systems which do not use /etc/timezone? int ClockHelper::tz( const QString& selectedzone ) { int ret = 0; QString tz = "/usr/share/zoneinfo/" + selectedzone; if( !KStandardDirs::findExe( "zic" ).isEmpty()) { KProcess::execute("zic", QStringList() << "-l" << selectedzone); } else if (!QFile::remove("/etc/localtime")) { ret |= TimezoneError; } else if (!QFile::copy(tz, "/etc/localtime")) { ret |= TimezoneError; } QFile fTimezoneFile("/etc/timezone"); if (fTimezoneFile.exists() && fTimezoneFile.open(QIODevice::WriteOnly | QIODevice::Truncate) ) { QTextStream t(&fTimezoneFile); t << selectedzone; fTimezoneFile.close(); } QString val = ':' + tz; setenv("TZ", val.toAscii(), 1); tzset(); return ret; } int ClockHelper::tzreset() { return 0; } ActionReply ClockHelper::save(const QVariantMap &args) { bool _ntp = args.value("ntp").toBool(); bool _date = args.value("date").toBool(); bool _tz = args.value("tz").toBool(); bool _tzreset = args.value("tzreset").toBool(); KComponentData data( "kcmdatetimehelper" ); int ret = 0; // error code // The order here is important if( _ntp ) ret |= ntp( args.value("ntpServers").toStringList(), args.value("ntpEnabled").toBool(), args.value("ntpUtility").toString() ); if( _date ) ret |= date( args.value("newdate").toString(), args.value("olddate").toString() ); if( _tz ) ret |= tz( args.value("tzone").toString() ); if( _tzreset ) ret |= tzreset(); if (ret == 0) { return ActionReply::SuccessReply; } else { ActionReply reply(ActionReply::HelperError); reply.setErrorCode(ret); return reply; } } KDE4_AUTH_HELPER_MAIN("org.kde.active.clockconfig", ClockHelper) diff --git a/applications/settings/modules/time/timesettings.cpp b/applications/settings/modules/time/timesettings.cpp index 8a27faba..52c11121 100644 --- a/applications/settings/modules/time/timesettings.cpp +++ b/applications/settings/modules/time/timesettings.cpp @@ -1,422 +1,422 @@ /* Copyright 2005 S.R.Haque . Copyright 2009 David Faure Copyright 2011 Sebastian Kügler This file is part of the KDE project This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2, as published by the Free Software Foundation. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "timesettings.h" #include "timezone.h" #include "timezonesmodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define FORMAT24H "%H:%M:%S" #define FORMAT12H "%l:%M:%S %p" class TimeSettingsPrivate { public: TimeSettings *q; QString timeFormat; QString timezone; QObject *timeZonesModel; QString timeZoneFilter; QString currentTimeText; QTime currentTime; QDate currentDate; QTimer *timer; QString ntpServer; void initSettings(); void initTimeZones(); QString displayName(const KTimeZone &zone); KSharedConfigPtr localeConfig; KConfigGroup localeSettings; KTimeZones *timeZones; QList timezones; }; TimeSettings::TimeSettings() { d = new TimeSettingsPrivate; d->q = this; d->timeZones = 0; d->timeZonesModel = 0; setTimeZone(KSystemTimeZones::local().name()); d->initSettings(); // Just for testing that data gets through d->timer = new QTimer(this); d->timer->setInterval(1000); connect(d->timer, SIGNAL(timeout()), SLOT(timeout())); d->timer->start(); kDebug() << "TimeSettings module loaded."; } TimeSettings::~TimeSettings() { kDebug() << "========================== timesettings destroy"; delete d; } void TimeSettingsPrivate::initTimeZones() { // Collect zones by localized city names, so that they can be sorted properly. QStringList cities; QStringList tz; QHash zonesByCity; if (!timeZones) { timeZones = KSystemTimeZones::timeZones(); // add UTC to the defaults default KTimeZone utc = KTimeZone::utc(); cities.append(utc.name()); zonesByCity.insert(utc.name(), utc); } //kDebug() << " TZ: cities: " << cities; const KTimeZones::ZoneMap zones = timeZones->zones(); QList _zones; QStandardItemModel *_zonesModel = new TimeZonesModel(q); for ( KTimeZones::ZoneMap::ConstIterator it = zones.begin(); it != zones.end(); ++it ) { const KTimeZone zone = it.value(); if (timeZoneFilter.isEmpty() || zone.name().contains(timeZoneFilter, Qt::CaseInsensitive)) { TimeZone *_zone = new TimeZone(zone); _zones.append(_zone); QStandardItem *item = new QStandardItem(_zone->name()); - item->setData(_zone->name().split("/").first(), Qt::UserRole+1); + item->setData(_zone->name().split('/').first(), Qt::UserRole+1); _zonesModel->appendRow(item); } } kDebug() << "Found: " << _zones.count() << " timezones."; //qSort( cities.begin(), cities.end(), localeLessThan ); q->setTimeZones(_zones); q->setTimeZonesModel(_zonesModel); } QString TimeSettingsPrivate::displayName( const KTimeZone &zone ) { return i18n( zone.name().toUtf8() ).replace( '_', ' ' ); } void TimeSettingsPrivate::initSettings() { localeConfig = KSharedConfig::openConfig("kdeglobals", KConfig::SimpleConfig); localeSettings = KConfigGroup(localeConfig, "Locale"); //setTimeFormat(d->localeSettings.readEntry("TimeFormat", QString(FORMAT24H))); //setTimeFormat(d->localeSettings.readEntry("TimeFormat", QString(FORMAT12H))); q->setTimeFormat( localeSettings.readEntry( "TimeFormat", QString() ) ); KConfig _config( "kcmclockrc", KConfig::NoGlobals ); KConfigGroup config(&_config, "NTP"); QStringList servers = config.readEntry("servers", QString()).split(',', QString::SkipEmptyParts); if (!servers.isEmpty()) { ntpServer = servers.first(); } //FIXME: why? if (ntpServer.length() < 3) { ntpServer = QString(); } } void TimeSettings::timeout() { setCurrentTime(QTime::currentTime()); setCurrentDate(QDate::currentDate()); } QString TimeSettings::currentTimeText() { return d->currentTimeText; } QTime TimeSettings::currentTime() const { return d->currentTime; } void TimeSettings::setCurrentTime(const QTime ¤tTime) { if (d->currentTime != currentTime) { d->currentTime = currentTime; d->currentTimeText = KGlobal::locale()->formatTime(QTime::currentTime(), true); emit currentTimeChanged(); } } QDate TimeSettings::currentDate() const { return d->currentDate; } void TimeSettings::setCurrentDate(const QDate ¤tDate) { if (d->currentDate != currentDate) { d->currentDate = currentDate; emit currentDateChanged(); } } QString TimeSettings::ntpServer() const { return d->ntpServer; } void TimeSettings::setNtpServer(const QString &server) { if (d->ntpServer != server) { d->ntpServer = server; emit ntpServerChanged(); } } QStringList TimeSettings::availableNtpServers() const { QStringList servers; servers << "pool.ntp.org" << "asia.pool.ntp.org" << "europe.pool.ntp.org" << "north-america.pool.ntp.org" << "oceania.pool.ntp.org"; return servers; } QString TimeSettings::findNtpUtility() { QByteArray envpath = qgetenv("PATH"); if (!envpath.isEmpty() && envpath[0] == ':') { envpath = envpath.mid(1); } QString path = "/sbin:/usr/sbin:"; if (!envpath.isEmpty()) { path += QString::fromLocal8Bit(envpath); } else { path += QLatin1String("/bin:/usr/bin"); } QString ntpUtility; foreach (const QString &possible_ntputility, QStringList() << "ntpdate" << "rdate" ) { if (!((ntpUtility = KStandardDirs::findExe(possible_ntputility, path)).isEmpty())) { kDebug() << "ntpUtility = " << ntpUtility; return ntpUtility; } } kDebug() << "ntpUtility not found!"; return QString(); } void TimeSettings::saveTime() { QVariantMap helperargs; //TODO: enable NTP // Save the order, but don't duplicate! QStringList list; list << d->ntpServer; helperargs["ntp"] = true; helperargs["ntpServers"] = list; helperargs["ntpEnabled"] = !d->ntpServer.isEmpty(); QString ntpUtility = findNtpUtility(); helperargs["ntpUtility"] = ntpUtility; if (!d->ntpServer.isEmpty() && !ntpUtility.isEmpty()) { // NTP Time setting - done in helper kDebug() << "Setting date from time server " << list; } else { // User time setting QDateTime dt(d->currentDate, d->currentTime); kDebug() << "Set date " << dt; helperargs["date"] = true; helperargs["newdate"] = QString::number(dt.toTime_t()); helperargs["olddate"] = QString::number(::time(0)); } /*TODO: enable timeZones QStringList selectedZones(tzonelist->selection()); if (selectedZones.count() > 0) { QString selectedzone(selectedZones[0]); helperargs["tz"] = true; helperargs["tzone"] = selectedzone; } else { helperargs["tzreset"] = true; // // make the helper reset the timezone }*/ KAuth::Action writeAction("org.kde.active.clockconfig.save"); writeAction.setHelperID("org.kde.active.clockconfig"); writeAction.setArguments(helperargs); KAuth::ActionReply reply = writeAction.execute(); if (reply.failed()) { kWarning()<< "KAuth returned an error code:" << reply.errorCode(); } } QString TimeSettings::timeFormat() { return d->timeFormat; } void TimeSettings::setTimeFormat(const QString &timeFormat) { if (d->timeFormat != timeFormat) { d->timeFormat = timeFormat; d->localeSettings.writeEntry("TimeFormat", timeFormat); d->localeConfig->sync(); KGlobal::locale()->setTimeFormat(d->timeFormat); KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_LOCALE); kDebug() << "TIME" << KGlobal::locale()->formatTime(QTime::currentTime(), false); emit timeFormatChanged(); timeout(); } } QString TimeSettings::timeZone() { return d->timezone; } void TimeSettings::setTimeZone(const QString &timezone) { if (d->timezone != timezone) { d->timezone = timezone; kDebug() << "booyah"; emit timeZoneChanged(); timeout(); } } QList TimeSettings::timeZones() { if (!d->timeZones) { d->initTimeZones(); } return d->timezones; } void TimeSettings::setTimeZones(QList timezones) { //if (d->timezones != timezones) { d->timezones = timezones; emit timeZonesChanged(); //} } QObject* TimeSettings::timeZonesModel() { if (!d->timeZones) { d->initTimeZones(); } return d->timeZonesModel; } void TimeSettings::setTimeZonesModel(QObject* timezones) { //if (d->timezones != timezones) { d->timeZonesModel = timezones; emit timeZonesModelChanged(); //} } void TimeSettings::timeZoneFilterChanged(const QString &filter) { kDebug() << "new filter: " << filter; d->timeZoneFilter = filter; d->timeZoneFilter.replace( ' ', '_' ); d->initTimeZones(); emit timeZonesChanged(); } void TimeSettings::saveTimeZone(const QString &newtimezone) { kDebug() << "Saving timezone to config: " << newtimezone; QVariantMap helperargs; helperargs["tz"] = true; helperargs["tzone"] = newtimezone; KAuth::Action writeAction("org.kde.active.clockconfig.save"); writeAction.setHelperID("org.kde.active.clockconfig"); writeAction.setArguments(helperargs); KAuth::ActionReply reply = writeAction.execute(); if (reply.failed()) { kWarning()<< "KAuth returned an error code:" << reply.errorCode(); } setTimeZone(newtimezone); emit timeZoneChanged(); } bool TimeSettings::twentyFour() { return timeFormat() == FORMAT24H; } void TimeSettings::setTwentyFour(bool t) { if (twentyFour() != t) { if (t) { setTimeFormat(FORMAT24H); } else { setTimeFormat(FORMAT12H); } kDebug() << "T24 toggled: " << t << d->timeFormat; emit twentyFourChanged(); emit currentTimeChanged(); timeout(); } } #include "timesettings.moc" diff --git a/components/metadatamodel/metadatacloudmodel.cpp b/components/metadatamodel/metadatacloudmodel.cpp index a8354319..71273f46 100644 --- a/components/metadatamodel/metadatacloudmodel.cpp +++ b/components/metadatamodel/metadatacloudmodel.cpp @@ -1,361 +1,361 @@ /* Copyright 2011 Marco Martin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "metadatacloudmodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include MetadataCloudModel::MetadataCloudModel(QObject *parent) : AbstractMetadataModel(parent), m_queryClient(0) { QHash roleNames; roleNames[Label] = "label"; roleNames[Count] = "count"; setRoleNames(roleNames); } MetadataCloudModel::~MetadataCloudModel() { } void MetadataCloudModel::setCloudCategory(QString category) { if (m_cloudCategory == category) { return; } m_cloudCategory = category; askRefresh(); emit cloudCategoryChanged(); } QString MetadataCloudModel::cloudCategory() const { return m_cloudCategory; } QVariantList MetadataCloudModel::categories() const { return m_categories; } void MetadataCloudModel::setAllowedCategories(const QVariantList &whitelist) { QSet set = variantToStringList(whitelist).toSet(); if (set == m_allowedCategories) { return; } m_allowedCategories = set; emit allowedCategoriesChanged(); } QVariantList MetadataCloudModel::allowedCategories() const { return stringToVariantList(m_allowedCategories.values()); } void MetadataCloudModel::doQuery() { QDeclarativePropertyMap *parameters = qobject_cast(extraParameters()); //check if really all properties to build the query are null if (m_cloudCategory.isEmpty()) { return; } setStatus(Waiting); QString query = "select distinct ?label count(*) as ?count where { "; if (m_cloudCategory == "kao:Activity") { query += " ?activity nao:isRelated ?r . ?activity rdf:type kao:Activity . ?activity kao:activityIdentifier ?label "; } else { query += " ?r " + m_cloudCategory + " ?label"; } if (!resourceType().isEmpty()) { QString type = resourceType(); bool negation = false; - if (type.startsWith("!")) { + if (type.startsWith('!')) { type = type.remove(0, 1); negation = true; } if (negation) { query += " . FILTER(!bif:exists((select (1) where { ?r rdf:type " + type + " . }))) "; } else { query += " . ?r rdf:type " + type; } if (type != "nfo:Bookmark") { //FIXME: remove bookmarks if not explicitly asked for query += " . FILTER(!bif:exists((select (1) where { ?r a . }))) "; } } if (!mimeType().isEmpty()) { QString type = mimeType(); bool negation = false; - if (type.startsWith("!")) { + if (type.startsWith('!')) { type = type.remove(0, 1); negation = true; } if (negation) { query += " . FILTER(!bif:exists((select (1) where { ?r nie:mimeType ?mimeType . FILTER(bif:contains(?mimeType, \"'" + type + "'\")) . }))) "; } else { query += " . ?r nie:mimeType ?mimeType . FILTER(bif:contains(?mimeType, \"'" + type + "'\")) "; } } if (parameters && parameters->size() > 0) { foreach (const QString &key, parameters->keys()) { QString parameter = parameters->value(key).toString(); bool negation = false; - if (parameter.startsWith("!")) { + if (parameter.startsWith('!')) { parameter = parameter.remove(0, 1); negation = true; } if (negation) { query += " . FILTER(!bif:exists((select (1) where { ?r " + key + " ?mimeType . FILTER(bif:contains(?mimeType, \"'" + parameter + "'\")) . }))) "; } else { query += " . ?r " + key + " ?mimeType . FILTER(bif:contains(?mimeType, \"'" + parameter + "'\")) "; } } } if (!activityId().isEmpty()) { QString activity = activityId(); bool negation = false; - if (activity.startsWith("!")) { + if (activity.startsWith('!')) { activity = activity.remove(0, 1); negation = true; } Nepomuk::Resource acRes(activity, Nepomuk::Vocabulary::KAO::Activity()); if (negation) { query += ". FILTER(!bif:exists((select (1) where { <" + acRes.resourceUri().toString() + "> ?r . }))) "; } else { query += " . <" + acRes.resourceUri().toString() + "> nao:isRelated ?r "; } } //this is an AND set of tags.. should be allowed OR as well? foreach (const QString &tag, tagStrings()) { QString individualTag = tag; bool negation = false; - if (individualTag.startsWith("!")) { + if (individualTag.startsWith('!')) { individualTag = individualTag.remove(0, 1); negation = true; } if (negation) { query += ". FILTER(!bif:exists((select (1) where { ?r nao:hasTag ?tagSet \ . ?tagSet ?tagLabel ?tag \ . ?tagLabel \ . FILTER(bif:contains(?tag, \"'"+individualTag+"'\"))}))) "; } else { query += ". ?r nao:hasTag ?tagSet \ . ?tagSet ?tagLabel ?tag \ . ?tagLabel \ . FILTER(bif:contains(?tag, \"'"+individualTag+"'\")) "; } } if (startDate().isValid() || endDate().isValid()) { if (startDate().isValid()) { query += " . { \ ?r ?v2 . FILTER(?v2>\"" + startDate().toString(Qt::ISODate) + "\"^^) . \ } UNION {\ ?r ?v3 . FILTER(?v3>\"" + startDate().toString(Qt::ISODate) + "\"^^) . \ } UNION {\ ?v4 ?r .\ ?v4 ?v5 .\ FILTER(?v5>\"" + startDate().toString(Qt::ISODate) + "\"^^) . \ }"; } if (endDate().isValid()) { query += " . { \ ?r ?v2 . FILTER(?v2<\"" + endDate().toString(Qt::ISODate) + "\"^^) . \ } UNION {\ ?r ?v3 . FILTER(?v3<\"" + endDate().toString(Qt::ISODate) + "\"^^) . \ } UNION {\ ?v4 ?r .\ ?v4 ?v5 .\ FILTER(?v5<\"" + endDate().toString(Qt::ISODate) + "\"^^) . \ }"; } } if (minimumRating() > 0) { query += " . ?r nao:numericRating ?rating filter (?rating >=" + QString::number(minimumRating()) + ") "; } if (maximumRating() > 0) { query += " . ?r nao:numericRating ?rating filter (?rating <=" + QString::number(maximumRating()) + ") "; } //Exclude who doesn't have url query += " . FILTER(bif:exists((select (1) where { ?r nie:url ?h . }))) "; query += " . ?r ?v1 . FILTER(?v1>0) . } group by ?label order by ?label"; kDebug() << "Performing the Sparql query" << query; beginResetModel(); m_results.clear(); endResetModel(); emit countChanged(); delete m_queryClient; m_queryClient = new Nepomuk::Query::QueryServiceClient(this); connect(m_queryClient, SIGNAL(newEntries(const QList &)), this, SLOT(newEntries(const QList &))); connect(m_queryClient, SIGNAL(entriesRemoved(const QList &)), this, SLOT(entriesRemoved(const QList &))); connect(m_queryClient, SIGNAL(finishedListing()), this, SLOT(finishedListing())); m_queryClient->sparqlQuery(query); } void MetadataCloudModel::newEntries(const QList< Nepomuk::Query::Result > &entries) { setStatus(Running); QVector > results; QVariantList categories; foreach (Nepomuk::Query::Result res, entries) { QString label; int count = res.additionalBinding(QLatin1String("count")).variant().toInt(); QVariant rawLabel = res.additionalBinding(QLatin1String("label")).variant(); if (rawLabel.canConvert()) { label = rawLabel.value().className(); } else if (!rawLabel.value().scheme().isEmpty()) { const QUrl url = rawLabel.value(); if (url.scheme() == "nepomuk") { label = Nepomuk::Resource(url).genericLabel(); //TODO: it should convert from ontology url to short form nfo:Document } else { label = propertyShortName(url); } } else if (rawLabel.canConvert()) { label = rawLabel.toString(); } else if (rawLabel.canConvert()) { label = QString::number(rawLabel.toInt()); } else { continue; } if (label.isEmpty() || !(m_allowedCategories.isEmpty() || m_allowedCategories.contains(label))) { continue; } results << QPair(label, count); categories << label; } if (results.count() > 0) { beginInsertRows(QModelIndex(), m_results.count(), m_results.count()+results.count()-1); m_results << results; m_categories << categories; endInsertRows(); emit countChanged(); emit categoriesChanged(); } } void MetadataCloudModel::entriesRemoved(const QList &urls) { //FIXME: optimize kDebug()<= 0) { beginRemoveRows(QModelIndex(), index, index); m_results.remove(index); endRemoveRows(); } } emit countChanged(); } void MetadataCloudModel::finishedListing() { setStatus(Idle); } QVariant MetadataCloudModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.column() != 0 || index.row() < 0 || index.row() >= m_results.count()){ return QVariant(); } const QPair row = m_results[index.row()]; switch (role) { case Label: return row.first; case Count: return row.second; default: return QVariant(); } } #include "metadatacloudmodel.moc" diff --git a/components/metadatamodel/metadatamodel.cpp b/components/metadatamodel/metadatamodel.cpp index c5b0de4d..c0763ff8 100644 --- a/components/metadatamodel/metadatamodel.cpp +++ b/components/metadatamodel/metadatamodel.cpp @@ -1,910 +1,910 @@ /* Copyright 2011 Marco Martin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "metadatamodel.h" #include "resourcewatcher.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kao.h" using namespace Nepomuk::Vocabulary; using namespace Soprano::Vocabulary; MetadataModel::MetadataModel(QObject *parent) : AbstractMetadataModel(parent), m_runningClients(0), m_countQueryClient(0), m_limit(0), m_pageSize(30), m_scoreResources(false), m_thumbnailSize(180, 120), m_thumbnailerPlugins(new QStringList(KIO::PreviewJob::availablePlugins())) { m_newEntriesTimer = new QTimer(this); m_newEntriesTimer->setSingleShot(true); connect(m_newEntriesTimer, SIGNAL(timeout()), this, SLOT(newEntriesDelayed())); m_previewTimer = new QTimer(this); m_previewTimer->setSingleShot(true); connect(m_previewTimer, SIGNAL(timeout()), this, SLOT(delayedPreview())); //using the same cache of the engine, they index both by url m_imageCache = new KImageCache("plasma_engine_preview", 10485760); m_watcher = new Nepomuk::ResourceWatcher(this); m_watcher->addProperty(NAO::numericRating()); connect(m_watcher, SIGNAL(propertyAdded(Nepomuk::Resource, Nepomuk::Types::Property, QVariant)), this, SLOT(propertyChanged(Nepomuk::Resource, Nepomuk::Types::Property, QVariant))); QHash roleNames; roleNames[Qt::DisplayRole] = "display"; roleNames[Qt::DecorationRole] = "decoration"; roleNames[Label] = "label"; roleNames[Description] = "description"; roleNames[Types] = "types"; roleNames[ClassName] = "className"; roleNames[GenericClassName] = "genericClassName"; roleNames[HasSymbol] = "hasSymbol"; roleNames[Icon] = "icon"; roleNames[Thumbnail] = "thumbnail"; roleNames[IsFile] = "isFile"; roleNames[Exists] = "exists"; roleNames[Rating] = "rating"; roleNames[NumericRating] = "numericRating"; roleNames[Symbols] = "symbols"; roleNames[ResourceUri] = "resourceUri"; roleNames[ResourceType] = "resourceType"; roleNames[MimeType] = "mimeType"; roleNames[Url] = "url"; roleNames[Topics] = "topics"; roleNames[TopicsNames] = "topicsNames"; roleNames[Tags] = "tags"; roleNames[TagsNames] = "tagsNames"; setRoleNames(roleNames); } MetadataModel::~MetadataModel() { delete m_imageCache; } void MetadataModel::setQuery(const Nepomuk::Query::Query &query) { m_query = query; if (Nepomuk::Query::QueryServiceClient::serviceAvailable()) { askRefresh(); } } Nepomuk::Query::Query MetadataModel::query() const { return m_query; } void MetadataModel::setQueryString(const QString &query) { if (query == m_queryString || query == "nepomuk") { return; } m_queryString = query; askRefresh(); emit queryStringChanged(); } QString MetadataModel::queryString() const { return m_queryString; } void MetadataModel::setLimit(int limit) { if (limit == m_limit) { return; } m_limit = limit; askRefresh(); emit limitChanged(); } int MetadataModel::limit() const { return m_limit; } void MetadataModel::setScoreResources(bool score) { if (m_scoreResources == score) { return; } m_scoreResources = score; askRefresh(); emit scoreResourcesChanged(); } bool MetadataModel::scoreResources() const { return m_scoreResources; } void MetadataModel::setLazyLoading(bool lazy) { //lazy loading depends from the page zise, that is not directly user controllable if (lazy == (m_pageSize > 0)) { return; } //TODO: a way to control this? maybe from the available memory? m_pageSize = lazy ? 30 : -1; askRefresh(); emit lazyLoadingChanged(); } bool MetadataModel::lazyLoading() const { return (m_pageSize > 0); } void MetadataModel::setSortBy(const QVariantList &sortBy) { QStringList stringList = variantToStringList(sortBy); if (m_sortBy == stringList) { return; } m_sortBy = stringList; askRefresh(); emit sortByChanged(); } QVariantList MetadataModel::sortBy() const { return stringToVariantList(m_sortBy); } void MetadataModel::setSortOrder(Qt::SortOrder sortOrder) { if (m_sortOrder == sortOrder) { return; } m_sortOrder = sortOrder; askRefresh(); emit sortOrderChanged(); } Qt::SortOrder MetadataModel::sortOrder() const { return m_sortOrder; } int MetadataModel::find(const QString &resourceUri) { int index = -1; int i = 0; Nepomuk::Resource resToFind = Nepomuk::Resource::fromResourceUri(resourceUri); foreach (const Nepomuk::Resource &res, m_resources) { if (res == resToFind) { index = i; break; } ++i; } return index; } void MetadataModel::doQuery() { QDeclarativePropertyMap *parameters = qobject_cast(extraParameters()); //check if really all properties to build the query are null if (m_queryString.isEmpty() && resourceType().isEmpty() && mimeType().isEmpty() && activityId().isEmpty() && tagStrings().size() == 0 && !startDate().isValid() && !endDate().isValid() && minimumRating() <= 0 && maximumRating() <= 0 && parameters->size() == 0) { return; } setStatus(Waiting); m_query = Nepomuk::Query::Query(); m_query.setQueryFlags(Nepomuk::Query::Query::WithoutFullTextExcerpt); Nepomuk::Query::AndTerm rootTerm; if (!m_queryString.isEmpty()) { rootTerm.addSubTerm(Nepomuk::Query::QueryParser::parseQuery(m_queryString).term()); } if (!resourceType().isEmpty()) { //FIXME: more elegant QString type = resourceType(); bool negation = false; - if (type.startsWith("!")) { + if (type.startsWith('!')) { type = type.remove(0, 1); negation = true; } if (negation) { rootTerm.addSubTerm(Nepomuk::Query::NegationTerm::negateTerm(Nepomuk::Query::ResourceTypeTerm(propertyUrl(type)))); } else { rootTerm.addSubTerm(Nepomuk::Query::ResourceTypeTerm(propertyUrl(type))); if (type != "nfo:Bookmark") { //FIXME: remove bookmarks if not explicitly asked for rootTerm.addSubTerm(Nepomuk::Query::NegationTerm::negateTerm(Nepomuk::Query::ResourceTypeTerm(propertyUrl("nfo:Bookmark")))); } } } if (!mimeType().isEmpty()) { QString type = mimeType(); bool negation = false; - if (type.startsWith("!")) { + if (type.startsWith('!')) { type = type.remove(0, 1); negation = true; } Nepomuk::Query::ComparisonTerm term(Nepomuk::Vocabulary::NIE::mimeType(), Nepomuk::Query::LiteralTerm(type)); if (negation) { rootTerm.addSubTerm(Nepomuk::Query::NegationTerm::negateTerm(term)); } else { rootTerm.addSubTerm(term); } } if (parameters && parameters->size() > 0) { foreach (const QString &key, parameters->keys()) { QString parameter = parameters->value(key).toString(); bool negation = false; - if (parameter.startsWith("!")) { + if (parameter.startsWith('!')) { parameter = parameter.remove(0, 1); negation = true; } //FIXME: Contains should work, but doesn't match for file names Nepomuk::Query::ComparisonTerm term(propertyUrl(key), Nepomuk::Query::LiteralTerm(parameter)); if (negation) { rootTerm.addSubTerm(Nepomuk::Query::NegationTerm::negateTerm(term)); } else { rootTerm.addSubTerm(term); } } } if (!activityId().isEmpty()) { QString activity = activityId(); bool negation = false; - if (activity.startsWith("!")) { + if (activity.startsWith('!')) { activity = activity.remove(0, 1); negation = true; } kDebug() << "Asking for resources of activity" << activityId(); Nepomuk::Resource acRes(activity, Nepomuk::Vocabulary::KAO::Activity()); Nepomuk::Query::ComparisonTerm term(Soprano::Vocabulary::NAO::isRelated(), Nepomuk::Query::ResourceTerm(acRes)); term.setInverted(true); if (negation) { rootTerm.addSubTerm(Nepomuk::Query::NegationTerm::negateTerm(term)); } else { rootTerm.addSubTerm(term); } } foreach (const QString &tag, tagStrings()) { QString individualTag = tag; bool negation = false; - if (individualTag.startsWith("!")) { + if (individualTag.startsWith('!')) { individualTag = individualTag.remove(0, 1); negation = true; } Nepomuk::Query::ComparisonTerm term( Soprano::Vocabulary::NAO::hasTag(), Nepomuk::Query::ResourceTerm(Nepomuk::Tag(individualTag))); if (negation) { rootTerm.addSubTerm(Nepomuk::Query::NegationTerm::negateTerm(term)); } else { rootTerm.addSubTerm(term); } } if (startDate().isValid() || endDate().isValid()) { rootTerm.addSubTerm(Nepomuk::Query::dateRangeQuery(startDate(), endDate()).term()); } if (minimumRating() > 0) { const Nepomuk::Query::LiteralTerm ratingTerm(minimumRating()); Nepomuk::Query::ComparisonTerm term = Nepomuk::Types::Property(propertyUrl("nao:numericRating")) > ratingTerm; rootTerm.addSubTerm(term); } if (maximumRating() > 0) { const Nepomuk::Query::LiteralTerm ratingTerm(maximumRating()); Nepomuk::Query::ComparisonTerm term = Nepomuk::Types::Property(propertyUrl("nao:numericRating")) < ratingTerm; rootTerm.addSubTerm(term); } if (m_scoreResources) { QString activity = activityId(); - if (activity.startsWith("!")) { + if (activity.startsWith('!')) { activity = activity.remove(0, 1); } Nepomuk::Query::ComparisonTerm term = Nepomuk::Query::ComparisonTerm(propertyUrl("kao:targettedResource"), Nepomuk::Query::Term()); term.setVariableName("c"); term.setInverted(true); Nepomuk::Query::AndTerm andTerm = Nepomuk::Query::AndTerm(); Nepomuk::Query::ResourceTypeTerm typeTerm(KAO::ResourceScoreCache()); andTerm.addSubTerm(typeTerm); if (!activity.isEmpty()) { Nepomuk::Query::ComparisonTerm usedActivityTerm(propertyUrl("kao:usedActivity"), Nepomuk::Query::ResourceTerm(Nepomuk::Resource(activity, Nepomuk::Vocabulary::KAO::Activity())) ); andTerm.addSubTerm(usedActivityTerm); } Nepomuk::Query::ComparisonTerm cachedScoreTerm(propertyUrl("kao:cachedScore"), Nepomuk::Query::Term()); cachedScoreTerm.setVariableName("score"); cachedScoreTerm.setSortWeight(1, Qt::DescendingOrder); andTerm.addSubTerm(cachedScoreTerm); term.setSubTerm(andTerm); rootTerm.addSubTerm(term); } //bind directly some properties, to avoid calling hyper inefficient resource::property { m_query.addRequestProperty(Nepomuk::Query::Query::RequestProperty(NIE::url())); m_query.addRequestProperty(Nepomuk::Query::Query::RequestProperty(NAO::hasSymbol())); m_query.addRequestProperty(Nepomuk::Query::Query::RequestProperty(NIE::mimeType())); m_query.addRequestProperty(Nepomuk::Query::Query::RequestProperty(NAO::description())); m_query.addRequestProperty(Nepomuk::Query::Query::RequestProperty(Xesam::description())); m_query.addRequestProperty(Nepomuk::Query::Query::RequestProperty(RDFS::comment())); } int weight = m_sortBy.length() + 1; foreach (const QString &sortProperty, m_sortBy) { Nepomuk::Query::ComparisonTerm sortTerm(propertyUrl(sortProperty), Nepomuk::Query::Term()); sortTerm.setSortWeight(weight, m_sortOrder); rootTerm.addSubTerm(sortTerm); --weight; } m_query.setTerm(rootTerm); kDebug()<<"Sparql query:"< &)), this, SLOT(countQueryResult(const QList &))); if (m_limit > 0) { m_query.setLimit(m_limit); } m_countQueryClient->sparqlQuery(m_query.toSparqlQuery(Nepomuk::Query::Query::CreateCountQuery)); //if page size is invalid, fetch all if (m_pageSize < 1) { fetchResultsPage(0); } } void MetadataModel::fetchResultsPage(int page) { Nepomuk::Query::QueryServiceClient *client = new Nepomuk::Query::QueryServiceClient(this); m_queryClients[page] = client; m_pagesForClient[client] = page; m_validIndexForPage[page] = 0; Nepomuk::Query::Query pageQuery(m_query); if (m_pageSize > 0) { pageQuery.setOffset(m_pageSize*page); pageQuery.setLimit(m_pageSize); } client->query(pageQuery); connect(client, SIGNAL(newEntries(const QList &)), this, SLOT(newEntries(const QList &))); connect(client, SIGNAL(entriesRemoved(const QList &)), this, SLOT(entriesRemoved(const QList &))); connect(client, SIGNAL(finishedListing()), this, SLOT(finishedListing())); m_queryClientsHistory << client; ++m_runningClients; } void MetadataModel::countQueryResult(const QList< Nepomuk::Query::Result > &entries) { setStatus(Running); //this should be always 1 foreach (Nepomuk::Query::Result res, entries) { int count = res.additionalBinding(QLatin1String("cnt")).variant().toInt(); if (count < m_resources.size()) { beginRemoveRows(QModelIndex(), count-1, m_resources.size()-1); m_resources.resize(count); endRemoveRows(); } else if (count > m_resources.size()) { beginInsertRows(QModelIndex(), m_resources.size(), count-1); m_resources.resize(count); endInsertRows(); } } } void MetadataModel::newEntries(const QList< Nepomuk::Query::Result > &entries) { setStatus(Running); const int page = m_pagesForClient.value(qobject_cast(sender())); foreach (Nepomuk::Query::Result res, entries) { //kDebug() << "Result!!!" << res.resource().genericLabel() << res.resource().type(); //kDebug() << "Result label:" << res.genericLabel(); Nepomuk::Resource resource = res.resource(); if (res.requestProperties().value(propertyUrl("nie:url")).toString().isEmpty()) { continue; } m_resourcesToInsert[page] << resource; //pre-popuplating of the cache to avoid accessing properties directly //label is a bit too complex to take from query m_cachedResources[resource][Label] = resource.genericLabel(); QString description = res.requestProperties().value(NAO::description()).toString(); if (description.isEmpty()) { description = res.requestProperties().value(Xesam::description()).toString(); } if (description.isEmpty()) { description = res.requestProperties().value(RDFS::comment()).toString(); } if (!description.isEmpty()) { m_cachedResources[resource][Description] = description; } m_cachedResources[resource][Url] = res.requestProperties().value(propertyUrl("nie:url")).toString(); QStringList types; foreach (const QUrl &u, resource.types()) { types << u.toString(); } m_cachedResources[resource][Types] = types; Soprano::Node symbol = res.requestProperties().value(NAO::hasSymbol()); if (!symbol.toString().isEmpty()) { m_cachedResources[resource][Icon] = symbol.toString(); } else { m_cachedResources[resource][Icon] = KMimeType::iconNameForUrl(m_cachedResources[resource][Url].toString()); } //those seems to not be possible avoiding to access the resource m_cachedResources[resource][ClassName] = resource.className(); m_cachedResources[resource][ResourceType] = resource.resourceType(); m_cachedResources[resource][IsFile] = resource.isFile(); m_cachedResources[resource][HasSymbol] = res.requestProperties().value(NAO::hasSymbol()).toString(); m_cachedResources[resource][MimeType] = res.requestProperties().value(NIE::mimeType()).toString(); //FIXME: The most complicated of all, this should really be simplified { //FIXME: a more elegant way is needed QString genericClassName = m_cachedResources.value(resource).value(ClassName).toString(); //FIXME: most bookmarks are Document too, so Bookmark wins if (m_cachedResources.value(resource).value(Label).value >().contains(NFO::Bookmark())) { m_cachedResources[resource][GenericClassName] = "Bookmark"; } else { Nepomuk::Types::Class resClass(resource.resourceType()); foreach (Nepomuk::Types::Class parentClass, resClass.parentClasses()) { const QString label = parentClass.label(); if (label == "Document" || label == "Audio" || label == "Video" || label == "Image" || label == "Contact") { genericClassName = label; break; //two cases where the class is 2 levels behind the level of generalization we want } else if (parentClass.label() == "RasterImage") { genericClassName = "Image"; } else if (parentClass.label() == "TextDocument") { genericClassName = "Document"; } } m_cachedResources[resource][GenericClassName] = genericClassName; } } } if (!m_newEntriesTimer->isActive() && !m_resourcesToInsert[page].isEmpty()) { m_newEntriesTimer->start(200); } } void MetadataModel::newEntriesDelayed() { if (m_resourcesToInsert.isEmpty()) { return; } m_elapsedTime.start(); QHash >::const_iterator i; for (i = m_resourcesToInsert.constBegin(); i != m_resourcesToInsert.constEnd(); ++i) { const QList resourcesToInsert = i.value(); m_watcher->stop(); int pageStart = 0; if (m_pageSize > 0) { pageStart = i.key() * m_pageSize; } int startOffset = m_validIndexForPage.value(i.key()); int offset = startOffset; //if new result arrive on an already running query, they may arrive before countQueryResult if (m_resources.size() < pageStart + startOffset + 1) { beginInsertRows(QModelIndex(), m_resources.size(), pageStart + startOffset); m_resources.resize(pageStart + startOffset + 1); endInsertRows(); } //this happens only when m_validIndexForPage has been invalidate by row removal if (!m_validIndexForPage.contains(i.key()) && m_resources[pageStart + startOffset].isValid()) { while (startOffset < m_resources.size() && m_resources[pageStart + startOffset].isValid()) { ++startOffset; ++offset; } } foreach (Nepomuk::Resource res, resourcesToInsert) { //kDebug() << "Result!!!" << res.genericLabel() << res.type(); //kDebug() << "Page:" << i.key() << "Index:"<< pageStart + offset; m_uriToResourceIndex[res.resourceUri()] = pageStart + offset; //there can be new results before the count query gets updated if (pageStart + offset < m_resources.size()) { m_resources[pageStart + offset] = res; m_watcher->addResource(res); ++offset; } else { beginInsertRows(QModelIndex(), m_resources.size(), pageStart + offset); m_resources.resize(pageStart + offset + 1); m_resources[pageStart + offset] = res; m_watcher->addResource(res); ++offset; endInsertRows(); } } m_validIndexForPage[i.key()] = offset; m_watcher->start(); emit dataChanged(createIndex(pageStart + startOffset, 0), createIndex(pageStart + startOffset + resourcesToInsert.count()-1, 0)); } kDebug() << "Elapsed time populating the model" << m_elapsedTime.elapsed(); m_resourcesToInsert.clear(); } void MetadataModel::propertyChanged(Nepomuk::Resource res, Nepomuk::Types::Property prop, QVariant val) { Q_UNUSED(prop) Q_UNUSED(val) const int index = m_uriToResourceIndex.value(res.resourceUri()); if (index >= 0) { emit dataChanged(createIndex(index, 0, 0), createIndex(index, 0, 0)); } } void MetadataModel::entriesRemoved(const QList &urls) { int prevIndex = -100; //pack all the stuff to remove in groups, to emit the least possible signals //this assumes urls are in the same order they arrived ion the results //it's a map because we want to remove values from the vector in inverted order to keep indexes valid trough the remove loop QMap toRemove; foreach (const QUrl &url, urls) { const int index = m_uriToResourceIndex.value(url); if (index == prevIndex + 1) { toRemove[prevIndex]++; } else { toRemove[index] = 1; } prevIndex = index; } //all the page indexes may be invalid now m_validIndexForPage.clear(); QMap::const_iterator i = toRemove.constEnd(); while (i != toRemove.constBegin()) { --i; beginRemoveRows(QModelIndex(), i.key(), i.key()+i.value()-1); m_resources.remove(i.key(), i.value()); endRemoveRows(); } //another loop, we don't depend to m_uriToResourceIndex in data(), but we take this doublesafety foreach (const QUrl &url, urls) { m_uriToResourceIndex.remove(url); } //FIXME: this loop makes all the optimizations useless, get rid either of it or the optimizations for (int i = 0; i < m_resources.count(); ++i) { m_uriToResourceIndex[m_resources[i].resourceUri()] = i; } emit countChanged(); } void MetadataModel::finishedListing() { --m_runningClients; if (m_runningClients <= 0) { setStatus(Idle); if (m_queryClientsHistory.count() > 10) { for (int i = 0; i < m_queryClientsHistory.count() - 10; ++i) { Nepomuk::Query::QueryServiceClient *client = m_queryClientsHistory.first(); m_queryClientsHistory.pop_front(); int page = m_pagesForClient.value(client); m_queryClients.remove(page); m_pagesForClient.remove(client); delete client; } } } } QVariant MetadataModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.column() != 0 || index.row() < 0 || index.row() >= m_resources.count()){ return QVariant(); } const Nepomuk::Resource &resource = m_resources[index.row()]; if (!resource.isValid() && m_pageSize > 0 && !m_queryClients.contains(floor(index.row()/m_pageSize))) { //HACK const_cast(this)->fetchResultsPage(floor(index.row()/m_pageSize)); return QVariant(); //m_pageSize <= 0, means fetch all } else if (!resource.isValid() && !m_queryClients.contains(0)) { //HACK const_cast(this)->fetchResultsPage(0); return QVariant(); } else if (!resource.isValid()) { return QVariant(); } //We're lucky: was cached if (m_cachedResources.value(resource).contains(role)) { return m_cachedResources.value(resource).value(role); } switch (role) { case Qt::DisplayRole: case Label: return m_cachedResources.value(resource).value(Label); case Qt::DecorationRole: return KIcon(m_cachedResources.value(resource).value(Icon).toString()); case HasSymbol: case Icon: return m_cachedResources.value(resource).value(Icon).toString(); case Thumbnail: { KUrl url(m_cachedResources.value(resource).value(Url).toString()); if (m_cachedResources.value(resource).value(IsFile).toBool() && url.isLocalFile()) { QImage preview = QImage(m_thumbnailSize, QImage::Format_ARGB32_Premultiplied); if (m_imageCache->findImage(url.prettyUrl(), &preview)) { return preview; } m_previewTimer->start(100); const_cast(this)->m_filesToPreview[url] = QPersistentModelIndex(index); } return QVariant(); } case Exists: return resource.exists(); case Rating: return resource.rating(); case NumericRating: return resource.property(NAO::numericRating()).toString(); case Symbols: return resource.symbols(); case ResourceUri: return resource.resourceUri(); case Topics: { QStringList topics; foreach (const Nepomuk::Resource &u, resource.topics()) { topics << u.resourceUri().toString(); } return topics; } case TopicsNames: { QStringList topicNames; foreach (const Nepomuk::Resource &u, resource.topics()) { topicNames << u.genericLabel(); } return topicNames; } case Tags: { QStringList tags; foreach (const Nepomuk::Tag &tag, resource.tags()) { tags << tag.resourceUri().toString(); } return tags; } case TagsNames: { QStringList tagNames; foreach (const Nepomuk::Tag &tag, resource.tags()) { tagNames << tag.genericLabel(); } return tagNames; } default: return QVariant(); } } void MetadataModel::delayedPreview() { QHash::const_iterator i = m_filesToPreview.constBegin(); KFileItemList list; while (i != m_filesToPreview.constEnd()) { KUrl file = i.key(); QPersistentModelIndex index = i.value(); if (!m_previewJobs.contains(file) && file.isValid()) { list.append(KFileItem(file, QString(), 0)); m_previewJobs.insert(file, QPersistentModelIndex(index)); } ++i; } if (list.size() > 0) { KIO::PreviewJob* job = KIO::filePreview(list, m_thumbnailSize, m_thumbnailerPlugins); //job->setIgnoreMaximumSize(true); kDebug() << "Created job" << job; connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)), this, SLOT(showPreview(const KFileItem&, const QPixmap&))); connect(job, SIGNAL(failed(const KFileItem&)), this, SLOT(previewFailed(const KFileItem&))); } m_filesToPreview.clear(); } void MetadataModel::showPreview(const KFileItem &item, const QPixmap &preview) { QPersistentModelIndex index = m_previewJobs.value(item.url()); m_previewJobs.remove(item.url()); if (!index.isValid()) { return; } m_imageCache->insertImage(item.url().prettyUrl(), preview.toImage()); //kDebug() << "preview size:" << preview.size(); emit dataChanged(index, index); } void MetadataModel::previewFailed(const KFileItem &item) { m_previewJobs.remove(item.url()); } // Just signal QSortFilterProxyModel to do the real sorting. void MetadataModel::sort(int column, Qt::SortOrder order) { Q_UNUSED(column); Q_UNUSED(order); beginResetModel(); endResetModel(); } void MetadataModel::setThumbnailSize(const QSize& size) { m_thumbnailSize = size; emit thumbnailSizeChanged(); } QSize MetadataModel::thumbnailSize() const { return m_thumbnailSize; } #include "metadatamodel.moc" diff --git a/components/metadatamodel/metadatatimelinemodel.cpp b/components/metadatamodel/metadatatimelinemodel.cpp index c23962f0..bfa7a775 100644 --- a/components/metadatamodel/metadatatimelinemodel.cpp +++ b/components/metadatamodel/metadatatimelinemodel.cpp @@ -1,340 +1,340 @@ /* Copyright 2011 Marco Martin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "metadatatimelinemodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kao.h" MetadataTimelineModel::MetadataTimelineModel(QObject *parent) : AbstractMetadataModel(parent), m_queryClient(0), m_totalCount(0) { QHash roleNames; roleNames[LabelRole] = "label"; roleNames[YearRole] = "year"; roleNames[MonthRole] = "month"; roleNames[DayRole] = "day"; roleNames[CountRole] = "count"; setRoleNames(roleNames); askRefresh(); } MetadataTimelineModel::~MetadataTimelineModel() { } void MetadataTimelineModel::setLevel(MetadataTimelineModel::Level level) { if (m_level == level) { return; } m_level = level; askRefresh(); emit levelChanged(); } MetadataTimelineModel::Level MetadataTimelineModel::level() const { return m_level; } QString MetadataTimelineModel::description() const { if (m_results.isEmpty()) { return QString(); } //TODO: manage cases where start and enddate cover more than one year/month switch (m_level) { case Year: return i18n("All years"); case Month: return KGlobal::locale()->calendar()->yearString(startDate(), KCalendarSystem::LongFormat); case Day: default: return i18nc("Month and year, such as March 2007", "%1 %2", KGlobal::locale()->calendar()->monthName(startDate(), KCalendarSystem::LongName), KGlobal::locale()->calendar()->yearString(startDate(), KCalendarSystem::LongFormat)); } } void MetadataTimelineModel::doQuery() { QDeclarativePropertyMap *parameters = qobject_cast(extraParameters()); m_totalCount = 0; setStatus(Waiting); QString monthQuery; QString dayQuery; if (m_level >= Month) { monthQuery = "bif:month(?label)"; } else { - monthQuery = "0"; + monthQuery = '0'; } if (m_level >= Day) { dayQuery = "bif:dayofmonth(?label)"; } else { - dayQuery = "0"; + dayQuery = '0'; } QString query = QString("select distinct bif:year(?label) as ?year %1 as ?month %2 as ?day count(*) as ?count where { ?r nie:lastModified ?label ").arg(monthQuery).arg(dayQuery); if (!resourceType().isEmpty()) { QString type = resourceType(); bool negation = false; - if (type.startsWith("!")) { + if (type.startsWith('!')) { type = type.remove(0, 1); negation = true; } if (negation) { query += " . FILTER(!bif:exists((select (1) where { ?r rdf:type " + type + " . }))) "; } else { query += " . ?r rdf:type " + type; } if (type != "nfo:Bookmark") { //FIXME: remove bookmarks if not explicitly asked for query += " . FILTER(!bif:exists((select (1) where { ?r a . }))) "; } } if (!mimeType().isEmpty()) { QString type = mimeType(); bool negation = false; - if (type.startsWith("!")) { + if (type.startsWith('!')) { type = type.remove(0, 1); negation = true; } if (negation) { query += " . FILTER(!bif:exists((select (1) where { ?r nie:mimeType ?mimeType . FILTER(bif:contains(?mimeType, \"'" + type + "'\")) . }))) "; } else { query += " . ?r nie:mimeType ?mimeType . FILTER(bif:contains(?mimeType, \"'" + type + "'\")) "; } } if (parameters && parameters->size() > 0) { foreach (const QString &key, parameters->keys()) { QString parameter = parameters->value(key).toString(); bool negation = false; - if (parameter.startsWith("!")) { + if (parameter.startsWith('!')) { parameter = parameter.remove(0, 1); negation = true; } if (negation) { query += " . FILTER(!bif:exists((select (1) where { ?r " + key + " ?mimeType . FILTER(bif:contains(?mimeType, \"'" + parameter + "'\")) . }))) "; } else { query += " . ?r " + key + " ?mimeType . FILTER(bif:contains(?mimeType, \"'" + parameter + "'\")) "; } } } if (!activityId().isEmpty()) { QString activity = activityId(); bool negation = false; - if (activity.startsWith("!")) { + if (activity.startsWith('!')) { activity = activity.remove(0, 1); negation = true; } Nepomuk::Resource acRes(activity, Nepomuk::Vocabulary::KAO::Activity()); if (negation) { query += ". FILTER(!bif:exists((select (1) where { <" + acRes.resourceUri().toString() + "> ?r . }))) "; } else { query += " . <" + acRes.resourceUri().toString() + "> nao:isRelated ?r "; } } //this is an AND set of tags.. should be allowed OR as well? foreach (const QString &tag, tagStrings()) { QString individualTag = tag; bool negation = false; - if (individualTag.startsWith("!")) { + if (individualTag.startsWith('!')) { individualTag = individualTag.remove(0, 1); negation = true; } if (negation) { query += ". FILTER(!bif:exists((select (1) where { ?r nao:hasTag ?tagSet \ . ?tagSet ?tagLabel ?tag \ . ?tagLabel \ . FILTER(bif:contains(?tag, \"'"+individualTag+"'\"))}))) "; } else { query += ". ?r nao:hasTag ?tagSet \ . ?tagSet ?tagLabel ?tag \ . ?tagLabel \ . FILTER(bif:contains(?tag, \"'"+individualTag+"'\")) "; } } if (startDate().isValid() || endDate().isValid()) { if (startDate().isValid()) { query += ". ?r ?v2 . FILTER(?v2>\"" + startDate().toString(Qt::ISODate) + "\"^^) "; } if (endDate().isValid()) { query += ". ?r ?v2 . FILTER(?v2<\"" + endDate().toString(Qt::ISODate) + "\"^^) "; } } if (minimumRating() > 0) { query += " . ?r nao:numericRating ?rating filter (?rating >=" + QString::number(minimumRating()) + ") "; } if (maximumRating() > 0) { query += " . ?r nao:numericRating ?rating filter (?rating <=" + QString::number(maximumRating()) + ") "; } query += " . ?r ?v1 . FILTER(?v1>0) . } "; //Group by construction query += " group by bif:year(?label) "; if (m_level >= Month) { query += " bif:month(?label) "; } if (m_level >= Day) { query += " bif:dayofmonth(?label) "; } query += " order by ?year ?month ?day "; kDebug() << "Performing the Sparql query" << query; beginResetModel(); m_results.clear(); endResetModel(); emit countChanged(); emit totalCountChanged(); emit descriptionChanged(); if (m_queryClient) { m_queryClient->close(); } delete m_queryClient; m_queryClient = new Nepomuk::Query::QueryServiceClient(this); connect(m_queryClient, SIGNAL(newEntries(const QList &)), this, SLOT(newEntries(const QList &))); connect(m_queryClient, SIGNAL(entriesRemoved(const QList &)), this, SLOT(entriesRemoved(const QList &))); connect(m_queryClient, SIGNAL(finishedListing()), this, SLOT(finishedListing())); m_queryClient->sparqlQuery(query); } void MetadataTimelineModel::newEntries(const QList< Nepomuk::Query::Result > &entries) { setStatus(Running); QVector > results; QVariantList categories; foreach (Nepomuk::Query::Result res, entries) { QString label; int count = res.additionalBinding(QLatin1String("count")).variant().toInt(); int year = res.additionalBinding(QLatin1String("year")).variant().toInt(); int month = res.additionalBinding(QLatin1String("month")).variant().toInt(); int day = res.additionalBinding(QLatin1String("day")).variant().toInt(); QHash resHash; resHash[YearRole] = year; resHash[MonthRole] = month; resHash[DayRole] = day; resHash[CountRole] = count; m_totalCount += count; results << resHash; } if (results.count() > 0) { beginInsertRows(QModelIndex(), m_results.count(), m_results.count()+results.count()); m_results << results; m_categories << categories; endInsertRows(); emit countChanged(); emit totalCountChanged(); emit descriptionChanged(); } } void MetadataTimelineModel::entriesRemoved(const QList &urls) { //FIXME: we don't have urls here return; emit countChanged(); emit totalCountChanged(); } void MetadataTimelineModel::finishedListing() { setStatus(Idle); } QVariant MetadataTimelineModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.column() != 0 || index.row() < 0 || index.row() >= m_results.count()){ return QVariant(); } const QHash row = m_results[index.row()]; if (role == LabelRole) { switch(m_level) { case Year: return row.value(YearRole); case Month: return KGlobal::locale()->calendar()->monthName(row.value(MonthRole), row.value(YearRole), KCalendarSystem::LongName); case Day: default: return row.value(DayRole); } } return row.value((Roles)role); } #include "metadatatimelinemodel.moc" diff --git a/components/mobilecomponents/fallbackcomponent.cpp b/components/mobilecomponents/fallbackcomponent.cpp index 3c4c2be4..10dc0e3d 100644 --- a/components/mobilecomponents/fallbackcomponent.cpp +++ b/components/mobilecomponents/fallbackcomponent.cpp @@ -1,48 +1,48 @@ /* * Copyright 2011 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program 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 Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "fallbackcomponent.h" #include #include #include FallbackComponent::FallbackComponent(QObject *parent) : QObject(parent) { } QString FallbackComponent::resolvePath(const QString &component, const QStringList &paths) { foreach (const QString &path, paths) { //kDebug() << "Searching for" << path; //TODO: cache this, to prevent too much disk access - QString resolved = KStandardDirs::locate("data", "plasma/" + component + "/" + path); + QString resolved = KStandardDirs::locate("data", "plasma/" + component + '/' + path); if (!resolved.isEmpty()) { return resolved; } } return QString(); } #include "fallbackcomponent.moc" diff --git a/dataengines/apps/appsource.cpp b/dataengines/apps/appsource.cpp index a033a844..9fe1e4c3 100644 --- a/dataengines/apps/appsource.cpp +++ b/dataengines/apps/appsource.cpp @@ -1,108 +1,108 @@ /* * Copyright 2009 Chani Armitage * Copyright 2011 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as * published by the Free Software Foundation * * This program 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 Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "appsource.h" #include #include #include AppSource::AppSource(const QString &name, QObject *parent) : Plasma::DataContainer(parent) { setObjectName(name); QStringList names = name.split(':'); if (names.length() == 2) { m_categories = names.last().split('|'); } KSharedConfigPtr ptr = KSharedConfig::openConfig("active-blacklistrc"); KConfigGroup config = KConfigGroup(ptr, "blacklist"); m_blackList = config.readEntry("apps", QStringList()); populate(); connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(sycocaChanged(QStringList))); } AppSource::~AppSource() { } void AppSource::sycocaChanged(const QStringList &changes) { if (changes.contains("apps") || changes.contains("xdgdata-apps")) { populate(); } } void AppSource::populate() { QString query = "exist Exec"; if (!m_categories.isEmpty()) { query += " and ("; bool first = true; foreach (const QString &category, m_categories) { if (!first) { query += " or "; } first = false; query += QString(" (exist Categories and '%1' ~subin Categories)").arg(category); } - query += ")"; + query += ')'; } //openSUSE: exclude YaST modules from the list query += " and (not (exist Categories and 'X-SuSE-YaST' in Categories))"; // Filter out blacklisted apps as to not show too much crap foreach (const QString appName, m_blackList) { query += QString(" and (DesktopEntryName != '%1' )").arg(appName); } //kWarning()<query("Application", query); removeAllData(); Plasma::DataEngine::Data data; foreach (const KService::Ptr &service, services) { if (service->noDisplay()) { continue; } QString description; if (!service->genericName().isEmpty() && service->genericName() != service->name()) { description = service->genericName(); } else if (!service->comment().isEmpty()) { description = service->comment(); } data["iconName"] = service->icon(); data["name"] = service->name(); data["genericName"] = service->genericName(); data["description"] = description; data["storageId"] = service->storageId(); data["entryPath"] = service->entryPath(); setData(service->storageId(), data); } checkForUpdate(); } #include "appsource.moc" diff --git a/dataengines/apps/groupsource.cpp b/dataengines/apps/groupsource.cpp index 75156658..bf95e695 100644 --- a/dataengines/apps/groupsource.cpp +++ b/dataengines/apps/groupsource.cpp @@ -1,108 +1,108 @@ /* * Copyright 2009 Chani Armitage * Copyright 2011 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as * published by the Free Software Foundation * * This program 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 Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "groupsource.h" #include #include #include GroupSource::GroupSource(const QString &name, QObject *parent) : Plasma::DataContainer(parent) { setObjectName(name); QStringList split = name.split(':'); if (split.length() == 2) { m_group = split.last(); } if (m_group.isEmpty()) { - m_group = "/"; + m_group = '/'; } populate(); connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(sycocaChanged(QStringList))); } GroupSource::~GroupSource() { } void GroupSource::sycocaChanged(const QStringList &changes) { if (changes.contains("apps") || changes.contains("xdgdata-apps")) { populate(); } } void GroupSource::populate() { KServiceGroup::Ptr group = KServiceGroup::group(m_group); removeAllData(); loadGroup(group); checkForUpdate(); } void GroupSource::loadGroup(KServiceGroup::Ptr group) { if (group && group->isValid()) { KServiceGroup::List list = group->entries(); for( KServiceGroup::List::ConstIterator it = list.constBegin(); it != list.constEnd(); it++) { const KSycocaEntry::Ptr p = (*it); if (p->isType(KST_KService)) { const KService::Ptr service = KService::Ptr::staticCast(p); if (!service->noDisplay()) { QString genericName = service->genericName(); if (genericName.isNull()) { genericName = service->comment(); } QString description; if (!service->genericName().isEmpty() && service->genericName() != service->name()) { description = service->genericName(); } else if (!service->comment().isEmpty()) { description = service->comment(); } Plasma::DataEngine::Data data; data["iconName"] = service->icon(); data["name"] = service->name(); data["genericName"] = service->genericName(); data["description"] = description; data["storageId"] = service->storageId(); data["entryPath"] = service->entryPath(); setData(service->storageId(), data); } } else if (p->isType(KST_KServiceGroup)) { const KServiceGroup::Ptr subGroup = KServiceGroup::Ptr::staticCast(p); if (!subGroup->noDisplay() && subGroup->childCount() > 0) { loadGroup(subGroup); } } } } } #include "groupsource.moc" diff --git a/dataengines/apps/groupssource.cpp b/dataengines/apps/groupssource.cpp index 95e9d9a5..5d3db77e 100644 --- a/dataengines/apps/groupssource.cpp +++ b/dataengines/apps/groupssource.cpp @@ -1,105 +1,105 @@ /* * Copyright 2009 Chani Armitage * Copyright 2011 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as * published by the Free Software Foundation * * This program 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 Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "groupssource.h" #include #include #include int GroupsSource::s_depth = 0; GroupsSource::GroupsSource(const QString &name, QObject *parent) : Plasma::DataContainer(parent), m_maxDepth(-1) { setObjectName(name); QStringList split = name.split(':'); if (split.length() >= 2) { m_group = split[1]; } if (split.length() == 3) { m_maxDepth = split[2].toInt(); } if (m_group.isEmpty()) { - m_group = "/"; + m_group = '/'; } populate(); connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(sycocaChanged(QStringList))); } GroupsSource::~GroupsSource() { } void GroupsSource::sycocaChanged(const QStringList &changes) { if (changes.contains("apps") || changes.contains("xdgdata-apps")) { populate(); } } void GroupsSource::populate() { KServiceGroup::Ptr group = KServiceGroup::group(m_group); s_depth = 0; removeAllData(); loadGroup(group); checkForUpdate(); } void GroupsSource::loadGroup(KServiceGroup::Ptr group) { if (m_maxDepth >= 0 && s_depth > m_maxDepth) { return; } ++s_depth; if (group && group->isValid()) { KServiceGroup::List list = group->entries(); for( KServiceGroup::List::ConstIterator it = list.constBegin(); it != list.constEnd(); it++) { const KSycocaEntry::Ptr p = (*it); if (p->isType(KST_KServiceGroup)) { const KServiceGroup::Ptr subGroup = KServiceGroup::Ptr::staticCast(p); Plasma::DataEngine::Data data; data["iconName"] = subGroup->icon(); data["name"] = subGroup->name(); data["description"] = subGroup->comment(); data["relPath"] = subGroup->relPath(); data["display"] = !subGroup->noDisplay(); data["childCount"] = subGroup->childCount(); setData(subGroup->relPath(), data); if (!subGroup->noDisplay() && subGroup->childCount() > 0) { loadGroup(subGroup); } } } } } #include "groupssource.moc" diff --git a/dataengines/metadata/metadataengine.cpp b/dataengines/metadata/metadataengine.cpp index 6229acb1..adf73e32 100644 --- a/dataengines/metadata/metadataengine.cpp +++ b/dataengines/metadata/metadataengine.cpp @@ -1,218 +1,218 @@ /* Copyright 2011 Sebastian Kügler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include // Nepomuk #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "metadataengine.h" #include #include //#include "activityservice/activityservice.h" #include "metadataservice/metadataservice.h" #include "resourcecontainer.h" #include #include #define RESULT_LIMIT 24 class MetadataEnginePrivate { public: QSize previewSize; KActivities::Consumer *activityConsumer; QDBusServiceWatcher *queryServiceWatcher; QStringList connectedSources; QStringList requestedSources; QTimer *preparesourcesTimer; }; MetadataEngine::MetadataEngine(QObject* parent, const QVariantList& args) : Plasma::DataEngine(parent, args) { Q_UNUSED(args); d = new MetadataEnginePrivate; setMaxSourceCount(RESULT_LIMIT); // Guard against loading too many connections d->queryServiceWatcher = new QDBusServiceWatcher(QLatin1String("org.kde.nepomuk.services.nepomukqueryservice"), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration, this); connect(d->queryServiceWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(serviceRegistered(QString))); d->activityConsumer = new KActivities::Consumer(this); d->preparesourcesTimer = new QTimer(this); d->preparesourcesTimer->setSingleShot(true); connect(d->preparesourcesTimer, SIGNAL(timeout()), this, SLOT(prepareSources())); } void MetadataEngine::init() { //kDebug() << "init."; } void MetadataEngine::serviceRegistered(const QString &service) { if (service == "org.kde.nepomuk.services.nepomukqueryservice") { foreach (const QString &source, d->connectedSources) { prepareSource(source); } // d->connectedSources.clear(); } } MetadataEngine::~MetadataEngine() { delete d; } QStringList MetadataEngine::sources() const { return QStringList(); } bool MetadataEngine::sourceRequestEvent(const QString &name) { QString massagedName = name; // if the strings ends with :number it's the limit for the query if (name.contains(QRegExp(".*:\\d+$"))) { - QStringList tokens = name.split(":"); + QStringList tokens = name.split(':'); massagedName = massagedName.mid(0, massagedName.lastIndexOf(":")); } if (name.startsWith('/')) { massagedName = "file://" + name; } foreach (const QString &s, Plasma::DataEngine::sources()) { if (s == name) { kDebug() << "!!! resource already exists." << name; return true; } } if (Nepomuk::ResourceManager::instance()->initialized()) { d->requestedSources << name; d->preparesourcesTimer->start(100); return true; //return prepareSource(name); } else { ResourceContainer *container = qobject_cast(containerForSource(massagedName)); Nepomuk::Query::Query query; if (!container) { container = new ResourceContainer(this); container->setObjectName(name); addSource(container); } d->connectedSources << name; return true; } } bool MetadataEngine::updateSourceEvent(const QString &source) { ResourceContainer *container = qobject_cast(containerForSource(source)); if (container) { prepareSource(source); } return false; } void MetadataEngine::prepareSources() { foreach (const QString &source, d->requestedSources) { prepareSource(source); } d->requestedSources.clear(); } bool MetadataEngine::prepareSource(const QString &name) { QString massagedName = name; if (name.startsWith('/')) { massagedName = "file://" + name; } kDebug() << "Creating resource synchronously"; Nepomuk::Resource resource(massagedName); kDebug() << resource.resourceUri(); if (!resource.exists()) { kDebug() << "Resource " << massagedName << " does not exist."; return false; } //return true; ResourceContainer *container = qobject_cast(containerForSource(massagedName)); if (container) { container->setResource(resource); } else { container = new ResourceContainer(this); container->setResource(resource); container->setObjectName(name); addSource(container); } return true; } Plasma::Service *MetadataEngine::serviceForSource(const QString &source) { //FIXME validate the name MetadataService *service = new MetadataService(source); service->setParent(this); return service; } #include "metadataengine.moc" diff --git a/dataengines/metadata/resourcecontainer.cpp b/dataengines/metadata/resourcecontainer.cpp index f6669ef4..dfe739dc 100644 --- a/dataengines/metadata/resourcecontainer.cpp +++ b/dataengines/metadata/resourcecontainer.cpp @@ -1,263 +1,263 @@ /* Copyright 2011 Marco Martin Copyright 2011 Sebastian Kügler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "resourcecontainer.h" #include "resourcewatcher.h" #include #include #include #include #include #include ResourceContainer::ResourceContainer(QObject *parent) : Plasma::DataContainer(parent) { m_watcher = new Nepomuk::ResourceWatcher(this); m_watcher->addProperty(QUrl("http://www.semanticdesktop.org/ontologies/2007/08/15/nao#numericRating")); connect(m_watcher, SIGNAL(propertyAdded(Nepomuk::Resource, Nepomuk::Types::Property, QVariant)), this, SLOT(propertyChanged(Nepomuk::Resource, Nepomuk::Types::Property, QVariant))); } ResourceContainer::~ResourceContainer() { } void ResourceContainer::propertyChanged(Nepomuk::Resource res, Nepomuk::Types::Property prop, QVariant val) { if (res != m_resource) { return; } setData(prop.name(), val); checkForUpdate(); } void ResourceContainer::setResource(Nepomuk::Resource resource) { if (m_resource == resource) { return; } m_resource = resource; //update the resource watcher { m_watcher->stop(); QList resources; resources << resource; m_watcher->setResources(resources); m_watcher->start(); } QString desc = resource.genericDescription(); if (desc.isEmpty()) { desc = resource.className(); } QString label = resource.genericLabel(); if (label.isEmpty()) { label = "Empty label."; } setData("label", label); setData("description", desc); // Types QStringList _types; foreach (const QUrl &u, resource.types()) { _types << u.toString(); } setData("types", _types); Nepomuk::Types::Class resClass(resource.resourceType()); //FIXME: a more elegant way is needed setData("genericClassName", resource.className()); foreach (Nepomuk::Types::Class parentClass, resClass.parentClasses()) { if (parentClass.label() == "Document" || parentClass.label() == "Audio" || parentClass.label() == "Video" || parentClass.label() == "Image" || parentClass.label() == "Contact") { setData("genericClassName", parentClass.label()); break; //two cases where the class is 2 levels behind the level of generalization we want } else if (parentClass.label() == "RasterImage") { setData("genericClassName", "Image"); } else if (parentClass.label() == "TextDocument") { setData("genericClassName", "Document"); } } QString _icon = resource.genericIcon(); if (_icon.isEmpty() && resource.isFile()) { KUrl url = resource.toFile().url(); if (!url.isEmpty()) { _icon = KMimeType::iconNameForUrl(url); } } if (_icon.isEmpty()) { // use resource types to find a suitable icon. //TODO _icon = icon(QStringList(resource.className())); //kDebug() << "symbol" << _icon; } - if (_icon.split(",").count() > 1) { + if (_icon.split(',').count() > 1) { kDebug() << "More than one icon!" << _icon; - _icon = _icon.split(",").last(); + _icon = _icon.split(',').last(); } setData("icon", _icon); setData("hasSymbol", _icon); setData("isFile", resource.isFile()); setData("exists", resource.exists()); setData("rating", resource.rating()); setData("symbols", resource.symbols()); setData("className", resource.className()); setData("resourceUri", resource.resourceUri()); setData("resourceType", resource.resourceType()); setData("query", objectName()); if (resource.isFile() && resource.toFile().url().isLocalFile()) { setData("url", resource.toFile().url().prettyUrl()); } // Topics QStringList _topics, _topicNames; foreach (const Nepomuk::Resource &u, resource.topics()) { _topics << u.resourceUri().toString(); _topicNames << u.genericLabel(); } setData("topics", _topics); setData("topicNames", _topicNames); // Tags QStringList _tags, _tagNames; foreach (const Nepomuk::Tag &tag, resource.tags()) { _tags << tag.resourceUri().toString(); _tagNames << tag.genericLabel(); } setData("tags", _tags); setData("tagNames", _tagNames); // Related QStringList _relateds; foreach (const Nepomuk::Resource &res, resource.isRelateds()) { _relateds << res.resourceUri().toString(); } setData("relateds", _relateds); // Dynamic properties QStringList _properties; QHash props = resource.properties(); foreach(const QUrl &propertyUrl, props.keys()) { QStringList _l = propertyUrl.toString().split('#'); if (_l.count() > 1) { QString key = _l[1]; _properties << key; //QString from = dynamic_cast(); if (resource.property(propertyUrl).variant().canConvert(QVariant::List)) { QVariantList tl = resource.property(propertyUrl).variant().toList(); foreach (QVariant vu, tl) { //kDebug() << vu.toString().startsWith("nepomuk:") << vu.toString().startsWith("akonadi:") << vu.toString(); if (vu.canConvert(QVariant::Url) && (vu.toString().startsWith("nepomuk:") || vu.toString().startsWith("akonadi:"))) { kDebug() << "HHH This is a list.!!!" << key << vu.toString(); } } } //kDebug() << " ... " << key << propertyUrl << resource.property(propertyUrl).variant(); if (key != "plainTextMessageContent" && !data().contains(key)) { setData(key, resource.property(propertyUrl).variant()); } // More properties } else { kWarning() << "Could not parse ontology URL, missing '#':" << propertyUrl.toString(); } } setData("properties", _properties); checkForUpdate(); } QString ResourceContainer::icon(const QStringList &types) { if (!m_icons.size()) { // Add fallback icons here from generic to specific // The list of types is also sorted in this way, so // we're returning the most specific icon, even with // the hardcoded mapping. // Files //m_icons["FileDataObject"] = QString("audio-x-generic"); // Audio m_icons["Audio"] = QString("audio-x-generic"); m_icons["MusicPiece"] = QString("audio-x-generic"); // Images m_icons["Image"] = QString("image-x-generic"); m_icons["RasterImage"] = QString("image-x-generic"); m_icons["Email"] = QString("internet-mail"); m_icons["Document"] = QString("kword"); m_icons["PersonContact"] = QString("x-office-contact"); // Filesystem m_icons["Website"] = QString("text-html"); // ... add some more // Filesystem m_icons["Bookmark"] = QString("bookmarks"); m_icons["BookmarksFolder"] = QString("bookmarks-organize"); m_icons["FileDataObject"] = QString("unknown"); m_icons["TextDocument"] = QString("text-enriched"); } // keep searching until the most specific icon is found QString _icon = "nepomuk"; foreach(const QString &t, types) { QString shortType = t.split('#').last(); if (shortType.isEmpty()) { shortType = t; } if (m_icons.keys().contains(shortType)) { _icon = m_icons[shortType]; //kDebug() << "found icon for type" << shortType << _icon; } } return _icon; } #include "resourcecontainer.moc" diff --git a/virtualkeyboard/keyboardshell/keyboarddialog.cpp b/virtualkeyboard/keyboardshell/keyboarddialog.cpp index bc49a41d..3d8e4b4d 100644 --- a/virtualkeyboard/keyboardshell/keyboarddialog.cpp +++ b/virtualkeyboard/keyboardshell/keyboarddialog.cpp @@ -1,374 +1,374 @@ /* * Copyright 2007-2008 Aaron Seigo * Copyright 2009 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation * * This program 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 General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "keyboarddialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include KeyboardDialog::KeyboardDialog(Plasma::Corona *corona, Plasma::Containment *containment, const QString &pluginName, int appletId, const QVariantList &appletArgs, QWidget *parent) : Plasma::Dialog(parent), m_applet(0), m_containment(0), m_corona(corona), m_location(Plasma::Floating), m_switchKeyboardLayoutScheduled(false) { setContainment(containment); m_closeButton = new Plasma::IconWidget(m_containment); m_closeButton->setSvg("widgets/configuration-icons", "close"); m_closeButton->setMaximumSize(QSize(KIconLoader::SizeMedium, KIconLoader::SizeMedium)); connect(m_closeButton, SIGNAL(clicked()), this, SLOT(hide())); m_keyboardLayoutButton = new Plasma::IconWidget(m_containment); m_keyboardLayoutButton->setMaximumSize(QSize(KIconLoader::SizeMedium, KIconLoader::SizeMedium)); connect(m_keyboardLayoutButton, SIGNAL(clicked()), this, SLOT(nextKeyboardLayout())); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.connect("org.kde.keyboard", "/Layouts", "org.kde.KeyboardLayouts", "currentLayoutChanged", this, SLOT(currentKeyboardLayoutChanged())); dbus.connect("org.kde.keyboard", "/Layouts", "org.kde.KeyboardLayouts", "layoutListChanged", this, SLOT(refreshKeyboardLayoutInformation())); m_moveButton = new Plasma::IconWidget(m_containment); m_moveButton->setSvg("keyboardshell/arrows", "up-arrow"); m_moveButton->setMaximumWidth(KIconLoader::SizeMedium); connect(m_moveButton, SIGNAL(clicked()), this, SLOT(swapScreenEdge())); m_containment->setFormFactor(Plasma::Planar); m_containment->setLocation(Plasma::BottomEdge); KWindowSystem::setType(winId(), NET::Dock); setAttribute(Qt::WA_X11DoNotAcceptFocus); setWindowFlags(Qt::X11BypassWindowManagerHint); QFileInfo info(pluginName); if (!info.isAbsolute()) { - info = QFileInfo(QDir::currentPath() + "/" + pluginName); + info = QFileInfo(QDir::currentPath() + '/' + pluginName); } if (info.exists()) { m_applet = Plasma::Applet::loadPlasmoid(info.absoluteFilePath(), appletId, appletArgs); } if (!m_applet) { m_applet = Plasma::Applet::load(pluginName, appletId, appletArgs); } if (!m_applet) { #ifndef NDEBUG kWarning() << "Keyboard Plasmoid not found .. failing!"; #endif exit(1); } // ensure that the keyboard knows when to reset itself connect(this, SIGNAL(dialogVisible(bool)), m_applet, SLOT(dialogStatusChanged(bool))); m_containment->addApplet(m_applet, QPointF(-1, -1), false); QGraphicsLinearLayout *lay = new QGraphicsLinearLayout(m_containment); lay->addItem(m_applet); m_controlButtonsLayouts = new QGraphicsLinearLayout(Qt::Vertical); lay->addItem(m_controlButtonsLayouts); m_controlButtonsLayouts->addItem(m_closeButton); m_controlButtonsLayouts->addItem(m_moveButton); m_controlButtonsLayouts->addItem(m_keyboardLayoutButton); setGraphicsWidget(m_containment); m_applet->setFlag(QGraphicsItem::ItemIsMovable, false); setWindowTitle(m_applet->name()); setWindowIcon(SmallIcon(m_applet->icon())); connect(this, SIGNAL(sceneRectAboutToChange()), this, SLOT(updateGeometry())); QDesktopWidget *desktop = QApplication::desktop(); connect(desktop, SIGNAL(resized(int )), this, SLOT(updateGeometry())); setFixedHeight(static_cast(applet())->graphicsWidget()->effectiveSizeHint(Qt::PreferredSize).height()); QRect screenGeom = desktop->screenGeometry(desktop->screenNumber(this)); screenGeom.setWidth(screenGeom.width()-100); setFixedWidth(screenGeom.width()); hide(); setLocation(Plasma::BottomEdge); refreshKeyboardLayoutInformation(); } KeyboardDialog::~KeyboardDialog() { emit storeApplet(m_applet); } void KeyboardDialog::setContainment(Plasma::Containment *c) { if (m_containment) { disconnect(m_containment, 0, this, 0); } m_containment = c; m_containment->setScreen(0); updateGeometry(); } Plasma::Applet *KeyboardDialog::applet() { return m_applet; } Plasma::Location KeyboardDialog::location() const { return m_location; } Plasma::FormFactor KeyboardDialog::formFactor() const { return m_containment->formFactor(); } void KeyboardDialog::nextKeyboardLayout() { m_switchKeyboardLayoutScheduled = true; refreshKeyboardLayoutInformation(); } void KeyboardDialog::refreshKeyboardLayoutInformation() { QDBusInterface keyboards("org.kde.keyboard", "/Layouts"); QDBusPendingReply reply = keyboards.asyncCall("getLayoutsList"); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(layoutsReceived(QDBusPendingCallWatcher*))); } void KeyboardDialog::layoutsReceived(QDBusPendingCallWatcher *watcher) { QDBusReply reply(*watcher); QTimer::singleShot(0, watcher, SLOT(deleteLater())); if (!reply.isValid()) { return; } m_keyboardLayouts = reply.value(); if (m_keyboardLayouts.size() < 2) { m_keyboardLayoutButton->hide(); m_controlButtonsLayouts->removeItem(m_keyboardLayoutButton); } else { if (!m_keyboardLayoutButton->isVisible()) { m_keyboardLayoutButton->show(); m_controlButtonsLayouts->addItem(m_keyboardLayoutButton); } QDBusInterface keyboards("org.kde.keyboard", "/Layouts"); QDBusPendingReply reply = keyboards.asyncCall("getCurrentLayout"); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(currentLayoutReceived(QDBusPendingCallWatcher*))); } } void KeyboardDialog::currentLayoutReceived(QDBusPendingCallWatcher *watcher) { QDBusReply reply(*watcher); QTimer::singleShot(0, watcher, SLOT(deleteLater())); if (!reply.isValid()) { return; } const QString layout = reply.value(); int index = m_keyboardLayouts.indexOf(layout); if (index == -1) { refreshKeyboardLayoutInformation(); return; } if (m_switchKeyboardLayoutScheduled) { m_switchKeyboardLayoutScheduled = false; index = (index + 1) % m_keyboardLayouts.count(); QDBusInterface keyboards("org.kde.keyboard", "/Layouts"); keyboards.asyncCall("setLayout", m_keyboardLayouts.at(index)); return; } QIcon icon; if (m_iconMap.contains(layout)) { icon = m_iconMap[layout]; } else { QString file; if (layout == "epo") { file = KStandardDirs::locate("data", "kcmkeyboard/pics/epo.png"); } else { QString countryCode; if (countryCode == "nec_vndr/jp") { countryCode = "jp"; } else if (layout.length() < 3) { countryCode = layout; } file = KStandardDirs::locate("locale", QString("l10n/%1/flag.png").arg(countryCode)); } if (!file.isEmpty()) { icon.addFile(file); } } if (icon.isNull()) { m_keyboardLayoutButton->setIcon(QIcon()); m_keyboardLayoutButton->setText(layout); m_iconMap.insert(layout, QIcon()); } else { m_iconMap.insert(layout, icon); m_keyboardLayoutButton->setIcon(icon); m_keyboardLayoutButton->setText(QString()); } } void KeyboardDialog::currentKeyboardLayoutChanged() { refreshKeyboardLayoutInformation(); } void KeyboardDialog::swapScreenEdge() { switch (m_location) { case Plasma::TopEdge: setLocation(Plasma::BottomEdge); break; case Plasma::RightEdge: setLocation(Plasma::LeftEdge); break; case Plasma::LeftEdge: setLocation(Plasma::RightEdge); break; case Plasma::BottomEdge: setLocation(Plasma::TopEdge); break; default: break; } } void KeyboardDialog::setLocation(const Plasma::Location location) { if (location == m_location) { return; } const Plasma::Location oldLocation = m_location; m_location = location; QDesktopWidget *desktop = QApplication::desktop(); const QRect screenGeom = desktop->screenGeometry(desktop->screenNumber(this)); switch (location) { case Plasma::TopEdge: setFixedSize(screenGeom.width() - 100, static_cast(applet())->graphicsWidget()->effectiveSizeHint(Qt::PreferredSize).height()); move(screenGeom.left() + 50, screenGeom.top()); m_moveButton->setSvg("keyboardshell/arrows", "down-arrow"); break; case Plasma::RightEdge: setFixedSize(static_cast(applet())->graphicsWidget()->effectiveSizeHint(Qt::PreferredSize).width(), screenGeom.height() - 100); move(screenGeom.right() - width(), screenGeom.top() + 50); m_moveButton->setSvg("keyboardshell/arrows", "left-arrow"); break; case Plasma::LeftEdge: setFixedSize(static_cast(applet())->graphicsWidget()->effectiveSizeHint(Qt::PreferredSize).width(), screenGeom.height() - 100); move(screenGeom.left(), screenGeom.top() + 50); m_moveButton->setSvg("keyboardshell/arrows", "right-arrow"); break; case Plasma::BottomEdge: setFixedSize(screenGeom.width() - 100, static_cast(applet())->graphicsWidget()->effectiveSizeHint(Qt::PreferredSize).height()); move(screenGeom.left() + 50, screenGeom.height() - height()); m_moveButton->setSvg("keyboardshell/arrows", "up-arrow"); break; default: // we don't support this location, so just revert back m_location = oldLocation; break; } if (isVisible()) { Plasma::WindowEffects::slideWindow(this, m_location); } } void KeyboardDialog::showEvent(QShowEvent *event) { KWindowSystem::setType(winId(), NET::Dock); unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove; KWindowSystem::setState(winId(), state); KWindowSystem::raiseWindow(effectiveWinId()); Plasma::Dialog::showEvent(event); //FIXME: this is an hack for the applet disabing itself in panic when doesn't immediately find a view Plasma::PopupApplet *pa = qobject_cast(m_applet); if (pa) { pa->graphicsWidget()->setEnabled(true); } } void KeyboardDialog::resizeEvent(QResizeEvent *event) { if (event->oldSize() == event->size()) { return; } Plasma::Dialog::resizeEvent(event); QDesktopWidget *desktop = QApplication::desktop(); switch (m_location) { case Plasma::TopEdge: move((desktop->size().width() / 2) - (event->size().width() / 2), desktop->screenGeometry().y()); break; case Plasma::RightEdge: move(desktop->size().width() - event->size().width(), (desktop->size().height() / 2) - (event->size().height() / 2)); break; case Plasma::LeftEdge: move(desktop->screenGeometry().x(), (desktop->size().height() / 2) - (event->size().width() / 2)); break; case Plasma::BottomEdge: move((desktop->size().width() / 2) - (event->size().width() / 2), desktop->size().height() - event->size().height()); break; default: break; } } #include "keyboarddialog.moc"