kbuildservicetypefactory.cpp
/* This file is part of the KDE libraries
* Copyright (C) 1999 David Faure <faure@kde.org>
*
* 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 "kbuildservicetypefactory.h"
#include "ksycoca.h"
#include "ksycocadict.h"
#include "kresourcelist.h"
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kmessageboxwrapper.h>
#include <kdebug.h>
#include <klocale.h>
#include <assert.h>
#include <kdesktopfile.h>
template class QDict<KMimeType>;
KBuildServiceTypeFactory::KBuildServiceTypeFactory() :
KServiceTypeFactory()
{
// Read servicetypes first, since they might be needed to read mimetype properties
m_resourceList = new KSycocaResourceList;
m_resourceList->add("servicetypes", "*.desktop");
m_resourceList->add("servicetypes", "*.kdelnk");
m_resourceList->add( "mime", "*.desktop" );
m_resourceList->add( "mime", "*.kdelnk" );
}
// return all service types for this factory
// i.e. first arguments to m_resourceList->add() above
QStringList KBuildServiceTypeFactory::resourceTypes()
{
return QStringList() << "servicetypes" << "mime";
}
KBuildServiceTypeFactory::~KBuildServiceTypeFactory()
{
delete m_resourceList;
}
KServiceType * KBuildServiceTypeFactory::findServiceTypeByName(const QString &_name)
{
assert (KSycoca::self()->isBuilding());
// We're building a database - the service type must be in memory
KSycocaEntry::Ptr * servType = (*m_entryDict)[ _name ];
if (!servType)
return 0;
return (KServiceType *) ((KSycocaEntry*)*servType);
}
KSycocaEntry *
KBuildServiceTypeFactory::createEntry(const QString &file, const char *resource)
{
QString name = file;
int pos = name.findRev('/');
if (pos != -1)
{
name = name.mid(pos+1);
}
if (name.isEmpty())
return 0;
KDesktopFile desktopFile(file, true, resource);
if ( desktopFile.readBoolEntry( "Hidden", false ) == true )
return 0;
// TODO check Type field first
QString mime = desktopFile.readEntry( "MimeType" );
QString service = desktopFile.readEntry( "X-KDE-ServiceType" );
if ( mime.isEmpty() && service.isEmpty() )
{
QString tmp = QString("The service/mime type config file\n%1\n"
"does not contain a ServiceType=...\nor MimeType=... entry").arg( file );
kdWarning(7012) << tmp << endl;
return 0;
}
KServiceType* e;
if ( mime == "inode/directory" )
e = new KFolderType( &desktopFile );
else if ( mime == "application/x-desktop" )
e = new KDEDesktopMimeType( &desktopFile );
else if ( mime == "application/x-executable" || mime == "application/x-shellscript" )
e = new KExecMimeType( &desktopFile );
else if ( !mime.isEmpty() )
e = new KMimeType( &desktopFile );
else
e = new KServiceType( &desktopFile );
if (e->isDeleted())
{
delete e;
return 0;
}
if ( !(e->isValid()) )
{
kdWarning(7012) << "Invalid ServiceType : " << file << endl;
delete e;
return 0;
}
return e;
}
void
KBuildServiceTypeFactory::saveHeader(QDataStream &str)
{
KSycocaFactory::saveHeader(str);
str << (Q_INT32) m_fastPatternOffset;
str << (Q_INT32) m_otherPatternOffset;
str << (Q_INT32) m_propertyTypeDict.count();
QMapIterator<QString, int> it;
for (it = m_propertyTypeDict.begin(); it != m_propertyTypeDict.end(); ++it)
{
str << it.key() << (Q_INT32)it.data();
}
}
void
KBuildServiceTypeFactory::save(QDataStream &str)
{
KSycocaFactory::save(str);
savePatternLists(str);
int endOfFactoryData = str.device()->at();
// Update header (pass #3)
saveHeader(str);
// Seek to end.
str.device()->at(endOfFactoryData);
}
void
KBuildServiceTypeFactory::savePatternLists(QDataStream &str)
{
// Store each patterns in one of the 2 string lists (for sorting)
QStringList fastPatterns; // for *.a to *.abcd
QStringList otherPatterns; // for the rest (core.*, *.tar.bz2, *~) ...
QDict<KMimeType> dict;
// For each mimetype in servicetypeFactory
for(QDictIterator<KSycocaEntry::Ptr> it ( *m_entryDict );
it.current();
++it)
{
KSycocaEntry *entry = (*it.current());
if ( entry->isType( KST_KMimeType ) )
{
KMimeType *mimeType = (KMimeType *) entry;
QStringList pat = mimeType->patterns();
QStringList::ConstIterator patit = pat.begin();
for ( ; patit != pat.end() ; ++patit )
{
const QString &pattern = *patit;
if ( pattern.findRev('*') == 0
&& pattern.findRev('.') == 1
&& pattern.length() <= 6 )
// it starts with "*.", has no other '*' and no other '.', and is max 6 chars
// => fast patttern
fastPatterns.append( pattern );
else if (!pattern.isEmpty()) // some stupid mimetype files have "Patterns=;"
otherPatterns.append( pattern );
// Assumption : there is only one mimetype for that pattern
// It doesn't really make sense otherwise, anyway.
dict.replace( pattern, mimeType );
}
}
}
// Sort the list - the fast one, useless for the other one
fastPatterns.sort();
Q_INT32 entrySize = 0;
Q_INT32 nrOfEntries = 0;
m_fastPatternOffset = str.device()->at();
// Write out fastPatternHeader (Pass #1)
str.device()->at(m_fastPatternOffset);
str << nrOfEntries;
str << entrySize;
// For each fast pattern
QStringList::ConstIterator it = fastPatterns.begin();
for ( ; it != fastPatterns.end() ; ++it )
{
int start = str.device()->at();
// Justify to 6 chars with spaces, so that the size remains constant
// in the database file.
QString paddedPattern = (*it).leftJustify(6).right(4); // remove leading "*."
//kdDebug(7021) << QString("FAST : '%1' '%2'").arg(paddedPattern).arg(dict[(*it)]->name()) << endl;
str << paddedPattern;
str << dict[(*it)]->offset();
entrySize = str.device()->at() - start;
nrOfEntries++;
}
// store position
m_otherPatternOffset = str.device()->at();
// Write out fastPatternHeader (Pass #2)
str.device()->at(m_fastPatternOffset);
str << nrOfEntries;
str << entrySize;
// For the other patterns
str.device()->at(m_otherPatternOffset);
it = otherPatterns.begin();
for ( ; it != otherPatterns.end() ; ++it )
{
//kdDebug(7021) << QString("OTHER : '%1' '%2'").arg(*it).arg(dict[(*it)]->name()) << endl;
str << (*it);
str << dict[(*it)]->offset();
}
str << QString(""); // end of list marker (has to be a string !)
}
void
KBuildServiceTypeFactory::addEntry(KSycocaEntry *newEntry, const char *resource)
{
KServiceType * serviceType = (KServiceType *) newEntry;
if ( (*m_entryDict)[ newEntry->name() ] )
{
// Already exists
if (serviceType->desktopEntryPath().endsWith("kdelnk"))
return; // Skip
// Replace
KSycocaFactory::removeEntry(newEntry);
}
KSycocaFactory::addEntry(newEntry, resource);
const QMap<QString,QVariant::Type>& pd = serviceType->propertyDefs();
QMap<QString,QVariant::Type>::ConstIterator pit = pd.begin();
for( ; pit != pd.end(); ++pit )
{
if (!m_propertyTypeDict.contains(pit.key()))
m_propertyTypeDict.insert(pit.key(), pit.data());
else if (m_propertyTypeDict[pit.key()] != pit.data())
kdWarning(7021) << "Property '"<< pit.key() << "' is defined multiple times ("<< serviceType->name() <<")" <<endl;
}
}
KBuildServiceTypeFactory::createEntry
virtual KSycocaEntry * createEntry(const QString &file, const char *resource)
Construct a KServiceType from a config file.
Definition: kbuildservicetypefactory.cpp:69
KBuildServiceTypeFactory::KBuildServiceTypeFactory
KBuildServiceTypeFactory()
Create factory.
Definition: kbuildservicetypefactory.cpp:34
KBuildServiceTypeFactory::saveHeader
virtual void saveHeader(QDataStream &str)
Write out header information.
Definition: kbuildservicetypefactory.cpp:127
KBuildServiceTypeFactory::addEntry
virtual void addEntry(KSycocaEntry *newEntry, const char *resource)
Add entry.
Definition: kbuildservicetypefactory.cpp:245
KBuildServiceTypeFactory::findServiceTypeByName
virtual KServiceType * findServiceTypeByName(const QString &_name)
Find a service type in the database file.
Definition: kbuildservicetypefactory.cpp:57
KBuildServiceTypeFactory::resourceTypes
static QStringList resourceTypes()
Returns all resource types for this service factory.
Definition: kbuildservicetypefactory.cpp:47
KBuildServiceTypeFactory::save
virtual void save(QDataStream &str)
Write out service type specific index files.
Definition: kbuildservicetypefactory.cpp:143

KDE Home | KDE Accessibility Home | Description of Access Keys