diff options
Diffstat (limited to 'tdm/kfrontend/themer/tdmthemer.cpp')
-rw-r--r-- | tdm/kfrontend/themer/tdmthemer.cpp | 404 |
1 files changed, 404 insertions, 0 deletions
diff --git a/tdm/kfrontend/themer/tdmthemer.cpp b/tdm/kfrontend/themer/tdmthemer.cpp new file mode 100644 index 000000000..d2dc77935 --- /dev/null +++ b/tdm/kfrontend/themer/tdmthemer.cpp @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2003 by Unai Garro <[email protected]> + * Copyright (C) 2004 by Enrico Ros <[email protected]> + * Copyright (C) 2004 by Stephan Kulow <[email protected]> + * Copyright (C) 2004 by Oswald Buddenhagen <[email protected]> + * + * 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 "tdmthemer.h" +#include "tdmitem.h" +#include "tdmpixmap.h" +#include "tdmrect.h" +#include "tdmlabel.h" + +#include <tdmconfig.h> +#include <kfdialog.h> + +#include <kiconloader.h> +#include <kimageeffect.h> +#include <klocale.h> +#include <ksimpleconfig.h> +#include <kdebug.h> + +#include <tqfile.h> +#include <tqfileinfo.h> +#include <tqtimer.h> // animation timer - TODO +#include <tqobjectlist.h> +#include <tqpainter.h> +#include <tqwidget.h> +#include <tqregion.h> +#include <tqlineedit.h> +#include <tqapplication.h> + +#include <unistd.h> + +extern bool argb_visual_available; + +/* + * KdmThemer. The main theming interface + */ +KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget *parent ) + : TQObject( parent ) + , rootItem( 0 ) + , backBuffer( 0 ) +{ + // Set the mode we're working in + m_currentMode = mode; + + // read the XML file and create DOM tree + TQString filename = _filename; + if (!::access( TQFile::encodeName( filename + "/GdmGreeterTheme.desktop" ), R_OK )) { + KSimpleConfig cfg( filename + "/GdmGreeterTheme.desktop" ); + cfg.setGroup( "GdmGreeterTheme" ); + filename += '/' + cfg.readEntry( "Greeter" ); + } + TQFile 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( parent, TQDomNode(), "tdm root" ); + + connect( rootItem, TQT_SIGNAL(needUpdate( int, int, int, int )), + widget(), TQT_SLOT(update( int, int, int, int )) ); + + rootItem->setBaseDir( TQFileInfo( filename ).dirPath( true ) ); + + // generate all the items defined in the theme + generateItems( rootItem ); + + connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SIGNAL(activated( const TQString & )) ); + connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SLOT(slotActivated( const TQString & )) ); + + TQTimer::singleShot(800, this, TQT_SLOT(slotPaintRoot())); + +/* *TODO* + // Animation timer + TQTimer *time = new TQTimer( this ); + time->start( 500 ); + connect( time, TQT_SIGNAL(timeout()), TQT_SLOT(update()) ) +*/ +} + +KdmThemer::~KdmThemer() +{ + delete rootItem; + delete backBuffer; +} + +inline TQWidget * +KdmThemer::widget() +{ + return static_cast<TQWidget *>(parent()); +} + +KdmItem * +KdmThemer::findNode( const TQString &item ) const +{ + return rootItem->findNode( item ); +} + +void +KdmThemer::updateGeometry( bool force ) +{ + rootItem->setGeometry( TQRect( TQPoint(), widget()->size() ), force ); +} + +// BEGIN other functions + +void +KdmThemer::widgetEvent( TQEvent *e ) +{ + if (!rootItem) + return; + switch (e->type()) { + case TQEvent::MouseMove: + { + TQMouseEvent *me = TQT_TQMOUSEEVENT(e); + rootItem->mouseEvent( me->x(), me->y() ); + } + break; + case TQEvent::MouseButtonPress: + { + TQMouseEvent *me = TQT_TQMOUSEEVENT(e); + rootItem->mouseEvent( me->x(), me->y(), true ); + } + break; + case TQEvent::MouseButtonRelease: + { + TQMouseEvent *me = TQT_TQMOUSEEVENT(e); + rootItem->mouseEvent( me->x(), me->y(), false, true ); + } + break; + case TQEvent::Show: + rootItem->show(); + break; + case TQEvent::Resize: + updateGeometry( false ); + showStructure( rootItem ); + break; + case TQEvent::Paint: + { + TQRect paintRect = TQT_TQPAINTEVENT(e)->rect(); + kdDebug() << timestamp() << " paint on: " << paintRect << endl; + + if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + if (!backBuffer) + backBuffer = new TQPixmap( widget()->size() ); + if (backBuffer->size() != widget()->size()) + backBuffer->resize( widget()->size() ); + + TQPainter p; + p.begin( backBuffer ); + rootItem->paint( &p, paintRect ); + p.end(); + + bitBlt( widget(), paintRect.topLeft(), backBuffer, paintRect ); + } + else { + // We have compositing support! + TQRgb blend_color = tqRgba(0, 0, 0, 0); // RGBA + float alpha = tqAlpha(blend_color) / 255.; + int pixel = tqAlpha(blend_color) << 24 | + int(tqRed(blend_color) * alpha) << 16 | + int(tqGreen(blend_color) * alpha) << 8 | + int(tqBlue(blend_color) * alpha); + TQPainter p1; + p1.begin( widget() ); + p1.fillRect( paintRect, TQColor(blend_color, pixel) ); + rootItem->paint( &p1, paintRect ); + p1.end(); + } + + } + break; + default: + break; + } +} + +/* +void +KdmThemer::pixmap( const TQRect &r, TQPixmap *px ) +{ + bitBlt( px, TQPoint( 0, 0 ), widget(), r ); +} +*/ + +void +KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node ) +{ + if (!parent) + return; + + TQDomNodeList subnodeList; //List of subnodes of this node + + /* + * Get the child nodes + */ + if (node.isNull()) { // It's the first node, get its child nodes + TQDomElement theme = domTree.documentElement(); + + // Get its tag, and check it's correct ("greeter") + if (theme.tagName() != "greeter") { + kdDebug() << timestamp() << " 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++) { + TQDomNode subnode = subnodeList.item( nod ); + TQDomElement el = subnode.toElement(); + TQString tagName = el.tagName(); + + if (tagName == "item") { + if (!willDisplay( subnode )) + continue; + TQString id = el.attribute("id"); + if (id.startsWith("plugin-specific-")) { + id = id.mid(strlen("plugin-specific-")); + if (!_pluginsLogin.contains(id)) + continue; + } + + // It's a new item. Draw it + TQString 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" || type == "list") { + newItem = new KdmRect( parent, subnode ); + newItem->setType( type ); + } + // newItem = new KdmEntry( 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 TQDomNode &node ) +{ + TQDomNode showNode = node.namedItem( "show" ); + + // No "show" node means this item can be displayed at all times + if (showNode.isNull()) + return true; + + TQDomElement el = showNode.toElement(); + + TQString modes = el.attribute( "modes" ); + if (!modes.isNull()) { + TQStringList modeList = TQStringList::split( ",", modes ); + + // If current mode isn't in this list, do not display item + if (modeList.find( m_currentMode ) == modeList.end()) + return false; + } + + TQString 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; + else if (type == "userlist") + return _userList; + else if ( type == "!userlist" ) + return !_userList; + +// if (type == "system") +// return true; + + // All tests passed, item will be displayed + return true; +} + +void +KdmThemer::showStructure( TQObject *obj ) +{ + + const TQObjectList wlist = obj->childrenListObject(); + static int counter = 0; + if (counter == 0) + kdDebug() << timestamp() << " \n\n<======= Widget tree =================" << endl; + if (!wlist.isEmpty()) { + counter++; + TQObjectListIterator it( wlist ); + TQObject *object; + + while ((object = it.current()) != 0) { + ++it; + TQString 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() << timestamp() << " \n\n<======= Widget tree =================\n\n" << endl; +} + +void +KdmThemer::slotActivated( const TQString &id ) +{ + TQString toactivate; + if (id == "username-label") + toactivate = "user-entry"; + else if (id == "password-label") + toactivate = "pw-entry"; + else + return; + + KdmItem *item = findNode(toactivate); + if (!item || !item->widget()) + return; + + item->widget()->setFocus(); + TQLineEdit *le = (TQLineEdit*)item->widget()->qt_cast(TQLINEEDIT_OBJECT_NAME_STRING); + if (le) + le->selectAll(); +} + +void +KdmThemer::slotPaintRoot() +{ + KdmItem *back_item = findNode("background"); + if (!back_item) + return; + + TQRect screen = TQApplication::desktop()->screenGeometry(0); + TQPixmap pm(screen.size()); + + TQPainter painter( &pm, true ); + back_item->paint( &painter, back_item->rect()); + painter.end(); + + TQT_TQWIDGET(TQApplication::desktop()->screen())->setErasePixmap(pm); + TQT_TQWIDGET(TQApplication::desktop()->screen())->erase(); +} + +#include "tdmthemer.moc" |