mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-24 10:52:49 +00:00
169 lines
No EOL
7.4 KiB
C++
169 lines
No EOL
7.4 KiB
C++
/**
|
|
* KStyle for KDE4
|
|
* Copyright (C) 2004-2005 Maksim Orlovich <maksim@kde.org>
|
|
* Copyright (C) 2005,2006 Sandro Giessl <giessl@kde.org>
|
|
*
|
|
* Based in part on the following software:
|
|
* KStyle for KDE3
|
|
* Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org>
|
|
* Portions (C) 1998-2000 TrollTech AS
|
|
* Keramik for KDE3,
|
|
* Copyright (C) 2002 Malte Starostik <malte@kde.org>
|
|
* (C) 2002-2003 Maksim Orlovich <maksim@kde.org>
|
|
* Portions (C) 2001-2002 Karol Szwed <gallium@kde.org>
|
|
* (C) 2001-2002 Fredrik Höglund <fredrik@kde.org>
|
|
* (C) 2000 Daniel M. Duley <mosfet@kde.org>
|
|
* (C) 2000 Dirk Mueller <mueller@kde.org>
|
|
* (C) 2001 Martijn Klingens <klingens@kde.org>
|
|
* (C) 2003 Sandro Giessl <sandro@giessl.com>
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Library General Public License for more details.
|
|
*
|
|
* Many thanks to Bradley T. Hughes for the 3 button scrollbar code.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This library 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
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public License
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "kstyle.h"
|
|
|
|
#include <QtGui/QWidget>
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
static const QStyle::StyleHint SH_KCustomStyleElement = (QStyle::StyleHint)0xff000001;
|
|
static const int X_KdeBase = 0xff000000;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
KStyle::KStyle()
|
|
{
|
|
controlCounter = subElementCounter = X_KdeBase;
|
|
hintCounter = X_KdeBase+1; //sic! X_KdeBase is covered by SH_KCustomStyleElement
|
|
}
|
|
|
|
QString KStyle::defaultStyle()
|
|
{
|
|
return QString::fromLatin1("oxygen");
|
|
}
|
|
|
|
/*
|
|
Custom Style Element runtime extension:
|
|
We reserve one StyleHint to let the effective style inform widgets whether it supports certain
|
|
string based style elements.
|
|
As this could lead to number conflicts (i.e. an app utilizing one of the hints itself for other
|
|
purposes) there're various safety mechanisms to rule out such interference.
|
|
|
|
1) It's most unlikely that a widget in some 3rd party app will accidentally call a general
|
|
QStyle/KStyle styleHint() or draw*() and (unconditionally) expect a valid return, however:
|
|
a. The StyleHint is not directly above Qt's custom base, assuming most 3rd party apps would
|
|
- in case - make use of such
|
|
b. In order to be accepted, the StyleHint query must pass a widget with a perfectly matching
|
|
name, containing the typical element prefix ("CE_", etc.) and being supported by the current style
|
|
c. Instead using Qt's fragile qstyleoption_cast on the QStyleOption provided to the StyleHint
|
|
query, try to dump out a string and hope for the best, we now manipulate the widgets objectName().
|
|
Plain Qt dependent widgets can do that themselves and if a widget uses KStyle's convenience access
|
|
functions, it won't notice this at all
|
|
|
|
2) The key problem is that a common KDE widget will run into an apps custom style which will then
|
|
falsely respond to the styleHint() call with an invalid value.
|
|
To prevent this, supporting styles *must* set a Q_CLASSINFO "X-KDE-CustomElements".
|
|
|
|
3) If any of the above traps snaps, the returned id is 0 - the QStyle default, indicating
|
|
that this element is not supported by the current style.
|
|
|
|
Obviously, this contains the "diminished clean" action to (temporarily) manipulate the
|
|
objectName() of a const QWidget* - but this happens completely inside KStyle or the widget, if
|
|
it does not make use of KStyles static convenience functions.
|
|
My biggest worry here would be, that in a multithreaded environment a thread (usually not being
|
|
owner of the widget) does something crucially relying on the widgets name property...
|
|
This however would also have to happen during the widget construction or stylechanges, when
|
|
the functions in doubt will typically be called.
|
|
So this is imho unlikely causing any trouble, ever.
|
|
*/
|
|
|
|
/*
|
|
The functions called by the real style implementation to add support for a certain element.
|
|
Checks for well-formed string (containing the element prefix) and returns 0 otherwise.
|
|
Checks whether the element is already supported or inserts it otherwise; Returns the proper id
|
|
NOTICE: We could check for "X-KDE-CustomElements", but this would bloat style start up times
|
|
(if they e.g. register 100 elements or so)
|
|
*/
|
|
static inline int newStyleElement(const QString &element, const char *check, int &counter, QHash<QString, int> *elements)
|
|
{
|
|
if (!element.contains(check))
|
|
return 0;
|
|
int id = elements->value(element, 0);
|
|
if (!id) {
|
|
++counter;
|
|
id = counter;
|
|
elements->insert(element, id);
|
|
}
|
|
return id;
|
|
}
|
|
|
|
QStyle::StyleHint KStyle::newStyleHint(const QString &element)
|
|
{
|
|
return (QStyle::StyleHint)newStyleElement(element, "SH_", hintCounter, &styleElements);
|
|
}
|
|
|
|
QStyle::ControlElement KStyle::newControlElement(const QString &element)
|
|
{
|
|
return (QStyle::ControlElement)newStyleElement(element, "CE_", controlCounter, &styleElements);
|
|
}
|
|
|
|
QStyle::SubElement KStyle::newSubElement(const QString &element)
|
|
{
|
|
return (QStyle::SubElement)newStyleElement(element, "SE_", subElementCounter, &styleElements);
|
|
}
|
|
|
|
/*
|
|
The functions called by widgets that request custom element support, passed to the effective style.
|
|
Collected in a static inline function due to similarity.
|
|
*/
|
|
static inline int customStyleElement(QStyle::StyleHint type, const QString &element, QWidget *widget)
|
|
{
|
|
if (!widget || widget->style()->metaObject()->indexOfClassInfo("X-KDE-CustomElements") < 0)
|
|
return 0;
|
|
|
|
const QString originalName = widget->objectName();
|
|
widget->setObjectName(element);
|
|
const int id = widget->style()->styleHint(type, 0, widget);
|
|
widget->setObjectName(originalName);
|
|
return id;
|
|
}
|
|
|
|
QStyle::StyleHint KStyle::customStyleHint(const QString &element, const QWidget *widget)
|
|
{
|
|
return (QStyle::StyleHint) customStyleElement(SH_KCustomStyleElement, element, const_cast<QWidget*>(widget));
|
|
}
|
|
|
|
QStyle::ControlElement KStyle::customControlElement(const QString &element, const QWidget *widget)
|
|
{
|
|
return (QStyle::ControlElement) customStyleElement(SH_KCustomStyleElement, element, const_cast<QWidget*>(widget));
|
|
}
|
|
|
|
QStyle::SubElement KStyle::customSubElement(const QString &element, const QWidget *widget)
|
|
{
|
|
return (QStyle::SubElement) customStyleElement(SH_KCustomStyleElement, element, const_cast<QWidget*>(widget));
|
|
}
|
|
|
|
#include "moc_kstyle.cpp" |