File indexing completed on 2024-11-24 04:39:36

0001 /*
0002     This file is part of Akonadi Contact.
0003 
0004     SPDX-FileCopyrightText: 2008 Volker Krause <vkrause@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "waitingoverlay_p.h"
0010 
0011 #include <KJob>
0012 #include <KLocalizedString>
0013 
0014 #include <QBoxLayout>
0015 #include <QEvent>
0016 #include <QLabel>
0017 #include <QPalette>
0018 
0019 //@cond PRIVATE
0020 using namespace Akonadi;
0021 WaitingOverlay::WaitingOverlay(KJob *job, QWidget *baseWidget, QWidget *parent)
0022     : QWidget(parent ? parent : baseWidget->window())
0023     , mBaseWidget(baseWidget)
0024 {
0025     Q_ASSERT(baseWidget);
0026     Q_ASSERT(parentWidget() != baseWidget);
0027 
0028     connect(baseWidget, &QObject::destroyed, this, &QObject::deleteLater);
0029     connect(job, &KJob::result, this, &QObject::deleteLater);
0030     mPreviousState = mBaseWidget->isEnabled();
0031 
0032     QBoxLayout *topLayout = new QVBoxLayout(this);
0033     topLayout->addStretch();
0034     auto description = new QLabel(this);
0035     description->setText(i18n("<p style=\"color: white;\"><b>Waiting for operation</b><br/></p>"));
0036     description->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
0037     topLayout->addWidget(description);
0038     topLayout->addStretch();
0039 
0040     QPalette p = palette();
0041     p.setColor(backgroundRole(), QColor(0, 0, 0, 128));
0042     setPalette(p);
0043     setAutoFillBackground(true);
0044 
0045     mBaseWidget->installEventFilter(this);
0046 
0047     reposition();
0048 }
0049 
0050 WaitingOverlay::~WaitingOverlay()
0051 {
0052     if (mBaseWidget) {
0053         mBaseWidget->setEnabled(mPreviousState);
0054     }
0055 }
0056 
0057 void WaitingOverlay::reposition()
0058 {
0059     if (!mBaseWidget) {
0060         return;
0061     }
0062 
0063     // reparent to the current top level widget of the base widget if needed
0064     // needed eg. in dock widgets
0065     if (parentWidget() != mBaseWidget->window()) {
0066         setParent(mBaseWidget->window());
0067     }
0068 
0069     // follow base widget visibility
0070     // needed eg. in tab widgets
0071     if (!mBaseWidget->isVisible()) {
0072         hide();
0073         return;
0074     }
0075     show();
0076 
0077     // follow position changes
0078     const QPoint topLevelPos = mBaseWidget->mapTo(window(), QPoint(0, 0));
0079     const QPoint parentPos = parentWidget()->mapFrom(window(), topLevelPos);
0080     move(parentPos);
0081 
0082     // follow size changes
0083     // TODO: hide/scale icon if we don't have enough space
0084     resize(mBaseWidget->size());
0085 }
0086 
0087 bool WaitingOverlay::eventFilter(QObject *object, QEvent *event)
0088 {
0089     if (object == mBaseWidget
0090         && (event->type() == QEvent::Move || event->type() == QEvent::Resize || event->type() == QEvent::Show || event->type() == QEvent::Hide
0091             || event->type() == QEvent::ParentChange)) {
0092         reposition();
0093     }
0094     return QWidget::eventFilter(object, event);
0095 }
0096 
0097 //@endcond
0098 
0099 #include "moc_waitingoverlay_p.cpp"