00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef INCLUDE_MENUITEM_DEF
00024 #define INCLUDE_MENUITEM_DEF
00025 #endif
00026
00027 #include "config.h"
00028 #include <tqevent.h>
00029 #include <tqobjectlist.h>
00030 #include <tqaccel.h>
00031 #include <tqpainter.h>
00032 #include <tqstyle.h>
00033 #include <tqtimer.h>
00034
00035 #include <tdeconfig.h>
00036 #include <tdeglobalsettings.h>
00037 #include <tdemenubar.h>
00038 #include <tdeapplication.h>
00039 #include <tdeglobal.h>
00040 #include <kdebug.h>
00041 #include <kmanagerselection.h>
00042
00043 #ifdef Q_WS_X11
00044 #include <twin.h>
00045 #include <twinmodule.h>
00046 #include <qxembed.h>
00047
00048 #include <X11/Xlib.h>
00049 #include <X11/Xutil.h>
00050 #include <X11/Xatom.h>
00051
00052 #ifndef None
00053 #define None 0L
00054 #endif
00055 #endif
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 class KMenuBar::KMenuBarPrivate
00071 {
00072 public:
00073 KMenuBarPrivate()
00074 : forcedTopLevel( false ),
00075 topLevel( false ),
00076 wasTopLevel( false ),
00077 #ifdef Q_WS_X11
00078 selection( NULL ),
00079 #endif
00080 min_size( 0, 0 )
00081 {
00082 }
00083 ~KMenuBarPrivate()
00084 {
00085 #ifdef Q_WS_X11
00086 delete selection;
00087 #endif
00088 }
00089 bool forcedTopLevel;
00090 bool topLevel;
00091 bool wasTopLevel;
00092 int frameStyle;
00093 int lineWidth;
00094 int margin;
00095 bool fallback_mode;
00096 #ifdef Q_WS_X11
00097 TDESelectionWatcher* selection;
00098 #endif
00099 TQTimer selection_timer;
00100 TQSize min_size;
00101 static Atom makeSelectionAtom();
00102 };
00103
00104 #ifdef Q_WS_X11
00105 static Atom selection_atom = None;
00106 static Atom msg_type_atom = None;
00107
00108 static
00109 void initAtoms()
00110 {
00111 char nm[ 100 ];
00112 sprintf( nm, "_KDE_TOPMENU_OWNER_S%d", DefaultScreen( tqt_xdisplay()));
00113 char nm2[] = "_KDE_TOPMENU_MINSIZE";
00114 char* names[ 2 ] = { nm, nm2 };
00115 Atom atoms[ 2 ];
00116 XInternAtoms( tqt_xdisplay(), names, 2, False, atoms );
00117 selection_atom = atoms[ 0 ];
00118 msg_type_atom = atoms[ 1 ];
00119 }
00120 #endif
00121
00122 Atom KMenuBar::KMenuBarPrivate::makeSelectionAtom()
00123 {
00124 #ifdef Q_WS_X11
00125 if( selection_atom == None )
00126 initAtoms();
00127 return selection_atom;
00128 #else
00129 return 0;
00130 #endif
00131 }
00132
00133 KMenuBar::KMenuBar(TQWidget *parent, const char *name)
00134 : TQMenuBar(parent, name)
00135 {
00136 #ifdef Q_WS_X11
00137 QXEmbed::initialize();
00138 #endif
00139 d = new KMenuBarPrivate;
00140 connect( &d->selection_timer, TQT_SIGNAL( timeout()),
00141 this, TQT_SLOT( selectionTimeout()));
00142
00143 connect( tqApp->desktop(), TQT_SIGNAL( resized( int )), TQT_SLOT( updateFallbackSize()));
00144
00145 if ( kapp )
00146
00147 connect( kapp, TQT_SIGNAL(toolbarAppearanceChanged(int)),
00148 this, TQT_SLOT(slotReadConfig()));
00149
00150 slotReadConfig();
00151 }
00152
00153 KMenuBar::~KMenuBar()
00154 {
00155 delete d;
00156 }
00157
00158 void KMenuBar::setTopLevelMenu(bool top_level)
00159 {
00160 d->forcedTopLevel = top_level;
00161 setTopLevelMenuInternal( top_level );
00162 }
00163
00164 void KMenuBar::setTopLevelMenuInternal(bool top_level)
00165 {
00166 if (d->forcedTopLevel)
00167 top_level = true;
00168
00169 d->wasTopLevel = top_level;
00170 if( parentWidget()
00171 && parentWidget()->topLevelWidget()->isFullScreen())
00172 top_level = false;
00173
00174 if ( isTopLevelMenu() == top_level )
00175 return;
00176 d->topLevel = top_level;
00177 if ( isTopLevelMenu() )
00178 {
00179 #ifdef Q_WS_X11
00180 d->selection = new TDESelectionWatcher( KMenuBarPrivate::makeSelectionAtom(),
00181 DefaultScreen( tqt_xdisplay()));
00182 connect( d->selection, TQT_SIGNAL( newOwner( Window )),
00183 this, TQT_SLOT( updateFallbackSize()));
00184 connect( d->selection, TQT_SIGNAL( lostOwner()),
00185 this, TQT_SLOT( updateFallbackSize()));
00186 #endif
00187 d->frameStyle = frameStyle();
00188 d->lineWidth = lineWidth();
00189 d->margin = margin();
00190 d->fallback_mode = false;
00191 bool wasShown = !isHidden();
00192 reparent( parentWidget(), (WFlags)(WType_TopLevel | WStyle_Tool | WStyle_Customize | WStyle_NoBorder), TQPoint(0,0), false );
00193 #ifdef Q_WS_X11
00194 KWin::setType( winId(), NET::TopMenu );
00195 if( parentWidget())
00196 XSetTransientForHint( tqt_xdisplay(), winId(), parentWidget()->topLevelWidget()->winId());
00197 #endif
00198 TQMenuBar::setFrameStyle( NoFrame );
00199 TQMenuBar::setLineWidth( 0 );
00200 TQMenuBar::setMargin( 0 );
00201 updateFallbackSize();
00202 d->min_size = TQSize( 0, 0 );
00203 if( parentWidget() && !parentWidget()->isTopLevel())
00204 setShown( parentWidget()->isVisible());
00205 else if ( wasShown )
00206 show();
00207 } else
00208 {
00209 #ifdef Q_WS_X11
00210 delete d->selection;
00211 d->selection = NULL;
00212 #endif
00213 setBackgroundMode( PaletteButton );
00214 setFrameStyle( d->frameStyle );
00215 setLineWidth( d->lineWidth );
00216 setMargin( d->margin );
00217 setMinimumSize( 0, 0 );
00218 setMaximumSize( TQWIDGETSIZE_MAX, TQWIDGETSIZE_MAX );
00219 updateMenuBarSize();
00220 if ( parentWidget() )
00221 reparent( parentWidget(), TQPoint(0,0), !isHidden());
00222 }
00223 }
00224
00225 bool KMenuBar::isTopLevelMenu() const
00226 {
00227 return d->topLevel;
00228 }
00229
00230
00231 void KMenuBar::show()
00232 {
00233 TQMenuBar::show();
00234 }
00235
00236 void KMenuBar::slotReadConfig()
00237 {
00238 TDEConfig *config = TDEGlobal::config();
00239 TDEConfigGroupSaver saver( config, "KDE" );
00240 setTopLevelMenuInternal( config->readBoolEntry( "macStyle", false ) );
00241 }
00242
00243 bool KMenuBar::eventFilter(TQObject *obj, TQEvent *ev)
00244 {
00245 if ( d->topLevel )
00246 {
00247 if ( parentWidget() && TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(parentWidget()->topLevelWidget()) )
00248 {
00249 if( ev->type() == TQEvent::Resize )
00250 return false;
00251 if ( ev->type() == TQEvent::Accel || ev->type() == TQEvent::AccelAvailable )
00252 {
00253 if ( TQApplication::sendEvent( topLevelWidget(), ev ) )
00254 return true;
00255 }
00256 if(ev->type() == TQEvent::ShowFullScreen )
00257
00258 setTopLevelMenuInternal( d->topLevel );
00259 }
00260 if( parentWidget() && TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(parentWidget()) && ev->type() == TQEvent::Reparent )
00261 {
00262 #ifdef Q_WS_X11
00263 XSetTransientForHint( tqt_xdisplay(), winId(), parentWidget()->topLevelWidget()->winId());
00264 #else
00265
00266 #endif
00267 setShown( parentWidget()->isTopLevel() || parentWidget()->isVisible());
00268 }
00269 if( parentWidget() && !parentWidget()->isTopLevel() && TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(parentWidget()))
00270 {
00271 if( ev->type() == TQEvent::Show )
00272 {
00273 #ifdef Q_WS_X11
00274 XSetTransientForHint( tqt_xdisplay(), winId(), parentWidget()->topLevelWidget()->winId());
00275 #else
00276
00277 #endif
00278 show();
00279 }
00280 if( ev->type() == TQEvent::Hide )
00281 hide();
00282 }
00283 }
00284 else
00285 {
00286 if( parentWidget() && TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(parentWidget()->topLevelWidget()))
00287 {
00288 if( ev->type() == TQEvent::WindowStateChange
00289 && !parentWidget()->topLevelWidget()->isFullScreen() )
00290 setTopLevelMenuInternal( d->wasTopLevel );
00291 }
00292 }
00293 return TQMenuBar::eventFilter( obj, ev );
00294 }
00295
00296
00297 void KMenuBar::showEvent( TQShowEvent *e )
00298 {
00299 TQMenuBar::showEvent(e);
00300 }
00301
00302 void KMenuBar::updateFallbackSize()
00303 {
00304 if( !d->topLevel )
00305 return;
00306 #ifdef Q_WS_X11
00307 if( d->selection->owner() != None )
00308 #endif
00309 {
00310
00311 d->selection_timer.stop();
00312 if( d->fallback_mode )
00313 {
00314 d->fallback_mode = false;
00315 KWin::setStrut( winId(), 0, 0, 0, 0 );
00316 setMinimumSize( 0, 0 );
00317 setMaximumSize( TQWIDGETSIZE_MAX, TQWIDGETSIZE_MAX );
00318 updateMenuBarSize();
00319 }
00320 return;
00321 }
00322 if( d->selection_timer.isActive())
00323 return;
00324 d->selection_timer.start( 100, true );
00325 }
00326
00327 void KMenuBar::selectionTimeout()
00328 {
00329 if ( d->topLevel )
00330 {
00331 d->fallback_mode = true;
00332 TDEConfigGroup xineramaConfig(TDEGlobal::config(),"Xinerama");
00333 int screen = xineramaConfig.readNumEntry("MenubarScreen",
00334 TQApplication::desktop()->screenNumber(TQPoint(0,0)) );
00335 TQRect area;
00336 if (kapp->desktop()->numScreens() < 2)
00337 area = kapp->desktop()->geometry();
00338 else
00339 area = kapp->desktop()->screenGeometry(screen);
00340 int margin = 0;
00341 move(area.left() - margin, area.top() - margin);
00342 setFixedSize(area.width() + 2* margin , heightForWidth( area.width() + 2 * margin ) );
00343 #ifdef Q_WS_X11
00344 int strut_height = height() - margin;
00345 if( strut_height < 0 )
00346 strut_height = 0;
00347 KWin::setStrut( winId(), 0, 0, strut_height, 0 );
00348 #endif
00349 }
00350 }
00351
00352 int KMenuBar::block_resize = 0;
00353
00354 void KMenuBar::resizeEvent( TQResizeEvent *e )
00355 {
00356 if( e->spontaneous() && d->topLevel && !d->fallback_mode )
00357 {
00358 ++block_resize;
00359 TQMenuBar::resizeEvent(e);
00360 --block_resize;
00361 }
00362 else
00363 TQMenuBar::resizeEvent(e);
00364 }
00365
00366 void KMenuBar::setGeometry( const TQRect& r )
00367 {
00368 setGeometry( r.x(), r.y(), r.width(), r.height() );
00369 }
00370
00371 void KMenuBar::setGeometry( int x, int y, int w, int h )
00372 {
00373 if( block_resize > 0 )
00374 {
00375 move( x, y );
00376 return;
00377 }
00378 checkSize( w, h );
00379 if( geometry() != TQRect( x, y, w, h ))
00380 TQMenuBar::setGeometry( x, y, w, h );
00381 }
00382
00383 void KMenuBar::resize( int w, int h )
00384 {
00385 if( block_resize > 0 )
00386 return;
00387 checkSize( w, h );
00388 if( size() != TQSize( w, h ))
00389 TQMenuBar::resize( w, h );
00390
00391 }
00392
00393 void KMenuBar::checkSize( int& w, int& h )
00394 {
00395 if( !d->topLevel || d->fallback_mode )
00396 return;
00397 TQSize s = sizeHint();
00398 w = s.width();
00399 h = s.height();
00400
00401
00402
00403 w = KMAX( w, d->min_size.width());
00404 h = KMAX( h, d->min_size.height());
00405 }
00406
00407
00408 TQSize KMenuBar::sizeHint() const
00409 {
00410 if( !d->topLevel || block_resize > 0 )
00411 return TQMenuBar::sizeHint();
00412
00413
00414 ++block_resize;
00415
00416 int h = heightForWidth( 1000000 );
00417 int w = TQMenuBar::sizeHint().width();
00418
00419 while( heightForWidth( w + 12 ) > h )
00420 w += 12;
00421 while( heightForWidth( w + 4 ) > h )
00422 w += 4;
00423 while( heightForWidth( w ) > h )
00424 ++w;
00425 --block_resize;
00426 return TQSize( w, h );
00427 }
00428
00429 #ifdef Q_WS_X11
00430 bool KMenuBar::x11Event( XEvent* ev )
00431 {
00432 if( ev->type == ClientMessage && ev->xclient.message_type == msg_type_atom
00433 && ev->xclient.window == winId())
00434 {
00435
00436
00437
00438
00439 d->min_size = TQSize( ev->xclient.data.l[ 1 ], ev->xclient.data.l[ 2 ] );
00440
00441 updateMenuBarSize();
00442 return true;
00443 }
00444 return TQMenuBar::x11Event( ev );
00445 }
00446 #endif
00447
00448 void KMenuBar::updateMenuBarSize()
00449 {
00450 menuContentsChanged();
00451 resize( sizeHint());
00452 }
00453
00454 void KMenuBar::setFrameStyle( int style )
00455 {
00456 if( d->topLevel )
00457 d->frameStyle = style;
00458 else
00459 TQMenuBar::setFrameStyle( style );
00460 }
00461
00462 void KMenuBar::setLineWidth( int width )
00463 {
00464 if( d->topLevel )
00465 d->lineWidth = width;
00466 else
00467 TQMenuBar::setLineWidth( width );
00468 }
00469
00470 void KMenuBar::setMargin( int margin )
00471 {
00472 if( d->topLevel )
00473 d->margin = margin;
00474 else
00475 TQMenuBar::setMargin( margin );
00476 }
00477
00478 void KMenuBar::closeEvent( TQCloseEvent* e )
00479 {
00480 if( d->topLevel )
00481 e->ignore();
00482 else
00483 TQMenuBar::closeEvent( e );
00484 }
00485
00486 void KMenuBar::drawContents( TQPainter* p )
00487 {
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 if( !d->topLevel )
00500 {
00501 TQMenuBar::drawContents(p);
00502 }
00503 else
00504 {
00505 bool up_enabled = isUpdatesEnabled();
00506 BackgroundMode bg_mode = backgroundMode();
00507 BackgroundOrigin bg_origin = backgroundOrigin();
00508
00509 setUpdatesEnabled(false);
00510 setBackgroundMode(X11ParentRelative);
00511 setBackgroundOrigin(WindowOrigin);
00512
00513 p->eraseRect( rect() );
00514 erase();
00515
00516 TQColorGroup g = colorGroup();
00517 bool e;
00518
00519 for ( int i=0; i<(int)count(); i++ )
00520 {
00521 TQMenuItem *mi = findItem( idAt( i ) );
00522
00523 if ( !mi->text().isNull() || mi->pixmap() )
00524 {
00525 TQRect r = itemRect(i);
00526 if(r.isEmpty() || !mi->isVisible())
00527 continue;
00528
00529 e = mi->isEnabledAndVisible();
00530 if ( e )
00531 g = isEnabled() ? ( isActiveWindow() ? palette().active() :
00532 palette().inactive() ) : palette().disabled();
00533 else
00534 g = palette().disabled();
00535
00536 bool item_active = ( actItem == i );
00537
00538 p->setClipRect(r);
00539
00540 if( item_active )
00541 {
00542 TQStyle::SFlags flags = TQStyle::Style_Default;
00543 if (isEnabled() && e)
00544 flags |= TQStyle::Style_Enabled;
00545 if ( item_active )
00546 flags |= TQStyle::Style_Active;
00547 if ( item_active && actItemDown )
00548 flags |= TQStyle::Style_Down;
00549 flags |= TQStyle::Style_HasFocus;
00550
00551 style().drawControl(TQStyle::CE_MenuBarItem, p, this,
00552 r, g, flags, TQStyleOption(mi));
00553 }
00554 else
00555 {
00556 style().drawItem(p, r, AlignCenter | AlignVCenter | ShowPrefix,
00557 g, e, mi->pixmap(), mi->text());
00558 }
00559 }
00560 }
00561
00562 setBackgroundOrigin(bg_origin);
00563 setBackgroundMode(bg_mode);
00564 setUpdatesEnabled(up_enabled);
00565 }
00566 }
00567
00568 void KMenuBar::virtual_hook( int, void* )
00569 { }
00570
00571 #include "tdemenubar.moc"