mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 18:32:51 +00:00
259 lines
8.1 KiB
C++
259 lines
8.1 KiB
C++
![]() |
/*
|
||
|
Copyright (c) 2008 Volker Krause <vkrause@kde.org>
|
||
|
|
||
|
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 "erroroverlay_p.h"
|
||
|
#include "ui_erroroverlay.h"
|
||
|
#include "selftestdialog_p.h"
|
||
|
|
||
|
#include <KDebug>
|
||
|
#include <KIcon>
|
||
|
#include <KLocalizedString>
|
||
|
|
||
|
#include <QtCore/QEvent>
|
||
|
#include <QPalette>
|
||
|
|
||
|
using namespace Akonadi;
|
||
|
|
||
|
//@cond PRIVATE
|
||
|
|
||
|
class ErrorOverlayStatic
|
||
|
{
|
||
|
public:
|
||
|
QVector<QPair<QPointer<QWidget>, QPointer<QWidget> > > baseWidgets;
|
||
|
};
|
||
|
|
||
|
K_GLOBAL_STATIC(ErrorOverlayStatic, sInstanceOverlay)
|
||
|
|
||
|
static bool isParentOf(QObject *o1, QObject *o2)
|
||
|
{
|
||
|
if (!o1 || !o2) {
|
||
|
return false;
|
||
|
}
|
||
|
if (o1 == o2) {
|
||
|
return true;
|
||
|
}
|
||
|
return isParentOf(o1, o2->parent());
|
||
|
}
|
||
|
|
||
|
ErrorOverlay::ErrorOverlay(QWidget *baseWidget, QWidget *parent)
|
||
|
: QWidget(parent ? parent : baseWidget->window())
|
||
|
, mBaseWidget(baseWidget)
|
||
|
, mOverlayActive(false)
|
||
|
, mBaseWidgetIsParent(false)
|
||
|
, ui(new Ui::ErrorOverlay)
|
||
|
{
|
||
|
Q_ASSERT(baseWidget);
|
||
|
|
||
|
mBaseWidgetIsParent = isParentOf(mBaseWidget, this);
|
||
|
|
||
|
// check existing overlays to detect cascading
|
||
|
for (QVector<QPair< QPointer<QWidget>, QPointer<QWidget> > >::Iterator it = sInstanceOverlay->baseWidgets.begin();
|
||
|
it != sInstanceOverlay->baseWidgets.end();) {
|
||
|
if ((*it).first == 0 || (*it).second == 0) {
|
||
|
// garbage collection
|
||
|
it = sInstanceOverlay->baseWidgets.erase(it);
|
||
|
continue;
|
||
|
}
|
||
|
if (isParentOf((*it).first, baseWidget)) {
|
||
|
// parent already has an overlay, kill ourselves
|
||
|
mBaseWidget = 0;
|
||
|
hide();
|
||
|
deleteLater();
|
||
|
return;
|
||
|
}
|
||
|
if (isParentOf(baseWidget, (*it).first)) {
|
||
|
// child already has overlay, kill that one
|
||
|
delete(*it).second;
|
||
|
it = sInstanceOverlay->baseWidgets.erase(it);
|
||
|
continue;
|
||
|
}
|
||
|
++it;
|
||
|
}
|
||
|
sInstanceOverlay->baseWidgets.append(qMakePair(mBaseWidget, QPointer<QWidget>(this)));
|
||
|
|
||
|
connect(baseWidget, SIGNAL(destroyed()), SLOT(deleteLater()));
|
||
|
mPreviousState = mBaseWidget->isEnabled();
|
||
|
|
||
|
ui->setupUi(this);
|
||
|
ui->notRunningIcon->setPixmap(KIcon(QLatin1String("akonadi")).pixmap(64));
|
||
|
ui->brokenIcon->setPixmap(KIcon(QString::fromLatin1("dialog-error")).pixmap(64));
|
||
|
ui->progressIcon->setPixmap(KIcon(QLatin1String("akonadi")).pixmap(32));
|
||
|
ui->quitButton->setText(KStandardGuiItem::quit().text());
|
||
|
ui->detailsQuitButton->setText(KStandardGuiItem::quit().text());
|
||
|
|
||
|
#ifndef KDEPIM_MOBILE_UI
|
||
|
ui->quitButton->hide();
|
||
|
ui->detailsQuitButton->hide();
|
||
|
#endif
|
||
|
|
||
|
connect(ui->startButton, SIGNAL(clicked()), SLOT(startClicked()));
|
||
|
connect(ui->quitButton, SIGNAL(clicked()), SLOT(quitClicked()));
|
||
|
connect(ui->detailsQuitButton, SIGNAL(clicked()), SLOT(quitClicked()));
|
||
|
connect(ui->selfTestButton, SIGNAL(clicked()), SLOT(selfTestClicked()));
|
||
|
|
||
|
const ServerManager::State state = ServerManager::state();
|
||
|
mOverlayActive = (state == ServerManager::Running);
|
||
|
serverStateChanged(state);
|
||
|
|
||
|
connect(ServerManager::self(), SIGNAL(stateChanged(Akonadi::ServerManager::State)),
|
||
|
SLOT(serverStateChanged(Akonadi::ServerManager::State)));
|
||
|
|
||
|
QPalette p = palette();
|
||
|
p.setColor(backgroundRole(), QColor(0, 0, 0, 128));
|
||
|
p.setColor(foregroundRole(), Qt::white);
|
||
|
setPalette(p);
|
||
|
setAutoFillBackground(true);
|
||
|
|
||
|
mBaseWidget->installEventFilter(this);
|
||
|
|
||
|
reposition();
|
||
|
}
|
||
|
|
||
|
ErrorOverlay::~ ErrorOverlay()
|
||
|
{
|
||
|
if (mBaseWidget && !mBaseWidgetIsParent) {
|
||
|
mBaseWidget->setEnabled(mPreviousState);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ErrorOverlay::reposition()
|
||
|
{
|
||
|
if (!mBaseWidget) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// reparent to the current top level widget of the base widget if needed
|
||
|
// needed eg. in dock widgets
|
||
|
if (parentWidget() != mBaseWidget->window()) {
|
||
|
setParent(mBaseWidget->window());
|
||
|
}
|
||
|
|
||
|
// follow base widget visibility
|
||
|
// needed eg. in tab widgets
|
||
|
if (!mBaseWidget->isVisible()) {
|
||
|
hide();
|
||
|
return;
|
||
|
}
|
||
|
if (mOverlayActive) {
|
||
|
show();
|
||
|
}
|
||
|
|
||
|
// follow position changes
|
||
|
const QPoint topLevelPos = mBaseWidget->mapTo(window(), QPoint(0, 0));
|
||
|
const QPoint parentPos = parentWidget()->mapFrom(window(), topLevelPos);
|
||
|
move(parentPos);
|
||
|
|
||
|
// follow size changes
|
||
|
// TODO: hide/scale icon if we don't have enough space
|
||
|
resize(mBaseWidget->size());
|
||
|
}
|
||
|
|
||
|
bool ErrorOverlay::eventFilter(QObject *object, QEvent *event)
|
||
|
{
|
||
|
if (object == mBaseWidget && mOverlayActive &&
|
||
|
(event->type() == QEvent::Move || event->type() == QEvent::Resize ||
|
||
|
event->type() == QEvent::Show || event->type() == QEvent::Hide ||
|
||
|
event->type() == QEvent::ParentChange)) {
|
||
|
reposition();
|
||
|
}
|
||
|
return QWidget::eventFilter(object, event);
|
||
|
}
|
||
|
|
||
|
void ErrorOverlay::startClicked()
|
||
|
{
|
||
|
const ServerManager::State state = ServerManager::state();
|
||
|
if (state == ServerManager::Running) {
|
||
|
serverStateChanged(state);
|
||
|
} else {
|
||
|
ServerManager::start();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ErrorOverlay::quitClicked()
|
||
|
{
|
||
|
qApp->quit();
|
||
|
}
|
||
|
|
||
|
void ErrorOverlay::selfTestClicked()
|
||
|
{
|
||
|
SelfTestDialog dlg;
|
||
|
dlg.exec();
|
||
|
}
|
||
|
|
||
|
void ErrorOverlay::serverStateChanged(ServerManager::State state)
|
||
|
{
|
||
|
if (!mBaseWidget) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (state == ServerManager::Running && mOverlayActive) {
|
||
|
mOverlayActive = false;
|
||
|
hide();
|
||
|
if (!mBaseWidgetIsParent) {
|
||
|
mBaseWidget->setEnabled(mPreviousState);
|
||
|
}
|
||
|
} else if (!mOverlayActive) {
|
||
|
mOverlayActive = true;
|
||
|
if (mBaseWidget->isVisible()) {
|
||
|
show();
|
||
|
}
|
||
|
|
||
|
if (!mBaseWidgetIsParent) {
|
||
|
mPreviousState = mBaseWidget->isEnabled();
|
||
|
mBaseWidget->setEnabled(false);
|
||
|
}
|
||
|
|
||
|
reposition();
|
||
|
}
|
||
|
|
||
|
if (mOverlayActive) {
|
||
|
switch (state) {
|
||
|
case ServerManager::NotRunning:
|
||
|
ui->stackWidget->setCurrentWidget(ui->notRunningPage);
|
||
|
break;
|
||
|
case ServerManager::Broken:
|
||
|
ui->stackWidget->setCurrentWidget(ui->brokenPage);
|
||
|
break;
|
||
|
case ServerManager::Starting:
|
||
|
ui->progressPage->setToolTip(i18n("Personal information management service is starting..."));
|
||
|
ui->progressDescription->setText(i18n("Personal information management service is starting..."));
|
||
|
ui->stackWidget->setCurrentWidget(ui->progressPage);
|
||
|
break;
|
||
|
case ServerManager::Stopping:
|
||
|
ui->progressPage->setToolTip(i18n("Personal information management service is shutting down..."));
|
||
|
ui->progressDescription->setText(i18n("Personal information management service is shutting down..."));
|
||
|
ui->stackWidget->setCurrentWidget(ui->progressPage);
|
||
|
break;
|
||
|
case ServerManager::Upgrading:
|
||
|
ui->progressPage->setToolTip(i18n("Personal information management service is performing a database upgrade."));
|
||
|
ui->progressDescription->setText(i18n("Personal information management service is performing a database upgrade.\n"
|
||
|
"This happens after a software update and is necessary to optimize performance.\n"
|
||
|
"Depending on the amount of personal information, this might take a few minutes."));
|
||
|
ui->stackWidget->setCurrentWidget(ui->progressPage);
|
||
|
break;
|
||
|
case ServerManager::Running:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//@endcond
|
||
|
|
||
|
#include "moc_erroroverlay_p.cpp"
|