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