/* 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 "tdesycoca.h"
# include "tdesycocadict.h"
# include "kresourcelist.h"
# include "kmimetype.h"
# include <tdeglobal.h>
# include <kstandarddirs.h>
# include <kmessageboxwrapper.h>
# include <tdelocale.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 ) ;
}