Remove more Gtk hacks

This commit is contained in:
Craig Drummond
2017-05-24 17:59:05 +01:00
committed by Craig Drummond
parent 388cab137d
commit 7d8e7323a3
15 changed files with 22 additions and 416 deletions

View File

@@ -23,6 +23,7 @@
#include "application.h"
#include "settings.h"
#include "support/proxystyle.h"
#include "models/mpdlibrarymodel.h"
#include "support/utils.h"
#include "mpd-interface/mpdstats.h"
@@ -37,8 +38,16 @@
#include "http/httpserver.h"
#include "config.h"
void Application::initObjects()
void Application::init()
{
#if defined Q_OS_WIN
qApp->setStyle(new ProxyStyle(ProxyStyle::VF_Side));
#elif defined Q_OS_MAC
qApp->setStyle(new ProxyStyle(ProxyStyle::VF_Side|ProxyStyle::VF_Top));
#else
qApp->setStyle(new ProxyStyle(0));
#endif
// Ensure these objects are created in the GUI thread...
ThreadCleaner::self();
MPDStatus::self();

View File

@@ -29,7 +29,7 @@
class Application : public SingleApplication
{
public:
static void initObjects();
static void init();
Application(int &argc, char **argv);
virtual ~Application() { };
};

View File

@@ -28,7 +28,7 @@
class Application : public QApplication
{
public:
static void initObjects();
static void init();
Application(int &argc, char **argv);
virtual ~Application() { }

View File

@@ -30,7 +30,7 @@
class Application : public SingleApplication, public QAbstractNativeEventFilter
{
public:
static void initObjects();
static void init();
Application(int &argc, char **argv);
virtual ~Application() { }
bool nativeEventFilter(const QByteArray &, void *message, long *result);

View File

@@ -270,7 +270,7 @@ int main(int argc, char *argv[])
#endif
loadTranslation("cantata", CANTATA_SYS_TRANS_DIR, lang);
Application::initObjects();
Application::init();
if (Settings::self()->firstRun()) {
InitialSettingsWizard wz;

View File

@@ -229,8 +229,6 @@ void MainWindow::init()
}
#endif
GtkStyle::applyTheme();
UNITY_MENU_ICON_CHECK
toolbar->ensurePolished();

View File

@@ -22,10 +22,6 @@ endif ()
set(SUPPORT_MOC_HDRS ${SUPPORT_MOC_HDRS} combobox.h)
if (NOT WIN32 AND NOT APPLE)
set(SUPPORT_SRCS ${SUPPORT_SRCS} gtkproxystyle.cpp shortcuthandler.cpp)
set(SUPPORT_MOC_HDRS ${SUPPORT_MOC_HDRS} shortcuthandler.h)
endif ()
if (APPLE)
set(SUPPORT_SRCS ${SUPPORT_SRCS} osxstyle.cpp flattoolbutton.cpp windowmanager.cpp)
set(SUPPORT_MOC_HDRS ${SUPPORT_MOC_HDRS} osxstyle.h windowmanager.h)

View File

@@ -1,98 +0,0 @@
/*
* Cantata
*
* Copyright (c) 2011-2017 Craig Drummond <craig.p.drummond@gmail.com>
*
* ----
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "gtkproxystyle.h"
#include "gtkstyle.h"
#include "shortcuthandler.h"
#include "acceleratormanager.h"
#include <QSpinBox>
#include <QAbstractScrollArea>
#include <QAbstractItemView>
#include <QMenu>
#include <QToolBar>
#include <QApplication>
#include <QPainter>
static const char * constAccelProp="catata-accel";
static inline void addEventFilter(QObject *object, QObject *filter)
{
object->removeEventFilter(filter);
object->installEventFilter(filter);
}
GtkProxyStyle::GtkProxyStyle(int modView)
: ProxyStyle(modView)
{
shortcutHander=new ShortcutHandler(this);
setBaseStyle(qApp->style());
}
GtkProxyStyle::~GtkProxyStyle()
{
}
int GtkProxyStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const
{
switch (hint) {
case SH_DialogButtonBox_ButtonsHaveIcons:
return false;
case SH_UnderlineShortcut:
return widget ? shortcutHander->showShortcut(widget) : true;
default:
break;
}
return ProxyStyle::styleHint(hint, option, widget, returnData);
}
void GtkProxyStyle::polish(QWidget *widget)
{
if (widget && qobject_cast<QMenu *>(widget) && !widget->property(constAccelProp).isValid()) {
AcceleratorManager::manage(widget);
widget->setProperty(constAccelProp, true);
}
ProxyStyle::polish(widget);
}
void GtkProxyStyle::polish(QPalette &pal)
{
ProxyStyle::polish(pal);
}
void GtkProxyStyle::polish(QApplication *app)
{
addEventFilter(app, shortcutHander);
ProxyStyle::polish(app);
}
void GtkProxyStyle::unpolish(QWidget *widget)
{
ProxyStyle::unpolish(widget);
}
void GtkProxyStyle::unpolish(QApplication *app)
{
app->removeEventFilter(shortcutHander);
ProxyStyle::unpolish(app);
}

View File

@@ -1,49 +0,0 @@
/*
* Cantata
*
* Copyright (c) 2011-2017 Craig Drummond <craig.p.drummond@gmail.com>
*
* ----
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef GTKPROXYSTYLE_H
#define GTKPROXYSTYLE_H
#include "config.h"
#include "proxystyle.h"
class ShortcutHandler;
class GtkProxyStyle : public ProxyStyle
{
public:
GtkProxyStyle(int modView);
~GtkProxyStyle();
int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const;
void polish(QWidget *widget);
void polish(QPalette &pal);
void polish(QApplication *app);
void unpolish(QWidget *widget);
void unpolish(QApplication *app);
private:
ShortcutHandler *shortcutHander;
};
#endif

View File

@@ -37,15 +37,10 @@
#define NO_GTK_SUPPORT
#endif
#ifndef NO_GTK_SUPPORT
#include "gtkproxystyle.h"
#endif
static bool usingGtkStyle=false;
bool GtkStyle::isActive()
{
#ifndef NO_GTK_SUPPORT
static bool usingGtkStyle=false;
#if defined Q_OS_WIN || defined Q_OS_MAC || defined QT_NO_STYLE_GTK
static bool init=false;
if (!init) {
init=true;
@@ -100,27 +95,4 @@ void GtkStyle::drawSelection(const QStyleOptionViewItem &opt, QPainter *painter,
painter->setOpacity(opacityB4);
}
// This function should probably be moved somewhere more appropriate!
void GtkStyle::applyTheme()
{
QProxyStyle *proxyStyle=0;
#ifndef NO_GTK_SUPPORT
if (isActive() && !proxyStyle) {
proxyStyle=new GtkProxyStyle(0);
}
#endif
#if defined Q_OS_WIN
int modViewFrame=ProxyStyle::VF_Side;
#elif defined Q_OS_MAC
int modViewFrame=ProxyStyle::VF_Side|ProxyStyle::VF_Top;
#else
int modViewFrame=0;
#endif
if (!proxyStyle) {
proxyStyle=new ProxyStyle(modViewFrame);
}
qApp->setStyle(proxyStyle);
}

View File

@@ -34,7 +34,6 @@ namespace GtkStyle
{
extern bool isActive();
extern void drawSelection(const QStyleOptionViewItem &opt, QPainter *painter, double opacity);
extern void applyTheme();
}
#endif

View File

@@ -55,6 +55,11 @@ void ProxyStyle::polish(QWidget *widget)
baseStyle()->polish(widget);
}
int ProxyStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const
{
return SH_DialogButtonBox_ButtonsHaveIcons == hint ? false : baseStyle()->styleHint(hint, option, widget, returnData);
}
void ProxyStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
baseStyle()->drawPrimitive(element, option, painter, widget);

View File

@@ -45,6 +45,7 @@ public:
void polish(QPalette &pal) { QProxyStyle::polish(pal); }
void polish(QApplication *app) { QProxyStyle::polish(app); }
void polish(QWidget *widget);
int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const;
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const;
#if !defined Q_OS_WIN && !defined Q_OS_MAC
QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt, const QWidget *widget) const;

View File

@@ -1,168 +0,0 @@
/*
* Cantata
*
* Copyright (c) 2011-2017 Craig Drummond <craig.p.drummond@gmail.com>
*
* ----
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "shortcuthandler.h"
#include <QMenu>
#include <QMenuBar>
#include <QEvent>
#include <QKeyEvent>
ShortcutHandler::ShortcutHandler(QObject *parent)
: QObject(parent)
, altDown(false)
{
}
ShortcutHandler::~ShortcutHandler()
{
}
bool ShortcutHandler::hasSeenAlt(const QWidget *widget) const
{
if (widget && !widget->isEnabled()) {
return false;
}
if (qobject_cast<const QMenu *>(widget)) {
return openMenus.count() && openMenus.last()==widget;
} else {
return openMenus.isEmpty() && seenAlt.contains(static_cast<QWidget *>(widget->window()));
}
}
bool ShortcutHandler::showShortcut(const QWidget *widget) const
{
return altDown && hasSeenAlt(widget);
}
void ShortcutHandler::widgetDestroyed(QObject *o)
{
updated.remove(static_cast<QWidget *>(o));
openMenus.removeAll(static_cast<QWidget *>(o));
}
void ShortcutHandler::updateWidget(QWidget *w)
{
if (!updated.contains(w)) {
updated.insert(w);
w->update();
connect(w, SIGNAL(destroyed(QObject *)), this, SLOT(widgetDestroyed(QObject *)));
}
}
bool ShortcutHandler::eventFilter(QObject *o, QEvent *e)
{
if (!o->isWidgetType()) {
return QObject::eventFilter(o, e);
}
QWidget *widget = qobject_cast<QWidget*>(o);
switch(e->type()) {
case QEvent::KeyPress:
if (Qt::Key_Alt==static_cast<QKeyEvent *>(e)->key()) {
altDown = true;
if (qobject_cast<QMenu *>(widget)) {
seenAlt.insert(widget);
updateWidget(widget);
if (widget->parentWidget() && widget->parentWidget()->window()) {
seenAlt.insert(widget->parentWidget()->window());
}
} else {
widget = widget->window();
seenAlt.insert(widget);
QList<QWidget *> l = widget->findChildren<QWidget*>();
for (int pos=0 ; pos < l.size() ; ++pos) {
QWidget *w = l.at(pos);
if (!(w->isWindow() || !w->isVisible())) { // || w->style()->styleHint(QStyle::SH_UnderlineShortcut, 0, w)))
updateWidget(w);
}
}
QList<QMenuBar *> m = widget->findChildren<QMenuBar*>();
for (int i = 0; i < m.size(); ++i) {
updateWidget(m.at(i));
}
}
}
break;
case QEvent::WindowDeactivate:
case QEvent::KeyRelease:
if (QEvent::WindowDeactivate==e->type() || Qt::Key_Alt==static_cast<QKeyEvent*>(e)->key()) {
altDown = false;
QSet<QWidget *>::ConstIterator it(updated.constBegin());
QSet<QWidget *>::ConstIterator end(updated.constEnd());
for (; it!=end; ++it) {
(*it)->update();
}
if (!updated.contains(widget)) {
widget->update();
}
seenAlt.clear();
updated.clear();
}
break;
case QEvent::Show:
if (qobject_cast<QMenu *>(widget)) {
QWidget *prev=openMenus.count() ? openMenus.last() : 0L;
openMenus.append(widget);
if(altDown && prev) {
prev->update();
}
connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(widgetDestroyed(QObject *)));
}
break;
case QEvent::Hide:
if (qobject_cast<QMenu *>(widget)) {
seenAlt.remove(widget);
updated.remove(widget);
openMenus.removeAll(widget);
if (altDown) {
if (openMenus.count()) {
openMenus.last()->update();
} else if(widget->parentWidget() && widget->parentWidget()->window()) {
widget->parentWidget()->window()->update();
}
}
}
break;
case QEvent::Close:
// Reset widget when closing
seenAlt.remove(widget);
updated.remove(widget);
seenAlt.remove(widget->window());
openMenus.removeAll(widget);
if (altDown) {
if(openMenus.count()) {
openMenus.last()->update();
} else if(widget->parentWidget() && widget->parentWidget()->window()) {
widget->parentWidget()->window()->update();
}
}
break;
default:
break;
}
return QObject::eventFilter(o, e);
}

View File

@@ -1,59 +0,0 @@
#ifndef __SHORTCUT_HANDLER_H__
#define __SHORTCUT_HANDLER_H__
/*
* Cantata
*
* Copyright (c) 2011-2017 Craig Drummond <craig.p.drummond@gmail.com>
*
* ----
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QObject>
#include <QSet>
#include <QList>
class QWidget;
class ShortcutHandler : public QObject
{
Q_OBJECT
public:
explicit ShortcutHandler(QObject *parent = 0);
virtual ~ShortcutHandler();
bool hasSeenAlt(const QWidget *widget) const;
bool isAltDown() const { return altDown; }
bool showShortcut(const QWidget *widget) const;
private Q_SLOTS:
void widgetDestroyed(QObject *o);
protected:
void updateWidget(QWidget *w);
bool eventFilter(QObject *watched, QEvent *event);
private:
bool altDown;
QSet<QWidget *> seenAlt;
QSet<QWidget *> updated;
QList<QWidget *> openMenus;
};
#endif