Mercurial > hg > svapp
view style/AppEventFilter.cpp @ 668:dac3781826da thorn-cpp
Experimental branch based on Thorn C++ code from RG
author | Chris Cannam |
---|---|
date | Tue, 30 Apr 2019 11:36:38 +0100 |
parents | |
children |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* Vect An experimental audio player for plural recordings of a work Centre for Digital Music, Queen Mary, University of London. This file is taken from Rosegarden, a MIDI and audio sequencer and musical notation editor. Copyright 2000-2018 the Rosegarden development team. Thorn style developed in stylesheet form by D. Michael McIntyre and reimplemented as a class by David Faure. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING included with this distribution for more information. */ #include "ThornStyle.h" #include "AppEventFilter.h" #include <QApplication> #include <QFileDialog> #include <QAbstractItemView> #include <QCheckBox> #include <QLabel> #include <QRadioButton> #include <QToolBar> #include <QWidget> #include <QDialogButtonBox> #include <QPushButton> #include <QComboBox> #include <QSpinBox> // Apply the style to widget and its children, recursively // Even though every widget goes through the event filter, this is needed // for the case where a whole widget hierarchy is suddenly reparented into the file dialog. // Then we need to apply the app style again. Testcase: scrollbars in file dialog. static void applyStyleRecursive(QWidget* widget, QStyle *style) { if (widget->style() != style) { widget->setStyle(style); } foreach (QObject* obj, widget->children()) { if (obj->isWidgetType()) { QWidget *w = static_cast<QWidget *>(obj); applyStyleRecursive(w, style); } } } AppEventFilter::AppEventFilter() : m_systemPalette(qApp->palette()), m_systemStyle(qApp->style()) { } bool AppEventFilter::shouldIgnoreThornStyle(QWidget *widget) const { return qobject_cast<QFileDialog *>(widget) || widget->inherits("KDEPlatformFileDialog") || widget->inherits("KDirSelectDialog"); } // when we ditch Qt4, we can switch to qCDebug... //#define DEBUG_EVENTFILTER bool AppEventFilter::eventFilter(QObject *watched, QEvent *event) { static bool s_insidePolish = false; // setStyle calls polish again, so skip doing the work twice if (!s_insidePolish && watched->isWidgetType() && event->type() == QEvent::Polish) { s_insidePolish = true; // This is called after every widget is created and just before being shown // (we use this so that it has a proper parent widget already) QWidget *widget = static_cast<QWidget *>(watched); if (shouldIgnoreThornStyle(widget)) { // The palette from the mainwindow propagated to the dialog, restore it. widget->setPalette(m_systemPalette); #ifdef DEBUG_EVENTFILTER qDebug() << widget << "now using app style (recursive)"; #endif applyStyleRecursive(widget, qApp->style()); s_insidePolish = false; return false; } QWidget *toplevel = widget->window(); #ifdef DEBUG_EVENTFILTER qDebug() << widget << "current widget style=" << widget->style() << "shouldignore=" << shouldIgnoreThornStyle(toplevel); #endif if (shouldIgnoreThornStyle(toplevel)) { // Here we should apply qApp->style() recursively on widget and its children, in case one was reparented #ifdef DEBUG_EVENTFILTER qDebug() << widget << widget->objectName() << "in" << toplevel << "now using app style (recursive)"; #endif applyStyleRecursive(widget, qApp->style()); } else if (widget->style() != &m_style) { #ifdef DEBUG_EVENTFILTER //qDebug() << " ToolTipBase=" << widget->palette().color(QPalette::ToolTipBase).name(); #endif // Apply style recursively because some child widgets (e.g. QHeaderView in QTreeWidget, in DeviceManagerDialog) don't seem to get here. if (qobject_cast<QAbstractItemView *>(widget)) { applyStyleRecursive(widget, &m_style); } else { widget->setStyle(&m_style); } #ifdef DEBUG_EVENTFILTER qDebug() << " now using style" << widget->style(); #endif if (widget->windowType() != Qt::Widget) { // window, tooltip, ... widget->setPalette(m_style.standardPalette()); #ifdef DEBUG_EVENTFILTER qDebug() << " after setPalette: ToolTipBase=" << widget->palette().color(QPalette::ToolTipBase).name(); #endif } else { #ifdef DEBUG_EVENTFILTER //qDebug() << " not a toplevel. ToolTipBase=" << widget->palette().color(QPalette::ToolTipBase).name(); #endif } polishWidget(widget); } s_insidePolish = false; } return false; // don't eat the event } void AppEventFilter::polishWidget(QWidget *widget) { if (QLabel *label = qobject_cast<QLabel *>(widget)) { if (qobject_cast<QToolBar *>(widget->parentWidget())) { /* Toolbars must be light enough for black icons, therefore black text on their QLabels, rather than white, is more appropriate. QToolBar QLabel { color: #000000; } */ QPalette pal = label->palette(); pal.setColor(label->foregroundRole(), Qt::black); label->setPalette(pal); //qDebug() << "made label black:" << label << label->text(); } if (widget->objectName() == "SPECIAL_LABEL") { widget->setAutoFillBackground(true); // QWidget#SPECIAL_LABEL { color: #000000; background-color: #999999; } QPalette palette = widget->palette(); palette.setColor(QPalette::WindowText, Qt::black); palette.setColor(QPalette::Window, QColor(0x99, 0x99, 0x99)); widget->setPalette(palette); } } else if (widget->objectName() == "Rosegarden Transport") { // Give the non-LED parts of the dialog the groupbox "lighter black" // background for improved contrast. QPalette transportPalette = widget->palette(); transportPalette.setColor(widget->backgroundRole(), QColor(0x40, 0x40, 0x40)); widget->setPalette(transportPalette); widget->setAutoFillBackground(true); } else if (QCheckBox *cb = qobject_cast<QCheckBox *>(widget)) { cb->setAttribute(Qt::WA_Hover); } else if (QRadioButton *rb = qobject_cast<QRadioButton *>(widget)) { rb->setAttribute(Qt::WA_Hover); } else if (QPushButton *pb = qobject_cast<QPushButton *>(widget)) { pb->setAttribute(Qt::WA_Hover); if (qobject_cast<QDialogButtonBox *>(widget->parentWidget())) { // Bug in QDialogButtonBox: if the app style sets QStyle::SH_DialogButtonBox_ButtonsHaveIcons // a later call to setStyle() doesn't remove the button icon again. // Fix submitted at https://codereview.qt-project.org/183788 pb->setIcon(QIcon()); } } else if (QComboBox *cb = qobject_cast<QComboBox *>(widget)) { cb->setAttribute(Qt::WA_Hover); } else if (QAbstractSpinBox *sb = qobject_cast<QAbstractSpinBox *>(widget)) { sb->setAttribute(Qt::WA_Hover); } }