mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 18:32:49 +00:00
159 lines
6.4 KiB
C++
159 lines
6.4 KiB
C++
/* This file is part of the KDE libraries
|
|
* Copyright 2008 David Faure <faure@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 of the License or ( at
|
|
* your option ) version 3 or, at the discretion of KDE e.V. ( which shall
|
|
* act as a proxy as in section 14 of the GPLv3 ), 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 Lesser 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 "kmimeassociations.h"
|
|
#include <kmimetype.h>
|
|
#include <kmimetyperepository_p.h>
|
|
#include <kservice.h>
|
|
#include <kconfiggroup.h>
|
|
#include <kconfig.h>
|
|
#include <kdebug.h>
|
|
#include <kglobal.h>
|
|
#include <kstandarddirs.h>
|
|
|
|
KMimeAssociations::KMimeAssociations(KOfferHash& offerHash)
|
|
: m_offerHash(offerHash)
|
|
{
|
|
}
|
|
|
|
/*
|
|
|
|
The goal of this class is to parse mimeapps.list files, which are used to
|
|
let users configure the application-mimetype associations.
|
|
|
|
Example file:
|
|
|
|
[Added Associations]
|
|
text/plain=kate.desktop;
|
|
|
|
[Removed Associations]
|
|
text/plain=gnome-gedit.desktop;gnu-emacs.desktop;
|
|
|
|
|
|
|
|
*/
|
|
|
|
bool KMimeAssociations::parseAllMimeAppsList()
|
|
{
|
|
// Using the "merged view" from KConfig is not enough since we -add- at every level, we don't replace.
|
|
const QStringList mimeappsFiles = KGlobal::dirs()->findAllResources("xdgdata-apps", "mimeapps.list");
|
|
if (mimeappsFiles.isEmpty())
|
|
return false;
|
|
|
|
int basePreference = 1000; // start high :)
|
|
QListIterator<QString> mimeappsIter( mimeappsFiles );
|
|
mimeappsIter.toBack();
|
|
while (mimeappsIter.hasPrevious()) { // global first, then local.
|
|
const QString mimeappsFile = mimeappsIter.previous();
|
|
kDebug(7021) << "Parsing" << mimeappsFile;
|
|
parseMimeAppsList(mimeappsFile, basePreference);
|
|
basePreference += 50;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void KMimeAssociations::parseMimeAppsList(const QString& file, int basePreference)
|
|
{
|
|
KConfig profile(file, KConfig::SimpleConfig);
|
|
parseAddedAssociations(KConfigGroup(&profile, "Added Associations"), file, basePreference);
|
|
parseRemovedAssociations(KConfigGroup(&profile, "Removed Associations"), file);
|
|
|
|
// KDE extension for parts and plugins, see settings/filetypes/mimetypedata.cpp
|
|
parseAddedAssociations(KConfigGroup(&profile, "Added KDE Service Associations"), file, basePreference);
|
|
parseRemovedAssociations(KConfigGroup(&profile, "Removed KDE Service Associations"), file);
|
|
}
|
|
|
|
void KMimeAssociations::parseAddedAssociations(const KConfigGroup& group, const QString& file, int basePreference)
|
|
{
|
|
Q_FOREACH(const QString& mimeName, group.keyList()) {
|
|
const QStringList services = group.readXdgListEntry(mimeName);
|
|
const QString resolvedMimeName = KMimeTypeRepository::self()->canonicalName(mimeName);
|
|
int pref = basePreference;
|
|
Q_FOREACH(const QString &service, services) {
|
|
KService::Ptr pService = KService::serviceByStorageId(service);
|
|
if (!pService) {
|
|
kDebug(7021) << file << "specifies unknown service" << service << "in" << group.name();
|
|
} else {
|
|
//kDebug(7021) << "adding mime" << resolvedMimeName << "to service" << pService->entryPath() << "pref=" << pref;
|
|
m_offerHash.addServiceOffer(resolvedMimeName, KServiceOffer(pService, pref, 0, pService->allowAsDefault()));
|
|
--pref;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KMimeAssociations::parseRemovedAssociations(const KConfigGroup& group, const QString& file)
|
|
{
|
|
Q_FOREACH(const QString& mime, group.keyList()) {
|
|
const QStringList services = group.readXdgListEntry(mime);
|
|
Q_FOREACH(const QString& service, services) {
|
|
KService::Ptr pService = KService::serviceByStorageId(service);
|
|
if (!pService) {
|
|
kDebug(7021) << file << "specifies unknown service" << service << "in" << group.name();
|
|
} else {
|
|
//kDebug(7021) << "removing mime" << mime << "from service" << pService.data() << pService->entryPath();
|
|
m_offerHash.removeServiceOffer(mime, pService);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KOfferHash::addServiceOffer(const QString& serviceType, const KServiceOffer& offer)
|
|
{
|
|
KService::Ptr service = offer.service();
|
|
//kDebug(7021) << "Adding" << service->entryPath() << "to" << serviceType << offer.preference();
|
|
ServiceTypeOffersData& data = m_serviceTypeData[serviceType]; // find or create
|
|
QList<KServiceOffer>& offers = data.offers;
|
|
QSet<KService::Ptr>& offerSet = data.offerSet;
|
|
if ( !offerSet.contains( service ) ) {
|
|
offers.append( offer );
|
|
offerSet.insert( service );
|
|
} else {
|
|
//kDebug(7021) << service->entryPath() << "already in" << serviceType;
|
|
// This happens when mimeapps.list mentions a service (to make it preferred)
|
|
// Update initialPreference to qMax(existing offer, new offer)
|
|
QMutableListIterator<KServiceOffer> sfit(data.offers);
|
|
while (sfit.hasNext()) {
|
|
if (sfit.next().service() == service) // we can compare KService::Ptrs because they are from the memory hash
|
|
sfit.value().setPreference( qMax(sfit.value().preference(), offer.preference()) );
|
|
}
|
|
}
|
|
}
|
|
|
|
void KOfferHash::removeServiceOffer(const QString& serviceType, KService::Ptr service)
|
|
{
|
|
ServiceTypeOffersData& data = m_serviceTypeData[serviceType]; // find or create
|
|
data.removedOffers.insert(service);
|
|
data.offerSet.remove(service);
|
|
QMutableListIterator<KServiceOffer> sfit(data.offers);
|
|
while (sfit.hasNext()) {
|
|
if (sfit.next().service()->storageId() == service->storageId())
|
|
sfit.remove();
|
|
}
|
|
}
|
|
|
|
bool KOfferHash::hasRemovedOffer(const QString& serviceType, KService::Ptr service) const
|
|
{
|
|
QHash<QString, ServiceTypeOffersData>::const_iterator it = m_serviceTypeData.find(serviceType);
|
|
if (it != m_serviceTypeData.end()) {
|
|
return (*it).removedOffers.contains(service);
|
|
}
|
|
return false;
|
|
}
|