1/* This file is part of the KDE project
2 Copyright (C) 2008-2009 Omat Holding B.V. <info@omat.nl>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program 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 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17*/
18
19#include "dock.h"
20#include "backupassistant.h"
21#include "restoreassistant.h"
22#include "akonaditrayadaptor.h"
23
24#include <QDBusConnectionInterface>
25#include <QToolButton>
26#include <QWidgetAction>
27
28#include <KDebug>
29#include <KIcon>
30#include <KLocalizedString>
31#include <KMenu>
32#include <KNotification>
33#include <KStandardShortcut>
34#include <KStandardDirs>
35
36#include <akonadi/control.h>
37#include <akonadi/agentinstance.h>
38#include <akonadi/agentmanager.h>
39#include <akonadi/servermanager.h>
40
41using namespace Akonadi;
42
43Tray::Tray() : QWidget()
44{
45 hide();
46 new Dock( this );
47}
48
49void Tray::setVisible( bool )
50{
51 // We don't want this Widget to get visible because of a click on the tray icon.
52 QWidget::setVisible( false );
53}
54
55Dock::Dock( QWidget *parent )
56 : KStatusNotifierItem( 0 ), m_explicitStart( false )
57{
58 m_parentWidget = parent;
59
60 setIconByName(QLatin1String("akonaditray"));
61 setCategory(SystemServices);
62 setStatus(Passive);
63 KMenu *menu = new KMenu();
64 m_title = menu->addTitle( i18n( "Akonadi" ) );
65
66 new AkonaditrayAdaptor( this );
67 QDBusConnection dbus = QDBusConnection::sessionBus();
68 dbus.registerObject( QLatin1String("/Actions"), this );
69
70 m_stopAction = menu->addAction( i18n( "&Stop Akonadi" ), this, SLOT(slotStopAkonadi()) );
71 m_startAction = menu->addAction( i18n( "S&tart Akonadi" ), this, SLOT(slotStartAkonadi()) );
72 m_backupAction = menu->addAction( i18n( "Make &Backup..." ), this, SLOT(slotStartBackup()) );
73 m_restoreAction = menu->addAction( i18n( "&Restore Backup..." ), this, SLOT(slotStartRestore()) );
74 menu->addAction( KIcon( QLatin1String("configure") ), i18n( "&Configure..." ), this, SLOT(slotConfigure()) );
75
76 setContextMenu( menu );
77 connect( menu, SIGNAL(aboutToShow()), SLOT(slotActivated()) );
78
79 connect( ServerManager::self(), SIGNAL(started()), SLOT(slotServerStarted()) );
80 connect( ServerManager::self(), SIGNAL(stopped()), SLOT(slotServerStopped()) );
81
82 AgentManager *manager = AgentManager::self();
83 connect( manager,
84 SIGNAL(instanceWarning(Akonadi::AgentInstance,QString)),
85 SLOT(slotInstanceWarning(Akonadi::AgentInstance,QString)) );
86 connect( manager,
87 SIGNAL(instanceError(Akonadi::AgentInstance,QString)),
88 SLOT(slotInstanceError(Akonadi::AgentInstance,QString)) );
89
90 updateMenu( ServerManager::isRunning() );
91}
92
93Dock::~Dock()
94{
95}
96
97void Dock::slotServerStarted()
98{
99 updateMenu( true );
100 if ( m_explicitStart ) {
101 showMessage( i18n( "Akonadi available" ),
102 i18n( "The Akonadi server has been started and can be used now." ), QLatin1String("akonadi") );
103 m_explicitStart = false;
104 }
105}
106
107void Dock::slotServerStopped()
108{
109 updateMenu( false );
110 showMessage( i18n( "Akonadi not available" ),
111 i18n( "The Akonadi server has been stopped, Akonadi related applications can no longer be used." ), QLatin1String("akonadi") );
112}
113
114void Dock::slotStopAkonadi()
115{
116 Akonadi::Control::stop( m_parentWidget );
117}
118
119void Dock::slotStartAkonadi()
120{
121 m_explicitStart = true;
122 Akonadi::Control::start( m_parentWidget );
123}
124
125void Dock::slotActivated()
126{
127 updateMenu( ServerManager::isRunning() );
128}
129
130void Dock::slotStartBackup()
131{
132 bool registered = ServerManager::isRunning();
133 Q_ASSERT( registered );
134 Q_UNUSED( registered );
135
136 QPointer<BackupAssistant> backup = new BackupAssistant( m_parentWidget );
137 backup->exec();
138 delete backup;
139}
140
141void Dock::slotStartRestore()
142{
143 bool registered = ServerManager::isRunning();
144 Q_ASSERT( registered );
145 Q_UNUSED( registered );
146
147 QPointer<RestoreAssistant> restore = new RestoreAssistant( m_parentWidget );
148 restore->exec();
149 delete restore;
150}
151
152void Dock::updateMenu( bool registered )
153{
154 if ( registered ) {
155 setToolTip( QLatin1String("akonadi"), i18n( "Akonadi available" ),
156 i18n( "The Akonadi server has been started and can be used now." ) );
157 } else {
158 setToolTip( QLatin1String("akonadi"), i18n( "Akonadi not available" ),
159 i18n( "The Akonadi server has been stopped, Akonadi related applications can no longer be used." ) );
160 }
161
162 /* kdelibs... */
163 QToolButton *button = static_cast<QToolButton*>(( static_cast<QWidgetAction*>( m_title ) )->defaultWidget() );
164 QAction* action = button->defaultAction();
165 action->setText( registered ? i18n( "Akonadi is running" ) : i18n( "Akonadi is not running" ) );
166 button->setDefaultAction( action );
167
168 m_stopAction->setVisible( registered );
169 m_backupAction->setEnabled( registered );
170 m_restoreAction->setEnabled( registered );
171 m_startAction->setVisible( !registered );
172}
173
174void Dock::slotInstanceWarning( const Akonadi::AgentInstance& agent, const QString& message )
175{
176 QString msg = message;
177 if ( !agent.name().isEmpty() )
178 msg = i18nc( "<source>: <error message>", "%1: %2", agent.name(), msg );
179 infoMessage( msg, agent.name() );
180}
181
182void Dock::infoMessage( const QString &message, const QString &title )
183{
184 KNotification::event( KNotification::Notification, title.isEmpty() ? i18n( "Akonadi message" ) : title,
185 message, QPixmap(), m_parentWidget );
186}
187
188void Dock::slotInstanceError( const Akonadi::AgentInstance& agent, const QString& message )
189{
190 QString msg = message;
191 if ( !agent.name().isEmpty() )
192 msg = i18nc( "<source>: <error message>", "%1: %2", agent.name(), msg );
193 errorMessage( msg, agent.name() );
194}
195
196void Dock::errorMessage( const QString &message, const QString &title )
197{
198 KNotification::event( KNotification::Error, title.isEmpty() ? i18n( "Akonadi error" ) : title,
199 message, DesktopIcon( QLatin1String("dialog-warning") ), m_parentWidget );
200}
201
202qlonglong Dock::getWinId()
203{
204 return ( qlonglong )m_parentWidget ->winId();
205}
206
207void Dock::slotConfigure()
208{
209 QProcess::startDetached( KStandardDirs::findExe( QLatin1String( "kcmshell4" ) ), QStringList() << QLatin1String("kcm_akonadi") );
210}
211
212