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 );
114 foreach( QWidget *registered_widget, _registered_widgets )
115 registered_widget->setStyleSheet( _style );
122 QStringList lines = text.split(
'\n' );
123 QRegExp urlRegex(
": *url\\((.*)\\)" );
124 QRegExp backgroundRegex(
"^ */\\* *Background: *([^ ]*) *([^ ]*) *\\*/$" );
125 QRegExp richTextRegex(
"^ */\\* *Richtext: *([^ ]*) *\\*/$" );
127 _backgrounds.clear();
129 for ( QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it )
135 if ( urlRegex.indexIn( line ) >= 0 )
137 QString fileName = urlRegex.cap( 1 );
138 QString fullPath = themeDir() + fileName;
139 yuiDebug() <<
"Expanding " << fileName <<
"\tto " << fullPath << std::endl;
140 line.replace( urlRegex,
": url(" + fullPath +
")");
143 if ( backgroundRegex.exactMatch( line ) )
145 QStringList name = backgroundRegex.cap( 1 ).split(
'#' );
146 QString fullPath = themeDir() + backgroundRegex.cap( 2 );
147 yuiDebug() <<
"Expanding background " << name[0] <<
"\tto " << fullPath << std::endl;
149 _backgrounds[ name[0] ].filename = fullPath;
150 _backgrounds[ name[0] ].full =
false;
152 if ( name.size() > 1 )
153 _backgrounds[ name[0] ].full = ( name[1] ==
"full" );
156 if ( richTextRegex.exactMatch( line ) )
158 QString filename = richTextRegex.cap( 1 );
159 QFile file( themeDir() +
"/" + filename );
161 if ( file.open( QIODevice::ReadOnly ) )
163 yuiDebug() <<
"Reading " << file.fileName();
164 _textStyle = file.readAll();
168 yuiError() <<
"Can't read " << file.fileName();
180 QY2Styler::themeDir()
const 182 return QString(YSettings::themeDir().c_str());
186 void QY2Styler::registerWidget( QWidget * widget )
188 widget->installEventFilter(
this );
189 widget->setAutoFillBackground(
true );
190 widget->setStyleSheet( _style );
191 _registered_widgets.push_back( widget );
195 void QY2Styler::unregisterWidget( QWidget *widget )
197 _children.remove( widget );
198 _registered_widgets.removeOne( widget );
202 void QY2Styler::registerChildWidget( QWidget * parent, QWidget * widget )
206 qDebug() <<
"Registering " << widget <<
" for parent " << parent << endl;
207 widget->installEventFilter(
this );
208 _children[parent].push_back( widget );
213 QY2Styler::getScaled(
const QString name,
const QSize & size )
215 QImage image = _backgrounds[name].pix;
217 if ( size != image.size() )
218 image = image.scaled( size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
220 image = image.convertToFormat( QImage::Format_ARGB32 );
222 if ( image.isNull() )
223 yuiError() <<
"Can't load pixmap from " << name << std::endl;
226 yuiMilestone() <<
"Loaded pixmap from \"" << name
227 <<
"\" size: " << image.size().width() <<
"x" << image.size().height()
235 void QY2Styler::renderParent( QWidget * wid )
238 QString name = wid->objectName();
241 wid->setPalette( QApplication::palette() );
244 if ( _backgrounds[name].pix.isNull() )
247 QRect fillRect = wid->contentsRect();
248 if ( _backgrounds[name].full )
249 fillRect = wid->rect();
253 if ( _backgrounds[name].lastscale != fillRect.size() )
255 _backgrounds[name].scaled = getScaled( name, fillRect.size() );
256 _backgrounds[name].lastscale = fillRect.size();
259 back = _backgrounds[name].scaled;
261 QPainter pain( &back );
265 foreach( child, _children[wid] )
268 QString name = child->objectName();
270 if (! child->isVisible() || _backgrounds[name].pix.isNull() )
273 QRect fillRect = child->contentsRect();
274 if ( _backgrounds[name].full )
275 fillRect = child->rect();
277 QString key = QString(
"style_%1_%2_%3" ).arg( name ).arg( fillRect.width() ).arg( fillRect.height() );
280 if ( QPixmapCache::find( key, scaled ) )
286 scaled = QPixmap::fromImage( getScaled( name, fillRect.size() ) );
287 QPixmapCache::insert( key, scaled );
289 pain.drawPixmap( wid->mapFromGlobal( child->mapToGlobal( fillRect.topLeft() ) ), scaled );
292 QPixmap result = QPixmap::fromImage( back );
294 QPalette p = wid->palette();
295 p.setBrush(QPalette::Window, result );
296 wid->setPalette( p );
301 QY2Styler::updateRendering( QWidget *wid )
306 QString name = wid->objectName();
308 if (! wid->isVisible() || !wid->updatesEnabled() )
311 if ( _backgrounds[name].pix.isNull() )
313 QString back = _backgrounds[ name ].filename;
315 if ( back.isEmpty() )
317 _backgrounds[ name ].pix = QImage();
321 QImage image ( back );
322 _backgrounds[ name ].pix = image;
324 if ( image.isNull() )
326 yuiError() <<
"Couldn't load background image \"" << back
327 <<
"\" for \"" << name <<
"\"" 332 yuiDebug() <<
"Loading background image \"" << back
333 <<
"\" for " << name <<
"\"" 342 if ( !_children.contains( wid ) )
344 QWidget *parent = wid->parentWidget();
345 while ( parent && !_children.contains( parent ) )
346 parent = parent->parentWidget();
349 renderParent( parent );
361 QY2Styler::eventFilter( QObject * obj, QEvent * ev )
363 if ( ev->type() == QEvent::Resize ||
364 ev->type() == QEvent::Show ||
365 ev->type() == QEvent::LayoutRequest ||
366 ev->type() == QEvent::UpdateRequest )
367 updateRendering( qobject_cast<QWidget*>( obj ) );
369 return QObject::eventFilter( obj, ev );
375 std::ostream & operator<<( std::ostream & stream,
const QString & str )
377 return stream << qPrintable( str );
381 std::ostream & operator<<( std::ostream & stream,
const QStringList & strList )
385 for ( QStringList::const_iterator it = strList.begin();
389 stream << qPrintable( *it ) <<
" ";
398 std::ostream & operator<<( std::ostream & stream,
const QWidget * widget )
400 #if LOGGING_CAUSES_QT4_THREADING_PROBLEMS 405 stream <<
"QWidget at " << hex << (
void *) widget << dec;
409 if ( widget->metaObject() )
410 stream << widget->metaObject()->className();
412 stream <<
"<QWidget>";
414 if ( ! widget->objectName().isEmpty() )
415 stream <<
" \"" << qPrintable( widget->objectName() ) <<
"\"";
417 stream <<
" at " << hex << widget << dec;
421 stream <<
"<NULL QWidget>";
430 #include "QY2Styler.moc"
void processUrls(QString &text)
Search and replace some self-defined macros in the style sheet.
QY2Styler(QObject *parent)
Constructor.