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
00060
00061 for ( QList<QPair< QPointer<QWidget>, QPointer<QWidget> > >::Iterator it = sInstanceOverlay->baseWidgets.begin();
00062 it != sInstanceOverlay->baseWidgets.end(); ) {
00063 if ( (*it).first == 0 || (*it).second == 0 ) {
00064
00065 it = sInstanceOverlay->baseWidgets.erase( it );
00066 continue;
00067 }
00068 if ( isParentOf( (*it).first, baseWidget ) ) {
00069
00070 mBaseWidget = 0;
00071 hide();
00072 deleteLater();
00073 return;
00074 }
00075 if ( isParentOf( baseWidget, (*it).first ) ) {
00076
00077 delete (*it).second;
00078 it = sInstanceOverlay->baseWidgets.erase( it );
00079 continue;
00080 }
00081 ++it;
00082 }
00083 sInstanceOverlay->baseWidgets.append( qMakePair( mBaseWidget, QPointer<QWidget>( this ) ) );
00084
00085 connect( baseWidget, SIGNAL(destroyed()), SLOT(deleteLater()) );
00086 mPreviousState = mBaseWidget->isEnabled();
00087
00088 QBoxLayout *topLayout = new QVBoxLayout( this );
00089 topLayout->addStretch();
00090 mIconLabel = new QLabel( this );
00091 mIconLabel->setPixmap( KIcon( QString::fromLatin1("dialog-error") ).pixmap( 64 ) );
00092 mIconLabel->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
00093 topLayout->addWidget( mIconLabel );
00094
00095 mDescLabel = new QLabel( this );
00096 mDescLabel->setText( i18n( "<p style=\"color: white;\"><b>Akonadi not operational.<br/>"
00097 "<a href=\"details\" style=\"color: white;\">Details...</a></b></p>" ) );
00098 mDescLabel->setWordWrap( true );
00099 mDescLabel->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
00100 connect( mDescLabel, SIGNAL(linkActivated(QString)), SLOT(linkActivated()) );
00101 topLayout->addWidget( mDescLabel );
00102 topLayout->addStretch();
00103
00104 setToolTip( i18n( "The Akonadi personal information management framework is not operational.\n"
00105 "Click on \"Details...\" to obtain detailed information on this problem." ) );
00106
00107 mOverlayActive = ServerManager::isRunning();
00108 if ( mOverlayActive )
00109 started();
00110 else
00111 stopped();
00112 connect( ServerManager::self(), SIGNAL(started()), SLOT(started()) );
00113 connect( ServerManager::self(), SIGNAL(stopped()), SLOT(stopped()) );
00114
00115 QPalette p = palette();
00116 p.setColor( backgroundRole(), QColor( 0, 0, 0, 128 ) );
00117 setPalette( p );
00118 setAutoFillBackground( true );
00119
00120 mBaseWidget->installEventFilter( this );
00121
00122 reposition();
00123 }
00124
00125 ErrorOverlay::~ ErrorOverlay()
00126 {
00127 if ( mBaseWidget )
00128 mBaseWidget->setEnabled( mPreviousState );
00129 }
00130
00131 void ErrorOverlay::reposition()
00132 {
00133 if ( !mBaseWidget )
00134 return;
00135
00136
00137
00138 if ( parentWidget() != mBaseWidget->window() )
00139 setParent( mBaseWidget->window() );
00140
00141
00142
00143 if ( !mBaseWidget->isVisible() ) {
00144 hide();
00145 return;
00146 }
00147 if ( mOverlayActive )
00148 show();
00149
00150
00151 const QPoint topLevelPos = mBaseWidget->mapTo( window(), QPoint( 0, 0 ) );
00152 const QPoint parentPos = parentWidget()->mapFrom( window(), topLevelPos );
00153 move( parentPos );
00154
00155
00156
00157 resize( mBaseWidget->size() );
00158 }
00159
00160 bool ErrorOverlay::eventFilter(QObject * object, QEvent * event)
00161 {
00162 if ( object == mBaseWidget && mOverlayActive &&
00163 ( event->type() == QEvent::Move || event->type() == QEvent::Resize ||
00164 event->type() == QEvent::Show || event->type() == QEvent::Hide ||
00165 event->type() == QEvent::ParentChange ) ) {
00166 reposition();
00167 }
00168 return QWidget::eventFilter( object, event );
00169 }
00170
00171 void ErrorOverlay::linkActivated()
00172 {
00173 SelfTestDialog dlg;
00174 dlg.exec();
00175 }
00176
00177 void ErrorOverlay::started()
00178 {
00179 if ( !mBaseWidget )
00180 return;
00181 mOverlayActive = false;
00182 hide();
00183 mBaseWidget->setEnabled( mPreviousState );
00184 }
00185
00186 void ErrorOverlay::stopped()
00187 {
00188 if ( !mBaseWidget )
00189 return;
00190 mOverlayActive = true;
00191 if ( mBaseWidget->isVisible() )
00192 show();
00193 mPreviousState = mBaseWidget->isEnabled();
00194 mBaseWidget->setEnabled( false );
00195 reposition();
00196 }
00197
00198
00199
00200 #include "erroroverlay_p.moc"