You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/kded/kbuildservicefactory.cpp

255 lines
6.8 KiB

/* This file is part of the KDE libraries
* Copyright (C) 1999 David Faure <faure@kde.org>
* 1999 Waldo Bastian <bastian@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 "kbuildservicefactory.h"
#include "ksycoca.h"
#include "ksycocadict.h"
#include "kresourcelist.h"
#include "kmimetype.h"
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kmessageboxwrapper.h>
#include <klocale.h>
#include <kdebug.h>
#include <assert.h>
KBuildServiceFactory::KBuildServiceFactory( KSycocaFactory *serviceTypeFactory,
KBuildServiceGroupFactory *serviceGroupFactory ) :
KServiceFactory(),
m_serviceDict(977),
m_dupeDict(977),
m_serviceTypeFactory( serviceTypeFactory ),
m_serviceGroupFactory( serviceGroupFactory )
{
m_resourceList = new KSycocaResourceList();
// m_resourceList->add( "apps", "*.desktop" );
// m_resourceList->add( "apps", "*.kdelnk" );
m_resourceList->add( "services", "*.desktop" );
m_resourceList->add( "services", "*.kdelnk" );
}
// return all service types for this factory
// i.e. first arguments to m_resourceList->add() above
TQStringList KBuildServiceFactory::resourceTypes()
{
return TQStringList() << "apps" << "services";
}
KBuildServiceFactory::~KBuildServiceFactory()
{
delete m_resourceList;
}
KService * KBuildServiceFactory::findServiceByName(const TQString &_name)
{
return m_serviceDict[_name];
}
KSycocaEntry *
KBuildServiceFactory::createEntry( const TQString& file, const char *resource )
{
TQString name = file;
int pos = name.findRev('/');
if (pos != -1)
{
name = name.mid(pos+1);
}
if (name.isEmpty())
return 0;
// Is it a .desktop file?
if (!name.endsWith(".desktop") && !name.endsWith(".kdelnk"))
return 0;
KDesktopFile desktopFile(file, true, resource);
KService * serv = new KService( &desktopFile );
if ( serv->isValid() && !serv->isDeleted() )
{
return serv;
} else {
if (!serv->isDeleted())
kdWarning(7012) << "Invalid Service : " << file << endl;
delete serv;
return 0L;
}
}
void
KBuildServiceFactory::saveHeader(TQDataStream &str)
{
KSycocaFactory::saveHeader(str);
str << (TQ_INT32) m_nameDictOffset;
str << (TQ_INT32) m_relNameDictOffset;
str << (TQ_INT32) m_offerListOffset;
str << (TQ_INT32) m_initListOffset;
str << (TQ_INT32) m_menuIdDictOffset;
}
void
KBuildServiceFactory::save(TQDataStream &str)
{
KSycocaFactory::save(str);
m_nameDictOffset = str.device()->at();
m_nameDict->save(str);
m_relNameDictOffset = str.device()->at();
m_relNameDict->save(str);
saveOfferList(str);
saveInitList(str);
m_menuIdDictOffset = str.device()->at();
m_menuIdDict->save(str);
int endOfFactoryData = str.device()->at();
// Update header (pass #3)
saveHeader(str);
// Seek to end.
str.device()->at(endOfFactoryData);
}
void
KBuildServiceFactory::saveOfferList(TQDataStream &str)
{
m_offerListOffset = str.device()->at();
bool isNumber;
for(TQDictIterator<KSycocaEntry::Ptr> itserv ( *m_entryDict );
itserv.current();
++itserv)
{
KService *service = (KService *) ((KSycocaEntry *)(*itserv.current()));
TQStringList serviceTypeList = service->serviceTypes();
KServiceType::List serviceTypes;
TQStringList::ConstIterator it = serviceTypeList.begin();
for( ; it != serviceTypeList.end(); ++it )
{
(*it).toInt(&isNumber);
if (isNumber)
continue;
KServiceType::Ptr serviceType = KServiceType::serviceType(*it);
if (!serviceType)
{
// kdWarning() << "'"<< service->desktopEntryPath() << "' specifies undefined mimetype/servicetype '"<< (*it) << "'" << endl;
continue;
}
serviceTypes.append(serviceType);
}
while(serviceTypes.count())
{
KServiceType::Ptr serviceType = serviceTypes.first();
serviceTypes.pop_front();
KServiceType::Ptr parentType = serviceType->parentType();
if (parentType)
serviceTypes.append(parentType);
serviceType->addService(service);
}
}
// For each entry in servicetypeFactory
for(TQDictIterator<KSycocaEntry::Ptr> it ( *(m_serviceTypeFactory->entryDict()) );
it.current();
++it)
{
// export associated services
KServiceType *entry = static_cast<KServiceType*>(static_cast<KSycocaEntry*>(*it.current()));
KService::List services = entry->services();
for(KService::List::ConstIterator it2 = services.begin();
it2 != services.end(); ++it2)
{
KService *service = *it2;
str << (TQ_INT32) entry->offset();
str << (TQ_INT32) service->offset();
}
}
str << (TQ_INT32) 0; // End of list marker (0)
}
void
KBuildServiceFactory::saveInitList(TQDataStream &str)
{
m_initListOffset = str.device()->at();
KService::List initList;
for(TQDictIterator<KSycocaEntry::Ptr> itserv ( *m_entryDict );
itserv.current();
++itserv)
{
KService::Ptr service = (KService *) ((KSycocaEntry *) *itserv.current());
if ( !service->init().isEmpty() )
{
initList.append(service);
}
}
str << (TQ_INT32) initList.count(); // Nr of init services.
for(KService::List::Iterator it = initList.begin();
it != initList.end();
++it)
{
str << (TQ_INT32) (*it)->offset();
}
}
void
KBuildServiceFactory::addEntry(KSycocaEntry *newEntry, const char *resource)
{
if (m_dupeDict.find(newEntry))
return;
KSycocaFactory::addEntry(newEntry, resource);
KService * service = (KService *) newEntry;
m_dupeDict.insert(newEntry, service);
if (!service->isDeleted())
{
TQString parent = service->parentApp();
if (!parent.isEmpty())
m_serviceGroupFactory->addNewChild(parent, resource, service);
}
TQString name = service->desktopEntryName();
m_nameDict->add( name, newEntry );
m_serviceDict.replace(name, service);
TQString relName = service->desktopEntryPath();
m_relNameDict->add( relName, newEntry );
TQString menuId = service->menuId();
if (!menuId.isEmpty())
m_menuIdDict->add( menuId, newEntry );
}