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 #ifndef Q_OS_WINCE
00024 #include "selftestdialog_p.h"
00025 #include "erroroverlay_p.h"
00026 #endif
00027
00028 #include <kdebug.h>
00029 #include <kglobal.h>
00030 #include <klocale.h>
00031
00032 #include <QtCore/QEventLoop>
00033 #include <QtCore/QCoreApplication>
00034 #include <QtCore/QTimer>
00035 #include <QtCore/QPointer>
00036 #include <QtGui/QFrame>
00037
00038 using namespace Akonadi;
00039
00040 namespace Akonadi {
00041 namespace Internal {
00042
00043 class ControlProgressIndicator : public QFrame
00044 {
00045 public:
00046 ControlProgressIndicator( QWidget *parent = 0 ) :
00047 QFrame( parent )
00048 {
00049 setWindowModality( Qt::ApplicationModal );
00050 resize( 400, 100 );
00051 setWindowFlags( Qt::FramelessWindowHint | Qt::Dialog );
00052 ui.setupUi( this );
00053
00054 setFrameShadow( QFrame::Plain );
00055 setFrameShape( QFrame::Box );
00056 }
00057
00058 void setMessage( const QString &msg )
00059 {
00060 ui.statusLabel->setText( msg );
00061 }
00062
00063 Ui::ControlProgressIndicator ui;
00064 };
00065
00066 class StaticControl : public Control
00067 {
00068 public:
00069 StaticControl() : Control() {}
00070 };
00071
00072 }
00073
00074 K_GLOBAL_STATIC( Internal::StaticControl, s_instance )
00075
00076
00079 class Control::Private
00080 {
00081 public:
00082 Private( Control *parent )
00083 : mParent( parent ), mEventLoop( 0 ),
00084 mProgressIndicator( 0 ),
00085 mSuccess( false ),
00086 mStarting( false ), mStopping( false )
00087 {
00088 }
00089
00090 ~Private()
00091 {
00092 delete mProgressIndicator;
00093 }
00094
00095 void setupProgressIndicator( const QString &msg, QWidget *parent = 0 )
00096 {
00097 if ( !mProgressIndicator )
00098 mProgressIndicator = new Internal::ControlProgressIndicator( parent );
00099
00100 mProgressIndicator->setMessage( msg );
00101 }
00102
00103 void createErrorOverlays()
00104 {
00105 #ifndef Q_OS_WINCE
00106 foreach ( QWidget* widget, mPendingOverlays )
00107 if ( widget )
00108 new ErrorOverlay( widget );
00109 #endif
00110 mPendingOverlays.clear();
00111 }
00112
00113 void cleanup()
00114 {
00115 s_instance.destroy();
00116 }
00117
00118 bool exec();
00119 void serverStateChanged(ServerManager::State state);
00120
00121 QPointer<Control> mParent;
00122 QEventLoop *mEventLoop;
00123 QPointer<Internal::ControlProgressIndicator> mProgressIndicator;
00124 QList<QPointer<QWidget> > mPendingOverlays;
00125 bool mSuccess;
00126
00127 bool mStarting;
00128 bool mStopping;
00129 };
00130
00131 bool Control::Private::exec()
00132 {
00133 if ( mProgressIndicator )
00134 mProgressIndicator->show();
00135
00136 kDebug() << "Starting/Stopping Akonadi (using an event loop).";
00137 mEventLoop = new QEventLoop( mParent );
00138 mEventLoop->exec();
00139 mEventLoop->deleteLater();
00140 mEventLoop = 0;
00141
00142 if ( !mSuccess ) {
00143 kWarning() << "Could not start/stop Akonadi!";
00144 #ifndef Q_OS_WINCE
00145 if ( mProgressIndicator && mStarting ) {
00146 QPointer<SelfTestDialog> dlg = new SelfTestDialog( mProgressIndicator->parentWidget() );
00147 dlg->exec();
00148 delete dlg;
00149 if ( !mParent )
00150 return false;
00151 }
00152 #endif
00153 }
00154
00155 delete mProgressIndicator;
00156 mProgressIndicator = 0;
00157 mStarting = false;
00158 mStopping = false;
00159
00160 const bool rv = mSuccess;
00161 mSuccess = false;
00162 return rv;
00163 }
00164
00165 void Control::Private::serverStateChanged(ServerManager::State state)
00166 {
00167 kDebug() << state;
00168 if ( mEventLoop && mEventLoop->isRunning() ) {
00169 mEventLoop->quit();
00170 mSuccess = (mStarting && state == ServerManager::Running) || (mStopping && state == ServerManager::NotRunning);
00171 }
00172 }
00173
00174 Control::Control()
00175 : d( new Private( this ) )
00176 {
00177 connect( ServerManager::self(), SIGNAL( stateChanged( Akonadi::ServerManager::State ) ),
00178 SLOT( serverStateChanged( Akonadi::ServerManager::State ) ) );
00179
00180
00181 if ( QCoreApplication::instance() )
00182 connect( QCoreApplication::instance(), SIGNAL( aboutToQuit() ), this, SLOT( cleanup() ) );
00183 }
00184
00185 Control::~Control()
00186 {
00187 delete d;
00188 }
00189
00190 bool Control::start()
00191 {
00192 if ( ServerManager::state() == ServerManager::Stopping ) {
00193 kDebug() << "Server is currently being stopped, wont try to start it now";
00194 return false;
00195 }
00196 if ( ServerManager::isRunning() || s_instance->d->mEventLoop ) {
00197 kDebug() << "Server is already running";
00198 return true;
00199 }
00200 s_instance->d->mStarting = true;
00201 if ( !ServerManager::start() ) {
00202 kDebug() << "ServerManager::start failed -> return false";
00203 return false;
00204 }
00205 return s_instance->d->exec();
00206 }
00207
00208 bool Control::stop()
00209 {
00210 if ( ServerManager::state() == ServerManager::Starting )
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 }
00259
00260 #include "control.moc"