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"