kontact

profilemanager.cpp
1 /*
2  This file is part of KDE Kontact.
3 
4  Copyright (c) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20  As a special exception, permission is given to link this program
21  with any edition of TQt, and distribute the resulting executable,
22  without including the source code for TQt in the source distribution.
23 */
24 
25 #include "profilemanager.h"
26 
27 #include <tdeio/job.h>
28 
29 #include <tdeapplication.h>
30 #include <tdeconfig.h>
31 #include <tdeglobal.h>
32 #include <kstandarddirs.h>
33 #include <kstaticdeleter.h>
34 #include <kurl.h>
35 
36 #include <tqdir.h>
37 #include <tqstringlist.h>
38 #include <tqvaluelist.h>
39 
40 Kontact::Profile::Profile( const TQString& id, bool isLocal ) : m_id( id ), m_local( isLocal )
41 {
42 }
43 
44 Kontact::Profile::Profile() : m_local( false )
45 {
46 }
47 
48 TQString Kontact::Profile::id() const
49 {
50  return m_id;
51 }
52 
53 TQString Kontact::Profile::name() const
54 {
55  return m_name;
56 }
57 
58 TQString Kontact::Profile::description() const
59 {
60  return m_description;
61 }
62 
63 bool Kontact::Profile::isNull() const
64 {
65  return m_id.isNull();
66 }
67 
68 void Kontact::Profile::setId( const TQString& id )
69 {
70  m_id = id;
71 }
72 
73 void Kontact::Profile::setDescription( const TQString& description )
74 {
75  m_description = description;
76 }
77 
78 void Kontact::Profile::setName( const TQString& name )
79 {
80  m_name = name;
81 }
82 
83 void Kontact::Profile::setLocal( SetLocalMode mode )
84 {
85  if ( m_local )
86  return;
87 
88  if ( mode == CopyProfileFiles )
89  copyConfigFiles( m_originalLocation, localSaveLocation() );
90 
91  m_local = true;
92 }
93 
94 bool Kontact::Profile::isLocal() const
95 {
96  return m_local;
97 }
98 
99 void Kontact::Profile::setOriginalLocation( const TQString& path )
100 {
101  m_originalLocation = path;
102 }
103 
104 TQString Kontact::Profile::localSaveLocation() const
105 {
106 
107  return m_id.isNull() ? TQString() : locateLocal( "data", "kontact/profiles/" + m_id, /*create folder=*/true );
108 }
109 
110 TQString Kontact::Profile::saveLocation() const
111 {
112  return m_local ? localSaveLocation() : m_originalLocation;
113 }
114 
115 bool Kontact::Profile::operator==( const Kontact::Profile& other ) const
116 {
117  return m_id == other.m_id && m_name == other.m_name && m_description == other.m_description;
118 }
119 
120 Kontact::ProfileManager* Kontact::ProfileManager::m_self = 0;
121 
122 static KStaticDeleter<Kontact::ProfileManager> profileManagerSD;
123 
124 Kontact::ProfileManager* Kontact::ProfileManager::self()
125 {
126  if ( m_self == 0 )
127  {
128  profileManagerSD.setObject( m_self, new Kontact::ProfileManager );
129  m_self->readConfig();
130  }
131  return m_self;
132 }
133 
134 Kontact::ProfileManager::ProfileManager( TQObject* parent ) : TQObject( parent )
135 {
136 }
137 
138 Kontact::ProfileManager::~ProfileManager()
139 {
140  writeConfig();
141 }
142 
143 void Kontact::ProfileManager::writeConfig() const
144 {
145  const TQValueList<Kontact::Profile> profiles = m_profiles.values();
146  for ( TQValueList<Kontact::Profile>::ConstIterator it = profiles.begin(), end = profiles.end(); it != end; ++it )
147  {
148  writeProfileConfig( *it );
149  }
150 }
151 
152 Kontact::Profile Kontact::ProfileManager::readFromConfiguration( const TQString& configFile, bool isLocal )
153 {
154  TDEConfig profileCfg( configFile, true /*read-only*/, false /*no KDE global*/ );
155  const TQString configDir = configFile.left( configFile.findRev( TQDir::separator(), -1 ) );
156  profileCfg.setGroup( "Kontact Profile" );
157  const TQString id = profileCfg.readEntry( "Identifier" );
158  Kontact::Profile profile( id );
159  profile.setName( profileCfg.readEntry( "Name" ) );
160  profile.setDescription( profileCfg.readEntry( "Description" ) );
161  profile.setOriginalLocation( configDir );
162  if ( isLocal )
163  profile.setLocal( Kontact::Profile::DoNotCopyProfileFiles );
164  return profile;
165 }
166 
167 void Kontact::ProfileManager::writeProfileConfig( const Kontact::Profile& profile ) const
168 {
169  const TQString profileDir = profile.saveLocation();
170  const TQString cfgPath = profileDir + "/profile.cfg";
171  TDEConfig profileCfg( cfgPath, false /*read-only*/, false /*no KDE global*/ );
172  profileCfg.setGroup( "Kontact Profile" );
173  profileCfg.writeEntry( "Identifier", profile.id() );
174  profileCfg.writeEntry( "Name", profile.name() );
175  profileCfg.writeEntry( "Description", profile.description() );
176 }
177 
178 void Kontact::ProfileManager::readConfig()
179 {
180 
181  const TQStringList profilePaths = TDEGlobal::dirs()->findAllResources( "data", TQString::fromLatin1( "kontact/profiles/*/profile.cfg" ) );
182 
183  typedef TQMap<TQString, Kontact::Profile> ProfileMap;
184  ProfileMap profiles;
185  ProfileMap globalProfiles;
186 
187  const TQString localPrefix = locateLocal( "data", "kontact/profiles/", /*createDir=*/false );
188  for ( TQStringList::ConstIterator it = profilePaths.begin(), end = profilePaths.end(); it != end; ++it )
189  {
190  const bool isLocal = (*it).startsWith( localPrefix );
191  const Kontact::Profile profile = readFromConfiguration( *it, isLocal );
192  if ( profile.isNull() )
193  continue;
194  if ( isLocal )
195  profiles[profile.id()] = profile;
196  else
197  globalProfiles[profile.id()] = profile;
198  }
199 
200  for ( ProfileMap::ConstIterator it = globalProfiles.begin(), end = globalProfiles.end(); it != end; ++it )
201  {
202  if ( !profiles.contains( it.key() ) )
203  profiles[it.key()] = it.data();
204  }
205 
206  for ( ProfileMap::ConstIterator it = profiles.begin(), end = profiles.end(); it != end; ++it )
207  {
208  addProfile( *it, false /*dont sync config */ );
209  }
210 }
211 
212 TQValueList<Kontact::Profile> Kontact::ProfileManager::profiles() const
213 {
214  return m_profiles.values();
215 }
216 
217 Kontact::Profile Kontact::ProfileManager::profileById( const TQString& id ) const
218 {
219  return m_profiles[id];
220 }
221 
222 void Kontact::ProfileManager::updateProfile( const Kontact::Profile& profile_ )
223 {
224  const TQString id = profile_.id();
225  if ( id.isNull() || m_profiles[id] == profile_ )
226  return;
227  Kontact::Profile profile( profile_ );
228  m_profiles[id] = profile;
229  profile.setLocal( Kontact::Profile::CopyProfileFiles );
230  writeProfileConfig( profile );
231  emit profileUpdated( id );
232 }
233 
234 void Kontact::Profile::copyConfigFiles( const TQString& source_, const TQString& dest_ )
235 {
236  const KURL source = KURL::fromPathOrURL( source_+"/*rc" );
237  const KURL dest = KURL::fromPathOrURL( dest_ );
238  TDEIO::CopyJob* job = TDEIO::copy( source, dest, /*showProgressInfo=*/false );
239  // TODO better check for the copy result
240 }
241 
242 void Kontact::ProfileManager::saveToProfile( const TQString& id )
243 {
244  Kontact::Profile profile = profileById( id );
245  if ( profile.isNull() )
246  return;
247  profile.setLocal( Kontact::Profile::CopyProfileFiles );
248  writeProfileConfig( profile );
249  emit saveToProfileRequested( id );
250 }
251 
252 bool Kontact::ProfileManager::addProfile( const Kontact::Profile& profile, bool syncConfig )
253 {
254  const TQString id = profile.id();
255  if ( m_profiles.contains( id ) )
256  return false;
257  m_profiles[id] = profile;
258  emit profileAdded( id );
259  emit saveToProfileRequested( id );
260  if ( syncConfig ) {
261  writeProfileConfig( profile );
262  }
263 
264  return true;
265 }
266 
267 void Kontact::ProfileManager::loadProfile( const TQString& id )
268 {
269  if ( !m_profiles.contains( id ) )
270  return;
271  emit profileLoaded( id );
272 }
273 
274 void Kontact::ProfileManager::removeProfile( const Kontact::Profile& profile )
275 {
276  removeProfile( profile.id() );
277 }
278 
279 void Kontact::ProfileManager::removeProfile( const TQString& id )
280 {
281  if ( !m_profiles.contains( id ) )
282  return;
283  Kontact::Profile profile = profileById( id );
284  if ( profile.isLocal() ) {
285  KURL location = KURL::fromPathOrURL( profile.saveLocation() );
286  TDEIO::DeleteJob* job = TDEIO::del( location, /*shred*/ false, /*showProgressInfo=*/false );
287  // TODO check result
288  }
289  m_profiles.remove( id );
290  emit profileRemoved( id );
291  }
292 
293 Kontact::ProfileManager::ExportError Kontact::ProfileManager::exportProfileToDirectory( const TQString& id, const TQString& path )
294 {
295  if ( !m_profiles.contains( id ) )
296  return SuccessfulExport;
297 
298  if ( !TQDir( path ).exists() )
299  return DirectoryDoesNotExist;
300 
301  const Kontact::Profile profile = profileById( id );
302  const KURL source = KURL::fromPathOrURL( profile.saveLocation() );
303  const KURL target = KURL::fromPathOrURL( path + TQDir::separator() + profile.name() );
304 
305  TDEIO::CopyJob* job = TDEIO::copy( source, target, /*showProgressInfo=*/false );
306  // TODO check result
307 
308  return SuccessfulExport;
309 }
310 
311 Kontact::ProfileManager::ImportError Kontact::ProfileManager::importProfileFromDirectory( const TQString& path )
312 {
313  Kontact::Profile profile = readFromConfiguration( path + "/profile.cfg", /*isLocal=*/ true );
314  if ( profile.isNull() )
315  return NoValidProfile;
316 
317  profile.setId( generateNewId() );
318 
319  const KURL source = KURL::fromPathOrURL( path );
320  const KURL target = KURL::fromPathOrURL( profile.saveLocation() );
321 
322  TDEIO::CopyJob* job = TDEIO::copy( source, target, /*showProgressInfo=*/false );
323  // TODO better check for the copy result
324 
325  addProfile( profile );
326 
327  return SuccessfulImport;
328 }
329 
330 TQString Kontact::ProfileManager::generateNewId() const
331 {
332  while ( true )
333  {
334  const TQString newId = TDEApplication::randomString( 10 );
335  if ( !m_profiles.contains( newId ) )
336  return newId;
337  }
338 }
339 
340 #include "profilemanager.moc"