#include "breezetoolsareamanager.h" #include "breezepropertynames.h" #include #include #include #include #include #include #include #include const char *colorProperty = "KDE_COLOR_SCHEME_PATH"; namespace Breeze { ToolsAreaManager::ToolsAreaManager() : QObject() { QString path; if (qApp && qApp->property(colorProperty).isValid()) { path = qApp->property(colorProperty).toString(); } recreateConfigWatcher(path); configUpdated(); } ToolsAreaManager::~ToolsAreaManager() { } void ToolsAreaManager::recreateConfigWatcher(const QString &path) { _config = KSharedConfig::openConfig(path); if (!path.startsWith(QLatin1Char('/'))) { _watcher = KConfigWatcher::create(_config); connect(_watcher.data(), &KConfigWatcher::configChanged, this, &ToolsAreaManager::configUpdated); } else { _watcher.reset(); } } template void appendIfNotAlreadyExists(T1 *list, T2 item) { for (auto listItem : *list) { if (listItem == item) { return; } } list->append(item); } void ToolsAreaManager::registerApplication(QApplication *application) { _listener = new AppListener(this); _listener->manager = this; if (application->property(colorProperty).isValid()) { auto path = application->property(colorProperty).toString(); recreateConfigWatcher(path); } application->installEventFilter(_listener); configUpdated(); } QRect ToolsAreaManager::toolsAreaRect(const QMainWindow *window) { Q_ASSERT(window); int itemHeight = window->menuWidget() ? window->menuWidget()->height() : 0; for (auto item : _windows[window]) { if (!item.isNull() && item->isVisible() && window->toolBarArea(item) == Qt::TopToolBarArea) { itemHeight = qMax(item->mapTo(window, item->rect().bottomLeft()).y(), itemHeight); } } if (itemHeight > 0) { itemHeight += 1; } return QRect(0, 0, window->width(), itemHeight); } bool ToolsAreaManager::tryRegisterToolBar(QPointer window, QPointer widget) { Q_ASSERT(!widget.isNull()); QPointer toolbar; if (!(toolbar = qobject_cast(widget))) { return false; } if (window->toolBarArea(toolbar) == Qt::TopToolBarArea) { widget->setPalette(palette()); appendIfNotAlreadyExists(&_windows[window], toolbar); return true; } return false; } void ToolsAreaManager::tryUnregisterToolBar(QPointer window, QPointer widget) { Q_ASSERT(!widget.isNull()); QPointer toolbar; if (!(toolbar = qobject_cast(widget))) { return; } if (window->toolBarArea(toolbar) != Qt::TopToolBarArea) { widget->setPalette(window->palette()); _windows[window].removeAll(toolbar); } } void ToolsAreaManager::configUpdated() { auto active = KColorScheme(QPalette::Active, KColorScheme::Header, _config); auto inactive = KColorScheme(QPalette::Inactive, KColorScheme::Header, _config); auto disabled = KColorScheme(QPalette::Disabled, KColorScheme::Header, _config); _palette = KColorScheme::createApplicationPalette(_config); _palette.setBrush(QPalette::Active, QPalette::Window, active.background()); _palette.setBrush(QPalette::Active, QPalette::WindowText, active.foreground()); _palette.setBrush(QPalette::Disabled, QPalette::Window, disabled.background()); _palette.setBrush(QPalette::Disabled, QPalette::WindowText, disabled.foreground()); _palette.setBrush(QPalette::Inactive, QPalette::Window, inactive.background()); _palette.setBrush(QPalette::Inactive, QPalette::WindowText, inactive.foreground()); for (auto window : _windows) { for (auto toolbar : window) { if (!toolbar.isNull()) { toolbar->setPalette(_palette); } } } _colorSchemeHasHeaderColor = KColorScheme::isColorSetSupported(_config, KColorScheme::Header); } bool AppListener::eventFilter(QObject *watched, QEvent *event) { Q_ASSERT(watched); Q_ASSERT(event); if (watched != qApp) { return false; } if (event->type() == QEvent::DynamicPropertyChange) { if (watched != qApp) { return false; } auto ev = static_cast(event); if (ev->propertyName() == colorProperty) { QString path; if (qApp && qApp->property(colorProperty).isValid()) { path = qApp->property(colorProperty).toString(); } manager->recreateConfigWatcher(path); manager->configUpdated(); } } return false; } bool ToolsAreaManager::eventFilter(QObject *watched, QEvent *event) { Q_ASSERT(watched); Q_ASSERT(event); QPointer parent = watched; QPointer mainWindow = nullptr; while (parent != nullptr) { if (qobject_cast(parent)) { mainWindow = qobject_cast(parent); break; } parent = parent->parent(); } if (QPointer mw = qobject_cast(watched)) { QChildEvent *ev = nullptr; if (event->type() == QEvent::ChildAdded || event->type() == QEvent::ChildRemoved) { ev = static_cast(event); } else { return false; } QPointer tb = qobject_cast(ev->child()); if (tb.isNull()) { return false; } if (ev->added()) { if (mw->toolBarArea(tb) == Qt::TopToolBarArea) { appendIfNotAlreadyExists(&_windows[mw], tb); } } else if (ev->removed()) { _windows[mw].removeAll(tb); } } else if (qobject_cast(watched)) { if (!mainWindow.isNull()) { tryUnregisterToolBar(mainWindow, qobject_cast(watched)); } } return false; } void ToolsAreaManager::registerWidget(QWidget *widget) { Q_ASSERT(widget); auto ptr = QPointer(widget); QPointer mainWindow = qobject_cast(ptr); if (mainWindow && mainWindow == mainWindow->window()) { const auto toolBars = mainWindow->findChildren(QString(), Qt::FindDirectChildrenOnly); for (auto *toolBar : toolBars) { tryRegisterToolBar(mainWindow, toolBar); } return; } auto parent = ptr; while (parent != nullptr) { if (qobject_cast(parent) || qobject_cast(parent)) { break; } if (auto window = qobject_cast(parent)) { mainWindow = window; } parent = parent->parentWidget(); } if (mainWindow == nullptr) { return; } if (mainWindow != mainWindow->window()) { return; } tryRegisterToolBar(mainWindow, widget); } void ToolsAreaManager::unregisterWidget(QWidget *widget) { Q_ASSERT(widget); auto ptr = QPointer(widget); if (QPointer window = qobject_cast(ptr)) { _windows.remove(window); return; } else if (QPointer toolbar = qobject_cast(ptr)) { auto parent = ptr; QPointer mainWindow = nullptr; while (parent != nullptr) { if (qobject_cast(parent)) { mainWindow = qobject_cast(parent); break; } parent = parent->parentWidget(); } if (mainWindow == nullptr) { return; } _windows[mainWindow].removeAll(toolbar); } } bool Breeze::ToolsAreaManager::hasHeaderColors() { return _colorSchemeHasHeaderColor; } }