You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
330 lines
8.2 KiB
330 lines
8.2 KiB
/*
|
|
* Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net>
|
|
* Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it>
|
|
* Copyright (C) 2004 by Stephan Kulow <coolo@kde.org>
|
|
* Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "kdmthemer.h"
|
|
#include "kdmitem.h"
|
|
#include "kdmpixmap.h"
|
|
#include "kdmrect.h"
|
|
#include "kdmlabel.h"
|
|
|
|
#include <kdmconfig.h>
|
|
#include <kfdialog.h>
|
|
|
|
#include <kiconloader.h>
|
|
#include <kimageeffect.h>
|
|
#include <klocale.h>
|
|
#include <ksimpleconfig.h>
|
|
#include <kdebug.h>
|
|
|
|
#include <qfile.h>
|
|
#include <qfileinfo.h>
|
|
//#include <qtimer.h> // animation timer - TODO
|
|
#include <qobjectlist.h>
|
|
#include <qpainter.h>
|
|
#include <qwidget.h>
|
|
#include <qregion.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
/*
|
|
* KdmThemer. The main theming interface
|
|
*/
|
|
KdmThemer::KdmThemer( const QString &_filename, const QString &mode, QWidget *parent )
|
|
: QObject( parent )
|
|
, rootItem( 0 )
|
|
, backBuffer( 0 )
|
|
{
|
|
// Set the mode we're working in
|
|
m_currentMode = mode;
|
|
|
|
// read the XML file and create DOM tree
|
|
QString filename = _filename;
|
|
if (!::access( QFile::encodeName( filename + "/GdmGreeterTheme.desktop" ), R_OK )) {
|
|
KSimpleConfig cfg( filename + "/GdmGreeterTheme.desktop" );
|
|
cfg.setGroup( "GdmGreeterTheme" );
|
|
filename += '/' + cfg.readEntry( "Greeter" );
|
|
}
|
|
QFile opmlFile( filename );
|
|
if (!opmlFile.open( IO_ReadOnly )) {
|
|
FDialog::box( widget(), errorbox, i18n( "Cannot open theme file %1" ).arg(filename) );
|
|
return;
|
|
}
|
|
if (!domTree.setContent( &opmlFile )) {
|
|
FDialog::box( widget(), errorbox, i18n( "Cannot parse theme file %1" ).arg(filename) );
|
|
return;
|
|
}
|
|
// Set the root (screen) item
|
|
rootItem = new KdmRect( 0, QDomNode(), "kdm root" );
|
|
connect( rootItem, SIGNAL(needUpdate( int, int, int, int )),
|
|
widget(), SLOT(update( int, int, int, int )) );
|
|
|
|
rootItem->setBaseDir( QFileInfo( filename ).dirPath( true ) );
|
|
|
|
// generate all the items defined in the theme
|
|
generateItems( rootItem );
|
|
|
|
connect( rootItem, SIGNAL(activated( const QString & )), SIGNAL(activated( const QString & )) );
|
|
|
|
/* *TODO*
|
|
// Animation timer
|
|
QTimer *time = new QTimer( this );
|
|
time->start( 500 );
|
|
connect( time, SIGNAL(timeout()), SLOT(update()) )
|
|
*/
|
|
}
|
|
|
|
KdmThemer::~KdmThemer()
|
|
{
|
|
delete rootItem;
|
|
delete backBuffer;
|
|
}
|
|
|
|
inline QWidget *
|
|
KdmThemer::widget()
|
|
{
|
|
return static_cast<QWidget *>(parent());
|
|
}
|
|
|
|
KdmItem *
|
|
KdmThemer::findNode( const QString &item ) const
|
|
{
|
|
return rootItem->findNode( item );
|
|
}
|
|
|
|
void
|
|
KdmThemer::updateGeometry( bool force )
|
|
{
|
|
rootItem->setGeometry( QRect( QPoint(), widget()->size() ), force );
|
|
}
|
|
|
|
// BEGIN other functions
|
|
|
|
void
|
|
KdmThemer::widgetEvent( QEvent *e )
|
|
{
|
|
if (!rootItem)
|
|
return;
|
|
switch (e->type()) {
|
|
case QEvent::MouseMove:
|
|
{
|
|
QMouseEvent *me = static_cast<QMouseEvent *>(e);
|
|
rootItem->mouseEvent( me->x(), me->y() );
|
|
}
|
|
break;
|
|
case QEvent::MouseButtonPress:
|
|
{
|
|
QMouseEvent *me = static_cast<QMouseEvent *>(e);
|
|
rootItem->mouseEvent( me->x(), me->y(), true );
|
|
}
|
|
break;
|
|
case QEvent::MouseButtonRelease:
|
|
{
|
|
QMouseEvent *me = static_cast<QMouseEvent *>(e);
|
|
rootItem->mouseEvent( me->x(), me->y(), false, true );
|
|
}
|
|
break;
|
|
case QEvent::Show:
|
|
rootItem->show();
|
|
break;
|
|
case QEvent::Resize:
|
|
updateGeometry( false );
|
|
showStructure( rootItem );
|
|
break;
|
|
case QEvent::Paint:
|
|
{
|
|
QRect paintRect = static_cast<QPaintEvent *>(e)->rect();
|
|
kdDebug() << "paint on: " << paintRect << endl;
|
|
|
|
if (!backBuffer)
|
|
backBuffer = new QPixmap( widget()->size() );
|
|
if (backBuffer->size() != widget()->size())
|
|
backBuffer->resize( widget()->size() );
|
|
|
|
QPainter p;
|
|
p.begin( backBuffer );
|
|
rootItem->paint( &p, paintRect );
|
|
p.end();
|
|
|
|
bitBlt( widget(), paintRect.topLeft(), backBuffer, paintRect );
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
void
|
|
KdmThemer::pixmap( const QRect &r, QPixmap *px )
|
|
{
|
|
bitBlt( px, QPoint( 0, 0 ), widget(), r );
|
|
}
|
|
*/
|
|
|
|
void
|
|
KdmThemer::generateItems( KdmItem *parent, const QDomNode &node )
|
|
{
|
|
if (!parent)
|
|
return;
|
|
|
|
QDomNodeList subnodeList; //List of subnodes of this node
|
|
|
|
/*
|
|
* Get the child nodes
|
|
*/
|
|
if (node.isNull()) { // It's the first node, get its child nodes
|
|
QDomElement theme = domTree.documentElement();
|
|
|
|
// Get its tag, and check it's correct ("greeter")
|
|
if (theme.tagName() != "greeter") {
|
|
kdDebug() << "This does not seem to be a correct theme file." << endl;
|
|
return;
|
|
}
|
|
// Get the list of child nodes
|
|
subnodeList = theme.childNodes();
|
|
} else
|
|
subnodeList = node.childNodes();
|
|
|
|
/*
|
|
* Go through each of the child nodes
|
|
*/
|
|
for (uint nod = 0; nod < subnodeList.count(); nod++) {
|
|
QDomNode subnode = subnodeList.item( nod );
|
|
QDomElement el = subnode.toElement();
|
|
QString tagName = el.tagName();
|
|
|
|
if (tagName == "item") {
|
|
if (!willDisplay( subnode ))
|
|
continue;
|
|
// It's a new item. Draw it
|
|
QString type = el.attribute( "type" );
|
|
|
|
KdmItem *newItem = 0;
|
|
|
|
if (type == "label")
|
|
newItem = new KdmLabel( parent, subnode );
|
|
else if (type == "pixmap")
|
|
newItem = new KdmPixmap( parent, subnode );
|
|
else if (type == "rect")
|
|
newItem = new KdmRect( parent, subnode );
|
|
else if (type == "entry") {
|
|
newItem = new KdmRect( parent, subnode );
|
|
newItem->setType( type );
|
|
}
|
|
// newItem = new KdmEntry( parent, subnode );
|
|
//else if (type=="list")
|
|
// newItem = new KdmList( parent, subnode );
|
|
else if (type == "svg")
|
|
newItem = new KdmPixmap( parent, subnode );
|
|
if (newItem) {
|
|
generateItems( newItem, subnode );
|
|
if (el.attribute( "button", "false" ) == "true")
|
|
newItem->inheritFromButton( newItem );
|
|
}
|
|
} else if (tagName == "box") {
|
|
if (!willDisplay( subnode ))
|
|
continue;
|
|
// It's a new box. Draw it
|
|
parent->setBoxLayout( subnode );
|
|
generateItems( parent, subnode );
|
|
} else if (tagName == "fixed") {
|
|
if (!willDisplay( subnode ))
|
|
continue;
|
|
// It's a new box. Draw it
|
|
parent->setFixedLayout( subnode );
|
|
generateItems( parent, subnode );
|
|
}
|
|
}
|
|
}
|
|
|
|
bool KdmThemer::willDisplay( const QDomNode &node )
|
|
{
|
|
QDomNode showNode = node.namedItem( "show" );
|
|
|
|
// No "show" node means this item can be displayed at all times
|
|
if (showNode.isNull())
|
|
return true;
|
|
|
|
QDomElement el = showNode.toElement();
|
|
|
|
QString modes = el.attribute( "modes" );
|
|
if (!modes.isNull()) {
|
|
QStringList modeList = QStringList::split( ",", modes );
|
|
|
|
// If current mode isn't in this list, do not display item
|
|
if (modeList.find( m_currentMode ) == modeList.end())
|
|
return false;
|
|
}
|
|
|
|
QString type = el.attribute( "type" );
|
|
if (type == "config" || type == "suspend")
|
|
return false; // not implemented (yet)
|
|
if (type == "timed")
|
|
return _autoLoginDelay != 0;
|
|
if (type == "chooser")
|
|
#ifdef XDMCP
|
|
return _loginMode != LOGIN_LOCAL_ONLY;
|
|
#else
|
|
return false;
|
|
#endif
|
|
if (type == "halt" || type == "reboot")
|
|
return _allowShutdown != SHUT_NONE;
|
|
// if (type == "system")
|
|
// return true;
|
|
|
|
// All tests passed, item will be displayed
|
|
return true;
|
|
}
|
|
|
|
void
|
|
KdmThemer::showStructure( QObject *obj )
|
|
{
|
|
|
|
const QObjectList *wlist = obj->children();
|
|
static int counter = 0;
|
|
if (counter == 0)
|
|
kdDebug() << "\n\n<======= Widget tree =================" << endl;
|
|
if (wlist) {
|
|
counter++;
|
|
QObjectListIterator it( *wlist );
|
|
QObject *object;
|
|
|
|
while ((object = it.current()) != 0) {
|
|
++it;
|
|
QString node;
|
|
for (int i = 1; i < counter; i++)
|
|
node += "-";
|
|
|
|
if (object->inherits( "KdmItem" )) {
|
|
KdmItem *widget = (KdmItem *)object;
|
|
kdDebug() << node << "|" << widget->type() << " me=" << widget->id << " " << widget->area << endl;
|
|
}
|
|
|
|
showStructure( object );
|
|
}
|
|
counter--;
|
|
}
|
|
if (counter == 0)
|
|
kdDebug() << "\n\n<======= Widget tree =================\n\n" << endl;
|
|
}
|
|
|
|
#include "kdmthemer.moc"
|