2 kopetestatusmanager.cpp - Kopete Status Manager
4 Copyright (c) 2008 by Roman Jarosz <kedgedev@centrum.cz>
5 Kopete (c) 2008 by the Kopete developers <kopete-devel@kde.org>
7 *************************************************************************
9 * This library is free software; you can redistribute it and/or *
10 * modify it under the terms of the GNU Lesser General Public *
11 * License as published by the Free Software Foundation; either *
12 * version 2 of the License, or (at your option) any later version. *
14 *************************************************************************
16 #include "kopetestatusmanager.h"
18 #include <QtCore/QFile>
19 #include <QtXml/QDomElement>
21 #include <ksavefile.h>
22 #include <kstandarddirs.h>
24 #include "kopeteaccountmanager.h"
25 #include "kopeteaccount.h"
26 #include "kopetecontact.h"
27 #include "kopeteonlinestatusmanager.h"
28 #include "kopetebehaviorsettings.h"
29 #include "kopetestatusitems.h"
30 #include "kopeteidletimer.h"
34 StatusManager
*StatusManager::instance
= 0L;
36 class StatusManager::Private
39 Status::StatusGroup
*root
;
40 QHash
<QString
, Status::StatusItem
*> uidHash
;
46 uint globalStatusCategory
;
47 Kopete::StatusMessage globalStatusMessage
;
48 Kopete::StatusMessage customStatusMessage
;
51 QList
<Kopete::Account
*> autoAwayAccounts
;
53 Kopete::IdleTimer
* idleTimer
;
56 StatusManager::StatusManager()
57 : QObject(), d( new Private
)
65 loadBehaviorSettings();
66 connect( Kopete::BehaviorSettings::self(), SIGNAL(configChanged()),
67 this, SLOT(loadBehaviorSettings()) );
69 connect( Kopete::AccountManager::self(), SIGNAL(accountUnregistered(const Kopete::Account
*)),
70 this, SLOT(accountUnregistered(const Kopete::Account
*)));
73 StatusManager::~StatusManager()
82 void StatusManager::saveXML()
84 QString filename
= KStandardDirs::locateLocal( "data", QLatin1String( "kopete/statuses.xml" ) );
85 KSaveFile
file(filename
);
88 QTextStream
stream (&file
);
89 stream
.setCodec(QTextCodec::codecForName("UTF-8"));
91 QDomDocument
doc( QString::fromLatin1( "kopete-statuses" ) );
92 doc
.appendChild( StatusManager::storeStatusItem( d
->root
) );
93 doc
.save( stream
, 4 );
99 void StatusManager::loadXML()
107 QString filename
= KStandardDirs::locateLocal( "data", QLatin1String( "kopete/statuses.xml" ) );
110 QFile
file( filename
);
111 if ( file
.open( QIODevice::ReadOnly
) )
113 if ( doc
.setContent( &file
) )
115 Kopete::Status::StatusItem
* rootItem
= StatusManager::parseStatusItem( doc
.documentElement() );
118 if ( rootItem
->isGroup() )
119 d
->root
= qobject_cast
<Status::StatusGroup
*>(rootItem
);
129 d
->root
= defaultStatuses();
133 updateUidHash( d
->root
);
136 StatusManager
*StatusManager::self()
139 instance
= new StatusManager
;
144 void StatusManager::setRootGroup( Kopete::Status::StatusGroup
*rootGroup
)
146 if ( !rootGroup
|| rootGroup
== d
->root
)
154 updateUidHash( d
->root
);
159 Status::StatusGroup
*StatusManager::getRootGroup() const
164 Kopete::Status::StatusGroup
*StatusManager::copyRootGroup() const
166 return qobject_cast
<Kopete::Status::StatusGroup
*>(d
->root
->copy());
169 const Status::StatusItem
*StatusManager::itemForUid( const QString
&uid
) const
171 return d
->uidHash
.value( uid
, 0 );
174 QDomElement
StatusManager::storeStatusItem( const Status::StatusItem
*item
)
176 QDomDocument statusDoc
;
177 QString rootName
= ( item
->isGroup() ) ? QLatin1String( "group" ) : QLatin1String( "status" );
178 statusDoc
.appendChild( statusDoc
.createElement( rootName
) );
179 statusDoc
.documentElement().setAttribute( "uid", item
->uid() );
180 statusDoc
.documentElement().setAttribute( "category", item
->category() );
182 QDomElement title
= statusDoc
.createElement( QLatin1String( "title" ) );
183 title
.appendChild( statusDoc
.createTextNode( item
->title() ) );
184 statusDoc
.documentElement().appendChild( title
);
186 if ( item
->isGroup() )
188 const Status::StatusGroup
*group
= qobject_cast
<const Kopete::Status::StatusGroup
*>( item
);
189 const QList
<Status::StatusItem
*> childs
= group
->childList();
190 foreach ( Status::StatusItem
*child
, childs
)
191 statusDoc
.documentElement().appendChild( storeStatusItem( child
) );
195 const Status::Status
*status
= qobject_cast
<const Kopete::Status::Status
*>( item
);
196 QDomElement message
= statusDoc
.createElement( QLatin1String( "message" ) );
197 message
.appendChild( statusDoc
.createTextNode( status
->message() ) );
198 statusDoc
.documentElement().appendChild( message
);
201 return statusDoc
.documentElement();
204 Status::StatusItem
*StatusManager::parseStatusItem( QDomElement element
)
206 if ( element
.isNull() )
209 if ( element
.tagName() == QString::fromUtf8( "group" ) )
211 Status::StatusGroup
* group
= new Status::StatusGroup( element
.attribute( "uid" ) );
212 group
->setCategory( (OnlineStatusManager::Category
)element
.attribute( "category", "0" ).toInt() );
214 QDomNode childNode
= element
.firstChild();
215 while ( !childNode
.isNull() )
217 QDomElement childElement
= childNode
.toElement();
218 if ( childElement
.tagName() == QLatin1String( "title" ) )
219 group
->setTitle( childElement
.text() );
220 else if ( childElement
.tagName() == QLatin1String( "group" ) || childElement
.tagName() == QLatin1String( "status" ) )
222 Status::StatusItem
*item
= StatusManager::parseStatusItem( childElement
);
224 group
->appendChild( item
);
226 childNode
= childNode
.nextSibling();
230 else if ( element
.tagName() == QString::fromUtf8( "status" ) )
232 Status::Status
* status
= new Status::Status( element
.attribute( "uid" ) );
233 status
->setCategory( (OnlineStatusManager::Category
)element
.attribute( "category", "0" ).toInt() );
235 QDomNode childNode
= element
.firstChild();
236 while ( !childNode
.isNull() )
238 QDomElement childElement
= childNode
.toElement();
239 if ( childElement
.tagName() == QLatin1String( "title" ) )
240 status
->setTitle( childElement
.text() );
241 else if ( childElement
.tagName() == QLatin1String( "message" ) )
242 status
->setMessage( childElement
.text() );
244 childNode
= childNode
.nextSibling();
252 void StatusManager::updateUidHash( Status::StatusItem
*item
)
254 if ( item
->isGroup() )
256 Kopete::Status::StatusGroup
*group
= qobject_cast
<Kopete::Status::StatusGroup
*>(item
);
257 QList
<Kopete::Status::StatusItem
*> childs
= group
->childList();
258 foreach( Kopete::Status::StatusItem
* child
, childs
)
259 updateUidHash( child
);
263 d
->uidHash
[item
->uid()] = item
;
267 Status::StatusGroup
*StatusManager::defaultStatuses() const
269 Status::StatusGroup
* group
= new Status::StatusGroup();
271 Status::Status
* status
= new Status::Status();
272 status
->setTitle( i18n( "Online" ) );
273 status
->setCategory( OnlineStatusManager::Online
);
274 group
->appendChild( status
);
276 status
= new Status::Status();
277 status
->setTitle( i18n( "Away" ) );
278 status
->setMessage( i18n( "I am gone right now, but I will be back later" ) );
279 status
->setCategory( OnlineStatusManager::Away
);
280 group
->appendChild( status
);
282 status
= new Status::Status();
283 status
->setTitle( i18n( "Busy" ) );
284 status
->setMessage( i18n( "Sorry, I am busy right now" ) );
285 status
->setCategory( OnlineStatusManager::Busy
);
286 group
->appendChild( status
);
288 status
= new Status::Status();
289 status
->setTitle( i18n( "Invisible" ) );
290 status
->setCategory( OnlineStatusManager::Invisible
);
291 group
->appendChild( status
);
293 status
= new Status::Status();
294 status
->setTitle( i18n( "Offline" ) );
295 status
->setCategory( OnlineStatusManager::Offline
);
296 group
->appendChild( status
);
301 void StatusManager::setGlobalStatus( uint category
, const Kopete::StatusMessage
&statusMessage
)
303 d
->globalStatusCategory
= category
;
304 d
->globalStatusMessage
= statusMessage
;
306 KConfigGroup
config( KGlobal::config(), "Status Manager" );
307 config
.writeEntry( "GlobalStatusCategory", d
->globalStatusCategory
);
308 config
.writeEntry( "GlobalStatusTitle", d
->globalStatusMessage
.title() );
309 config
.writeEntry( "GlobalStatusMessage", d
->globalStatusMessage
.message() );
312 emit
globalStatusChanged();
315 void StatusManager::setGlobalStatusMessage( const Kopete::StatusMessage
&statusMessage
)
317 d
->globalStatusMessage
= statusMessage
;
319 KConfigGroup
config( KGlobal::config(), "Status Manager" );
320 config
.writeEntry( "GlobalStatusTitle", d
->globalStatusMessage
.title() );
321 config
.writeEntry( "GlobalStatusMessage", d
->globalStatusMessage
.message() );
324 emit
globalStatusChanged();
327 Kopete::StatusMessage
StatusManager::globalStatusMessage() const
329 return d
->globalStatusMessage
;
332 void StatusManager::setActive()
334 kDebug(14010) << "Found activity on desktop, setting accounts online";
338 if ( d
->goAvailable
)
340 QList
<Kopete::Account
*>::iterator it
, itEnd
= d
->autoAwayAccounts
.end();
341 for( it
= d
->autoAwayAccounts
.begin(); it
!= itEnd
; ++it
)
343 if( (*it
)->isConnected() && (*it
)->isAway() )
345 (*it
)->setOnlineStatus( Kopete::OnlineStatusManager::self()->onlineStatus( (*it
)->protocol(),
346 Kopete::OnlineStatusManager::Online
) );
349 d
->autoAwayAccounts
.clear();
354 void StatusManager::setAutoAway()
356 kDebug(14010) << "Going AutoAway!";
361 // Set all accounts that are not away already to away.
362 // We remember them so later we only set the accounts to
363 // available that we set to away (and not the user).
364 QList
<Kopete::Account
*> accountList
= Kopete::AccountManager::self()->accounts();
366 QList
<Kopete::Account
*>::iterator it
, itEnd
= accountList
.end();
367 for( it
= accountList
.begin(); it
!= itEnd
; ++it
)
369 if( (*it
)->myself()->onlineStatus().status() == Kopete::OnlineStatus::Online
)
371 d
->autoAwayAccounts
.append( (*it
) );
373 if( d
->useCustomStatus
)
375 // Display a specific away message
376 (*it
)->setOnlineStatus( Kopete::OnlineStatusManager::self()->onlineStatus( (*it
)->protocol(),
377 Kopete::OnlineStatusManager::Idle
), d
->customStatusMessage
);
381 // Display the last global away message used
382 (*it
)->setOnlineStatus( Kopete::OnlineStatusManager::self()->onlineStatus( (*it
)->protocol(),
383 Kopete::OnlineStatusManager::Idle
), d
->globalStatusMessage
);
390 bool StatusManager::autoAway()
395 bool StatusManager::globalAway()
397 return ( d
->globalStatusCategory
== OnlineStatusManager::Away
||
398 d
->globalStatusCategory
== OnlineStatusManager::ExtendedAway
||
399 d
->globalStatusCategory
== OnlineStatusManager::Busy
);
402 void StatusManager::accountUnregistered( const Kopete::Account
*account
)
404 d
->autoAwayAccounts
.removeAll( const_cast<Kopete::Account
*>(account
) );
407 void StatusManager::loadSettings()
409 KConfigGroup
config( KGlobal::config(), "Status Manager" );
410 d
->globalStatusCategory
= config
.readEntry( "GlobalStatusCategory", 0 );
412 Kopete::StatusMessage statusMessage
;
413 statusMessage
.setTitle( config
.readEntry( "GlobalStatusTitle", QString() ) );
414 statusMessage
.setMessage( config
.readEntry( "GlobalStatusMessage", QString() ) );
415 d
->globalStatusMessage
= statusMessage
;
418 void StatusManager::loadBehaviorSettings()
420 d
->awayTimeout
= Kopete::BehaviorSettings::self()->autoAwayTimeout();
421 d
->goAvailable
= Kopete::BehaviorSettings::self()->autoAwayGoAvailable();
422 d
->useCustomStatus
= Kopete::BehaviorSettings::self()->useCustomAwayMessage();
424 Kopete::StatusMessage customStatusMessage
;
425 customStatusMessage
.setTitle( Kopete::BehaviorSettings::self()->autoAwayCustomTitle() );
426 customStatusMessage
.setMessage( Kopete::BehaviorSettings::self()->autoAwayCustomMessage() );
427 d
->customStatusMessage
= customStatusMessage
;
429 Kopete::IdleTimer
* idleTimer
= Kopete::IdleTimer::self();
430 idleTimer
->unregisterTimeout( this );
432 if ( Kopete::BehaviorSettings::self()->useAutoAway() )
433 idleTimer
->registerTimeout( d
->awayTimeout
, this, SLOT(setActive()), SLOT(setAutoAway()) );
438 #include "kopetestatusmanager.moc"