File indexing completed on 2024-04-28 05:26:27

0001 #include "breezetoolsareamanager.h"
0002 #include "breezepropertynames.h"
0003 
0004 #include <QMainWindow>
0005 #include <QMdiArea>
0006 #include <QMenuBar>
0007 #include <QObject>
0008 #include <QToolBar>
0009 #include <QWidget>
0010 #include <QWindow>
0011 
0012 #include <KColorUtils>
0013 
0014 const char *colorProperty = "KDE_COLOR_SCHEME_PATH";
0015 
0016 namespace Breeze
0017 {
0018 ToolsAreaManager::ToolsAreaManager(Helper *helper, QObject *parent)
0019     : QObject(parent)
0020     , _helper(helper)
0021 {
0022     if (qApp && qApp->property(colorProperty).isValid()) {
0023         auto path = qApp->property(colorProperty).toString();
0024         _config = KSharedConfig::openConfig(path);
0025     } else {
0026         _config = KSharedConfig::openConfig();
0027     }
0028     _watcher = KConfigWatcher::create(_config);
0029     connect(_watcher.data(), &KConfigWatcher::configChanged, this, &ToolsAreaManager::configUpdated);
0030     configUpdated();
0031 }
0032 
0033 ToolsAreaManager::~ToolsAreaManager()
0034 {
0035 }
0036 
0037 template<class T1, class T2>
0038 void appendIfNotAlreadyExists(T1 *list, T2 item)
0039 {
0040     for (auto listItem : *list) {
0041         if (listItem == item) {
0042             return;
0043         }
0044     }
0045     list->append(item);
0046 }
0047 
0048 void ToolsAreaManager::registerApplication(QApplication *application)
0049 {
0050     _listener = new AppListener(this);
0051     _listener->manager = this;
0052     if (application->property(colorProperty).isValid()) {
0053         auto path = application->property(colorProperty).toString();
0054         _config = KSharedConfig::openConfig(path);
0055         _watcher = KConfigWatcher::create(_config);
0056         connect(_watcher.data(), &KConfigWatcher::configChanged, this, &ToolsAreaManager::configUpdated);
0057     }
0058     application->installEventFilter(_listener);
0059     configUpdated();
0060 }
0061 
0062 QRect ToolsAreaManager::toolsAreaRect(const QMainWindow *window)
0063 {
0064     Q_ASSERT(window);
0065 
0066     int itemHeight = window->menuWidget() ? window->menuWidget()->height() : 0;
0067     for (auto item : _windows[window]) {
0068         if (!item.isNull() && item->isVisible() && window->toolBarArea(item) == Qt::TopToolBarArea) {
0069             itemHeight = qMax(item->mapTo(window, item->rect().bottomLeft()).y(), itemHeight);
0070         }
0071     }
0072     if (itemHeight > 0) {
0073         itemHeight += 1;
0074     }
0075 
0076     return QRect(0, 0, window->width(), itemHeight);
0077 }
0078 
0079 bool ToolsAreaManager::tryRegisterToolBar(QPointer<QMainWindow> window, QPointer<QWidget> widget)
0080 {
0081     Q_ASSERT(!widget.isNull());
0082 
0083     QPointer<QToolBar> toolbar;
0084     if (!(toolbar = qobject_cast<QToolBar *>(widget))) {
0085         return false;
0086     }
0087 
0088     if (window->toolBarArea(toolbar) == Qt::TopToolBarArea) {
0089         widget->setPalette(palette());
0090         appendIfNotAlreadyExists(&_windows[window], toolbar);
0091         return true;
0092     }
0093 
0094     return false;
0095 }
0096 
0097 void ToolsAreaManager::tryUnregisterToolBar(QPointer<QMainWindow> window, QPointer<QWidget> widget)
0098 {
0099     Q_ASSERT(!widget.isNull());
0100 
0101     QPointer<QToolBar> toolbar;
0102     if (!(toolbar = qobject_cast<QToolBar *>(widget))) {
0103         return;
0104     }
0105 
0106     if (window->toolBarArea(toolbar) != Qt::TopToolBarArea) {
0107         widget->setPalette(window->palette());
0108         _windows[window].removeAll(toolbar);
0109     }
0110 }
0111 
0112 void ToolsAreaManager::configUpdated()
0113 {
0114     auto active = KColorScheme(QPalette::Active, KColorScheme::Header, _config);
0115     auto inactive = KColorScheme(QPalette::Inactive, KColorScheme::Header, _config);
0116     auto disabled = KColorScheme(QPalette::Disabled, KColorScheme::Header, _config);
0117 
0118     _palette = KColorScheme::createApplicationPalette(_config);
0119 
0120     _palette.setBrush(QPalette::Active, QPalette::Window, active.background());
0121     _palette.setBrush(QPalette::Active, QPalette::WindowText, active.foreground());
0122     _palette.setBrush(QPalette::Disabled, QPalette::Window, disabled.background());
0123     _palette.setBrush(QPalette::Disabled, QPalette::WindowText, disabled.foreground());
0124     _palette.setBrush(QPalette::Inactive, QPalette::Window, inactive.background());
0125     _palette.setBrush(QPalette::Inactive, QPalette::WindowText, inactive.foreground());
0126 
0127     for (auto window : _windows) {
0128         for (auto toolbar : window) {
0129             if (!toolbar.isNull()) {
0130                 toolbar->setPalette(_palette);
0131             }
0132         }
0133     }
0134 
0135     _colorSchemeHasHeaderColor = KColorScheme::isColorSetSupported(_config, KColorScheme::Header);
0136 }
0137 
0138 bool AppListener::eventFilter(QObject *watched, QEvent *event)
0139 {
0140     Q_ASSERT(watched);
0141     Q_ASSERT(event);
0142 
0143     if (watched != qApp) {
0144         return false;
0145     }
0146 
0147     if (event->type() == QEvent::DynamicPropertyChange) {
0148         if (watched != qApp) {
0149             return false;
0150         }
0151         auto ev = static_cast<QDynamicPropertyChangeEvent *>(event);
0152         if (ev->propertyName() == colorProperty) {
0153             if (qApp && qApp->property(colorProperty).isValid()) {
0154                 auto path = qApp->property(colorProperty).toString();
0155                 manager->_config = KSharedConfig::openConfig(path);
0156             } else {
0157                 manager->_config = KSharedConfig::openConfig();
0158             }
0159             manager->_watcher = KConfigWatcher::create(manager->_config);
0160             connect(manager->_watcher.data(), &KConfigWatcher::configChanged, manager, &ToolsAreaManager::configUpdated);
0161             manager->configUpdated();
0162         }
0163     }
0164 
0165     return false;
0166 }
0167 
0168 bool ToolsAreaManager::eventFilter(QObject *watched, QEvent *event)
0169 {
0170     Q_ASSERT(watched);
0171     Q_ASSERT(event);
0172 
0173     QPointer<QObject> parent = watched;
0174     QPointer<QMainWindow> mainWindow = nullptr;
0175     while (parent != nullptr) {
0176         if (qobject_cast<QMainWindow *>(parent)) {
0177             mainWindow = qobject_cast<QMainWindow *>(parent);
0178             break;
0179         }
0180         parent = parent->parent();
0181     }
0182 
0183     if (QPointer<QMainWindow> mw = qobject_cast<QMainWindow *>(watched)) {
0184         QChildEvent *ev = nullptr;
0185         if (event->type() == QEvent::ChildAdded || event->type() == QEvent::ChildRemoved) {
0186             ev = static_cast<QChildEvent *>(event);
0187         }
0188 
0189         QPointer<QToolBar> tb = qobject_cast<QToolBar *>(ev->child());
0190         if (tb.isNull()) {
0191             return false;
0192         }
0193 
0194         if (ev->added()) {
0195             if (mw->toolBarArea(tb) == Qt::TopToolBarArea) {
0196                 appendIfNotAlreadyExists(&_windows[mw], tb);
0197             }
0198         } else if (ev->removed()) {
0199             _windows[mw].removeAll(tb);
0200         }
0201     } else if (qobject_cast<QToolBar *>(watched)) {
0202         if (!mainWindow.isNull()) {
0203             tryUnregisterToolBar(mainWindow, qobject_cast<QWidget *>(watched));
0204         }
0205     }
0206 
0207     return false;
0208 }
0209 
0210 void ToolsAreaManager::registerWidget(QWidget *widget)
0211 {
0212     Q_ASSERT(widget);
0213     auto ptr = QPointer<QWidget>(widget);
0214 
0215     auto parent = ptr;
0216     QPointer<QMainWindow> mainWindow = nullptr;
0217     while (parent != nullptr) {
0218         if (qobject_cast<QMdiArea *>(parent) || qobject_cast<QDockWidget *>(parent)) {
0219             break;
0220         }
0221         if (qobject_cast<QMainWindow *>(parent)) {
0222             mainWindow = qobject_cast<QMainWindow *>(parent);
0223         }
0224         parent = parent->parentWidget();
0225     }
0226     if (mainWindow == nullptr) {
0227         return;
0228     }
0229     if (mainWindow != mainWindow->window()) {
0230         return;
0231     }
0232     tryRegisterToolBar(mainWindow, widget);
0233 }
0234 
0235 void ToolsAreaManager::unregisterWidget(QWidget *widget)
0236 {
0237     Q_ASSERT(widget);
0238     auto ptr = QPointer<QWidget>(widget);
0239 
0240     if (QPointer<QMainWindow> window = qobject_cast<QMainWindow *>(ptr)) {
0241         _windows.remove(window);
0242         return;
0243     } else if (QPointer<QToolBar> toolbar = qobject_cast<QToolBar *>(ptr)) {
0244         auto parent = ptr;
0245         QPointer<QMainWindow> mainWindow = nullptr;
0246         while (parent != nullptr) {
0247             if (qobject_cast<QMainWindow *>(parent)) {
0248                 mainWindow = qobject_cast<QMainWindow *>(parent);
0249                 break;
0250             }
0251             parent = parent->parentWidget();
0252         }
0253         if (mainWindow == nullptr) {
0254             return;
0255         }
0256         _windows[mainWindow].removeAll(toolbar);
0257     }
0258 }
0259 
0260 bool Breeze::ToolsAreaManager::hasHeaderColors()
0261 {
0262     return _colorSchemeHasHeaderColor;
0263 }
0264 }