akonadi
control.cpp
00001 /* 00002 Copyright (c) 2007 Volker Krause <vkrause@kde.org> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 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 // mProgressIndicator is a widget, so it better be deleted before the QApplication is deleted 00180 // Otherwise we get a crash in QCursor code with Qt-4.5 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 // delay the overlay creation since we rely on widget being reparented 00254 // correctly already 00255 QTimer::singleShot( 0, s_instance, SLOT(createErrorOverlays()) ); 00256 } 00257 00258 } 00259 00260 #include "control.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu Aug 2 2012 15:25:18 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu Aug 2 2012 15:25:18 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.