00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "control.h"
00021 #include "servermanager.h"
00022 #include "ui_controlprogressindicator.h"
00023 #include "selftestdialog_p.h"
00024 #include "erroroverlay_p.h"
00025
00026 #include <kdebug.h>
00027 #include <kglobal.h>
00028 #include <klocale.h>
00029
00030 #include <QtCore/QEventLoop>
00031 #include <QtCore/QCoreApplication>
00032 #include <QtCore/QTimer>
00033 #include <QtGui/QFrame>
00034
00035 using namespace Akonadi;
00036
00037 namespace Akonadi {
00038 namespace Internal {
00039
00040 class ControlProgressIndicator : public QFrame
00041 {
00042 public:
00043 ControlProgressIndicator( QWidget *parent = 0 ) :
00044 QFrame( parent )
00045 {
00046 setWindowModality( Qt::ApplicationModal );
00047 resize( 400, 100 );
00048 setWindowFlags( Qt::FramelessWindowHint | Qt::Dialog );
00049 ui.setupUi( this );
00050
00051 setFrameShadow( QFrame::Plain );
00052 setFrameShape( QFrame::Box );
00053 }
00054
00055 void setMessage( const QString &msg )
00056 {
00057 ui.statusLabel->setText( msg );
00058 }
00059
00060 Ui::ControlProgressIndicator ui;
00061 };
00062
00063 class StaticControl : public Control
00064 {
00065 public:
00066 StaticControl() : Control() {}
00067 };
00068
00069 }
00070
00071 K_GLOBAL_STATIC( Internal::StaticControl, s_instance )
00072
00073
00076 class Control::Private
00077 {
00078 public:
00079 Private( Control *parent )
00080 : mParent( parent ), mEventLoop( 0 ),
00081 mProgressIndicator( 0 ),
00082 mSuccess( false ),
00083 mStarting( false ), mStopping( false )
00084 {
00085 }
00086
00087 ~Private()
00088 {
00089 delete mProgressIndicator;
00090 }
00091
00092 void setupProgressIndicator( const QString &msg, QWidget *parent = 0 )
00093 {
00094 if ( !mProgressIndicator )
00095 mProgressIndicator = new Internal::ControlProgressIndicator( parent );
00096
00097 mProgressIndicator->setMessage( msg );
00098 }
00099
00100 void createErrorOverlays()
00101 {
00102 foreach ( QWidget* widget, mPendingOverlays )
00103 if ( widget )
00104 new ErrorOverlay( widget );
00105 mPendingOverlays.clear();
00106 }
00107
00108 void cleanup()
00109 {
00110 s_instance.destroy();
00111 }
00112
00113 bool exec();
00114 void serverStateChanged(ServerManager::State state);
00115
00116 QPointer<Control> mParent;
00117 QEventLoop *mEventLoop;
00118 QPointer<Internal::ControlProgressIndicator> mProgressIndicator;
00119 QList<QPointer<QWidget> > mPendingOverlays;
00120 bool mSuccess;
00121
00122 bool mStarting;
00123 bool mStopping;
00124 };
00125
00126 bool Control::Private::exec()
00127 {
00128 if ( mProgressIndicator )
00129 mProgressIndicator->show();
00130
00131 kDebug() << "Starting/Stopping Akonadi (using an event loop).";
00132 mEventLoop = new QEventLoop( mParent );
00133 mEventLoop->exec();
00134 mEventLoop->deleteLater();
00135 mEventLoop = 0;
00136
00137 if ( !mSuccess ) {
00138 kWarning() << "Could not start/stop Akonadi!";
00139 if ( mProgressIndicator && mStarting ) {
00140 QPointer<SelfTestDialog> dlg = new SelfTestDialog( mProgressIndicator->parentWidget() );
00141 dlg->exec();
00142 delete dlg;
00143 if ( !mParent )
00144 return false;
00145 }
00146 }
00147
00148 delete mProgressIndicator;
00149 mProgressIndicator = 0;
00150 mStarting = false;
00151 mStopping = false;
00152
00153 const bool rv = mSuccess;
00154 mSuccess = false;
00155 return rv;
00156 }
00157
00158 void Control::Private::serverStateChanged(ServerManager::State state)
00159 {
00160 kDebug() << state;
00161 if ( mEventLoop && mEventLoop->isRunning() ) {
00162 mEventLoop->quit();
00163 mSuccess = (mStarting && state == ServerManager::Running) || (mStopping && state == ServerManager::NotRunning);
00164 }
00165 }
00166
00167 Control::Control()
00168 : d( new Private( this ) )
00169 {
00170 connect( ServerManager::self(), SIGNAL( stateChanged( Akonadi::ServerManager::State ) ),
00171 SLOT( serverStateChanged( Akonadi::ServerManager::State ) ) );
00172
00173
00174 if ( QCoreApplication::instance() )
00175 connect( QCoreApplication::instance(), SIGNAL( aboutToQuit() ), this, SLOT( cleanup() ) );
00176 }
00177
00178 Control::~Control()
00179 {
00180 delete d;
00181 }
00182
00183 bool Control::start()
00184 {
00185 if ( ServerManager::state() == ServerManager::Stopping ) {
00186 kDebug() << "Server is currently being stopped, wont try to start it now";
00187 return false;
00188 }
00189 if ( ServerManager::isRunning() || s_instance->d->mEventLoop ) {
00190 kDebug() << "Server is already running";
00191 return true;
00192 }
00193 s_instance->d->mStarting = true;
00194 if ( !ServerManager::start() ) {
00195 kDebug() << "ServerManager::start failed -> return false";
00196 return false;
00197 }
00198 return s_instance->d->exec();
00199 }
00200
00201 bool Control::stop()
00202 {
00203 if ( ServerManager::state() == ServerManager::Starting )
00204 return false;
00205 if ( !ServerManager::isRunning() || s_instance->d->mEventLoop )
00206 return true;
00207 s_instance->d->mStopping = true;
00208 if ( !ServerManager::stop() )
00209 return false;
00210 return s_instance->d->exec();
00211 }
00212
00213 bool Control::restart()
00214 {
00215 if ( ServerManager::isRunning() ) {
00216 if ( !stop() )
00217 return false;
00218 }
00219 return start();
00220 }
00221
00222 bool Control::start(QWidget * parent)
00223 {
00224 s_instance->d->setupProgressIndicator( i18n( "Starting Akonadi server..." ), parent );
00225 return start();
00226 }
00227
00228 bool Control::stop(QWidget * parent)
00229 {
00230 s_instance->d->setupProgressIndicator( i18n( "Stopping Akonadi server..." ), parent );
00231 return stop();
00232 }
00233
00234 bool Control::restart(QWidget * parent)
00235 {
00236 if ( ServerManager::isRunning() ) {
00237 if ( !stop( parent ) )
00238 return false;
00239 }
00240 return start( parent );
00241 }
00242
00243 void Control::widgetNeedsAkonadi(QWidget * widget)
00244 {
00245 s_instance->d->mPendingOverlays.append( widget );
00246
00247
00248 QTimer::singleShot( 0, s_instance, SLOT( createErrorOverlays() ) );
00249 }
00250
00251 }
00252
00253 #include "control.moc"