• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • sources
  • kde-4.12
  • kdelibs
  • kdecore
  • services
kservicefactory.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  * Copyright (C) 1999-2006 David Faure <faure@kde.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License version 2 as published by the Free Software Foundation;
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Library General Public License for more details.
12  *
13  * You should have received a copy of the GNU Library General Public License
14  * along with this library; see the file COPYING.LIB. If not, write to
15  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  * Boston, MA 02110-1301, USA.
17  **/
18 
19 #include "kservicefactory.h"
20 #include "ksycoca.h"
21 #include "ksycocatype.h"
22 #include "ksycocadict_p.h"
23 #include "kservice.h"
24 
25 #include <klocale.h>
26 #include <kdebug.h>
27 #include <kglobal.h>
28 #include <kstandarddirs.h>
29 
30 extern int servicesDebugArea();
31 
32 K_GLOBAL_STATIC(KSycocaFactorySingleton<KServiceFactory>, kServiceFactoryInstance)
33 
34 KServiceFactory::KServiceFactory()
35  : KSycocaFactory( KST_KServiceFactory ),
36  m_nameDict(0),
37  m_relNameDict(0),
38  m_menuIdDict(0)
39 {
40  kServiceFactoryInstance->instanceCreated(this);
41  m_offerListOffset = 0;
42  m_nameDictOffset = 0;
43  m_relNameDictOffset = 0;
44  m_menuIdDictOffset = 0;
45  if (!KSycoca::self()->isBuilding()) {
46  QDataStream* str = stream();
47  Q_ASSERT(str);
48  if (!str)
49  return;
50  // Read Header
51  qint32 i;
52  (*str) >> i;
53  m_nameDictOffset = i;
54  (*str) >> i;
55  m_relNameDictOffset = i;
56  (*str) >> i;
57  m_offerListOffset = i;
58  (*str) >> i;
59  m_menuIdDictOffset = i;
60 
61  const int saveOffset = str->device()->pos();
62  // Init index tables
63  m_nameDict = new KSycocaDict(str, m_nameDictOffset);
64  // Init index tables
65  m_relNameDict = new KSycocaDict(str, m_relNameDictOffset);
66  // Init index tables
67  m_menuIdDict = new KSycocaDict(str, m_menuIdDictOffset);
68  str->device()->seek(saveOffset);
69  }
70 }
71 
72 KServiceFactory::~KServiceFactory()
73 {
74  if (kServiceFactoryInstance.exists())
75  kServiceFactoryInstance->instanceDestroyed(this);
76  delete m_nameDict;
77  delete m_relNameDict;
78  delete m_menuIdDict;
79 }
80 
81 KServiceFactory * KServiceFactory::self()
82 {
83  return kServiceFactoryInstance->self();
84 }
85 
86 KService::Ptr KServiceFactory::findServiceByName(const QString &_name)
87 {
88  if (!sycocaDict()) return KService::Ptr(); // Error!
89 
90  // Warning : this assumes we're NOT building a database
91  // But since findServiceByName isn't called in that case...
92  // [ see KServiceTypeFactory for how to do it if needed ]
93 
94  int offset = sycocaDict()->find_string( _name );
95  if (!offset) return KService::Ptr(); // Not found
96 
97  KService::Ptr newService(createEntry(offset));
98 
99  // Check whether the dictionary was right.
100  if (newService && (newService->name() != _name)) {
101  // No it wasn't...
102  return KService::Ptr();
103  }
104  return newService;
105 }
106 
107 KService::Ptr KServiceFactory::findServiceByDesktopName(const QString &_name)
108 {
109  if (!m_nameDict) return KService::Ptr(); // Error!
110 
111  // Warning : this assumes we're NOT building a database
112  // KBuildServiceFactory reimplements it for the case where we are building one
113 
114  int offset = m_nameDict->find_string( _name );
115  if (!offset) return KService::Ptr(); // Not found
116 
117  KService::Ptr newService(createEntry(offset));
118 
119  // Check whether the dictionary was right.
120  if (newService && (newService->desktopEntryName() != _name)) {
121  // No it wasn't...
122  return KService::Ptr();
123  }
124  return newService;
125 }
126 
127 KService::Ptr KServiceFactory::findServiceByDesktopPath(const QString &_name)
128 {
129  if (!m_relNameDict) return KService::Ptr(); // Error!
130 
131  // Warning : this assumes we're NOT building a database
132  // KBuildServiceFactory reimplements it for the case where we are building one
133 
134  int offset = m_relNameDict->find_string( _name );
135  if (!offset) {
136  //kDebug(servicesDebugArea()) << "findServiceByDesktopPath:" << _name << "not found";
137  return KService::Ptr(); // Not found
138  }
139 
140  KService::Ptr newService(createEntry(offset));
141  if (!newService) {
142  kDebug(servicesDebugArea()) << "findServiceByDesktopPath: createEntry failed!";
143  }
144  // Check whether the dictionary was right
145  // It's ok that it's wrong, for the case where we're looking up an unknown service,
146  // and the hash value gave us another one.
147  if (newService && (newService->entryPath() != _name)) {
148  // No it wasn't...
149  return KService::Ptr();
150  }
151  return newService;
152 }
153 
154 KService::Ptr KServiceFactory::findServiceByMenuId(const QString &_menuId)
155 {
156  if (!m_menuIdDict) return KService::Ptr(); // Error!
157 
158  // Warning : this assumes we're NOT building a database
159  // KBuildServiceFactory reimplements it for the case where we are building one
160 
161  int offset = m_menuIdDict->find_string( _menuId );
162  if (!offset) return KService::Ptr(); // Not found
163 
164  KService::Ptr newService(createEntry(offset));
165 
166  // Check whether the dictionary was right.
167  if (newService && (newService->menuId() != _menuId)) {
168  // No it wasn't...
169  return KService::Ptr();
170  }
171  return newService;
172 }
173 
174 KService* KServiceFactory::createEntry(int offset) const
175 {
176  KService * newEntry = 0L;
177  KSycocaType type;
178  QDataStream *str = KSycoca::self()->findEntry(offset, type);
179  switch(type) {
180  case KST_KService:
181  newEntry = new KService(*str, offset);
182  break;
183  default:
184  kError(7011) << "KServiceFactory: unexpected object entry in KSycoca database (type=" << int(type) << ")";
185  return 0;
186  }
187  if (!newEntry->isValid()) {
188  kError(7011) << "KServiceFactory: corrupt object in KSycoca database!";
189  delete newEntry;
190  newEntry = 0;
191  }
192  return newEntry;
193 }
194 
195 KService::List KServiceFactory::allServices()
196 {
197  KService::List result;
198  const KSycocaEntry::List list = allEntries();
199  KSycocaEntry::List::const_iterator it = list.begin();
200  const KSycocaEntry::List::const_iterator end = list.end();
201  for( ; it != end; ++it ) {
202  const KSycocaEntry::Ptr entry = *it;
203  if ( entry->isType( KST_KService ) )
204  result.append( KService::Ptr::staticCast( entry ) );
205  }
206  return result;
207 }
208 
209 QList<KServiceOffer> KServiceFactory::offers( int serviceTypeOffset, int serviceOffersOffset )
210 {
211  QList<KServiceOffer> list;
212 
213  // Jump to the offer list
214  QDataStream* str = stream();
215  str->device()->seek( m_offerListOffset + serviceOffersOffset );
216 
217  qint32 aServiceTypeOffset, aServiceOffset, initialPreference, mimeTypeInheritanceLevel;
218  while (true)
219  {
220  (*str) >> aServiceTypeOffset;
221  if ( aServiceTypeOffset ) {
222  (*str) >> aServiceOffset;
223  (*str) >> initialPreference;
224  (*str) >> mimeTypeInheritanceLevel;
225  if ( aServiceTypeOffset == serviceTypeOffset ) {
226  // Save stream position !
227  const int savedPos = str->device()->pos();
228  // Create Service
229  KService * serv = createEntry( aServiceOffset );
230  if (serv) {
231  KService::Ptr servPtr( serv );
232  list.append( KServiceOffer( servPtr, initialPreference, mimeTypeInheritanceLevel, servPtr->allowAsDefault() ) );
233  }
234  // Restore position
235  str->device()->seek( savedPos );
236  } else
237  break; // too far
238  }
239  else
240  break; // 0 => end of list
241  }
242  return list;
243 }
244 
245 KService::List KServiceFactory::serviceOffers( int serviceTypeOffset, int serviceOffersOffset )
246 {
247  KService::List list;
248 
249  // Jump to the offer list
250  QDataStream* str = stream();
251  str->device()->seek( m_offerListOffset + serviceOffersOffset );
252 
253  qint32 aServiceTypeOffset, aServiceOffset, initialPreference, mimeTypeInheritanceLevel;
254  while (true) {
255  (*str) >> aServiceTypeOffset;
256  if ( aServiceTypeOffset )
257  {
258  (*str) >> aServiceOffset;
259  (*str) >> initialPreference;
260  (*str) >> mimeTypeInheritanceLevel;
261  if ( aServiceTypeOffset == serviceTypeOffset )
262  {
263  // Save stream position !
264  const int savedPos = str->device()->pos();
265  // Create service
266  KService * serv = createEntry( aServiceOffset );
267  if (serv)
268  list.append( KService::Ptr( serv ) );
269  // Restore position
270  str->device()->seek( savedPos );
271  } else
272  break; // too far
273  }
274  else
275  break; // 0 => end of list
276  }
277  return list;
278 }
279 
280 bool KServiceFactory::hasOffer( int serviceTypeOffset, int serviceOffersOffset, int testedServiceOffset )
281 {
282  // Save stream position
283  QDataStream* str = stream();
284  const int savedPos = str->device()->pos();
285 
286  // Jump to the offer list
287  str->device()->seek( m_offerListOffset + serviceOffersOffset );
288  bool found = false;
289  qint32 aServiceTypeOffset, aServiceOffset, initialPreference, mimeTypeInheritanceLevel;
290  while (!found)
291  {
292  (*str) >> aServiceTypeOffset;
293  if ( aServiceTypeOffset ) {
294  (*str) >> aServiceOffset;
295  (*str) >> initialPreference;
296  (*str) >> mimeTypeInheritanceLevel;
297  if ( aServiceTypeOffset == serviceTypeOffset )
298  {
299  if( aServiceOffset == testedServiceOffset )
300  found = true;
301  } else
302  break; // too far
303  }
304  else
305  break; // 0 => end of list
306  }
307  // Restore position
308  str->device()->seek( savedPos );
309  return found;
310 }
311 
312 void KServiceFactory::virtual_hook( int id, void* data )
313 { KSycocaFactory::virtual_hook( id, data ); }
314 
KServiceFactory::findServiceByDesktopPath
virtual KService::Ptr findServiceByDesktopPath(const QString &_name)
Find a service ( by desktop path, e.g.
Definition: kservicefactory.cpp:127
KSycocaDict
Definition: ksycocadict_p.h:36
KSycocaFactory::stream
QDataStream * stream() const
Definition: ksycocafactory.cpp:241
KSharedPtr< KService >
KServiceFactory::findServiceByDesktopName
virtual KService::Ptr findServiceByDesktopName(const QString &_name)
Find a service (by desktop file name, e.g.
Definition: kservicefactory.cpp:107
KServiceFactory::m_nameDict
KSycocaDict * m_nameDict
Definition: kservicefactory.h:113
kdebug.h
servicesDebugArea
int servicesDebugArea()
Definition: kservice.cpp:47
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
This macro makes it easy to use non-POD types as global statics.
Definition: kglobal.h:221
KService
Represent a service, like an application or plugin bound to one or several mimetypes (or servicetypes...
Definition: kservice.h:58
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Definition: kdebug.h:187
KServiceFactory::allServices
KService::List allServices()
Definition: kservicefactory.cpp:195
QString
KSycocaFactory
Definition: ksycocafactory.h:36
klocale.h
KSycocaEntry::isValid
bool isValid() const
Definition: ksycocaentry.cpp:151
KST_KService
Definition: ksycocatype.h:31
ksycocatype.h
kservicefactory.h
KService::allowAsDefault
bool allowAsDefault() const
Set to true if it is allowed to use this service as the default (main) action for the files it suppor...
Definition: kservice.cpp:955
KServiceFactory::hasOffer
bool hasOffer(int serviceTypeOffset, int serviceOffersOffset, int testedServiceOffset)
Test if a specific service is associated with a specific servicetype.
Definition: kservicefactory.cpp:280
kglobal.h
KSycocaDict::find_string
int find_string(const QString &key) const
Looks up an entry identified by 'key'.
Definition: ksycocadict.cpp:146
ksycocadict_p.h
KSycoca::findEntry
QDataStream * findEntry(int offset, KSycocaType &type)
Definition: ksycoca.cpp:370
KSycocaEntry::entryPath
QString entryPath() const
Definition: ksycocaentry.cpp:104
KServiceFactory::m_relNameDict
KSycocaDict * m_relNameDict
Definition: kservicefactory.h:115
KService::Ptr
KSharedPtr< KService > Ptr
Definition: kservice.h:61
KService::menuId
QString menuId() const
Returns the menu ID of the service desktop entry.
Definition: kservice.cpp:771
KServiceFactory::m_menuIdDict
KSycocaDict * m_menuIdDict
Definition: kservicefactory.h:117
KSycocaFactory::allEntries
virtual KSycocaEntry::List allEntries() const
Get a list of all entries from the database.
Definition: ksycocafactory.cpp:183
KSycocaFactory::sycocaDict
const KSycocaDict * sycocaDict() const
Definition: ksycocafactory.cpp:231
KServiceFactory::virtual_hook
virtual void virtual_hook(int id, void *data)
Virtual hook, used to add new "virtual" functions while maintaining binary compatibility.
Definition: kservicefactory.cpp:312
KSycocaFactory::virtual_hook
virtual void virtual_hook(int id, void *data)
Virtual hook, used to add new "virtual" functions while maintaining binary compatibility.
Definition: ksycocafactory.cpp:246
KServiceFactory::~KServiceFactory
virtual ~KServiceFactory()
Definition: kservicefactory.cpp:72
KServiceFactory::m_offerListOffset
int m_offerListOffset
Definition: kservicefactory.h:112
kservice.h
KServiceOffer
Holds the user's preference of a service.
Definition: kserviceoffer.h:38
ksycoca.h
KSycocaFactory::offset
int offset() const
Definition: ksycocafactory.cpp:221
KServiceFactory::offers
KServiceOfferList offers(int serviceTypeOffset, int serviceOffersOffset)
Definition: kservicefactory.cpp:209
KService::desktopEntryName
QString desktopEntryName() const
Returns the filename of the service desktop entry without any extension.
Definition: kservice.cpp:889
kstandarddirs.h
KSharedPtr::staticCast
static KSharedPtr< T > staticCast(const KSharedPtr< U > &o)
Convert KSharedPtr to KSharedPtr, using a static_cast.
Definition: ksharedptr.h:173
KST_KServiceFactory
Definition: ksycocatype.h:44
KServiceFactory::findServiceByName
KService::Ptr findServiceByName(const QString &_name)
Find a service (by translated name, e.g.
Definition: kservicefactory.cpp:86
KServiceFactory::findServiceByMenuId
virtual KService::Ptr findServiceByMenuId(const QString &_menuId)
Find a service ( by menu id, e.g.
Definition: kservicefactory.cpp:154
KServiceFactory::serviceOffers
KService::List serviceOffers(int serviceTypeOffset, int serviceOffersOffset)
Definition: kservicefactory.cpp:245
qint32
kDebug
#define kDebug
Definition: kdebug.h:316
KServiceFactory
Definition: kservicefactory.h:41
KServiceFactory::createEntry
virtual KSycocaEntry * createEntry(const QString &, const char *) const
Construct a KService from a config file.
Definition: kservicefactory.h:54
KServiceFactory::self
static KServiceFactory * self()
Definition: kservicefactory.cpp:81
KSycocaEntry::name
QString name() const
Definition: ksycocaentry.cpp:157
KSycoca::self
static KSycoca * self()
Get or create the only instance of KSycoca (read-only)
Definition: ksycoca.cpp:293
KSycocaFactorySingleton
Template for making it easier to define a threadsafe singleton for each factory, with support for kbu...
Definition: ksycocafactory.h:176
QList< Ptr >
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:47:09 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal