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( "Offline" ) );
290 status
->setCategory( OnlineStatusManager::Offline
);
291 group
->appendChild( status
);
296 void StatusManager::setGlobalStatus( uint category
, const Kopete::StatusMessage
&statusMessage
)
298 d
->globalStatusCategory
= category
;
299 d
->globalStatusMessage
= statusMessage
;
301 KConfigGroup
config( KGlobal::config(), "Status Manager" );
302 config
.writeEntry( "GlobalStatusCategory", d
->globalStatusCategory
);
303 config
.writeEntry( "GlobalStatusTitle", d
->globalStatusMessage
.title() );
304 config
.writeEntry( "GlobalStatusMessage", d
->globalStatusMessage
.message() );
307 emit
globalStatusChanged();
310 void StatusManager::setGlobalStatusMessage( const Kopete::StatusMessage
&statusMessage
)
312 d
->globalStatusMessage
= statusMessage
;
314 KConfigGroup
config( KGlobal::config(), "Status Manager" );
315 config
.writeEntry( "GlobalStatusTitle", d
->globalStatusMessage
.title() );
316 config
.writeEntry( "GlobalStatusMessage", d
->globalStatusMessage
.message() );
319 emit
globalStatusChanged();
322 Kopete::StatusMessage
StatusManager::globalStatusMessage() const
324 return d
->globalStatusMessage
;
327 void StatusManager::setActive()
329 kDebug(14010) << "Found activity on desktop, setting accounts online";
333 if ( d
->goAvailable
)
335 QList
<Kopete::Account
*>::iterator it
, itEnd
= d
->autoAwayAccounts
.end();
336 for( it
= d
->autoAwayAccounts
.begin(); it
!= itEnd
; ++it
)
338 if( (*it
)->isConnected() && (*it
)->isAway() )
340 (*it
)->setOnlineStatus( Kopete::OnlineStatusManager::self()->onlineStatus( (*it
)->protocol(),
341 Kopete::OnlineStatusManager::Online
) );
344 d
->autoAwayAccounts
.clear();
349 void StatusManager::setAutoAway()
351 kDebug(14010) << "Going AutoAway!";
356 // Set all accounts that are not away already to away.
357 // We remember them so later we only set the accounts to
358 // available that we set to away (and not the user).
359 QList
<Kopete::Account
*> accountList
= Kopete::AccountManager::self()->accounts();
361 QList
<Kopete::Account
*>::iterator it
, itEnd
= accountList
.end();
362 for( it
= accountList
.begin(); it
!= itEnd
; ++it
)
364 if( (*it
)->myself()->onlineStatus().status() == Kopete::OnlineStatus::Online
)
366 d
->autoAwayAccounts
.append( (*it
) );
368 if( d
->useCustomStatus
)
370 // Display a specific away message
371 (*it
)->setOnlineStatus( Kopete::OnlineStatusManager::self()->onlineStatus( (*it
)->protocol(),
372 Kopete::OnlineStatusManager::Idle
), d
->customStatusMessage
);
376 // Display the last global away message used
377 (*it
)->setOnlineStatus( Kopete::OnlineStatusManager::self()->onlineStatus( (*it
)->protocol(),
378 Kopete::OnlineStatusManager::Idle
), d
->globalStatusMessage
);
385 bool StatusManager::autoAway()
390 bool StatusManager::globalAway()
392 return ( d
->globalStatusCategory
== OnlineStatusManager::Away
||
393 d
->globalStatusCategory
== OnlineStatusManager::ExtendedAway
||
394 d
->globalStatusCategory
== OnlineStatusManager::Busy
);
397 void StatusManager::accountUnregistered( const Kopete::Account
*account
)
399 d
->autoAwayAccounts
.removeAll( const_cast<Kopete::Account
*>(account
) );
402 void StatusManager::loadSettings()
404 KConfigGroup
config( KGlobal::config(), "Status Manager" );
405 d
->globalStatusCategory
= config
.readEntry( "GlobalStatusCategory", 0 );
407 Kopete::StatusMessage statusMessage
;
408 statusMessage
.setTitle( config
.readEntry( "GlobalStatusTitle", QString() ) );
409 statusMessage
.setMessage( config
.readEntry( "GlobalStatusMessage", QString() ) );
410 d
->globalStatusMessage
= statusMessage
;
413 void StatusManager::loadBehaviorSettings()
415 d
->awayTimeout
= Kopete::BehaviorSettings::self()->autoAwayTimeout();
416 d
->goAvailable
= Kopete::BehaviorSettings::self()->autoAwayGoAvailable();
417 d
->useCustomStatus
= Kopete::BehaviorSettings::self()->useCustomAwayMessage();
419 Kopete::StatusMessage customStatusMessage
;
420 customStatusMessage
.setTitle( Kopete::BehaviorSettings::self()->autoAwayCustomTitle() );
421 customStatusMessage
.setMessage( Kopete::BehaviorSettings::self()->autoAwayCustomMessage() );
422 d
->customStatusMessage
= customStatusMessage
;
424 Kopete::IdleTimer
* idleTimer
= Kopete::IdleTimer::self();
425 idleTimer
->unregisterTimeout( this );
427 if ( Kopete::BehaviorSettings::self()->useAutoAway() )
428 idleTimer
->registerTimeout( d
->awayTimeout
, this, SLOT(setActive()), SLOT(setAutoAway()) );
433 #include "kopetestatusmanager.moc"