File indexing completed on 2024-04-28 15:29:24

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2003 Daniel Molkentin <molkentin@kde.org>
0004     SPDX-FileCopyrightText: 2003 David Faure <faure@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "statusbarextension.h"
0010 
0011 #include "kparts_logging.h"
0012 
0013 #include "guiactivateevent.h"
0014 #include "readonlypart.h"
0015 
0016 #include <KMainWindow>
0017 
0018 #include <QObject>
0019 #include <QPointer>
0020 #include <QStatusBar>
0021 
0022 using namespace KParts;
0023 
0024 ///////////////////////////////////////////////////////////////////
0025 // Helper Classes
0026 ///////////////////////////////////////////////////////////////////
0027 
0028 class KParts::StatusBarItem
0029 {
0030 public:
0031     StatusBarItem() // for QValueList
0032         : m_widget(nullptr)
0033         , m_visible(false)
0034     {
0035     }
0036     StatusBarItem(QWidget *widget, int stretch, bool permanent)
0037         : m_widget(widget)
0038         , m_stretch(stretch)
0039         , m_permanent(permanent)
0040         , m_visible(false)
0041     {
0042     }
0043 
0044     QWidget *widget() const
0045     {
0046         return m_widget;
0047     }
0048 
0049     void ensureItemShown(QStatusBar *sb)
0050     {
0051         if (m_widget && !m_visible) {
0052             if (m_permanent) {
0053                 sb->addPermanentWidget(m_widget, m_stretch);
0054             } else {
0055                 sb->addWidget(m_widget, m_stretch);
0056             }
0057             m_visible = true;
0058             m_widget->show();
0059         }
0060     }
0061     void ensureItemHidden(QStatusBar *sb)
0062     {
0063         if (m_widget && m_visible) {
0064             sb->removeWidget(m_widget);
0065             m_visible = false;
0066             m_widget->hide();
0067         }
0068     }
0069 
0070 private:
0071     QPointer<QWidget> m_widget;
0072     int m_stretch;
0073     bool m_permanent;
0074     bool m_visible; // true when the item has been added to the statusbar
0075 };
0076 
0077 class KParts::StatusBarExtensionPrivate
0078 {
0079 public:
0080     StatusBarExtensionPrivate(StatusBarExtension *qq)
0081         : q(qq)
0082         , m_statusBar(nullptr)
0083         , m_activated(true)
0084     {
0085     }
0086 
0087     StatusBarExtension *q;
0088     QList<StatusBarItem> m_statusBarItems; // Our statusbar items
0089     QStatusBar *m_statusBar;
0090     bool m_activated;
0091 };
0092 
0093 ///////////////////////////////////////////////////////////////////
0094 
0095 StatusBarExtension::StatusBarExtension(KParts::Part *parent)
0096     : QObject(parent)
0097     , d(new StatusBarExtensionPrivate(this))
0098 {
0099     parent->installEventFilter(this);
0100 }
0101 
0102 StatusBarExtension::StatusBarExtension(KParts::ReadOnlyPart *parent)
0103     : QObject(parent)
0104     , d(new StatusBarExtensionPrivate(this))
0105 {
0106     parent->installEventFilter(this);
0107 }
0108 
0109 StatusBarExtension::~StatusBarExtension()
0110 {
0111     QStatusBar *sb = d->m_statusBar;
0112     for (int i = d->m_statusBarItems.count() - 1; i >= 0; --i) {
0113         if (d->m_statusBarItems[i].widget()) {
0114             if (sb) {
0115                 d->m_statusBarItems[i].ensureItemHidden(sb);
0116             }
0117             d->m_statusBarItems[i].widget()->deleteLater();
0118         }
0119     }
0120 }
0121 
0122 StatusBarExtension *StatusBarExtension::childObject(QObject *obj)
0123 {
0124     return obj->findChild<KParts::StatusBarExtension *>(QString(), Qt::FindDirectChildrenOnly);
0125 }
0126 
0127 bool StatusBarExtension::eventFilter(QObject *watched, QEvent *ev)
0128 {
0129     if (!GUIActivateEvent::test(ev) || !::qobject_cast<KParts::Part *>(watched)) {
0130         return QObject::eventFilter(watched, ev);
0131     }
0132 
0133     QStatusBar *sb = statusBar();
0134     if (!sb) {
0135         return QObject::eventFilter(watched, ev);
0136     }
0137 
0138     GUIActivateEvent *gae = static_cast<GUIActivateEvent *>(ev);
0139     d->m_activated = gae->activated();
0140 
0141     if (d->m_activated) {
0142         for (auto &item : d->m_statusBarItems) {
0143             item.ensureItemShown(sb);
0144         }
0145     } else {
0146         for (auto &item : d->m_statusBarItems) {
0147             item.ensureItemHidden(sb);
0148         }
0149     }
0150 
0151     return false;
0152 }
0153 
0154 QStatusBar *StatusBarExtension::statusBar() const
0155 {
0156     if (!d->m_statusBar) {
0157         KParts::Part *part = qobject_cast<KParts::Part *>(parent());
0158         QWidget *w = part ? part->widget() : nullptr;
0159         KMainWindow *mw = w ? qobject_cast<KMainWindow *>(w->topLevelWidget()) : nullptr;
0160         if (mw) {
0161             d->m_statusBar = mw->statusBar();
0162         }
0163     }
0164     return d->m_statusBar;
0165 }
0166 
0167 void StatusBarExtension::setStatusBar(QStatusBar *status)
0168 {
0169     d->m_statusBar = status;
0170 }
0171 
0172 void StatusBarExtension::addStatusBarItem(QWidget *widget, int stretch, bool permanent)
0173 {
0174     d->m_statusBarItems.append(StatusBarItem(widget, stretch, permanent));
0175     StatusBarItem &it = d->m_statusBarItems.last();
0176     QStatusBar *sb = statusBar();
0177     if (sb && d->m_activated) {
0178         it.ensureItemShown(sb);
0179     }
0180 }
0181 
0182 void StatusBarExtension::removeStatusBarItem(QWidget *widget)
0183 {
0184     QStatusBar *sb = statusBar();
0185     QList<StatusBarItem>::iterator it = d->m_statusBarItems.begin();
0186     for (; it != d->m_statusBarItems.end(); ++it) {
0187         if ((*it).widget() == widget) {
0188             if (sb) {
0189                 (*it).ensureItemHidden(sb);
0190             }
0191             d->m_statusBarItems.erase(it);
0192             return;
0193         }
0194     }
0195 
0196     qCWarning(KPARTSLOG) << "StatusBarExtension::removeStatusBarItem. Widget not found :" << widget;
0197 }
0198 
0199 #include "moc_statusbarextension.cpp"