Index: colors/kcolorscheme.cpp
===================================================================
--- colors/kcolorscheme.cpp     (revision 708763)
+++ colors/kcolorscheme.cpp     (working copy)
@@ -27,6 +27,7 @@

 #include <QtGui/QColor>
 #include <QtGui/QBrush>
+#include <QtGui/QWidget>

 typedef struct {
     int NormalBackground[3];
@@ -187,6 +203,7 @@
 }
 //END KColorSchemePrivate

+//BEGIN KColorScheme
 KColorScheme::KColorScheme(const KColorScheme &other) : d(other.d)
 {
 }
@@ -327,4 +344,92 @@
             return KColorUtils::darken(KColorUtils::shade(color, darkAmount, chromaAdjust), 0.5 + 0.3 * y);
     }
 }
+
+void KColorScheme::adjustBackground(QPalette &palette, BackgroundRole newRole, QPalette::ColorRole color, ColorSet set) {
+    palette.setBrush(QPalette::Active,   color, KColorScheme(QPalette::Active,   set).background(newRole));
+    palette.setBrush(QPalette::Inactive, color, KColorScheme(QPalette::Inactive, set).background(newRole));
+    palette.setBrush(QPalette::Disabled, color, KColorScheme(QPalette::Disabled, set).background(newRole));
+}
+
+void KColorScheme::adjustForeground(QPalette &palette, ForegroundRole newRole, QPalette::ColorRole color, ColorSet set) {
+    palette.setBrush(QPalette::Active,   color, KColorScheme(QPalette::Active,   set).foreground(newRole));
+    palette.setBrush(QPalette::Inactive, color, KColorScheme(QPalette::Inactive, set).foreground(newRole));
+    palette.setBrush(QPalette::Disabled, color, KColorScheme(QPalette::Disabled, set).foreground(newRole));
+}
+//END KColorScheme
+
+//BEGIN KStatefulBrush
+class KStatefulBrushPrivate : public QBrush // for now, just be a QBrush
+{
+    public:
+        KStatefulBrushPrivate() : QBrush() {}
+        KStatefulBrushPrivate(const QBrush &brush) : QBrush(brush) {} // not explicit
+};
+
+KStatefulBrush::KStatefulBrush(KColorScheme::ColorSet set, KColorScheme::ForegroundRole role,
+                               KSharedConfigPtr config)
+{
+    d = new KStatefulBrushPrivate[3];
+    d[0] = KColorScheme(QPalette::Active,   set, config).foreground(role);
+    d[1] = KColorScheme(QPalette::Disabled, set, config).foreground(role);
+    d[2] = KColorScheme(QPalette::Inactive, set, config).foreground(role);
+}
+
+KStatefulBrush::KStatefulBrush(KColorScheme::ColorSet set, KColorScheme::BackgroundRole role,
+                               KSharedConfigPtr config)
+{
+    d = new KStatefulBrushPrivate[3];
+    d[0] = KColorScheme(QPalette::Active,   set, config).background(role);
+    d[1] = KColorScheme(QPalette::Disabled, set, config).background(role);
+    d[2] = KColorScheme(QPalette::Inactive, set, config).background(role);
+}
+
+KStatefulBrush::KStatefulBrush(KColorScheme::ColorSet set, KColorScheme::DecorationRole role,
+                               KSharedConfigPtr config)
+{
+    d = new KStatefulBrushPrivate[3];
+    d[0] = KColorScheme(QPalette::Active,   set, config).decoration(role);
+    d[1] = KColorScheme(QPalette::Disabled, set, config).decoration(role);
+    d[2] = KColorScheme(QPalette::Inactive, set, config).decoration(role);
+}
+
+KStatefulBrush::KStatefulBrush(const KStatefulBrush &other)
+{
+    d = new KStatefulBrushPrivate[3];
+    d[0] = other.d[0];
+    d[1] = other.d[1];
+    d[2] = other.d[2];
+}
+
+KStatefulBrush::~KStatefulBrush()
+{
+    delete[] d;
+}
+
+QBrush KStatefulBrush::brush(QPalette::ColorGroup state) const
+{
+    switch (state) {
+        case QPalette::Inactive:
+            return d[2];
+        case QPalette::Disabled:
+            return d[1];
+        default:
+            return d[0];
+    }
+}
+
+QBrush KStatefulBrush::brush(const QPalette &pal) const
+{
+    return brush(pal.currentColorGroup());
+}
+
+QBrush KStatefulBrush::brush(const QWidget *widget) const
+{
+    if (widget)
+        return brush(widget->palette());
+    else
+        return QBrush();
+}
+//END KStatefulBrush
+
 // kate: space-indent on; indent-width 4; replace-tabs on; auto-insert-doxygen on;
Index: colors/kcolorscheme.h
===================================================================
--- colors/kcolorscheme.h       (revision 708763)
+++ colors/kcolorscheme.h       (working copy)
@@ -52,6 +52,19 @@
  * foreground for any other set. Individual colors may be quickly referenced by
  * creating an anonymous instance and invoking a lookup member.
  *
+ * @note
+ * Historically, it was not needed for applications to give much concern to the
+ * state of a widget (active, inactive, disabled) since only the disabled state
+ * was different, and only slightly. As a result, the old KGlobalSettings color
+ * getters did not care about the widget state. However, starting with KDE4,
+ * the color palettes for the various states may be wildly different.
+ * Therefore, it is important to take the state into account. This is why the
+ * KColorScheme constructor requires a QPalette::ColorGroup as an argument.
+ *
+ * To facilitate working with potentially-varying states, two convenience API's
+ * are provided. These are KColorScheme::adjustBackground and its sister
+ * KColorScheme::adjustForeground, and the helper class ::KStatefulBrush.
+ *
  * @see KColorScheme::ColorSet, KColorScheme::ForegroundRole,
  * KColorScheme::BackgroundRole, KColorScheme::DecorationRole,
  * KColorScheme::ShadeRole
@@ -271,6 +284,10 @@
     /**
      * Construct a palette from given color set and state, using the colors
      * from the given KConfig (if null, the system colors are used).
+     *
+     * @note Don't construct a KColorScheme unless you understand why you are
+     * doing so, and how you will deal with widget states (or why you don't
+     * need to). You probably want a ::KStatefulBrush instead.
      */
     explicit KColorScheme(QPalette::ColorGroup, ColorSet = View, KSharedConfigPtr = KSharedConfigPtr());

@@ -337,9 +354,97 @@
     static QColor shade(const QColor&, ShadeRole,
                         qreal contrast, qreal chromaAdjust = 0.0);

+    static void adjustBackground(QPalette &,
+                                 BackgroundRole newRole = NormalBackground,
+                                 QPalette::ColorRole color = QPalette::Base,
+                                 ColorSet set = View);
+
+    static void adjustForeground(QPalette &,
+                                 ForegroundRole newRole = NormalText,
+                                 QPalette::ColorRole color = QPalette::Text,
+                                 ColorSet set = View);
+
 private:
     QExplicitlySharedDataPointer<KColorSchemePrivate> d;
 };

+/**
+ * A container for a "state-aware" brush.
+ *
+ * KStatefulBrush provides an easy and safe way to store a color for use in a
+ * user interface. It is "safe" both in that it will make it easy to deal with
+ * widget states in a correct manner, and that it insulates you against changes
+ * in QPalette::ColorGroup.
+ *
+ * Basically, a stateful brush is used to cache a particular "color" from the
+ * KDE system palette (usually, one which does not live in QPalette) in the way
+ * you would have used a QColor in KDE3. When you are ready to draw using the
+ * brush, you use the current state to retrieve the appropriate brush.
+ *
+ * @note As of Qt 4.3, QPalette::ColorGroup is missing a state for disabled
+ * widgets in an inactive window. Hopefully Trolltech will fix this bug, at
+ * which point KColorScheme and KStatefulBrush will be updated to recognize the
+ * new state. Using KStatefulBrush will allow your application to inherit these
+ * changes "for free", without even recompiling.
+ */
+class KStatefulBrush
+{
+public:
+
+    /**
+     * Construct a stateful brush from given color set and foreground role,
+     * using the colors from the given KConfig (if null, the system colors are
+     * used).
+     */
+    explicit KStatefulBrush(KColorScheme::ColorSet,
+                            KColorScheme::ForegroundRole,
+                            KSharedConfigPtr = KSharedConfigPtr());
+
+    /**
+     * Construct a stateful brush from given color set and background role,
+     * using the colors from the given KConfig (if null, the system colors are
+     * used).
+     */
+    explicit KStatefulBrush(KColorScheme::ColorSet,
+                            KColorScheme::BackgroundRole,
+                            KSharedConfigPtr = KSharedConfigPtr());
+
+    /**
+     * Construct a stateful brush from given color set and decoration role,
+     * using the colors from the given KConfig (if null, the system colors are
+     * used).
+     */
+    explicit KStatefulBrush(KColorScheme::ColorSet,
+                            KColorScheme::DecorationRole,
+                            KSharedConfigPtr = KSharedConfigPtr());
+
+    KStatefulBrush(const KStatefulBrush&);
+    ~KStatefulBrush();
+
+    /**
+     * Retrieve the brush for the specified widget state.
+     */
+    QBrush brush(QPalette::ColorGroup) const;
+
+    /**
+     * Retrieve the brush, using a QPalette reference to determine the correct
+     * state. Use when your painting code has easy access to the QPalette that
+     * it is supposed to be using.
+     */
+    QBrush brush(const QPalette&) const;
+
+    /**
+     * Retrieve the brush, using a QPalette reference to determine the correct
+     * state. Use when you have a pointer to the widget that you are painting.
+     *
+     * @note If you pass an invalid widget, you will get a default brush (i.e.
+     * <tt>QBrush()</tt>).
+     */
+    QBrush brush(const QWidget*) const;
+
+private:
+    class KStatefulBrushPrivate *d;
+};
+
 #endif // KCOLORSCHEME_H
 // kate: space-indent on; indent-width 4; replace-tabs on; auto-insert-doxygen on;
