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

KDECore

  • kdecore
  • services
kservicetypeprofile.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  * Copyright (C) 1999 Torben Weis <weis@kde.org>
3  * Copyright (C) 2006 David Faure <faure@kde.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License version 2 as published by the Free Software Foundation;
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB. If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #include "kservicetypeprofile.h"
21 #include "kservicetypeprofile_p.h"
22 #include <QMutex>
23 #include "kservice.h"
24 #include "kservicetype.h"
25 #include "kservicetypefactory.h"
26 #include "kservicefactory.h"
27 
28 #include <kconfig.h>
29 #include <kstandarddirs.h>
30 #include <kdebug.h>
31 #include <kconfiggroup.h>
32 
33 #include <QtCore/QHash>
34 #include <QtAlgorithms>
35 
36 // servicetype -> profile
37 class KServiceTypeProfiles : public QHash<QString, KServiceTypeProfileEntry *>
38 {
39 public:
40  KServiceTypeProfiles() { m_parsed = false; ensureParsed(); }
41  ~KServiceTypeProfiles() { clear(); }
42  void clear() {
43  QMutexLocker lock(&m_mutex);
44  qDeleteAll( *this );
45  QHash<QString, KServiceTypeProfileEntry *>::clear();
46  m_parsed = false;
47  }
48  bool hasProfile(const QString& serviceType) {
49  QMutexLocker lock(&m_mutex);
50  ensureParsed();
51  return contains(serviceType);
52  }
53  void ensureParsed(); // mutex must be locked when calling this
54  QMutex m_mutex;
55 private:
56  bool m_parsed;
57 };
58 
59 
60 K_GLOBAL_STATIC(KServiceTypeProfiles, s_serviceTypeProfiles)
61 
62 static bool s_configurationMode = false;
63 
64 void KServiceTypeProfiles::ensureParsed()
65 {
66  if (m_parsed)
67  return;
68  m_parsed = true;
69 
70  // Make sure that a KServiceTypeFactory gets created.
71  (void) KServiceTypeFactory::self();
72 
73  // Read the service type profiles from servicetype_profilerc (new in kde4)
74  // See writeServiceTypeProfile for a description of the file format.
75  // ### Since this new format names groups after servicetypes maybe we can even
76  // avoid doing any init upfront, and just look up the group when asked...
77  KConfig configFile( QString::fromLatin1("servicetype_profilerc"), KConfig::NoGlobals );
78  const QStringList tmpList = configFile.groupList();
79  for (QStringList::const_iterator aIt = tmpList.begin();
80  aIt != tmpList.end(); ++aIt) {
81  const QString type = *aIt;
82  KConfigGroup config(&configFile, type);
83  const int count = config.readEntry( "NumberOfEntries", 0 );
84  KServiceTypeProfileEntry* p = this->value( type, 0 );
85  if ( !p ) {
86  p = new KServiceTypeProfileEntry();
87  this->insert( type, p );
88  }
89 
90  for ( int i = 0; i < count; ++i ) {
91  const QString num = QString::fromLatin1("Entry") + QString::number(i);
92  const QString serviceId = config.readEntry( num + QLatin1String("_Service"), QString() );
93  if (!serviceId.isEmpty()) {
94  const int pref = config.readEntry( num + QLatin1String("_Preference"), 0 );
95  //kDebug(7014) << "adding service " << serviceId << " to profile for " << type << " with preference " << pref;
96  p->addService( serviceId, pref );
97  }
98  }
99  }
100 }
101 
102 //static
103 void KServiceTypeProfile::clearCache()
104 {
105  if (s_serviceTypeProfiles.exists())
106  s_serviceTypeProfiles->clear();
107 }
108 
116 namespace KServiceTypeProfile {
117  KServiceOfferList sortServiceTypeOffers( const KServiceOfferList& list, const QString& servicetype );
118 }
119 
120 KServiceOfferList KServiceTypeProfile::sortServiceTypeOffers( const KServiceOfferList& list, const QString& serviceType )
121 {
122  QMutexLocker lock(&s_serviceTypeProfiles->m_mutex);
123  s_serviceTypeProfiles->ensureParsed();
124  KServiceTypeProfileEntry* profile = s_serviceTypeProfiles->value(serviceType, 0);
125 
126  KServiceOfferList offers;
127 
128  KServiceOfferList::const_iterator it = list.begin();
129  const KServiceOfferList::const_iterator end = list.end();
130  for( ; it != end; ++it )
131  {
132  const KService::Ptr servPtr = (*it).service();
133  //kDebug(7014) << "KServiceTypeProfile::offers considering " << servPtr->storageId();
134  // Look into the profile (if there's one), to find this service's preference.
135  bool foundInProfile = false;
136  if ( profile )
137  {
138  QMap<QString,int>::ConstIterator it2 = profile->m_mapServices.constFind( servPtr->storageId() );
139  if( it2 != profile->m_mapServices.constEnd() )
140  {
141  const int pref = it2.value();
142  //kDebug(7014) << "found in mapServices pref=" << pref;
143  if ( pref > 0 ) { // 0 disables the service
144  offers.append( KServiceOffer( servPtr, pref, 0, servPtr->allowAsDefault() ) );
145  }
146  foundInProfile = true;
147  }
148  }
149  if ( !foundInProfile )
150  {
151  // This offer isn't in the profile
152  // This can be because we have no profile at all, or because the
153  // services have been installed after the profile was written,
154  // but it's also the case for any service that's neither App nor ReadOnlyPart, e.g. RenameDlg/Plugin
155  //kDebug(7014) << "not found in mapServices. Appending.";
156 
157  // If there's a profile, we use 0 as the preference to ensure new apps don't take over existing apps (which default to 1)
158  offers.append( KServiceOffer( servPtr,
159  profile ? 0 : (*it).preference(),
160  0,
161  servPtr->allowAsDefault() ) );
162  }
163  }
164 
165  qStableSort( offers );
166 
167  //kDebug(7014) << "KServiceTypeProfile::offers returning " << offers.count() << " offers";
168  return offers;
169 }
170 
171 bool KServiceTypeProfile::hasProfile( const QString& serviceType )
172 {
173  return s_serviceTypeProfiles->hasProfile(serviceType);
174 }
175 
176 void KServiceTypeProfile::writeServiceTypeProfile( const QString& serviceType,
177  const KService::List& services,
178  const KService::List& disabledServices )
179 {
180  /*
181  * [ServiceType]
182  * NumEntries=3
183  * Entry0_Service=serv.desktop
184  * Entry0_Preference=10
185  * Entry1_Service=otherserv.desktop
186  * Entry1_Preference=5
187  * Entry2_Service=broken_service.desktop
188  * Entry2_Preference=0
189  */
190 
191  KConfig configFile( QString::fromLatin1("servicetype_profilerc"), KConfig::SimpleConfig);
192  configFile.deleteGroup( serviceType );
193 
194  KConfigGroup config(&configFile, serviceType );
195  const int count = services.count();
196  config.writeEntry( "NumberOfEntries", count + disabledServices.count() );
197  KService::List::ConstIterator servit = services.begin();
198  int i = 0;
199  for( ; servit != services.end(); ++servit, ++i ) {
200  if (!servit->isNull()) {
201  const QString num = QString::fromLatin1("Entry") + QString::number(i);
202  config.writeEntry( num + QLatin1String("_Service"), (*servit)->storageId() );
203  config.writeEntry( num + QLatin1String("_Preference"), count - i );
204  }
205  }
206  servit = disabledServices.begin();
207  for( ; servit != disabledServices.end(); ++servit, ++i ) {
208  if (!servit->isNull()) {
209  const QString num = QString::fromLatin1("Entry") + QString::number(i);
210  config.writeEntry( num + QLatin1String("_Service"), (*servit)->storageId() );
211  config.writeEntry( num + QLatin1String("_Preference"), 0 );
212  }
213  }
214  configFile.sync();
215 
216  // Drop the whole cache...
217  clearCache();
218 }
219 
220 void KServiceTypeProfile::deleteServiceTypeProfile( const QString& serviceType)
221 {
222  KConfig config(QString::fromLatin1("servicetype_profilerc"), KConfig::SimpleConfig);
223  config.deleteGroup( serviceType );
224  config.sync();
225 
226  // Not threadsafe, but well the whole idea of using this method isn't
227  // threadsafe in the first place.
228  if (s_serviceTypeProfiles.exists()) {
229  delete s_serviceTypeProfiles->take( serviceType );
230  }
231 }
232 
233 void KServiceTypeProfile::setConfigurationMode()
234 {
235  s_configurationMode = true;
236 }
237 
238 bool KServiceTypeProfile::configurationMode()
239 {
240  return s_configurationMode;
241 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Tue Jul 23 2013 21:56:51 by doxygen 1.8.1.1 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-4.10.5 API Reference

Skip menu "kdelibs-4.10.5 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
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