Qtopia library API Documentation

qpedecoration_qws.cpp

00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 #ifdef QWS
00021 #define QTOPIA_INTERNAL_LANGLIST
00022 #include <qapplication.h>
00023 #include <qstyle.h>
00024 #include <qwidget.h>
00025 #include <qpainter.h>
00026 #include <qtimer.h>
00027 #include <qwhatsthis.h>
00028 #include <qpopupmenu.h>
00029 #include "qcopenvelope_qws.h"
00030 #include "qpedecoration_qws.h"
00031 #include <qdialog.h>
00032 #include <qdrawutil.h>
00033 #include <qgfx_qws.h>
00034 #include "qpeapplication.h"
00035 #include "resource.h"
00036 #include "global.h"
00037 #include "qlibrary.h"
00038 #include "windowdecorationinterface.h"
00039 #include <qpe/qlibrary.h>
00040 #include <qfile.h>
00041 #include <qsignal.h>
00042 
00043 #include <stdlib.h>
00044 
00045 extern Q_EXPORT QRect qt_maxWindowRect;
00046 
00047 #define WHATSTHIS_MODE
00048 
00049 #ifndef QT_NO_QWS_QPE_WM_STYLE
00050 
00051 #ifndef QT_NO_IMAGEIO_XPM
00052 
00053 /* XPM */
00054 static const char * const qpe_close_xpm[] = {
00055 "16 16 3 1",
00056 "       c None",
00057 ".      c #FFFFFF",
00058 "+      c #000000",
00059 "                ",
00060 "                ",
00061 "      .....     ",
00062 "    ..+++++..   ",
00063 "   .+++++++++.  ",
00064 "   .+..+++..+.  ",
00065 "  .++...+...++. ",
00066 "  .+++.....+++. ",
00067 "  .++++...++++. ",
00068 "  .+++.....+++. ",
00069 "  .++...+...++. ",
00070 "   .+..+++..+.  ",
00071 "   .+++++++++.  ",
00072 "    ..+++++..   ",
00073 "      .....     ",
00074 "                "};
00075 
00076 /* XPM */
00077 static const char * const qpe_accept_xpm[] = {
00078 "16 16 3 1",
00079 "       c None",
00080 ".      c #FFFFFF",
00081 "+      c #000000",
00082 "                ",
00083 "                ",
00084 "      .....     ",
00085 "    ..+++++..   ",
00086 "   .+++++++++.  ",
00087 "   .+++++++++.  ",
00088 "  .+++++++..++. ",
00089 "  .++.+++...++. ",
00090 "  .+...+...+++. ",
00091 "  .+......++++. ",
00092 "  .++....+++++. ",
00093 "   .++..+++++.  ",
00094 "   .+++++++++.  ",
00095 "    ..+++++..   ",
00096 "      .....     ",
00097 "                "};
00098 
00099 #endif // QT_NO_IMAGEIO_XPM
00100 
00101 class DecorHackWidget : public QWidget
00102 {
00103 public:
00104     bool needsOk() {
00105     return (getWState() & WState_Reserved1 ) ||
00106          (inherits("QDialog") && !inherits("QMessageBox")
00107           && !inherits("QWizard") );
00108     }
00109 };
00110 
00111 static QImage scaleButton( const QImage &img, int height )
00112 {
00113     if ( img.height() != 0 && img.height() != height ) {
00114     return img.smoothScale( img.width()*height/img.height(), height );
00115     } else {
00116     return img;
00117     }
00118 }
00119 
00120 class TLWidget : public QWidget
00121 {
00122 public:
00123     QWSManager *manager()
00124     {
00125     return topData()->qwsManager;
00126     }
00127 
00128     QTLWExtra *topExtra()
00129     {
00130     return topData();
00131     }
00132 
00133     void setWState( uint s ) { QWidget::setWState( s ); }
00134     void clearWState( uint s ) { QWidget::clearWState( s ); }
00135 };
00136 
00137 
00138 QPEManager::QPEManager( QPEDecoration *d, QObject *parent )
00139     : QObject( parent ), decoration( d ), helpState(0), inWhatsThis(FALSE)
00140 {
00141     wtTimer = new QTimer( this );
00142     connect( wtTimer, SIGNAL(timeout()), this, SLOT(whatsThisTimeout()) );
00143 }
00144 
00145 
00146 void QPEManager::updateActive()
00147 {
00148     QWidget *newActive = qApp->activeWindow();
00149     if ( newActive && (QWidget*)active == newActive )
00150     return;
00151 
00152     if ( active && (!newActive || ((TLWidget *)newActive)->manager()) ) {
00153     ((TLWidget *)(QWidget*)active)->manager()->removeEventFilter( this );
00154     }
00155 
00156     if ( newActive && ((TLWidget *)newActive)->manager() ) {
00157     active = newActive;
00158     ((TLWidget *)(QWidget*)active)->manager()->installEventFilter( this );
00159     } else if ( !newActive ) {
00160     active = 0;
00161     }
00162 }
00163 
00164 int QPEManager::pointInQpeRegion( QWidget *w, const QPoint &p )
00165 {
00166     QRect rect(w->geometry());
00167 
00168     if ( decoration->region( w, rect,
00169         (QWSDecoration::Region)QPEDecoration::Help ).contains(p) )
00170     return QPEDecoration::Help;
00171 
00172     for (int i = QWSDecoration::LastRegion; i >= QWSDecoration::Title; i--) {
00173     if (decoration->region(w, rect, (QWSDecoration::Region)i).contains(p))
00174         return (QWSDecoration::Region)i;
00175     }
00176 
00177     return QWSDecoration::None;
00178 }
00179 
00180 bool QPEManager::eventFilter( QObject *o, QEvent *e )
00181 {
00182     QWSManager *mgr = (QWSManager *)o;
00183     QWidget *w = mgr->widget();
00184     switch ( e->type() ) {
00185     case QEvent::MouseButtonPress:
00186         {
00187         pressTime = QTime::currentTime();
00188         QPoint p = ((QMouseEvent*)e)->globalPos();
00189         int inRegion = pointInQpeRegion( w, p );
00190 #ifdef WHATSTHIS_MODE
00191         if ( !w->geometry().contains(p) && QWhatsThis::inWhatsThisMode() ) {
00192             QString text;
00193             switch ( inRegion ) {
00194             case QWSDecoration::Close:
00195                 if ( ((DecorHackWidget*)w)->needsOk() )
00196                 text = tr("Click to close this window, discarding changes.");
00197                 else
00198                 text = tr("Click to close this window.");
00199                 break;
00200             case QWSDecoration::Minimize:
00201                 text = tr("Click to close this window and apply changes.");
00202                 break;
00203             case QWSDecoration::Maximize:
00204                 if ( w->isMaximized() )
00205                 text = tr("Click to make this window movable.");
00206                 else
00207                 text = tr("Click to make this window use all available screen area.");
00208                 break;
00209             default:
00210                 break;
00211             }
00212             QWhatsThis::leaveWhatsThisMode( text );
00213             whatsThisTimeout();
00214             helpState = 0;
00215             return true;
00216         }
00217 #endif
00218         if ( inRegion == QPEDecoration::Help ) {
00219 #ifdef WHATSTHIS_MODE
00220             wtTimer->start( 400, TRUE );
00221 #endif
00222             helpState = QWSButton::Clicked|QWSButton::MouseOver;
00223             drawButton( w, QPEDecoration::Help, helpState );
00224             return true;
00225         }
00226         }
00227         break;
00228     case QEvent::MouseButtonRelease:
00229         if ( helpState & QWSButton::Clicked ) {
00230         wtTimer->stop();
00231         helpState = 0;
00232         drawButton( w, QPEDecoration::Help, helpState );
00233         QPoint p = ((QMouseEvent*)e)->globalPos();
00234         if ( pointInQpeRegion( w, p ) == QPEDecoration::Help ) {
00235             decoration->help( w );
00236         }
00237         return true;
00238         }
00239         break;
00240     case QEvent::MouseMove:
00241         if ( helpState & QWSButton::Clicked ) {
00242         int oldState = helpState;
00243         QPoint p = ((QMouseEvent*)e)->globalPos();
00244         if ( pointInQpeRegion( w, p ) == QPEDecoration::Help ) {
00245             helpState = QWSButton::Clicked|QWSButton::MouseOver;
00246         } else {
00247             helpState = 0;
00248         }
00249         if ( helpState != oldState )
00250             drawButton( w, QPEDecoration::Help, helpState );
00251         }
00252         break;
00253     default:
00254         break;
00255     }
00256     return QObject::eventFilter( o, e );
00257 }
00258 
00259 void QPEManager::drawButton( QWidget *w, QPEDecoration::QPERegion r, int state )
00260 {
00261     QPainter painter(w);
00262     QRegion rgn = ((TLWidget *)w)->topExtra()->decor_allocated_region;
00263     painter.internalGfx()->setWidgetDeviceRegion( rgn );
00264     painter.setClipRegion(decoration->region(w, w->rect(),QWSDecoration::All));
00265     decoration->paintButton( &painter, w, (QWSDecoration::Region)r, state );
00266 }
00267 
00268 void QPEManager::drawTitle( QWidget *w )
00269 {
00270     QPainter painter(w);
00271     QRegion rgn = ((TLWidget *)w)->topExtra()->decor_allocated_region;
00272     painter.internalGfx()->setWidgetDeviceRegion( rgn );
00273     painter.setClipRegion(decoration->region(w, w->rect(),QWSDecoration::All));
00274     decoration->paint( &painter, w );
00275     decoration->paintButton(&painter, w, QWSDecoration::Menu, 0);
00276     decoration->paintButton(&painter, w, QWSDecoration::Close, 0);
00277     decoration->paintButton(&painter, w, QWSDecoration::Minimize, 0);
00278     decoration->paintButton(&painter, w, QWSDecoration::Maximize, 0);
00279 }
00280 
00281 void QPEManager::whatsThisTimeout()
00282 {
00283     if ( !QWhatsThis::inWhatsThisMode() ) {
00284     if ( inWhatsThis ) {
00285         if ( whatsThis ) {
00286         QWidget *w = whatsThis;
00287         whatsThis = 0;
00288         drawTitle( w );
00289         }
00290         wtTimer->stop();
00291     } else {
00292         QWhatsThis::enterWhatsThisMode();
00293         helpState = 0;
00294         updateActive();
00295         if ( active ) {
00296         whatsThis = active;
00297         drawTitle( active );
00298         // check periodically to see if we've left whats this mode
00299         wtTimer->start( 250 );
00300         }
00301     }
00302     inWhatsThis = !inWhatsThis;
00303     }
00304 }
00305 
00306 //===========================================================================
00307 
00308 static QImage *okImage( int th )
00309 {
00310     static QImage *i = 0;
00311     if ( !i || i->height() != th ) {
00312     delete i;
00313     i = new QImage(scaleButton(Resource::loadImage("OKButton"),th));
00314     }
00315     return i;
00316 }
00317 
00318 static QImage *closeImage( int th )
00319 {
00320     static QImage *i = 0;
00321     if ( !i || i->height() != th ) {
00322     delete i;
00323     i = new QImage(scaleButton(Resource::loadImage("CloseButton"),th));
00324     }
00325     return i;
00326 }
00327 
00328 static QImage *helpImage( int th )
00329 {
00330     static QImage *i = 0;
00331     if ( !i || i->height() != th ) {
00332     delete i;
00333     i = new QImage(scaleButton(Resource::loadImage("HelpButton"),th));
00334     }
00335     return i;
00336 }
00337 
00338 static QImage *maximizeImage( int th )
00339 {
00340     static QImage *i = 0;
00341     if ( !i || i->height() != th ) {
00342     delete i;
00343     i = new QImage(scaleButton(Resource::loadImage("MaximizeButton"),th));
00344     }
00345     return i;
00346 }
00347 
00348 int WindowDecorationInterface::metric( Metric m, const WindowData *wd ) const
00349 {
00350     switch ( m ) {
00351     case TitleHeight:
00352         if ( QApplication::desktop()->height() > 320 )
00353         return 19;
00354         else
00355         return 15;
00356     case LeftBorder:
00357     case RightBorder:
00358     case TopBorder:
00359     case BottomBorder:
00360         return 4;
00361     case OKWidth:
00362         return okImage(metric(TitleHeight,wd))->width();
00363     case CloseWidth:
00364         return closeImage(metric(TitleHeight,wd))->width();
00365     case HelpWidth:
00366         return helpImage(metric(TitleHeight,wd))->width();
00367     case MaximizeWidth:
00368         return maximizeImage(metric(TitleHeight,wd))->width();
00369     case CornerGrabSize:
00370         return 16;
00371     }
00372 
00373     return 0;
00374 }
00375 
00376 void WindowDecorationInterface::drawArea( Area a, QPainter *p, const WindowData *wd ) const
00377 {
00378     int th = metric( TitleHeight, wd );
00379     QRect r = wd->rect;
00380 
00381     switch ( a ) {
00382     case Border:
00383         {
00384         const QColorGroup &cg = wd->palette.active();
00385         qDrawWinPanel(p, r.x()-metric(LeftBorder,wd),
00386             r.y()-th-metric(TopBorder,wd),
00387             r.width()+metric(LeftBorder,wd)+metric(RightBorder,wd),
00388             r.height()+th+metric(TopBorder,wd)+metric(BottomBorder,wd),
00389             cg, FALSE, &cg.brush(QColorGroup::Background));
00390         }
00391         break;
00392     case Title:
00393         {
00394         const QColorGroup &cg = wd->palette.active();
00395         QBrush titleBrush;
00396         QPen   titleLines;
00397 
00398         if ( wd->flags & WindowData::Active ) {
00399             titleBrush = cg.brush(QColorGroup::Highlight);
00400             titleLines = titleBrush.color().dark();
00401         } else {
00402             titleBrush = cg.brush(QColorGroup::Background);
00403             titleLines = titleBrush.color();
00404         }
00405 
00406         p->fillRect( r.x(), r.y()-th, r.width(), th, titleBrush);
00407 
00408         p->setPen( titleLines );
00409         for ( int i = r.y()-th; i < r.y(); i += 2 )
00410             p->drawLine( r.left(), i, r.right(), i );
00411         }
00412         break;
00413     case TitleText:
00414         p->drawText( r.x()+3+metric(HelpWidth,wd), r.top()-th,
00415         r.width()-metric(OKWidth,wd)-metric(CloseWidth,wd),
00416         th, QPainter::AlignVCenter, wd->caption);
00417         break;
00418     }
00419 }
00420 
00421 void WindowDecorationInterface::drawButton( Button b, QPainter *p, const WindowData *wd, int x, int y, int, int, QWSButton::State state ) const
00422 {
00423     QImage *img = 0;
00424     switch ( b ) {
00425     case OK:
00426         img = okImage(metric(TitleHeight,wd));
00427         break;
00428     case Close:
00429         img = closeImage(metric(TitleHeight,wd));
00430         break;
00431     case Help:
00432         img = helpImage(metric(TitleHeight,wd));
00433         break;
00434     case Maximize:
00435         img = maximizeImage(metric(TitleHeight,wd));
00436         break;
00437     }
00438 
00439     if ( img ) {
00440     if ((state & QWSButton::MouseOver) && (state & QWSButton::Clicked))
00441         p->drawImage(x+2, y+2, *img);
00442     else
00443         p->drawImage(x+1, y+1, *img);
00444     }
00445 }
00446 
00447 QRegion WindowDecorationInterface::mask( const WindowData *wd ) const
00448 {
00449     int th = metric(TitleHeight,wd);
00450     QRect rect( wd->rect );
00451     QRect r(rect.left() - metric(LeftBorder,wd),
00452         rect.top() - th - metric(TopBorder,wd),
00453         rect.width() + metric(LeftBorder,wd) + metric(RightBorder,wd),
00454         rect.height() + th + metric(TopBorder,wd) + metric(BottomBorder,wd));
00455     return QRegion(r) - rect;
00456 }
00457 
00458 class DefaultWindowDecoration : public WindowDecorationInterface
00459 {
00460 public:
00461     DefaultWindowDecoration(){}
00462     QString name() const {
00463     return qApp->translate("WindowDecoration", "Default",
00464         "List box text for default window decoration");
00465     }
00466     QPixmap icon() const {
00467     return QPixmap();
00468     }
00469     QRESULT queryInterface( const QUuid &uuid, QUnknownInterface **iface ) {
00470     *iface = 0;
00471     if ( uuid == IID_QUnknown )
00472         *iface = this;
00473     else if ( uuid == IID_WindowDecoration )
00474         *iface = this;
00475         else
00476             return QS_FALSE;
00477 
00478     if ( *iface )
00479         (*iface)->addRef();
00480     return QS_OK;
00481     }
00482     Q_REFCOUNT
00483 
00484 };
00485 
00486 static WindowDecorationInterface *wdiface = 0;
00487 static QLibrary* wdlib = 0;
00488 static QString libname;
00489 
00490 //===========================================================================
00491 bool QPEDecoration::helpExists() const
00492 {
00493     if ( helpFile.isNull() ) {
00494     QStringList helpPath = Global::helpPath();
00495     QString hf = QString(qApp->argv()[0]) + ".html";
00496     bool he = FALSE;
00497     for (QStringList::ConstIterator it=helpPath.begin(); it!=helpPath.end() && !he; ++it)
00498         he = QFile::exists( *it + "/" + hf );
00499     ((QPEDecoration*)this)->helpFile = hf;
00500     ((QPEDecoration*)this)->helpexists = he;
00501     return he;
00502     }
00503     return helpexists;
00504 }
00505 
00506 QPEDecoration::QPEDecoration()
00507     : QWSDefaultDecoration()
00508 {
00509     if ( wdlib ) {
00510     delete wdlib;
00511     wdlib = 0;
00512     } else {
00513     delete wdiface;
00514     }
00515     wdiface = new DefaultWindowDecoration;
00516 
00517     helpexists = FALSE; // We don't know (flagged by helpFile being null)
00518     qpeManager = new QPEManager( this );
00519     imageOk = Resource::loadImage( "OKButton" );
00520     imageClose = Resource::loadImage( "CloseButton" );
00521     imageHelp = Resource::loadImage( "HelpButton" );
00522 }
00523 
00524 QPEDecoration::QPEDecoration( const QString &plugin )
00525     : QWSDefaultDecoration()
00526 {
00527     libname = plugin;
00528 
00529     if ( wdlib ) {
00530         wdiface->release();
00531         wdlib->unload();
00532         delete wdlib;
00533         wdlib = 0;
00534     } else {
00535         delete wdiface;
00536     }
00537 
00538     WindowDecorationInterface *iface = 0;
00539     QString path = QPEApplication::qpeDir() + "/plugins/decorations/";
00540 
00541 #ifdef Q_OS_MACX
00542     if ( plugin.find( ".dylib" ) > 0 ) {
00543 #else
00544     if ( plugin.find( ".so" ) > 0 ) {
00545 #endif
00546         // full library name supplied
00547         path += plugin;
00548     } else {
00549 #ifdef Q_OS_MACX
00550         path += "lib" + plugin.lower() + ".dylib"; // compatibility
00551 #else
00552         path += "lib" + plugin.lower() + ".so"; // compatibility
00553 #endif
00554     }
00555 
00556     QLibrary *lib = new QLibrary( path );
00557     if ( lib->queryInterface( IID_WindowDecoration, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
00558     wdiface = iface;
00559     wdlib = lib;
00560     } else {
00561     delete lib;
00562     wdiface = new DefaultWindowDecoration;
00563     }
00564 
00565 
00566 
00567     helpexists = FALSE; // We don't know (flagged by helpFile being null)
00568     qpeManager = new QPEManager( this );
00569 }
00570 
00571 QPEDecoration::~QPEDecoration()
00572 {
00573     delete qpeManager;
00574 }
00575 
00576 const char **QPEDecoration::menuPixmap()
00577 {
00578     return (const char **)0;
00579 }
00580 
00581 const char **QPEDecoration::closePixmap()
00582 {
00583     return (const char **)qpe_close_xpm;
00584 }
00585 
00586 const char **QPEDecoration::minimizePixmap()
00587 {
00588     return (const char **)qpe_accept_xpm;
00589 }
00590 
00591 const char **QPEDecoration::maximizePixmap()
00592 {
00593     return (const char **)0;
00594 }
00595 
00596 const char **QPEDecoration::normalizePixmap()
00597 {
00598     return (const char **)0;
00599 }
00600 
00601 int QPEDecoration::getTitleHeight( const QWidget *w )
00602 {
00603     WindowDecorationInterface::WindowData wd;
00604     windowData( w, wd );
00605     return wdiface->metric(WindowDecorationInterface::TitleHeight,&wd);
00606 }
00607 
00608 /*
00609     If rect is empty, no frame is added. (a hack, really)
00610 */
00611 QRegion QPEDecoration::region(const QWidget *widget, const QRect &rect, QWSDecoration::Region type)
00612 {
00613     qpeManager->updateActive();
00614 
00615     WindowDecorationInterface::WindowData wd;
00616     windowData( widget, wd );
00617     wd.rect = rect;
00618 
00619     int titleHeight = wdiface->metric(WindowDecorationInterface::TitleHeight,&wd);
00620     int okWidth = wdiface->metric(WindowDecorationInterface::OKWidth,&wd);
00621     int closeWidth = wdiface->metric(WindowDecorationInterface::CloseWidth,&wd);
00622     int helpWidth = wdiface->metric(WindowDecorationInterface::HelpWidth,&wd);
00623     int grab = wdiface->metric(WindowDecorationInterface::CornerGrabSize,&wd);
00624 
00625     QRegion region;
00626 
00627     switch ((int)type) {
00628     case Menu:
00629         break;
00630     case Maximize:
00631         if ( !widget->inherits( "QDialog" ) && qApp->desktop()->width() > 350 ) {
00632         int maximizeWidth = wdiface->metric(WindowDecorationInterface::MaximizeWidth,&wd);
00633         int left = rect.right() - maximizeWidth - closeWidth;
00634         if ( ((DecorHackWidget *)widget)->needsOk() )
00635             left -= okWidth;
00636         QRect r(left, rect.top() - titleHeight, closeWidth, titleHeight);
00637         region = r;
00638         }
00639         break;
00640     case Minimize:
00641         if ( ((DecorHackWidget *)widget)->needsOk() ) {
00642         QRect r(rect.right() - okWidth,
00643             rect.top() - titleHeight, okWidth, titleHeight);
00644         if (r.left() > rect.left() + titleHeight)
00645             region = r;
00646         }
00647         break;
00648     case Close:
00649         {
00650         int left = rect.right() - closeWidth;
00651         if ( ((DecorHackWidget *)widget)->needsOk() )
00652             left -= okWidth;
00653         QRect r(left, rect.top() - titleHeight, closeWidth, titleHeight);
00654         region = r;
00655         }
00656         break;
00657         case Title:
00658         if ( !widget->isMaximized() ) {
00659         int width = rect.width() - helpWidth - closeWidth;
00660         if ( ((DecorHackWidget *)widget)->needsOk() )
00661             width -= okWidth;
00662         QRect r(rect.left()+helpWidth, rect.top() - titleHeight,
00663             width, titleHeight);
00664         if (r.width() > 0)
00665             region = r;
00666         }
00667         break;
00668     case Help:
00669         if ( helpExists() || widget->testWFlags(Qt::WStyle_ContextHelp) ) {
00670         QRect r(rect.left(), rect.top() - titleHeight,
00671               helpWidth, titleHeight);
00672         region = r;
00673         }
00674         break;
00675     case Top:
00676         if ( !widget->isMaximized() ) {
00677         QRegion m = wdiface->mask(&wd);
00678         QRect br = m.boundingRect();
00679         int b = wdiface->metric(WindowDecorationInterface::TopBorder,&wd);
00680         region = m & QRect( br.left()+grab, br.top(),
00681                     br.width()-2*grab, b );
00682         }
00683         break;
00684     case Left:
00685         if ( !widget->isMaximized() ) {
00686         QRegion m = wdiface->mask(&wd);
00687         QRect br = m.boundingRect();
00688         int b = wdiface->metric(WindowDecorationInterface::LeftBorder,&wd);
00689         region = m & QRect( br.left(), br.top()+grab,
00690                     b, br.height()-2*grab );
00691         }
00692         break;
00693     case Right:
00694         if ( !widget->isMaximized() ) {
00695         QRegion m = wdiface->mask(&wd);
00696         QRect br = m.boundingRect();
00697         int b = wdiface->metric(WindowDecorationInterface::RightBorder,&wd);
00698         region = m & QRect( rect.right(), br.top()+grab,
00699                     b, br.height()-2*grab );
00700         }
00701         break;
00702     case Bottom:
00703         if ( !widget->isMaximized() ) {
00704         QRegion m = wdiface->mask(&wd);
00705         QRect br = m.boundingRect();
00706         int b = wdiface->metric(WindowDecorationInterface::BottomBorder,&wd);
00707         region = m & QRect( br.left()+grab, rect.bottom(),
00708                     br.width()-2*grab, b );
00709         }
00710         break;
00711     case TopLeft:
00712         if ( !widget->isMaximized() ) {
00713         QRegion m = wdiface->mask(&wd);
00714         QRect br = m.boundingRect();
00715         int tb = wdiface->metric(WindowDecorationInterface::TopBorder,&wd);
00716         int lb = wdiface->metric(WindowDecorationInterface::LeftBorder,&wd);
00717         QRegion crgn( br.left(), br.top(), grab, tb );
00718         crgn |= QRect( br.left(), br.top(), lb, grab );
00719         region = m & crgn;
00720         }
00721         break;
00722     case TopRight:
00723         if ( !widget->isMaximized() ) {
00724         QRegion m = wdiface->mask(&wd);
00725         QRect br = m.boundingRect();
00726         int tb = wdiface->metric(WindowDecorationInterface::TopBorder,&wd);
00727         int rb = wdiface->metric(WindowDecorationInterface::RightBorder,&wd);
00728         QRegion crgn( br.right()-grab, br.top(), grab, tb );
00729         crgn |= QRect( br.right()-rb, br.top(), rb, grab );
00730         region = m & crgn;
00731         }
00732         break;
00733     case BottomLeft:
00734         if ( !widget->isMaximized() ) {
00735         QRegion m = wdiface->mask(&wd);
00736         QRect br = m.boundingRect();
00737         region = m & QRect( br.left(), br.bottom()-grab, grab, grab );
00738         }
00739         break;
00740     case BottomRight:
00741         if ( !widget->isMaximized() ) {
00742         QRegion m = wdiface->mask(&wd);
00743         QRect br = m.boundingRect();
00744         region = m & QRect( br.right()-grab, br.bottom()-grab, grab, grab );
00745         }
00746         break;
00747     case All:
00748         if ( widget->isMaximized() )
00749         region = QWSDefaultDecoration::region(widget, rect, type);
00750         else
00751         region = wdiface->mask(&wd) - rect;
00752         break;
00753     default:
00754         region = QWSDefaultDecoration::region(widget, rect, type);
00755         break;
00756     }
00757 
00758     return region;
00759 }
00760 
00761 void QPEDecoration::paint(QPainter *painter, const QWidget *widget)
00762 {
00763     WindowDecorationInterface::WindowData wd;
00764     windowData( widget, wd );
00765 
00766     int titleWidth = getTitleWidth(widget);
00767     int titleHeight = wdiface->metric(WindowDecorationInterface::TitleHeight,&wd);
00768 
00769     QRect rect(widget->rect());
00770 
00771     // title bar rect
00772     QRect tbr( rect.left(), rect.top() - titleHeight, rect.width(), titleHeight );
00773 
00774 #ifndef QT_NO_PALETTE
00775     QRegion oldClip = painter->clipRegion();
00776     painter->setClipRegion( oldClip - QRegion( tbr ) ); // reduce flicker
00777     wdiface->drawArea( WindowDecorationInterface::Border, painter, &wd );
00778     painter->setClipRegion( oldClip );
00779 
00780     if (titleWidth > 0) {
00781     const QColorGroup &cg = widget->palette().active();
00782     QBrush titleBrush;
00783     QPen   titlePen;
00784 
00785     if ( wd.flags & WindowDecorationInterface::WindowData::Active ) {
00786         titleBrush = cg.brush(QColorGroup::Highlight);
00787         titlePen   = cg.color(QColorGroup::HighlightedText);
00788     } else {
00789         titleBrush = cg.brush(QColorGroup::Background);
00790         titlePen   = cg.color(QColorGroup::Text);
00791     }
00792 
00793     wdiface->drawArea( WindowDecorationInterface::Title, painter, &wd );
00794 
00795     // Draw caption
00796     painter->setPen(titlePen);
00797     QFont f( QApplication::font() );
00798     f.setWeight( QFont::Bold );
00799     painter->setFont(f);
00800     wdiface->drawArea( WindowDecorationInterface::TitleText, painter, &wd );
00801     }
00802 #endif //QT_NO_PALETTE
00803 
00804     paintButton( painter, widget, (QWSDecoration::Region)Help, 0 );
00805 }
00806 
00807 void QPEDecoration::paintButton(QPainter *painter, const QWidget *w,
00808             QWSDecoration::Region type, int state)
00809 {
00810     WindowDecorationInterface::Button b;
00811     switch ((int)type) {
00812     case Close:
00813         b = WindowDecorationInterface::Close;
00814         break;
00815     case Minimize:
00816         if ( ((DecorHackWidget *)w)->needsOk() )
00817         b = WindowDecorationInterface::OK;
00818         else if ( helpExists() )
00819         b = WindowDecorationInterface::Help;
00820         else
00821         return;
00822         break;
00823     case Help:
00824         b = WindowDecorationInterface::Help;
00825         break;
00826     case Maximize:
00827         b = WindowDecorationInterface::Maximize;
00828         break;
00829     default:
00830         return;
00831     }
00832 
00833     WindowDecorationInterface::WindowData wd;
00834     windowData( w, wd );
00835 
00836     int titleHeight = wdiface->metric(WindowDecorationInterface::TitleHeight,&wd);
00837     QRect rect(w->rect());
00838     QRect tbr( rect.left(), rect.top() - titleHeight, rect.width(), titleHeight );
00839     QRect brect(region(w, w->rect(), type).boundingRect());
00840 
00841     const QColorGroup &cg = w->palette().active();
00842     if ( wd.flags & WindowDecorationInterface::WindowData::Active )
00843     painter->setPen( cg.color(QColorGroup::HighlightedText) );
00844     else
00845     painter->setPen( cg.color(QColorGroup::Text) );
00846 
00847     QRegion oldClip = painter->clipRegion();
00848     painter->setClipRegion( QRect(brect.x(), tbr.y(), brect.width(), tbr.height()) ); // reduce flicker
00849     wdiface->drawArea( WindowDecorationInterface::Title, painter, &wd );
00850     wdiface->drawButton( b, painter, &wd, brect.x(), brect.y(), brect.width(), brect.height(), (QWSButton::State)state );
00851     painter->setClipRegion( oldClip );
00852 }
00853 
00854 //#define QPE_DONT_SHOW_TITLEBAR
00855 
00856 void QPEDecoration::maximize( QWidget *widget )
00857 {
00858 #ifdef QPE_DONT_SHOW_TITLEBAR
00859     if ( !widget->inherits( "QDialog" ) ) {
00860     widget->setGeometry( qt_maxWindowRect );
00861     } else
00862 #endif
00863     {
00864     QWSDecoration::maximize( widget );
00865     }
00866 }
00867 
00868 QPopupMenu *QPEDecoration::menu( const QWidget *, const QPoint & )
00869 {
00870     QPopupMenu *m = new QPopupMenu();
00871 
00872     m->insertItem(QPEManager::tr("Restore"), (int)Normalize);
00873     m->insertItem(QPEManager::tr("Move"), (int)Title);
00874     m->insertItem(QPEManager::tr("Size"), (int)BottomRight);
00875     m->insertItem(QPEManager::tr("Maximize"), (int)Maximize);
00876     m->insertSeparator();
00877     m->insertItem(QPEManager::tr("Close"), (int)Close);
00878 
00879     return m;
00880 }
00881 
00882 #ifndef QT_NO_DIALOG
00883 class HackDialog : public QDialog
00884 {
00885 public:
00886     void acceptIt() {
00887     if ( isA( "QMessageBox" ) )
00888         qApp->postEvent( this, new QKeyEvent( QEvent::KeyPress, Key_Enter, '\n', 0, "\n" ) );
00889     else
00890         accept();
00891     }
00892 };
00893 #endif
00894 
00895 
00896 void QPEDecoration::minimize( QWidget *widget )
00897 {
00898 #ifndef QT_NO_DIALOG
00899     // We use the minimize button as an "accept" button.
00900     if ( widget->inherits( "QDialog" ) ) {
00901         HackDialog *d = (HackDialog *)widget;
00902         d->acceptIt();
00903     }
00904 #endif
00905     else if ( ((DecorHackWidget *)widget)->needsOk() ) {
00906     QSignal s;
00907     s.connect( widget, SLOT( accept() ) );
00908     s.activate();
00909     } else {
00910     help( widget );
00911     }
00912 }
00913 
00914 void QPEDecoration::help( QWidget *w )
00915 {
00916     if ( helpExists() ) {
00917     QString hf = helpFile;
00918     QString localHelpFile = QString(qApp->argv()[0]) + "-" + w->name() + ".html";
00919     QStringList helpPath = Global::helpPath();
00920     for (QStringList::ConstIterator it=helpPath.begin(); it!=helpPath.end(); ++it) {
00921         if ( QFile::exists( *it + "/" + localHelpFile ) ) {
00922         hf = localHelpFile;
00923         break;
00924         }
00925     }
00926     Global::execute( "helpbrowser", hf );
00927     } else if ( w && w->testWFlags(Qt::WStyle_ContextHelp) ) {
00928     QWhatsThis::enterWhatsThisMode();
00929         QWhatsThis::leaveWhatsThisMode( QObject::tr(
00930         "<Qt>Comprehensive help is not available for this application, "
00931         "however there is context-sensitive help.<p>To use context-sensitive help:<p>"
00932         "<ol><li>click and hold the help button."
00933         "<li>when the title bar shows <b>What's this...</b>, "
00934         "click on any control.</ol></Qt>" ) );
00935     }
00936 }
00937 
00938 void QPEDecoration::windowData( const QWidget *w, WindowDecorationInterface::WindowData &wd ) const
00939 {
00940     wd.rect = w->rect();
00941     if ( qpeManager->whatsThisWidget() == w )
00942         wd.caption = QObject::tr( "What's this..." );
00943     else
00944     wd.caption = w->caption();
00945     wd.palette = qApp->palette();
00946     wd.flags = 0;
00947     wd.flags |= w->isMaximized() ? WindowDecorationInterface::WindowData::Maximized : 0;
00948     wd.flags |= w->testWFlags(Qt::WStyle_Dialog) ? WindowDecorationInterface::WindowData::Dialog : 0;
00949     const QWidget *active = qpeManager->activeWidget();
00950     wd.flags |= w == active ? WindowDecorationInterface::WindowData::Active : 0;
00951     wd.reserved = 1;
00952 }
00953 
00954 /*
00955 #ifndef QT_NO_POPUPMENU
00956 QPopupMenu *QPEDecoration::menu(QWSManager*, const QWidget*, const QPoint&)
00957 {
00958     return 0;
00959 }
00960 #endif
00961 */
00962 
00963 
00964 
00965 
00966 #endif // QT_NO_QWS_QPE_WM_STYLE
00967 #endif
KDE Logo
This file is part of the documentation for OPIE Version 1.5.5.
Documentation copyright © 1997-2003 the KDE developers. 2003 OPIE developers
Generated on Tue Feb 10 20:24:07 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001