Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

qpedecoration_qws.cpp

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

Generated on Sat Nov 5 16:16:39 2005 for OPIE by  doxygen 1.4.2