26 #define YUILogComponent "qt-styler"
27 #include <yui/YUILog.h>
28 #include <yui/YUIException.h>
29 #include <yui/Libyui_config.h>
30 #include <YSettings.h>
32 #include "QY2Styler.h"
36 #include <QStringList>
37 #include <QApplication>
40 #include <QSvgRenderer>
42 #include <QPixmapCache>
44 #define LOGGING_CAUSES_QT4_THREADING_PROBLEMS 1
46 std::ostream & operator<<( std::ostream & stream,
const QString & str );
47 std::ostream & operator<<( std::ostream & stream,
const QStringList & strList );
48 std::ostream & operator<<( std::ostream & stream,
const QWidget * widget );
56 QPixmapCache::setCacheLimit( 5 * 1024 );
57 yuiDebug() <<
"Styler created" << std::endl;
68 yuiDebug() <<
"Creating QY2Styler singleton" << std::endl;
71 YUI_CHECK_NEW( styler );
73 QString style = getenv(
"Y2STYLE");
75 if ( ! style.isEmpty() )
76 styler->loadStyleSheet( style );
78 styler->loadStyleSheet(
"style.qss" );
85 void QY2Styler::loadStyleSheet(
const QString & filename )
87 QFile file( themeDir() + filename );
89 if ( file.open( QIODevice::ReadOnly ) )
91 yuiMilestone() <<
"Using style sheet \"" << file.fileName() <<
"\"" << std::endl;
92 QString text = file.readAll();
93 setStyleSheet( text );
97 yuiMilestone() <<
"Couldn't open style sheet \"" << file.fileName() <<
"\"" << std::endl;
102 void QY2Styler::setStyleSheet(
const QString & text )
108 QList< QWidget* > childlist;
110 foreach( childlist, _children )
111 foreach( child, childlist )
112 child->setStyleSheet( _style );
119 QStringList lines = text.split(
'\n' );
120 QRegExp urlRegex(
": *url\\((.*)\\)" );
121 QRegExp backgroundRegex(
"^ */\\* *Background: *([^ ]*) *([^ ]*) *\\*/$" );
122 QRegExp richTextRegex(
"^ */\\* *Richtext: *([^ ]*) *\\*/$" );
124 _backgrounds.clear();
126 for ( QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it )
132 if ( urlRegex.indexIn( line ) >= 0 )
134 QString fileName = urlRegex.cap( 1 );
135 QString fullPath = themeDir() + fileName;
136 yuiDebug() <<
"Expanding " << fileName <<
"\tto " << fullPath << std::endl;
137 line.replace( urlRegex,
": url(" + fullPath +
")");
140 if ( backgroundRegex.exactMatch( line ) )
142 QStringList name = backgroundRegex.cap( 1 ).split(
'#' );
143 QString fullPath = themeDir() + backgroundRegex.cap( 2 );
144 yuiDebug() <<
"Expanding background " << name[0] <<
"\tto " << fullPath << std::endl;
146 _backgrounds[ name[0] ].filename = fullPath;
147 _backgrounds[ name[0] ].full =
false;
149 if ( name.size() > 1 )
150 _backgrounds[ name[0] ].full = ( name[1] ==
"full" );
153 if ( richTextRegex.exactMatch( line ) )
155 QString filename = richTextRegex.cap( 1 );
156 QFile file( themeDir() +
"/" + filename );
158 if ( file.open( QIODevice::ReadOnly ) )
160 yuiDebug() <<
"Reading " << file.fileName();
161 _textStyle = file.readAll();
165 yuiError() <<
"Can't read " << file.fileName();
177 QY2Styler::themeDir()
const
179 return QString(YSettings::themeDir().c_str());
183 void QY2Styler::registerWidget( QWidget * widget )
185 widget->installEventFilter(
this );
186 widget->setAutoFillBackground(
true );
187 widget->setStyleSheet( _style );
191 void QY2Styler::unregisterWidget( QWidget *widget )
193 _children.remove( widget );
197 void QY2Styler::registerChildWidget( QWidget * parent, QWidget * widget )
201 qDebug() <<
"Registering " << widget <<
" for parent " << parent << endl;
202 widget->installEventFilter(
this );
203 _children[parent].push_back( widget );
208 QY2Styler::getScaled(
const QString name,
const QSize & size )
210 QImage image = _backgrounds[name].pix;
212 if ( size != image.size() )
213 image = image.scaled( size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
215 image = image.convertToFormat( QImage::Format_ARGB32 );
217 if ( image.isNull() )
218 yuiError() <<
"Can't load pixmap from " << name << std::endl;
221 yuiMilestone() <<
"Loaded pixmap from \"" << name
222 <<
"\" size: " << image.size().width() <<
"x" << image.size().height()
230 void QY2Styler::renderParent( QWidget * wid )
233 QString name = wid->objectName();
236 wid->setPalette( QApplication::palette() );
239 if ( _backgrounds[name].pix.isNull() )
242 QRect fillRect = wid->contentsRect();
243 if ( _backgrounds[name].full )
244 fillRect = wid->rect();
248 if ( _backgrounds[name].lastscale != fillRect.size() )
250 _backgrounds[name].scaled = getScaled( name, fillRect.size() );
251 _backgrounds[name].lastscale = fillRect.size();
254 back = _backgrounds[name].scaled;
256 QPainter pain( &back );
260 foreach( child, _children[wid] )
263 QString name = child->objectName();
265 if (! child->isVisible() || _backgrounds[name].pix.isNull() )
268 QRect fillRect = child->contentsRect();
269 if ( _backgrounds[name].full )
270 fillRect = child->rect();
272 QString key = QString(
"style_%1_%2_%3" ).arg( name ).arg( fillRect.width() ).arg( fillRect.height() );
275 if ( QPixmapCache::find( key, scaled ) )
281 scaled = QPixmap::fromImage( getScaled( name, fillRect.size() ) );
282 QPixmapCache::insert( key, scaled );
284 pain.drawPixmap( wid->mapFromGlobal( child->mapToGlobal( fillRect.topLeft() ) ), scaled );
287 QPixmap result = QPixmap::fromImage( back );
289 QPalette p = wid->palette();
290 p.setBrush(QPalette::Window, result );
291 wid->setPalette( p );
296 QY2Styler::updateRendering( QWidget *wid )
301 QString name = wid->objectName();
303 if (! wid->isVisible() || !wid->updatesEnabled() )
306 if ( _backgrounds[name].pix.isNull() )
308 QString back = _backgrounds[ name ].filename;
310 if ( back.isEmpty() )
312 _backgrounds[ name ].pix = QImage();
316 QImage image ( back );
317 _backgrounds[ name ].pix = image;
319 if ( image.isNull() )
321 yuiError() <<
"Couldn't load background image \"" << back
322 <<
"\" for \"" << name <<
"\""
327 yuiDebug() <<
"Loading background image \"" << back
328 <<
"\" for " << name <<
"\""
337 if ( !_children.contains( wid ) )
339 QWidget *parent = wid->parentWidget();
340 while ( parent && !_children.contains( parent ) )
341 parent = parent->parentWidget();
344 renderParent( parent );
356 QY2Styler::eventFilter( QObject * obj, QEvent * ev )
358 if ( ev->type() == QEvent::Resize ||
359 ev->type() == QEvent::Show ||
360 ev->type() == QEvent::LayoutRequest ||
361 ev->type() == QEvent::UpdateRequest )
362 updateRendering( qobject_cast<QWidget*>( obj ) );
364 return QObject::eventFilter( obj, ev );
370 std::ostream & operator<<( std::ostream & stream,
const QString & str )
372 return stream << qPrintable( str );
376 std::ostream & operator<<( std::ostream & stream,
const QStringList & strList )
380 for ( QStringList::const_iterator it = strList.begin();
384 stream << qPrintable( *it ) <<
" ";
393 std::ostream & operator<<( std::ostream & stream,
const QWidget * widget )
395 #if LOGGING_CAUSES_QT4_THREADING_PROBLEMS
400 stream <<
"QWidget at " << hex << (
void *) widget << dec;
404 if ( widget->metaObject() )
405 stream << widget->metaObject()->className();
407 stream <<
"<QWidget>";
409 if ( ! widget->objectName().isEmpty() )
410 stream <<
" \"" << qPrintable( widget->objectName() ) <<
"\"";
412 stream <<
" at " << hex << widget << dec;
416 stream <<
"<NULL QWidget>";
425 #include "QY2Styler.moc"
void processUrls(QString &text)
Search and replace some self-defined macros in the style sheet.
QY2Styler(QObject *parent)
Constructor.