akonadi
erroroverlay.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "erroroverlay_p.h"
00021 #include "servermanager.h"
00022 #include "selftestdialog_p.h"
00023
00024 #include <KDebug>
00025 #include <KIcon>
00026 #include <KLocale>
00027
00028 #include <QtCore/QEvent>
00029 #include <QtGui/QBoxLayout>
00030 #include <QtGui/QLabel>
00031 #include <QtGui/QPalette>
00032
00033 using namespace Akonadi;
00034
00035
00036
00037 class ErrorOverlayStatic
00038 {
00039 public:
00040 QList<QPair<QPointer<QWidget>, QPointer<QWidget> > > baseWidgets;
00041 };
00042
00043 K_GLOBAL_STATIC( ErrorOverlayStatic, sInstanceOverlay )
00044
00045 static bool isParentOf( QObject* o1, QObject* o2 )
00046 {
00047 if ( !o1 || !o2 )
00048 return false;
00049 if ( o1 == o2 )
00050 return true;
00051 return isParentOf( o1, o2->parent() );
00052 }
00053
00054 ErrorOverlay::ErrorOverlay( QWidget *baseWidget, QWidget * parent ) :
00055 QWidget( parent ? parent : baseWidget->window() ),
00056 mBaseWidget( baseWidget )
00057 {
00058 Q_ASSERT( baseWidget );
00059 Q_ASSERT( parentWidget() != baseWidget );
00060
00061
00062 for ( QList<QPair< QPointer<QWidget>, QPointer<QWidget> > >::Iterator it = sInstanceOverlay->baseWidgets.begin();
00063 it != sInstanceOverlay->baseWidgets.end(); ) {
00064 if ( (*it).first == 0 || (*it).second == 0 ) {
00065
00066 it = sInstanceOverlay->baseWidgets.erase( it );
00067 continue;
00068 }
00069 if ( isParentOf( (*it).first, baseWidget ) ) {
00070
00071 mBaseWidget = 0;
00072 hide();
00073 deleteLater();
00074 return;
00075 }
00076 if ( isParentOf( baseWidget, (*it).first ) ) {
00077
00078 delete (*it).second;
00079 it = sInstanceOverlay->baseWidgets.erase( it );
00080 continue;
00081 }
00082 ++it;
00083 }
00084 sInstanceOverlay->baseWidgets.append( qMakePair( mBaseWidget, QPointer<QWidget>( this ) ) );
00085
00086 connect( baseWidget, SIGNAL(destroyed()), SLOT(deleteLater()) );
00087 mPreviousState = mBaseWidget->isEnabled();
00088
00089 QBoxLayout *topLayout = new QVBoxLayout( this );
00090 topLayout->addStretch();
00091 mIconLabel = new QLabel( this );
00092 mIconLabel->setPixmap( KIcon( "dialog-error" ).pixmap( 64 ) );
00093 mIconLabel->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
00094 topLayout->addWidget( mIconLabel );
00095
00096 mDescLabel = new QLabel( this );
00097 mDescLabel->setText( i18n( "<p style=\"color: white;\"><b>Akonadi not operational.<br/>"
00098 "<a href=\"details\" style=\"color: white;\">Details...</a></b></p>" ) );
00099 mDescLabel->setWordWrap( true );
00100 mDescLabel->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
00101 connect( mDescLabel, SIGNAL(linkActivated(QString)), SLOT(linkActivated()) );
00102 topLayout->addWidget( mDescLabel );
00103 topLayout->addStretch();
00104
00105 setToolTip( i18n( "The Akonadi personal information management framework is not operational.\n"
00106 "Click on \"Details...\" to obtain detailed information on this problem." ) );
00107
00108 mOverlayActive = ServerManager::isRunning();
00109 if ( mOverlayActive )
00110 started();
00111 else
00112 stopped();
00113 connect( ServerManager::self(), SIGNAL(started()), SLOT(started()) );
00114 connect( ServerManager::self(), SIGNAL(stopped()), SLOT(stopped()) );
00115
00116 QPalette p = palette();
00117 p.setColor( backgroundRole(), QColor( 0, 0, 0, 128 ) );
00118 setPalette( p );
00119 setAutoFillBackground( true );
00120
00121 mBaseWidget->installEventFilter( this );
00122
00123 reposition();
00124 }
00125
00126 ErrorOverlay::~ ErrorOverlay()
00127 {
00128 if ( mBaseWidget )
00129 mBaseWidget->setEnabled( mPreviousState );
00130 }
00131
00132 void ErrorOverlay::reposition()
00133 {
00134 if ( !mBaseWidget )
00135 return;
00136
00137
00138
00139 if ( parentWidget() != mBaseWidget->window() )
00140 setParent( mBaseWidget->window() );
00141
00142
00143
00144 if ( !mBaseWidget->isVisible() ) {
00145 hide();
00146 return;
00147 }
00148 if ( mOverlayActive )
00149 show();
00150
00151
00152 const QPoint topLevelPos = mBaseWidget->mapTo( window(), QPoint( 0, 0 ) );
00153 const QPoint parentPos = parentWidget()->mapFrom( window(), topLevelPos );
00154 move( parentPos );
00155
00156
00157
00158 resize( mBaseWidget->size() );
00159 }
00160
00161 bool ErrorOverlay::eventFilter(QObject * object, QEvent * event)
00162 {
00163 if ( object == mBaseWidget && mOverlayActive &&
00164 ( event->type() == QEvent::Move || event->type() == QEvent::Resize ||
00165 event->type() == QEvent::Show || event->type() == QEvent::Hide ||
00166 event->type() == QEvent::ParentChange ) ) {
00167 reposition();
00168 }
00169 return QWidget::eventFilter( object, event );
00170 }
00171
00172 void ErrorOverlay::linkActivated()
00173 {
00174 SelfTestDialog dlg;
00175 dlg.exec();
00176 }
00177
00178 void ErrorOverlay::started()
00179 {
00180 if ( !mBaseWidget )
00181 return;
00182 mOverlayActive = false;
00183 hide();
00184 mBaseWidget->setEnabled( mPreviousState );
00185 }
00186
00187 void ErrorOverlay::stopped()
00188 {
00189 if ( !mBaseWidget )
00190 return;
00191 mOverlayActive = true;
00192 if ( mBaseWidget->isVisible() )
00193 show();
00194 mPreviousState = mBaseWidget->isEnabled();
00195 mBaseWidget->setEnabled( false );
00196 reposition();
00197 }
00198
00199
00200
00201 #include "erroroverlay_p.moc"