Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / workspace / kdm / kfrontend / themer / parse.cpp
blobd06a4124cdf362344354ca2a11ff9945e3213e49
1 /*
2 * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net>
3 * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it>
4 * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org>
5 * Copyright (C) 2004,2006 by Oswald Buddenhagen <ossi@kde.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "parse.h"
24 #include <kdm_greet.h>
26 #include <QComboBox>
27 #include <QDomElement>
28 #include <QFrame>
29 #include <QLineEdit>
30 #include <QStack>
31 #include <QWidget>
33 void
34 parseSize( const QString &s, DataPoint &pt )
36 if (s.isEmpty())
37 return;
39 int p;
40 if (s == "box") { // box value
41 pt.type = DTbox;
42 pt.val = 0;
43 } else if (s == "scale") {
44 pt.type = DTscale;
45 pt.val = 0;
46 } else if ((p = s.indexOf( '%' )) >= 0) { // percent value
47 pt.type = DTpercent;
48 QString sCopy = s;
49 sCopy.remove( p, 1 );
50 pt.levels = 0;
51 while ((p = sCopy.indexOf( '^' )) >= 0) {
52 sCopy.remove( p, 1 );
53 pt.levels++;
55 sCopy.replace( ',', '.' );
56 pt.val = (int)sCopy.toDouble();
57 } else { // int value
58 pt.type = DTpixel;
59 QString sCopy = s;
60 if (sCopy.at( 0 ) == '-') {
61 sCopy.remove( 0, 1 );
62 pt.type = DTnpixel;
64 sCopy.replace( ',', '.' );
65 pt.val = (int)sCopy.toDouble();
70 static QString
71 getword( QString &rs )
73 int splitAt = rs.lastIndexOf( ' ' ) + 1;
74 QString s( rs.mid( splitAt ) );
75 rs.truncate( splitAt - 1 );
76 return s;
79 void
80 parseFont( const QString &is, FontType &ft )
82 if (is.isNull())
83 return;
84 QString rs( is.simplified() );
85 if ((ft.present = !rs.isEmpty())) {
86 QString s( getword( rs ) );
87 bool ok;
88 if (s.endsWith( "px" )) {
89 int ps = s.left( s.length() - 2 ).toInt( &ok );
90 if (ok) {
91 ft.font.setPixelSize( ps );
92 s = getword( rs );
94 } else {
95 double ps = s.toDouble( &ok );
96 if (ok) {
97 ft.font.setPointSizeF( ps );
98 s = getword( rs );
101 forever {
102 QString ss( s.toLower() );
103 if (ss == "oblique")
104 ft.font.setStyle( QFont::StyleOblique );
105 else if (ss == "italic")
106 ft.font.setStyle( QFont::StyleItalic );
107 else if (ss == "ultra-light")
108 ft.font.setWeight( 13 );
109 else if (ss == "light")
110 ft.font.setWeight( QFont::Light );
111 else if (ss == "medium")
112 ft.font.setWeight( 50 );
113 else if (ss == "semi-bold")
114 ft.font.setWeight( QFont::DemiBold );
115 else if (ss == "bold")
116 ft.font.setWeight( QFont::Bold );
117 else if (ss == "ultra-bold")
118 ft.font.setWeight( QFont::Black );
119 else if (ss == "heavy")
120 ft.font.setWeight( 99 );
121 else if (ss == "ultra-condensed")
122 ft.font.setStretch( QFont::UltraCondensed );
123 else if (ss == "extra-condensed")
124 ft.font.setStretch( QFont::ExtraCondensed );
125 else if (ss == "condensed")
126 ft.font.setStretch( QFont::Condensed );
127 else if (ss == "semi-condensed")
128 ft.font.setStretch( QFont::SemiCondensed );
129 else if (ss == "semi-expanded")
130 ft.font.setStretch( QFont::SemiExpanded );
131 else if (ss == "expanded")
132 ft.font.setStretch( QFont::Expanded );
133 else if (ss == "extra-expanded")
134 ft.font.setStretch( QFont::ExtraExpanded );
135 else if (ss == "ultra-expanded")
136 ft.font.setStretch( QFont::UltraExpanded );
137 else if (ss == "normal" || // no-op
138 ss == "small-caps" || // this and following ignored
139 ss == "not-rotated" || ss == "south" || ss == "upside-down" ||
140 ss == "north" ||
141 ss == "rotated-left" || ss == "east" ||
142 ss == "rotated-right" || ss == "west")
144 } else
145 break;
146 s = getword( rs );
148 if (!rs.isEmpty())
149 rs.append( ' ' ).append( s );
150 else
151 rs = s;
152 QStringList ffs = rs.split( QRegExp( " ?, ?" ), QString::SkipEmptyParts );
153 if (!ffs.isEmpty()) {
154 foreach (QString ff, ffs) {
155 ft.font.setFamily( ff );
156 if (ft.font.exactMatch())
157 return;
159 ft.font.setFamily( ffs.first() );
162 // don't inherit settings from parent widgets
163 ft.font.setFamily( ft.font.family() );
164 if (ft.font.pixelSize() > 0)
165 ft.font.setPixelSize( ft.font.pixelSize() );
166 else
167 ft.font.setPointSize( ft.font.pointSize() );
168 ft.font.setStyle( ft.font.style() );
169 ft.font.setStretch( ft.font.stretch() );
170 ft.font.setWeight( ft.font.weight() );
173 void
174 parseFont( const QDomElement &el, FontType &ft )
176 parseFont( el.attribute( "font", QString() ), ft );
180 bool
181 parseColor( const QString &s, const QString &a, QColor &color )
183 bool ok = false;
184 if (s.startsWith( '#' )) {
185 uint hexColor = s.mid( 1 ).toUInt( &ok, 16 );
186 if (ok) {
187 if (s.length() == 9)
188 color.setRgba( hexColor );
189 else
190 color.setRgb( hexColor );
191 } else
192 return false;
194 if (!a.isEmpty()) {
195 float fltAlpha = a.toFloat( &ok );
196 if (ok)
197 color.setAlphaF( fltAlpha );
199 return ok;
202 void
203 parseColor( const QDomElement &el, QColor &color )
205 parseColor( el.attribute( "color" ), el.attribute( "alpha" ), color );
209 static void
210 parsePalEnt( const QDomElement &el, const QString &pfx, const QString &core,
211 QPalette &pal, QPalette::ColorGroup cg, QPalette::ColorRole cr )
213 QColor col = pal.color( cg, cr );
214 if (parseColor( el.attribute( pfx + core + "-color" ),
215 el.attribute( pfx + core + "-alpha" ), col ))
216 pal.setColor( cg, cr, col );
219 static void
220 parsePalEnt( const QDomElement &el, const QString &core,
221 QPalette &pal, QPalette::ColorRole cr )
223 parsePalEnt( el, "all-", core, pal, QPalette::Active, cr );
224 parsePalEnt( el, "all-", core, pal, QPalette::Inactive, cr );
225 parsePalEnt( el, "all-", core, pal, QPalette::Disabled, cr );
226 parsePalEnt( el, QString(), core, pal, QPalette::Active, cr );
227 parsePalEnt( el, QString(), core, pal, QPalette::Inactive, cr );
228 parsePalEnt( el, "active-", core, pal, QPalette::Active, cr );
229 parsePalEnt( el, "inactive-", core, pal, QPalette::Inactive, cr );
230 parsePalEnt( el, "disabled-", core, pal, QPalette::Disabled, cr );
233 void
234 parseStyle( const QDomElement &el, StyleType &style )
236 parseFont( el, style.font );
237 parseFont( el.attribute( "edit-font", QString() ), style.editfont );
238 parsePalEnt( el, "window", style.palette, QPalette::Window );
239 parsePalEnt( el, "window-text", style.palette, QPalette::WindowText );
240 parsePalEnt( el, "base", style.palette, QPalette::Base );
241 parsePalEnt( el, "alternate-base", style.palette, QPalette::AlternateBase );
242 parsePalEnt( el, "text", style.palette, QPalette::Text );
243 parsePalEnt( el, "highlight", style.palette, QPalette::Highlight );
244 parsePalEnt( el, "highlighted-text", style.palette, QPalette::HighlightedText );
245 parsePalEnt( el, "button", style.palette, QPalette::Button );
246 parsePalEnt( el, "button-text", style.palette, QPalette::ButtonText );
247 parsePalEnt( el, "bright-text", style.palette, QPalette::BrightText );
248 QString frame = el.attribute( "frame", QString() );
249 if (!frame.isNull())
250 style.frame = frame == "true";
253 void
254 setWidgetAttribs( QWidget *widget, const StyleType &style, bool frame )
256 widget->setFont(
257 (style.editfont.present &&
258 (qobject_cast<QLineEdit *>(widget) ||
259 qobject_cast<QComboBox *>(widget) ||
260 widget->objectName() == "edit")) ?
261 style.editfont.font : style.font.font );
263 if (!frame) {
264 if (QFrame *frm = qobject_cast<QFrame *>(widget)) {
265 if ((widget->windowFlags() & Qt::WindowType_Mask) == Qt::Widget)
266 frm->setFrameStyle( QFrame::NoFrame );
267 } else if (QLineEdit *le = qobject_cast<QLineEdit *>(widget))
268 le->setFrame( false );
269 else if (QComboBox *cb = qobject_cast<QComboBox *>(widget))
270 cb->setFrame( false );
273 foreach (QObject *child, widget->children())
274 if (QWidget *cw = qobject_cast<QWidget *>(child))
275 setWidgetAttribs( cw, style, frame ||
276 (widget->testAttribute( Qt::WA_OpaquePaintEvent ) ||
277 (widget->autoFillBackground() &&
278 !widget->testAttribute( Qt::WA_NoSystemBackground ) &&
279 widget->palette().brush( widget->backgroundRole() ).isOpaque() )));
282 static QString prefix;
283 static QStack<QString> prefixes;
285 #define dbgs ((debugLevel & DEBUG_THEMING) ? QDebug( QtDebugMsg ) : kDebugDevNull())
287 QDebug
288 enter( const char *fct )
290 prefixes.push( prefix );
291 prefix.replace( '-', ' ' ).append( " |-" );
292 if (prefixes.top().isEmpty())
293 return dbgs << fct;
294 return dbgs << (qPrintable( prefixes.top() ) + 1) << fct;
297 QDebug
298 debug()
300 if (prefix.isEmpty())
301 return dbgs;
302 return dbgs << (qPrintable( prefix ) + 1);
305 QDebug
306 leave()
308 prefix[prefix.length() - 2] = '\\';
309 QString nprefix( prefix );
310 prefix = prefixes.pop();
311 return dbgs << (qPrintable( nprefix ) + 1);