summaryrefslogtreecommitdiffstats
path: root/tdeio/tdeio/kservicefactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdeio/tdeio/kservicefactory.cpp')
-rw-r--r--tdeio/tdeio/kservicefactory.cpp291
1 files changed, 291 insertions, 0 deletions
diff --git a/tdeio/tdeio/kservicefactory.cpp b/tdeio/tdeio/kservicefactory.cpp
new file mode 100644
index 000000000..f4646fa75
--- /dev/null
+++ b/tdeio/tdeio/kservicefactory.cpp
@@ -0,0 +1,291 @@
+/* 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 "kservicefactory.h"
+#include "tdesycoca.h"
+#include "tdesycocatype.h"
+#include "tdesycocadict.h"
+#include "kservice.h"
+
+#include <tqstring.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kstaticdeleter.h>
+
+KServiceFactory::KServiceFactory()
+ : KSycocaFactory( KST_KServiceFactory )
+{
+ m_offerListOffset = 0;
+ m_nameDictOffset = 0;
+ m_relNameDictOffset = 0;
+ m_menuIdDictOffset = 0;
+ if (m_str)
+ {
+ // Read Header
+ TQ_INT32 i;
+ (*m_str) >> i;
+ m_nameDictOffset = i;
+ (*m_str) >> i;
+ m_relNameDictOffset = i;
+ (*m_str) >> i;
+ m_offerListOffset = i;
+ (*m_str) >> i;
+ m_initListOffset = i;
+ (*m_str) >> i;
+ m_menuIdDictOffset = i;
+
+ int saveOffset = m_str->device()->at();
+ // Init index tables
+ m_nameDict = new KSycocaDict(m_str, m_nameDictOffset);
+ // Init index tables
+ m_relNameDict = new KSycocaDict(m_str, m_relNameDictOffset);
+ // Init index tables
+ m_menuIdDict = new KSycocaDict(m_str, m_menuIdDictOffset);
+ saveOffset = m_str->device()->at(saveOffset);
+ }
+ else
+ {
+ // Build new database
+ m_nameDict = new KSycocaDict();
+ m_relNameDict = new KSycocaDict();
+ m_menuIdDict = new KSycocaDict();
+ }
+ _self = this;
+}
+
+KServiceFactory::~KServiceFactory()
+{
+ _self = 0L;
+ delete m_nameDict;
+ delete m_relNameDict;
+ delete m_menuIdDict;
+}
+
+KServiceFactory * KServiceFactory::self()
+{
+ if (!_self) {
+ _self = new KServiceFactory();
+ }
+ return _self;
+}
+
+KService * KServiceFactory::findServiceByName(const TQString &_name)
+{
+ if (!m_sycocaDict) return 0; // Error!
+
+ // Warning : this assumes we're NOT building a database
+ // But since findServiceByName isn't called in that case...
+ // [ see KServiceTypeFactory for how to do it if needed ]
+
+ int offset = m_sycocaDict->find_string( _name );
+ if (!offset) return 0; // Not found
+
+ KService * newService = createEntry(offset);
+
+ // Check whether the dictionary was right.
+ if (newService && (newService->name() != _name))
+ {
+ // No it wasn't...
+ delete newService;
+ newService = 0; // Not found
+ }
+ return newService;
+}
+
+KService * KServiceFactory::findServiceByDesktopName(const TQString &_name)
+{
+ if (!m_nameDict) return 0; // Error!
+
+ // Warning : this assumes we're NOT building a database
+ // But since findServiceByName isn't called in that case...
+ // [ see KServiceTypeFactory for how to do it if needed ]
+
+ int offset = m_nameDict->find_string( _name );
+ if (!offset) return 0; // Not found
+
+ KService * newService = createEntry(offset);
+
+ // Check whether the dictionary was right.
+ if (newService && (newService->desktopEntryName() != _name))
+ {
+ // No it wasn't...
+ delete newService;
+ newService = 0; // Not found
+ }
+ return newService;
+}
+
+KService * KServiceFactory::findServiceByDesktopPath(const TQString &_name)
+{
+ if (!m_relNameDict) return 0; // Error!
+
+ // Warning : this assumes we're NOT building a database
+ // But since findServiceByName isn't called in that case...
+ // [ see KServiceTypeFactory for how to do it if needed ]
+
+ int offset = m_relNameDict->find_string( _name );
+ if (!offset) return 0; // Not found
+
+ KService * newService = createEntry(offset);
+
+ // Check whether the dictionary was right.
+ if (newService && (newService->desktopEntryPath() != _name))
+ {
+ // No it wasn't...
+ delete newService;
+ newService = 0; // Not found
+ }
+ return newService;
+}
+
+KService * KServiceFactory::findServiceByMenuId(const TQString &_menuId)
+{
+ if (!m_menuIdDict) return 0; // Error!
+
+ // Warning : this assumes we're NOT building a database
+ // But since findServiceByMenuId isn't called in that case...
+ // [ see KServiceTypeFactory for how to do it if needed ]
+
+ int offset = m_menuIdDict->find_string( _menuId );
+ if (!offset) return 0; // Not found
+
+ KService * newService = createEntry(offset);
+
+ // Check whether the dictionary was right.
+ if (newService && (newService->menuId() != _menuId))
+ {
+ // No it wasn't...
+ delete newService;
+ newService = 0; // Not found
+ }
+ return newService;
+}
+
+KService* KServiceFactory::createEntry(int offset)
+{
+ KService * newEntry = 0L;
+ KSycocaType type;
+ TQDataStream *str = KSycoca::self()->findEntry(offset, type);
+ switch(type)
+ {
+ case KST_KService:
+ newEntry = new KService(*str, offset);
+ break;
+
+ default:
+ kdError(7011) << TQString(TQString("KServiceFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type)) << endl;
+ return 0;
+ }
+ if (!newEntry->isValid())
+ {
+ kdError(7011) << "KServiceFactory: corrupt object in KSycoca database!\n" << endl;
+ delete newEntry;
+ newEntry = 0;
+ }
+ return newEntry;
+}
+
+KService::List KServiceFactory::allServices()
+{
+ KService::List result;
+ KSycocaEntry::List list = allEntries();
+ for( KSycocaEntry::List::Iterator it = list.begin();
+ it != list.end();
+ ++it)
+ {
+ KService *newService = dynamic_cast<KService *>((*it).data());
+ if (newService)
+ result.append( KService::Ptr( newService ) );
+ }
+ return result;
+}
+
+KService::List KServiceFactory::allInitServices()
+{
+ KService::List list;
+ if (!m_str) return list;
+
+ // Assume we're NOT building a database
+
+ m_str->device()->at(m_initListOffset);
+ TQ_INT32 entryCount;
+ (*m_str) >> entryCount;
+
+ TQ_INT32 *offsetList = new TQ_INT32[entryCount];
+ for(int i = 0; i < entryCount; i++)
+ {
+ (*m_str) >> offsetList[i];
+ }
+
+ for(int i = 0; i < entryCount; i++)
+ {
+ KService *newEntry = createEntry(offsetList[i]);
+ if (newEntry)
+ {
+ list.append( KService::Ptr( newEntry ) );
+ }
+ }
+ delete [] offsetList;
+ return list;
+}
+
+KService::List KServiceFactory::offers( int serviceTypeOffset )
+{
+ KService::List list;
+
+ TQDataStream *str = m_str;
+ // Jump to the offer list
+ str->device()->at( m_offerListOffset );
+
+ TQ_INT32 aServiceTypeOffset;
+ TQ_INT32 aServiceOffset;
+ // We might want to do a binary search instead of a linear search
+ // since servicetype offsets are sorted. Bah.
+ while (true)
+ {
+ (*str) >> aServiceTypeOffset;
+ if ( aServiceTypeOffset )
+ {
+ (*str) >> aServiceOffset;
+ if ( aServiceTypeOffset == serviceTypeOffset )
+ {
+ // Save stream position !
+ int savedPos = str->device()->at();
+ // Create Service
+ KService * serv = createEntry( aServiceOffset );
+ if (serv)
+ list.append( KService::Ptr( serv ) );
+ // Restore position
+ str->device()->at( savedPos );
+ } else if ( aServiceTypeOffset > (TQ_INT32)serviceTypeOffset )
+ break; // too far
+ }
+ else
+ break; // 0 => end of list
+ }
+ return list;
+}
+
+KServiceFactory *KServiceFactory::_self = 0;
+
+void KServiceFactory::virtual_hook( int id, void* data )
+{ KSycocaFactory::virtual_hook( id, data ); }
+