diff --git a/akonadi/control.cpp b/akonadi/control.cpp index 42d20582d..92af7ea83 100644 --- a/akonadi/control.cpp +++ b/akonadi/control.cpp @@ -1,258 +1,258 @@ /* Copyright (c) 2007 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "control.h" #include "servermanager.h" #include "ui_controlprogressindicator.h" #include "selftestdialog_p.h" #include "erroroverlay_p.h" #include "firstrun_p.h" #include #include #include #include #include #include #include using namespace Akonadi; class ControlProgressIndicator : public QFrame { public: ControlProgressIndicator( QWidget *parent = 0 ) : QFrame( parent ) { setWindowModality( Qt::ApplicationModal ); resize( 400, 100 ); setWindowFlags( Qt::FramelessWindowHint | Qt::Dialog ); ui.setupUi( this ); setFrameShadow( QFrame::Plain ); setFrameShape( QFrame::Box ); } void setMessage( const QString &msg ) { ui.statusLabel->setText( msg ); } Ui::ControlProgressIndicator ui; }; +class StaticControl : public Control +{ + public: + StaticControl() : Control() {} +}; + +K_GLOBAL_STATIC( StaticControl, s_instance ) + /** * @internal */ class Control::Private { public: Private( Control *parent ) : mParent( parent ), mEventLoop( 0 ), mProgressIndicator( 0 ), mFirstRunner( 0 ), mSuccess( false ), mStarting( false ), mStopping( false ) { KGlobal::locale()->insertCatalog( QString::fromLatin1("libakonadi") ); if ( ServerManager::isRunning() ) mFirstRunner = new Firstrun( mParent ); } ~Private() { delete mProgressIndicator; } void setupProgressIndicator( const QString &msg, QWidget *parent = 0 ) { if ( mProgressIndicator ) return; mProgressIndicator = new ControlProgressIndicator( parent ); mProgressIndicator->setMessage( msg ); } void createErrorOverlays() { foreach ( QWidget* widget, mPendingOverlays ) new ErrorOverlay( widget ); mPendingOverlays.clear(); } + void cleanup() + { + s_instance.destroy(); + } + bool exec(); void serverStarted(); void serverStopped(); QPointer mParent; QEventLoop *mEventLoop; QPointer mProgressIndicator; QList mPendingOverlays; Firstrun *mFirstRunner; bool mSuccess; bool mStarting; bool mStopping; }; -class StaticControl : public Control -{ - public: - StaticControl() : Control() {} -}; - -K_GLOBAL_STATIC( StaticControl, s_instance ) - -void Control::cleanup() -{ - s_instance.destroy(); -} - bool Control::Private::exec() { if ( mProgressIndicator ) mProgressIndicator->show(); kDebug( 5250 ) << "Starting Akonadi (using an event loop)."; mEventLoop = new QEventLoop( mParent ); // safety timeout QTimer::singleShot( 10000, mEventLoop, SLOT(quit()) ); mEventLoop->exec(); mEventLoop->deleteLater(); mEventLoop = 0; if ( !mSuccess ) { kWarning( 5250 ) << "Could not start/stop Akonadi!"; if ( mProgressIndicator && mStarting ) { QPointer dlg = new SelfTestDialog( mProgressIndicator->parentWidget() ); dlg->exec(); delete dlg; - if ( !mParent ) + if ( !mParent ) return false; } } delete mProgressIndicator; mProgressIndicator = 0; mStarting = false; mStopping = false; const bool rv = mSuccess; mSuccess = false; return rv; } void Control::Private::serverStarted() { if ( mEventLoop && mEventLoop->isRunning() && mStarting ) { mEventLoop->quit(); mSuccess = true; } if ( !mFirstRunner ) mFirstRunner = new Firstrun( mParent ); } void Control::Private::serverStopped() { if ( mEventLoop && mEventLoop->isRunning() && mStopping ) { mEventLoop->quit(); mSuccess = true; } } Control::Control() : d( new Private( this ) ) { - connect( ServerManager::self(), SIGNAL(started()), SLOT(serverStarted()) ); - connect( ServerManager::self(), SIGNAL(stopped()), SLOT(serverStopped()) ); + connect( ServerManager::self(), SIGNAL( started() ), SLOT( serverStarted() ) ); + connect( ServerManager::self(), SIGNAL( stopped() ), SLOT( serverStopped() ) ); // mProgressIndicator is a widget, so it better be deleted before the QApplication is deleted // Otherwise we get a crash in QCursor code with Qt-4.5 if ( QCoreApplication::instance() ) - connect( QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(cleanup()) ); + connect( QCoreApplication::instance(), SIGNAL( aboutToQuit() ), this, SLOT( cleanup() ) ); } Control::~Control() { delete d; } bool Control::start() { if ( s_instance->d->mStopping ) return false; if ( ServerManager::isRunning() || s_instance->d->mEventLoop ) return true; s_instance->d->mStarting = true; if ( !ServerManager::start() ) return false; return s_instance->d->exec(); } bool Control::stop() { if ( s_instance->d->mStarting ) return false; if ( !ServerManager::isRunning() || s_instance->d->mEventLoop ) return true; s_instance->d->mStopping = true; if ( !ServerManager::stop() ) return false; return s_instance->d->exec(); } bool Control::restart() { if ( ServerManager::isRunning() ) { if ( !stop() ) return false; } return start(); } bool Control::start(QWidget * parent) { s_instance->d->setupProgressIndicator( i18n( "Starting Akonadi server..." ), parent ); return start(); } bool Control::stop(QWidget * parent) { s_instance->d->setupProgressIndicator( i18n( "Stopping Akonadi server..." ), parent ); return stop(); } bool Control::restart(QWidget * parent) { if ( ServerManager::isRunning() ) { if ( !stop( parent ) ) return false; } return start( parent ); } void Control::widgetNeedsAkonadi(QWidget * widget) { s_instance->d->mPendingOverlays.append( widget ); // delay the overlay creation since we rely on widget being reparented // correctly already QTimer::singleShot( 0, s_instance, SLOT(createErrorOverlays()) ); } #include "control.moc" diff --git a/akonadi/control.h b/akonadi/control.h index 4e1ce9dc2..22a8a73db 100644 --- a/akonadi/control.h +++ b/akonadi/control.h @@ -1,145 +1,143 @@ /* Copyright (c) 2007 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef AKONADI_CONTROL_H #define AKONADI_CONTROL_H #include "akonadi_export.h" #include namespace Akonadi { /** * @short Provides methods to control the Akonadi server process. * * This class provides high-level methods to control the Akonadi * server. These methods are synchronously (ie. use a sub-eventloop) * and can show dialogs. For more low-level methods see * Akonadi::ServerManager. * * While the Akonadi server normally is started by the KDE session * manager, it is not guaranteed that your application is running * inside a KDE session. Therefore it is recommended to execute * Akonadi::Control::start() during startup to ensure the Akonadi * server is running. * * Example: * * @code * * if ( !Akonadi::Control::start() ) { * qDebug() << "Unable to start Akonadi server, exit application"; * return 1; * } else { * ... * } * * @endcode * * @author Volker Krause * * @see Akonadi::ServerManager */ class AKONADI_EXPORT Control : public QObject { Q_OBJECT public: /** * Destroys the control object. */ ~Control(); /** * Starts the Akonadi server synchronously if it is not already running. * @return @c true if the server was started successfully or was already * running, @c false otherwise */ static bool start(); /** * Same as start(), but with GUI feedback. * @param parent The parent widget. * @since 4.2 */ static bool start( QWidget *parent ); /** * Stops the Akonadi server synchronously if it is currently running. * @return @c true if the server was shutdown successfully or was * not running at all, @c false otherwise. * @since 4.2 */ static bool stop(); /** * Same as stop(), but with GUI feedback. * @param parent The parent widget. * @since 4.2 */ static bool stop( QWidget *parent ); /** * Restarts the Akonadi server synchronously. * @return @c true if the restart was successful, @c false otherwise, * the server state is undefined in this case. * @since 4.2 */ static bool restart(); /** * Same as restart(), but with GUI feedback. * @param parent The parent widget. * @since 4.2 */ static bool restart( QWidget *parent ); /** * Disable the given widget when Akonadi is not operational and show * an error overlay (given enough space). Cascading use is automatically * detected. * @param widget The widget depending on Akonadi being operational. * @since 4.2 */ static void widgetNeedsAkonadi( QWidget *widget ); protected: /** * Creates the control object. */ Control(); - private Q_SLOTS: - void cleanup(); - private: //@cond PRIVATE class Private; Private* const d; Q_PRIVATE_SLOT( d, void serverStarted() ) Q_PRIVATE_SLOT( d, void serverStopped() ) Q_PRIVATE_SLOT( d, void createErrorOverlays() ) + Q_PRIVATE_SLOT( d, void cleanup() ) //@endcond }; } #endif