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
00061 class StaticControl : public Control
00062 {
00063 public:
00064 StaticControl() : Control() {}
00065 };
00066
00067 K_GLOBAL_STATIC( StaticControl, s_instance )
00068
00069
00072 class Control::Private
00073 {
00074 public:
00075 Private( Control *parent )
00076 : mParent( parent ), mEventLoop( 0 ),
00077 mProgressIndicator( 0 ),
00078 mFirstRunner( 0 ),
00079 mSuccess( false ),
00080 mStarting( false ), mStopping( false )
00081 {
00082 KGlobal::locale()->insertCatalog( QString::fromLatin1("libakonadi") );
00083 if ( ServerManager::isRunning() )
00084 mFirstRunner = new Firstrun( mParent );
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 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 serverStarted();
00115 void serverStopped();
00116
00117 QPointer<Control> mParent;
00118 QEventLoop *mEventLoop;
00119 QPointer<ControlProgressIndicator> mProgressIndicator;
00120 QList<QPointer<QWidget> > mPendingOverlays;
00121 Firstrun *mFirstRunner;
00122 bool mSuccess;
00123
00124 bool mStarting;
00125 bool mStopping;
00126 };
00127
00128 bool Control::Private::exec()
00129 {
00130 if ( mProgressIndicator )
00131 mProgressIndicator->show();
00132
00133 kDebug() << "Starting Akonadi (using an event loop).";
00134 mEventLoop = new QEventLoop( mParent );
00135
00136 QTimer::singleShot( 10000, mEventLoop, SLOT(quit()) );
00137 mEventLoop->exec();
00138 mEventLoop->deleteLater();
00139 mEventLoop = 0;
00140
00141 if ( !mSuccess ) {
00142 kWarning() << "Could not start/stop Akonadi!";
00143 if ( mProgressIndicator && mStarting ) {
00144 QPointer<SelfTestDialog> dlg = new SelfTestDialog( mProgressIndicator->parentWidget() );
00145 dlg->exec();
00146 delete dlg;
00147 if ( !mParent )
00148 return false;
00149 }
00150 }
00151
00152 delete mProgressIndicator;
00153 mProgressIndicator = 0;
00154 mStarting = false;
00155 mStopping = false;
00156
00157 const bool rv = mSuccess;
00158 mSuccess = false;
00159 return rv;
00160 }
00161
00162 void Control::Private::serverStarted()
00163 {
00164 if ( mEventLoop && mEventLoop->isRunning() && mStarting ) {
00165 mEventLoop->quit();
00166 mSuccess = true;
00167 }
00168 if ( !mFirstRunner )
00169 mFirstRunner = new Firstrun( mParent );
00170 }
00171
00172 void Control::Private::serverStopped()
00173 {
00174 if ( mEventLoop && mEventLoop->isRunning() && mStopping ) {
00175 mEventLoop->quit();
00176 mSuccess = true;
00177 }
00178 }
00179
00180
00181 Control::Control()
00182 : d( new Private( this ) )
00183 {
00184 connect( ServerManager::self(), SIGNAL( started() ), SLOT( serverStarted() ) );
00185 connect( ServerManager::self(), SIGNAL( stopped() ), SLOT( serverStopped() ) );
00186
00187
00188 if ( QCoreApplication::instance() )
00189 connect( QCoreApplication::instance(), SIGNAL( aboutToQuit() ), this, SLOT( cleanup() ) );
00190 }
00191
00192 Control::~Control()
00193 {
00194 delete d;
00195 }
00196
00197 bool Control::start()
00198 {
00199 if ( s_instance->d->mStopping )
00200 return false;
00201 if ( ServerManager::isRunning() || s_instance->d->mEventLoop )
00202 return true;
00203 s_instance->d->mStarting = true;
00204 if ( !ServerManager::start() )
00205 return false;
00206 return s_instance->d->exec();
00207 }
00208
00209 bool Control::stop()
00210 {
00211 if ( s_instance->d->mStarting )
00212 return false;
00213 if ( !ServerManager::isRunning() || s_instance->d->mEventLoop )
00214 return true;
00215 s_instance->d->mStopping = true;
00216 if ( !ServerManager::stop() )
00217 return false;
00218 return s_instance->d->exec();
00219 }
00220
00221 bool Control::restart()
00222 {
00223 if ( ServerManager::isRunning() ) {
00224 if ( !stop() )
00225 return false;
00226 }
00227 return start();
00228 }
00229
00230 bool Control::start(QWidget * parent)
00231 {
00232 s_instance->d->setupProgressIndicator( i18n( "Starting Akonadi server..." ), parent );
00233 return start();
00234 }
00235
00236 bool Control::stop(QWidget * parent)
00237 {
00238 s_instance->d->setupProgressIndicator( i18n( "Stopping Akonadi server..." ), parent );
00239 return stop();
00240 }
00241
00242 bool Control::restart(QWidget * parent)
00243 {
00244 if ( ServerManager::isRunning() ) {
00245 if ( !stop( parent ) )
00246 return false;
00247 }
00248 return start( parent );
00249 }
00250
00251 void Control::widgetNeedsAkonadi(QWidget * widget)
00252 {
00253 s_instance->d->mPendingOverlays.append( widget );
00254
00255
00256 QTimer::singleShot( 0, s_instance, SLOT(createErrorOverlays()) );
00257 }
00258
00259 #include "control.moc"