~ubuntu-branches/ubuntu/quantal/muse/quantal

« back to all changes in this revision

Viewing changes to muse/widgets/popupmenu.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fabrice Coutadeur
  • Date: 2010-11-17 21:43:38 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20101117214338-1hvfl7oo2dsqnvrb
Tags: 1.1-0ubuntu1
* New upstream release (LP: #668631)
* Switch to dpkg-source 3.0 (quilt) format
* Switch to dh7 short form
* debian/rules:
  - added --enable-dssi and --enable-osc to conf flags for dssi support
  - added -ljackserver to LDFLAGS to fix a FTBFS because of --as-needed
* debian/control:
  - added build build dependency on liblo-dev and dssi-dev for dssi support
  - bump Standards-version to 3.9.1. No changes required.
* debian/muse.desktop, debian/muse.xpm: dropped as desktop file and icon is
  now shipped upstream.
* fix-desktop-categories.patch: fix Categories tag in upstream desktop file
* 10_es_locale_fix.dpatch: refreshed and converted to quilt as
  fix_es_locale.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=========================================================
 
2
//  MusE
 
3
//  Linux Music Editor
 
4
//  $Id: popupmenu.cpp,v 1.1.1.1 2010/07/18 03:21:00 terminator356 Exp $
 
5
//
 
6
//  (C) Copyright 1999-2010 Werner Schweer (ws@seh.de)
 
7
//
 
8
//  PopupMenu sub-class of QPopupMenu created by Tim.
 
9
//=========================================================
 
10
 
 
11
 
 
12
 
 
13
//=========================================================
 
14
//
 
15
// NOTICE: This sub-class of QPopupMenu *automatically* deletes
 
16
//          and *clears* any sub popup menus, when clear() is called.
 
17
//         Therefore a parent widget is *not* necessary when 
 
18
//          creating sub popup menus to add to the popup.
 
19
//
 
20
//=========================================================
 
21
 
 
22
 
 
23
// MusE: want no menu bar here. Can't use, not needed for now anyway.
 
24
#define QT_NO_MENUBAR
 
25
#define QT_NO_WHATSTHIS
 
26
 
 
27
#include <qapplication.h>
 
28
//#include <qtimer.h>
 
29
#include <qguardedptr.h>
 
30
//#include <qmenubar.h>
 
31
//#include <qstyle.h>
 
32
//#include <qdatetime.h>
 
33
 
 
34
#include "popupmenu.h"
 
35
 
 
36
// used to provide ONE single-shot timer
 
37
//static QTimer * singleSingleShot = 0;
 
38
//static bool preventAnimation = FALSE;
 
39
// Used to detect motion prior to mouse-release
 
40
static int motion;
 
41
static PopupMenu* active_popup_menu = 0;
 
42
 
 
43
/*
 
44
static void cleanup()
 
45
{
 
46
    delete singleSingleShot;
 
47
    singleSingleShot = 0;
 
48
}
 
49
 
 
50
static void popupSubMenuLater( int msec, QPopupMenu * receiver ) {
 
51
//static void popupSubMenuLater( int msec, PopupMenu * receiver ) {
 
52
    if ( !singleSingleShot ) {
 
53
        singleSingleShot = new QTimer( qApp, "popup submenu timer" );
 
54
        qAddPostRoutine( cleanup );
 
55
    }
 
56
 
 
57
    singleSingleShot->disconnect( SIGNAL(timeout()) );
 
58
    QObject::connect( singleSingleShot, SIGNAL(timeout()),
 
59
                      receiver, SLOT(subMenuTimer()) );
 
60
    singleSingleShot->start( msec, TRUE );
 
61
}
 
62
*/
 
63
 
 
64
/*
 
65
//======================
 
66
// MenuDataData
 
67
//======================
 
68
 
 
69
class QMenuDataData {
 
70
public:
 
71
    QMenuDataData();
 
72
    QGuardedPtr<QWidget> aWidget;
 
73
    int aInt;
 
74
};
 
75
 
 
76
//======================
 
77
// QPopupMenuPrivate
 
78
//======================
 
79
 
 
80
class QPopupMenuPrivate {
 
81
public:
 
82
    struct Scroll {
 
83
        enum { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
 
84
        uint scrollable : 2;
 
85
        uint direction : 1;
 
86
        int topScrollableIndex, scrollableSize;
 
87
        QTime lastScroll;
 
88
        QTimer *scrolltimer;
 
89
    } scroll;
 
90
    QSize calcSize;
 
91
    QRegion mouseMoveBuffer;
 
92
};
 
93
*/
 
94
 
 
95
//======================
 
96
// PopupMenu
 
97
//======================
 
98
 
 
99
PopupMenu::PopupMenu(QWidget* parent, const char* name) 
 
100
          : QPopupMenu(parent, name)
 
101
{
 
102
  // It's too bad QPopupMenu::d is private. 
 
103
  // It will be redundant and this will be our own private member.
 
104
  //d = new QPopupMenuPrivate;
 
105
  //d->scroll.scrollableSize = d->scroll.topScrollableIndex = 0;
 
106
  //d->scroll.scrollable = QPopupMenuPrivate::Scroll::ScrollNone;
 
107
  //d->scroll.scrolltimer = 0;
 
108
}
 
109
 
 
110
PopupMenu::~PopupMenu()
 
111
{
 
112
  //if(d->scroll.scrolltimer)
 
113
  //  delete d->scroll.scrolltimer;
 
114
 
 
115
  //preventAnimation = FALSE;
 
116
  //delete d;
 
117
  
 
118
  // Make sure to clear the popup so that any child popups are also deleted !
 
119
  //popup->clear();
 
120
}
 
121
 
 
122
void PopupMenu::menuDelPopup(QPopupMenu *popup)
 
123
{
 
124
  //printf("PopupMenu::menuDelPopup deleting popup...\n");
 
125
  
 
126
  // Make sure to clear the popup so that any child popups are also deleted !
 
127
  // Tested OK. All the popups are deleted.
 
128
  popup->clear();
 
129
  
 
130
  popup->disconnect( SIGNAL(activatedRedirect(int)) );
 
131
  popup->disconnect( SIGNAL(highlightedRedirect(int)) );
 
132
  disconnect( popup, SIGNAL(destroyed(QObject*)),
 
133
              this, SLOT(popupDestroyed(QObject*)) );
 
134
  delete popup;
 
135
}
 
136
 
 
137
/*
 
138
void PopupMenu::setFirstItemActive()
 
139
{
 
140
    QMenuItemListIt it(*QPopupMenu::mitems);
 
141
    register QMenuItem *mi;
 
142
    int ai = 0;
 
143
    //if(d->scroll.scrollable)
 
144
    //    ai = d->scroll.topScrollableIndex;
 
145
    while ( (mi=it.current()) ) 
 
146
    {
 
147
        ++it;
 
148
        if(!mi->isSeparator() && mi->id() != QMenuData::d->aInt &&
 
149
           (style().styleHint(QStyle::SH_PopupMenu_AllowActiveAndDisabled, this) || mi->isEnabledAndVisible())) 
 
150
        {
 
151
          setActiveItem( ai );
 
152
          return;
 
153
        }
 
154
        ai++;
 
155
    }
 
156
    QPopupMenu::actItem = -1;
 
157
}
 
158
*/
 
159
 
 
160
/*
 
161
void PopupMenu::hideAllPopups()
 
162
{
 
163
    //register QMenuData *top = this;             // find top level popup
 
164
    register MenuData *top = this;             // find top level popup
 
165
    if ( !preventAnimation )
 
166
        QTimer::singleShot( 10, this, SLOT(allowAnimation()) );
 
167
    preventAnimation = TRUE;
 
168
 
 
169
    if ( !isPopup() )
 
170
        return; // nothing to do
 
171
 
 
172
    //while ( top->parentMenu && top->parentMenu->isPopupMenu
 
173
    while ( top->parentMenu && ((MenuData*)top->parentMenu)->isPopupMenu
 
174
            //&& ((QPopupMenu*)top->parentMenu)->isPopup() )
 
175
            && ((PopupMenu*)((MenuData*)top->parentMenu))->isPopup() )
 
176
        //top = top->parentMenu;
 
177
        top = (MenuData*)top->parentMenu;
 
178
    //((QPopupMenu*)top)->hide();                 // cascade from top level
 
179
    ((PopupMenu*)top)->hide();                 // cascade from top level
 
180
 
 
181
#ifndef QT_NO_WHATSTHIS
 
182
    if (whatsThisItem) {
 
183
        qWhatsThisBDH();
 
184
        whatsThisItem = 0;
 
185
    }
 
186
#endif
 
187
 
 
188
}
 
189
*/
 
190
 
 
191
/*
 
192
void PopupMenu::hidePopups()
 
193
{
 
194
    if ( !preventAnimation )
 
195
        QTimer::singleShot( 10, this, SLOT(allowAnimation()) );
 
196
    preventAnimation = TRUE;
 
197
 
 
198
    //QMenuItemListIt it(*mitems);
 
199
    QMenuItemListIt it(*MenuData::mitems);
 
200
    register QMenuItem *mi;
 
201
    while ( (mi=it.current()) ) {
 
202
        ++it;
 
203
        if ( mi->popup() && mi->popup()->parentMenu == this ) //avoid circularity
 
204
            mi->popup()->hide();
 
205
    }
 
206
    popupActive = -1;                           // no active sub menu
 
207
    if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this))
 
208
        d->mouseMoveBuffer = QRegion();
 
209
 
 
210
    QRect mfrect = itemGeometry( actItem );
 
211
    setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
 
212
}
 
213
*/
 
214
 
 
215
bool PopupMenu::tryMenuBar( QMouseEvent *e )
 
216
{
 
217
    register QMenuData *top = this;             // find top level
 
218
    //register PopupMenu *top = this;             // find top level
 
219
    //while ( top->parentMenu )
 
220
    while ( ((PopupMenu*)top)->parentMenu )
 
221
        //top = top->parentMenu;
 
222
        //top = (MenuData*)top->parentMenu;
 
223
        top = ((PopupMenu*)top)->parentMenu;
 
224
#ifndef QT_NO_MENUBAR
 
225
    return top->isMenuBar ?
 
226
        ((QMenuBar *)top)->tryMouseEvent( this, e ) :
 
227
                              ((QPopupMenu*)top)->tryMouseEvent(this, e );
 
228
#else
 
229
    //return ((QPopupMenu*)top)->tryMouseEvent(this, e );
 
230
    return ((PopupMenu*)top)->tryMouseEvent(this, e );
 
231
#endif
 
232
}
 
233
 
 
234
//bool PopupMenu::tryMouseEvent( QPopupMenu *p, QMouseEvent * e)
 
235
bool PopupMenu::tryMouseEvent( PopupMenu *p, QMouseEvent * e)
 
236
{
 
237
    if ( p == this )
 
238
        return FALSE;
 
239
    QPoint pos = mapFromGlobal( e->globalPos() );
 
240
    if ( !rect().contains( pos ) )              // outside
 
241
        return FALSE;
 
242
    QMouseEvent ee( e->type(), pos, e->globalPos(), e->button(), e->state() );
 
243
    event( &ee );
 
244
    return TRUE;
 
245
}
 
246
 
 
247
/*
 
248
void PopupMenu::byeMenuBar()
 
249
{
 
250
#ifndef QT_NO_MENUBAR
 
251
    //register QMenuData *top = this;             // find top level
 
252
    register MenuData *top = this;             // find top level
 
253
    while ( top->parentMenu )
 
254
        top = top->parentMenu;
 
255
#endif
 
256
    hideAllPopups();
 
257
#ifndef QT_NO_MENUBAR
 
258
    if ( top->isMenuBar )
 
259
        ((QMenuBar *)top)->goodbye();
 
260
#endif
 
261
}
 
262
*/
 
263
 
 
264
void PopupMenu::actSig(int id, bool inwhatsthis)
 
265
{
 
266
    if(!inwhatsthis) 
 
267
    {
 
268
      emit activated( id );
 
269
#if defined(QT_ACCESSIBILITY_SUPPORT)
 
270
      if(!fromAccel)
 
271
        QAccessible::updateAccessibility(this, indexOf(id)+1, QAccessible::MenuCommand);
 
272
#endif
 
273
    } 
 
274
    else 
 
275
    {
 
276
#ifndef QT_NO_WHATSTHIS
 
277
      QRect r(itemGeometry(indexOf(id)));
 
278
      QPoint p(r.center().x(), r.bottom());
 
279
      QString whatsThis = findItem(id)->whatsThis();
 
280
      if(whatsThis.isNull())
 
281
        whatsThis = QWhatsThis::textFor(this, p);
 
282
      QWhatsThis::leaveWhatsThisMode(whatsThis, mapToGlobal(p), this);
 
283
#endif
 
284
    }
 
285
 
 
286
    emit activatedRedirect(id);
 
287
}
 
288
 
 
289
/*
 
290
void PopupMenu::mousePressEvent(QMouseEvent *e)
 
291
{
 
292
    printf("PopupMenu::mousePressEvent\n");
 
293
    
 
294
    
 
295
    //int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
296
    //if (rect().contains(e->pos()) &&
 
297
    //    ((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up
 
298
    //     (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown &&
 
299
    //         e->pos().y() >= contentsRect().height() - sh))) //down
 
300
    //    return;
 
301
    
 
302
    mouseBtDn = TRUE;                           // mouse button down
 
303
    int item = itemAtPos( e->pos() );
 
304
    if ( item == -1 ) {
 
305
        //if ( !rect().contains(e->pos()) && !tryMenuBar(e) ) {
 
306
        //    byeMenuBar();
 
307
        //}
 
308
        return;
 
309
    }
 
310
    register QMenuItem *mi = mitems->at(item);
 
311
    ///if ( item != actItem )                      // new item activated
 
312
    ///    setActiveItem( item );
 
313
 
 
314
    QPopupMenu *popup = mi->popup();
 
315
    if(popup) 
 
316
    {
 
317
        if(popup->isVisible())              // sub menu already open
 
318
        {    
 
319
            //int pactItem = popup->actItem;
 
320
            //popup->actItem = -1;
 
321
            //popup->hidePopups();
 
322
            //popup->updateRow( pactItem );
 
323
        } 
 
324
        else                                 // open sub menu
 
325
        {    
 
326
            //hidePopups();
 
327
            popupSubMenuLater( 20, this );
 
328
        }
 
329
    } 
 
330
    else 
 
331
    {
 
332
        //hidePopups();
 
333
    }
 
334
}
 
335
*/
 
336
 
 
337
void PopupMenu::mouseReleaseEvent(QMouseEvent *e)
 
338
{
 
339
    // do not hide a standalone context menu on press-release, unless
 
340
    // the user moved the mouse significantly
 
341
    //if(!parentMenu && !mouseBtDn && actItem < 0 && motion < 6)
 
342
    //  return;
 
343
 
 
344
    //mouseBtDn = FALSE;
 
345
    //MenuData::mouseBtDn = FALSE;
 
346
    QPopupMenu::mouseBtDn = FALSE;
 
347
 
 
348
    // if the user released the mouse outside the menu, pass control
 
349
    // to the menubar or our parent menu
 
350
    //int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
351
    if(!rect().contains(e->pos()) && tryMenuBar(e))
 
352
      return;
 
353
    //else 
 
354
    //if((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up
 
355
    //   (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown &&
 
356
    //    e->pos().y() >= contentsRect().height() - sh)) //down
 
357
    //  return;
 
358
 
 
359
    if(QPopupMenu::actItem < 0) 
 
360
    { 
 
361
      // we do not have an active item
 
362
      // if the release is inside without motion (happens with
 
363
      // oversized popup menus on small screens), ignore it
 
364
      if(rect().contains(e->pos()) && motion < 6)
 
365
        return;
 
366
      ///else
 
367
      ///  byeMenuBar();
 
368
    } 
 
369
    else 
 
370
    { 
 
371
      // selected menu item!
 
372
      register QMenuItem *mi = QPopupMenu::mitems->at(QPopupMenu::actItem);
 
373
      if(mi->widget()) 
 
374
      {
 
375
        QWidget* widgetAt = QApplication::widgetAt(e->globalPos(), TRUE);
 
376
        if(widgetAt && widgetAt != this) 
 
377
        {
 
378
          QMouseEvent me(e->type(), widgetAt->mapFromGlobal(e->globalPos()),
 
379
                         e->globalPos(), e->button(), e->state());
 
380
          QApplication::sendEvent( widgetAt, &me );
 
381
        }
 
382
      }
 
383
      //QPopupMenu *popup = mi->popup();
 
384
      PopupMenu *popup = (PopupMenu*)mi->popup();
 
385
#ifndef QT_NO_WHATSTHIS
 
386
      bool b = QWhatsThis::inWhatsThisMode();
 
387
#else
 
388
      const bool b = FALSE;
 
389
#endif
 
390
      if(!mi->isEnabledAndVisible()) 
 
391
      {
 
392
#ifndef QT_NO_WHATSTHIS
 
393
        if(b) 
 
394
        {
 
395
          actItem = -1;
 
396
          updateItem(mi->id());
 
397
          byeMenuBar();
 
398
          actSig(mi->id(), b);
 
399
        }
 
400
#endif
 
401
      } 
 
402
      else  
 
403
      if(popup) 
 
404
      {
 
405
        //popup->setFirstItemActive();
 
406
      } 
 
407
      else 
 
408
      {                                
 
409
        // normal menu item
 
410
        ///byeMenuBar();       // deactivate menu bar
 
411
        if(mi->isEnabledAndVisible()) 
 
412
        {
 
413
          ///QPopupMenu::actItem = -1;
 
414
          QPopupMenu::updateItem(mi->id());
 
415
          active_popup_menu = this;
 
416
          QGuardedPtr<QSignal> signal = mi->signal();
 
417
          actSig(mi->id(), b);
 
418
          if(signal && !b)
 
419
            signal->activate();
 
420
          active_popup_menu = 0;
 
421
        }
 
422
      }
 
423
    }
 
424
}
 
425
 
 
426
 
 
427
 
 
428
 
 
429
 
 
430
 
 
431
/****************************************************************************
 
432
**
 
433
** Implementation of QPopupMenu class
 
434
**
 
435
** Created : 941128
 
436
**
 
437
** Copyright (C) 1992-2008 Trolltech ASA.  All rights reserved.
 
438
**
 
439
** This file is part of the widgets module of the Qt GUI Toolkit.
 
440
**
 
441
** This file may be used under the terms of the GNU General
 
442
** Public License versions 2.0 or 3.0 as published by the Free
 
443
** Software Foundation and appearing in the files LICENSE.GPL2
 
444
** and LICENSE.GPL3 included in the packaging of this file.
 
445
** Alternatively you may (at your option) use any later version
 
446
** of the GNU General Public License if such license has been
 
447
** publicly approved by Trolltech ASA (or its successors, if any)
 
448
** and the KDE Free Qt Foundation.
 
449
**
 
450
** Please review the following information to ensure GNU General
 
451
** Public Licensing requirements will be met:
 
452
** http://trolltech.com/products/qt/licenses/licensing/opensource/.
 
453
** If you are unsure which license is appropriate for your use, please
 
454
** review the following information:
 
455
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
 
456
** or contact the sales department at sales@trolltech.com.
 
457
**
 
458
** This file may be used under the terms of the Q Public License as
 
459
** defined by Trolltech ASA and appearing in the file LICENSE.QPL
 
460
** included in the packaging of this file.  Licensees holding valid Qt
 
461
** Commercial licenses may use this file in accordance with the Qt
 
462
** Commercial License Agreement provided with the Software.
 
463
**
 
464
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
 
465
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
 
466
** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
 
467
** herein.
 
468
**
 
469
**********************************************************************/
 
470
 
 
471
/*
 
472
#include "popupmenu.h"
 
473
#ifndef QT_NO_POPUPMENU
 
474
#include <qmenubar.h>
 
475
#include <qaccel.h>
 
476
#include <qpainter.h>
 
477
#include <qdrawutil.h>
 
478
#include <qapplication.h>
 
479
#include <qpixmap.h>
 
480
#include <qpixmapcache.h>
 
481
#include <qtimer.h>
 
482
#include <qwhatsthis.h>
 
483
#include <qobjectlist.h>
 
484
#include <qguardedptr.h>
 
485
//#include <qeffects_p.h>
 
486
#include <qcursor.h>
 
487
#include <qstyle.h>
 
488
#include <qtimer.h>
 
489
#include <qdatetime.h>
 
490
#if defined(QT_ACCESSIBILITY_SUPPORT)
 
491
#include <qaccessible.h>
 
492
#endif
 
493
 
 
494
//#define ANIMATED_POPUP
 
495
//#define BLEND_POPUP
 
496
 
 
497
// Motif style parameters
 
498
 
 
499
static const int motifArrowHMargin      = 6;    // arrow horizontal margin
 
500
static const int motifArrowVMargin      = 2;    // arrow vertical margin
 
501
 
 
502
#if 0
 
503
# define DEBUG_SLOPPY_SUBMENU
 
504
#endif
 
505
 
 
506
// used for internal communication
 
507
static PopupMenu * syncMenu = 0;
 
508
static int syncMenuId = 0;
 
509
 
 
510
// Used to detect motion prior to mouse-release
 
511
static int motion;
 
512
 
 
513
// used to provide ONE single-shot timer
 
514
static QTimer * singleSingleShot = 0;
 
515
 
 
516
static bool supressAboutToShow = FALSE;
 
517
 
 
518
static void cleanup()
 
519
{
 
520
    delete singleSingleShot;
 
521
    singleSingleShot = 0;
 
522
}
 
523
 
 
524
static void popupSubMenuLater( int msec, PopupMenu * receiver ) {
 
525
    if ( !singleSingleShot ) {
 
526
        singleSingleShot = new QTimer( qApp, "popup submenu timer" );
 
527
        qAddPostRoutine( cleanup );
 
528
    }
 
529
 
 
530
    singleSingleShot->disconnect( SIGNAL(timeout()) );
 
531
    QObject::connect( singleSingleShot, SIGNAL(timeout()),
 
532
                      receiver, SLOT(subMenuTimer()) );
 
533
    singleSingleShot->start( msec, TRUE );
 
534
}
 
535
 
 
536
static bool preventAnimation = FALSE;
 
537
 
 
538
#ifndef QT_NO_WHATSTHIS
 
539
extern void qWhatsThisBDH();
 
540
static QMenuItem* whatsThisItem = 0;
 
541
#endif
 
542
 
 
543
class QMenuDataData {
 
544
    // attention: also defined in qmenudata.cpp
 
545
public:
 
546
    QMenuDataData();
 
547
    QGuardedPtr<QWidget> aWidget;
 
548
    int aInt;
 
549
};
 
550
 
 
551
class QPopupMenuPrivate {
 
552
public:
 
553
    struct Scroll {
 
554
        enum { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
 
555
        uint scrollable : 2;
 
556
        uint direction : 1;
 
557
        int topScrollableIndex, scrollableSize;
 
558
        QTime lastScroll;
 
559
        QTimer *scrolltimer;
 
560
    } scroll;
 
561
    QSize calcSize;
 
562
    QRegion mouseMoveBuffer;
 
563
};
 
564
 
 
565
static PopupMenu* active_popup_menu = 0;
 
566
 
 
567
PopupMenu::PopupMenu( QWidget *parent, const char *name )
 
568
    : QFrame( parent, name, WType_Popup  | WNoAutoErase )
 
569
{
 
570
    d = new QPopupMenuPrivate;
 
571
    d->scroll.scrollableSize = d->scroll.topScrollableIndex = 0;
 
572
    d->scroll.scrollable = QPopupMenuPrivate::Scroll::ScrollNone;
 
573
    d->scroll.scrolltimer = 0;
 
574
    isPopupMenu   = TRUE;
 
575
#ifndef QT_NO_ACCEL
 
576
    autoaccel     = 0;
 
577
    accelDisabled = FALSE;
 
578
#endif
 
579
    popupActive   = -1;
 
580
    snapToMouse   = TRUE;
 
581
    tab = 0;
 
582
    checkable = 0;
 
583
    tornOff = 0;
 
584
    pendingDelayedContentsChanges = 0;
 
585
    pendingDelayedStateChanges = 0;
 
586
    maxPMWidth = 0;
 
587
 
 
588
    tab = 0;
 
589
    ncols = 1;
 
590
    setFrameStyle( QFrame::PopupPanel | QFrame::Raised );
 
591
    setMouseTracking(style().styleHint(QStyle::SH_PopupMenu_MouseTracking, this));
 
592
    //style().polishPopupMenu( this );
 
593
    style().polishPopupMenu( (QPopupMenu*)this );
 
594
    setBackgroundMode( PaletteButton );
 
595
    connectModalRecursionSafety = 0;
 
596
 
 
597
    setFocusPolicy( StrongFocus );
 
598
}
 
599
 
 
600
PopupMenu::~PopupMenu()
 
601
{
 
602
    if ( syncMenu == this && qApp ) {
 
603
        qApp->exit_loop();
 
604
        syncMenu = 0;
 
605
    }
 
606
 
 
607
    if(d->scroll.scrolltimer)
 
608
        delete d->scroll.scrolltimer;
 
609
 
 
610
    if ( isVisible() ) {
 
611
        parentMenu = 0;
 
612
        hidePopups();
 
613
    }
 
614
 
 
615
    delete (QWidget*) QMenuData::d->aWidget;  // tear-off menu
 
616
 
 
617
    preventAnimation = FALSE;
 
618
    delete d;
 
619
}
 
620
 
 
621
 
 
622
void PopupMenu::updateItem( int id )           // update popup menu item
 
623
{
 
624
    updateRow( indexOf(id) );
 
625
}
 
626
 
 
627
 
 
628
void PopupMenu::setCheckable( bool enable )
 
629
{
 
630
    if ( isCheckable() != enable ) {
 
631
        checkable = enable;
 
632
        badSize = TRUE;
 
633
        if ( QMenuData::d->aWidget )
 
634
            ( (PopupMenu*)(QWidget*)QMenuData::d->aWidget)->setCheckable( enable );
 
635
    }
 
636
}
 
637
 
 
638
bool PopupMenu::isCheckable() const
 
639
{
 
640
    return checkable;
 
641
}
 
642
 
 
643
void PopupMenu::menuContentsChanged()
 
644
{
 
645
    // here the part that can't be delayed
 
646
    QMenuData::menuContentsChanged();
 
647
    badSize = TRUE;                             // might change the size
 
648
#if defined(Q_WS_MAC) && !defined(QMAC_QMENUBAR_NO_NATIVE)
 
649
    mac_dirty_popup = 1;
 
650
#endif
 
651
    if( pendingDelayedContentsChanges )
 
652
        return;
 
653
    pendingDelayedContentsChanges = 1;
 
654
    if( !pendingDelayedStateChanges ) // if the timer hasn't been started yet
 
655
        QTimer::singleShot( 0, this, SLOT(performDelayedChanges()));
 
656
}
 
657
 
 
658
void PopupMenu::performDelayedContentsChanged()
 
659
{
 
660
    pendingDelayedContentsChanges = 0;
 
661
    // here the part the can be delayed
 
662
#ifndef QT_NO_ACCEL
 
663
    // if performDelayedStateChanged() will be called too,
 
664
    // it will call updateAccel() too, no need to do it twice
 
665
    if( !pendingDelayedStateChanges )
 
666
        updateAccel( 0 );
 
667
#endif
 
668
    if ( isVisible() ) {
 
669
        if ( tornOff )
 
670
            return;
 
671
        updateSize(TRUE);
 
672
        update();
 
673
    }
 
674
    PopupMenu* p = (PopupMenu*)(QWidget*)QMenuData::d->aWidget;
 
675
    if ( p && p->isVisible() ) {
 
676
        p->updateSize(TRUE);
 
677
        p->update();
 
678
    }
 
679
#if defined(Q_WS_MAC) && !defined(QMAC_QMENUBAR_NO_NATIVE)
 
680
    mac_dirty_popup = 1;
 
681
#endif
 
682
}
 
683
 
 
684
 
 
685
void PopupMenu::menuStateChanged()
 
686
{
 
687
    // here the part that can't be delayed
 
688
    if( pendingDelayedStateChanges )
 
689
        return;
 
690
    pendingDelayedStateChanges = 1;
 
691
    if( !pendingDelayedContentsChanges ) // if the timer hasn't been started yet
 
692
        QTimer::singleShot( 0, this, SLOT(performDelayedChanges()));
 
693
}
 
694
 
 
695
void PopupMenu::performDelayedStateChanged()
 
696
{
 
697
    pendingDelayedStateChanges = 0;
 
698
    // here the part that can be delayed
 
699
#ifndef QT_NO_ACCEL
 
700
    updateAccel( 0 ); // ### when we have a good solution for the accel vs. focus widget problem, remove that. That is only a workaround
 
701
    // if you remove this, see performDelayedContentsChanged()
 
702
#endif
 
703
    update();
 
704
    if ( QMenuData::d->aWidget )
 
705
        QMenuData::d->aWidget->update();
 
706
}
 
707
 
 
708
void PopupMenu::performDelayedChanges()
 
709
{
 
710
    if( pendingDelayedContentsChanges )
 
711
        performDelayedContentsChanged();
 
712
    if( pendingDelayedStateChanges )
 
713
        performDelayedStateChanged();
 
714
}
 
715
 
 
716
void PopupMenu::menuInsPopup( PopupMenu *popup )
 
717
{
 
718
    connect( popup, SIGNAL(activatedRedirect(int)),
 
719
             SLOT(subActivated(int)) );
 
720
    connect( popup, SIGNAL(highlightedRedirect(int)),
 
721
             SLOT(subHighlighted(int)) );
 
722
    connect( popup, SIGNAL(destroyed(QObject*)),
 
723
             this, SLOT(popupDestroyed(QObject*)) );
 
724
}
 
725
 
 
726
void PopupMenu::menuDelPopup( PopupMenu *popup )
 
727
{
 
728
    popup->disconnect( SIGNAL(activatedRedirect(int)) );
 
729
    popup->disconnect( SIGNAL(highlightedRedirect(int)) );
 
730
    disconnect( popup, SIGNAL(destroyed(QObject*)),
 
731
                this, SLOT(popupDestroyed(QObject*)) );
 
732
}
 
733
 
 
734
 
 
735
void PopupMenu::frameChanged()
 
736
{
 
737
    menuContentsChanged();
 
738
}
 
739
 
 
740
void PopupMenu::popup( const QPoint &pos, int indexAtPoint )
 
741
{
 
742
    if ( !isPopup() && isVisible() )
 
743
        hide();
 
744
 
 
745
    //avoid circularity
 
746
    if ( isVisible() || !isEnabled() )
 
747
        return;
 
748
 
 
749
#if defined(Q_WS_MAC) && !defined(QMAC_QMENUBAR_NO_NATIVE)
 
750
    if( macPopupMenu(pos, indexAtPoint ))
 
751
        return;
 
752
#endif
 
753
 
 
754
#if (QT_VERSION-0 >= 0x040000)
 
755
#error "Fix this now"
 
756
    // #### should move to QWidget - anything might need this functionality,
 
757
    // #### since anything can have WType_Popup window flag.
 
758
    // #### This includes stuff in QPushButton and some stuff for setting
 
759
    // #### the geometry of QDialog.
 
760
    // QPopupMenu
 
761
    // ::exec()
 
762
    // ::popup()
 
763
    // QPushButton (shouldn't require QMenuPopup)
 
764
    // ::popupPressed
 
765
    // Some stuff in qwidget.cpp for dialogs... can't remember exactly.
 
766
    // Also the code here indicatets the parameter should be a rect, not a
 
767
    // point.
 
768
#endif
 
769
 
 
770
    if(d->scroll.scrollable) {
 
771
        d->scroll.scrollable = QPopupMenuPrivate::Scroll::ScrollNone;
 
772
        d->scroll.topScrollableIndex = d->scroll.scrollableSize = 0;
 
773
        badSize = TRUE;
 
774
    }
 
775
    updateSize();
 
776
 
 
777
    QPoint mouse = QCursor::pos();
 
778
    snapToMouse = pos == mouse;
 
779
 
 
780
    // have to emit here as a menu might be setup in a slot connected
 
781
    // to aboutToShow which will change the size of the menu
 
782
    bool s = supressAboutToShow;
 
783
    supressAboutToShow = TRUE;
 
784
    if ( !s) {
 
785
        emit aboutToShow();
 
786
        updateSize(TRUE);
 
787
    }
 
788
 
 
789
    int screen_num;
 
790
    if (QApplication::desktop()->isVirtualDesktop())
 
791
        screen_num =
 
792
            QApplication::desktop()->screenNumber( QApplication::reverseLayout() ?
 
793
                                                   pos+QPoint(width(),0) : pos );
 
794
    else
 
795
        screen_num = QApplication::desktop()->screenNumber( this );
 
796
#ifdef Q_WS_MAC
 
797
    QRect screen = QApplication::desktop()->availableGeometry( screen_num );
 
798
#else
 
799
    QRect screen = QApplication::desktop()->screenGeometry( screen_num );
 
800
#endif
 
801
    int sw = screen.width();                    // screen width
 
802
    int sh = screen.height();                   // screen height
 
803
    int sx = screen.x();                        // screen pos
 
804
    int sy = screen.y();
 
805
    int x  = pos.x();
 
806
    int y  = pos.y();
 
807
    if ( indexAtPoint >= 0 )                    // don't subtract when < 0
 
808
        y -= itemGeometry( indexAtPoint ).y();          // (would subtract 2 pixels!)
 
809
    int w  = width();
 
810
    int h  = height();
 
811
 
 
812
    if ( snapToMouse ) {
 
813
        if ( qApp->reverseLayout() )
 
814
            x -= w;
 
815
        if ( x+w > sx+sw )
 
816
            x = mouse.x()-w;
 
817
        if ( y+h > sy+sh )
 
818
            y = mouse.y()-h;
 
819
        if ( x < sx )
 
820
            x = mouse.x();
 
821
        if ( y < sy )
 
822
            y = sy;
 
823
    }
 
824
 
 
825
    if ( x+w > sx+sw )                          // the complete widget must
 
826
        x = sx+sw - w;                          //   be visible
 
827
    if ( y+h > sy+sh )
 
828
        y = sy+sh - h;
 
829
    if ( x < sx )
 
830
        x = sx;
 
831
    if ( y < sy )
 
832
        y = sy;
 
833
 
 
834
    if(style().styleHint(QStyle::SH_PopupMenu_Scrollable, this)) {
 
835
        int off_top = 0, off_bottom = 0;
 
836
        if(y+h > sy+sh)
 
837
            off_bottom = (y+h) - (sy+sh);
 
838
        if(y < sy)
 
839
            off_top = sy - y;
 
840
        if(off_bottom || off_top) {
 
841
            int ch = updateSize().height(); //store the old height, before setting scrollable --Sam
 
842
            const int vextra = style().pixelMetric(QStyle::PM_PopupMenuFrameVerticalExtra, this);
 
843
            d->scroll.scrollableSize = h - off_top - off_bottom - 2*vextra;
 
844
            if(off_top) {
 
845
                move( x, y = sy );
 
846
                d->scroll.scrollable = d->scroll.scrollable | QPopupMenuPrivate::Scroll::ScrollUp;
 
847
            }
 
848
            if( off_bottom )
 
849
                d->scroll.scrollable = d->scroll.scrollable | QPopupMenuPrivate::Scroll::ScrollDown;
 
850
            if( off_top != off_bottom && indexAtPoint >= 0 ) {
 
851
                ch -= (vextra * 2);
 
852
                if(ch > sh) //no bigger than the screen!
 
853
                    ch = sh;
 
854
                if( ch > d->scroll.scrollableSize ) 
 
855
                    d->scroll.scrollableSize = ch;
 
856
            }
 
857
 
 
858
            updateSize(TRUE); //now set the size using the scrollable/scrollableSize as above
 
859
            w = width();
 
860
            h = height();
 
861
            if(indexAtPoint >= 0) { 
 
862
                if(off_top) { //scroll to it
 
863
                    register QMenuItem *mi = NULL;
 
864
                    QMenuItemListIt it(*mitems);
 
865
                    for(int tmp_y = 0; tmp_y < off_top && (mi=it.current()); ) {
 
866
                        QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this,
 
867
                                                            QSize(0, itemHeight( mi )),
 
868
                                                            QStyleOption(mi,maxPMWidth,0));
 
869
                        tmp_y += sz.height();
 
870
                        d->scroll.topScrollableIndex++;
 
871
                    }
 
872
                } 
 
873
            }
 
874
        }
 
875
    }
 
876
    move( x, y );
 
877
    motion=0;
 
878
    actItem = -1;
 
879
 
 
880
#ifndef QT_NO_EFFECTS
 
881
    int hGuess = qApp->reverseLayout() ? QEffects::LeftScroll : QEffects::RightScroll;
 
882
    int vGuess = QEffects::DownScroll;
 
883
    if ( qApp->reverseLayout() ) {
 
884
        if ( snapToMouse && ( x + w/2 > mouse.x() ) ||
 
885
            ( parentMenu && parentMenu->isPopupMenu &&
 
886
            ( x + w/2 > ((PopupMenu*)parentMenu)->x() ) ) )
 
887
            hGuess = QEffects::RightScroll;
 
888
    } else {
 
889
        if ( snapToMouse && ( x + w/2 < mouse.x() ) ||
 
890
            ( parentMenu && parentMenu->isPopupMenu &&
 
891
            ( x + w/2 < ((PopupMenu*)parentMenu)->x() ) ) )
 
892
            hGuess = QEffects::LeftScroll;
 
893
    }
 
894
 
 
895
#ifndef QT_NO_MENUBAR
 
896
    if ( snapToMouse && ( y + h/2 < mouse.y() ) ||
 
897
        ( parentMenu && parentMenu->isMenuBar &&
 
898
        ( y + h/2 < ((QMenuBar*)parentMenu)->mapToGlobal( ((QMenuBar*)parentMenu)->pos() ).y() ) ) )
 
899
        vGuess = QEffects::UpScroll;
 
900
#endif
 
901
 
 
902
    if ( QApplication::isEffectEnabled( UI_AnimateMenu ) &&
 
903
         preventAnimation == FALSE ) {
 
904
        if ( QApplication::isEffectEnabled( UI_FadeMenu ) )
 
905
            qFadeEffect( this );
 
906
        else if ( parentMenu )
 
907
            qScrollEffect( this, parentMenu->isPopupMenu ? hGuess : vGuess );
 
908
        else
 
909
            qScrollEffect( this, hGuess | vGuess );
 
910
    } else
 
911
#endif
 
912
    {
 
913
        show();
 
914
    }
 
915
#if defined(QT_ACCESSIBILITY_SUPPORT)
 
916
    QAccessible::updateAccessibility( this, 0, QAccessible::PopupMenuStart );
 
917
#endif
 
918
}
 
919
 
 
920
void PopupMenu::subActivated( int id )
 
921
{
 
922
    emit activatedRedirect( id );
 
923
}
 
924
 
 
925
void PopupMenu::subHighlighted( int id )
 
926
{
 
927
    emit highlightedRedirect( id );
 
928
}
 
929
 
 
930
static bool fromAccel = FALSE;
 
931
 
 
932
#ifndef QT_NO_ACCEL
 
933
void PopupMenu::accelActivated( int id )
 
934
{
 
935
    QMenuItem *mi = findItem( id );
 
936
    if ( mi && mi->isEnabledAndVisible() ) {
 
937
        QGuardedPtr<QSignal> signal = mi->signal();
 
938
        fromAccel = TRUE;
 
939
        actSig( mi->id() );
 
940
        fromAccel = FALSE;
 
941
        if ( signal )
 
942
            signal->activate();
 
943
    }
 
944
}
 
945
 
 
946
void PopupMenu::accelDestroyed()               // accel about to be deleted
 
947
{
 
948
    autoaccel = 0;                              // don't delete it twice!
 
949
}
 
950
#endif //QT_NO_ACCEL
 
951
 
 
952
void PopupMenu::popupDestroyed( QObject *o )
 
953
{
 
954
    removePopup( (PopupMenu*)o );
 
955
}
 
956
 
 
957
void PopupMenu::actSig( int id, bool inwhatsthis )
 
958
{
 
959
    if ( !inwhatsthis ) {
 
960
        emit activated( id );
 
961
#if defined(QT_ACCESSIBILITY_SUPPORT)
 
962
        if ( !fromAccel )
 
963
            QAccessible::updateAccessibility( this, indexOf(id)+1, QAccessible::MenuCommand );
 
964
#endif
 
965
    } else {
 
966
#ifndef QT_NO_WHATSTHIS
 
967
        QRect r( itemGeometry( indexOf( id ) ) );
 
968
        QPoint p( r.center().x(), r.bottom() );
 
969
        QString whatsThis = findItem( id )->whatsThis();
 
970
        if ( whatsThis.isNull() )
 
971
            whatsThis = QWhatsThis::textFor( this, p );
 
972
        QWhatsThis::leaveWhatsThisMode( whatsThis, mapToGlobal( p ), this );
 
973
#endif
 
974
    }
 
975
 
 
976
    emit activatedRedirect( id );
 
977
}
 
978
 
 
979
void PopupMenu::hilitSig( int id )
 
980
{
 
981
    emit highlighted( id );
 
982
    emit highlightedRedirect( id );
 
983
 
 
984
#if defined(QT_ACCESSIBILITY_SUPPORT)
 
985
    QAccessible::updateAccessibility( this, indexOf(id)+1, QAccessible::Focus );
 
986
    QAccessible::updateAccessibility( this, indexOf(id)+1, QAccessible::Selection );
 
987
#endif
 
988
}
 
989
 
 
990
void PopupMenu::setFirstItemActive()
 
991
{
 
992
    QMenuItemListIt it(*mitems);
 
993
    register QMenuItem *mi;
 
994
    int ai = 0;
 
995
    if(d->scroll.scrollable)
 
996
        ai = d->scroll.topScrollableIndex;
 
997
    while ( (mi=it.current()) ) {
 
998
        ++it;
 
999
        if ( !mi->isSeparator() && mi->id() != QMenuData::d->aInt &&
 
1000
             ( style().styleHint( QStyle::SH_PopupMenu_AllowActiveAndDisabled, this ) || mi->isEnabledAndVisible() )) {
 
1001
            setActiveItem( ai );
 
1002
            return;
 
1003
        }
 
1004
        ai++;
 
1005
    }
 
1006
    actItem = -1;
 
1007
}
 
1008
 
 
1009
void PopupMenu::hideAllPopups()
 
1010
{
 
1011
    register QMenuData *top = this;             // find top level popup
 
1012
    if ( !preventAnimation )
 
1013
        QTimer::singleShot( 10, this, SLOT(allowAnimation()) );
 
1014
    preventAnimation = TRUE;
 
1015
 
 
1016
    if ( !isPopup() )
 
1017
        return; // nothing to do
 
1018
 
 
1019
    while ( top->parentMenu && top->parentMenu->isPopupMenu
 
1020
            && ((PopupMenu*)top->parentMenu)->isPopup() )
 
1021
        top = top->parentMenu;
 
1022
    ((PopupMenu*)top)->hide();                 // cascade from top level
 
1023
 
 
1024
#ifndef QT_NO_WHATSTHIS
 
1025
    if (whatsThisItem) {
 
1026
        qWhatsThisBDH();
 
1027
        whatsThisItem = 0;
 
1028
    }
 
1029
#endif
 
1030
 
 
1031
}
 
1032
 
 
1033
void PopupMenu::hidePopups()
 
1034
{
 
1035
    if ( !preventAnimation )
 
1036
        QTimer::singleShot( 10, this, SLOT(allowAnimation()) );
 
1037
    preventAnimation = TRUE;
 
1038
 
 
1039
    QMenuItemListIt it(*mitems);
 
1040
    register QMenuItem *mi;
 
1041
    while ( (mi=it.current()) ) {
 
1042
        ++it;
 
1043
        if ( mi->popup() && mi->popup()->parentMenu == this ) //avoid circularity
 
1044
            mi->popup()->hide();
 
1045
    }
 
1046
    popupActive = -1;                           // no active sub menu
 
1047
    if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this))
 
1048
        d->mouseMoveBuffer = QRegion();
 
1049
 
 
1050
    QRect mfrect = itemGeometry( actItem );
 
1051
    setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
 
1052
}
 
1053
 
 
1054
bool PopupMenu::tryMenuBar( QMouseEvent *e )
 
1055
{
 
1056
    register QMenuData *top = this;             // find top level
 
1057
    while ( top->parentMenu )
 
1058
        top = top->parentMenu;
 
1059
#ifndef QT_NO_MENUBAR
 
1060
    return top->isMenuBar ?
 
1061
        ((QMenuBar *)top)->tryMouseEvent( this, e ) :
 
1062
                              ((PopupMenu*)top)->tryMouseEvent(this, e );
 
1063
#else
 
1064
    return ((PopupMenu*)top)->tryMouseEvent(this, e );
 
1065
#endif
 
1066
}
 
1067
 
 
1068
bool PopupMenu::tryMouseEvent( PopupMenu *p, QMouseEvent * e)
 
1069
{
 
1070
    if ( p == this )
 
1071
        return FALSE;
 
1072
    QPoint pos = mapFromGlobal( e->globalPos() );
 
1073
    if ( !rect().contains( pos ) )              // outside
 
1074
        return FALSE;
 
1075
    QMouseEvent ee( e->type(), pos, e->globalPos(), e->button(), e->state() );
 
1076
    event( &ee );
 
1077
    return TRUE;
 
1078
}
 
1079
 
 
1080
void PopupMenu::byeMenuBar()
 
1081
{
 
1082
#ifndef QT_NO_MENUBAR
 
1083
    register QMenuData *top = this;             // find top level
 
1084
    while ( top->parentMenu )
 
1085
        top = top->parentMenu;
 
1086
#endif
 
1087
    hideAllPopups();
 
1088
#ifndef QT_NO_MENUBAR
 
1089
    if ( top->isMenuBar )
 
1090
        ((QMenuBar *)top)->goodbye();
 
1091
#endif
 
1092
}
 
1093
 
 
1094
int PopupMenu::itemAtPos( const QPoint &pos, bool ignoreSeparator ) const
 
1095
{
 
1096
    if ( !contentsRect().contains(pos) )
 
1097
        return -1;
 
1098
 
 
1099
    int row = 0;
 
1100
    int x = contentsRect().x();
 
1101
    int y = contentsRect().y();
 
1102
    QMenuItem *mi;
 
1103
    QMenuItemListIt it( *mitems );
 
1104
    if(d->scroll.scrollable) {
 
1105
        if(d->scroll.topScrollableIndex) {
 
1106
            for( ; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++)
 
1107
                ++it;
 
1108
            if(!mi) {
 
1109
                row = 0;
 
1110
                it.toFirst();
 
1111
            }
 
1112
            y += style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
1113
        }
 
1114
    }
 
1115
    int itemw = contentsRect().width() / ncols;
 
1116
    QSize sz;
 
1117
    while ( (mi=it.current()) ) {
 
1118
        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown &&
 
1119
           y >= contentsRect().height() - style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this))
 
1120
            return -1;
 
1121
        ++it;
 
1122
        if ( !mi->isVisible() ) {
 
1123
            ++row;
 
1124
            continue;
 
1125
        }
 
1126
        int itemh = itemHeight( mi );
 
1127
 
 
1128
        sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this,
 
1129
                                      QSize(0, itemh),
 
1130
                                      QStyleOption(mi,maxPMWidth));
 
1131
        sz = sz.expandedTo(QSize(itemw, sz.height()));
 
1132
        itemw = sz.width();
 
1133
        itemh = sz.height();
 
1134
 
 
1135
        if ( ncols > 1 && y + itemh > contentsRect().bottom() ) {
 
1136
            y = contentsRect().y();
 
1137
            x +=itemw;
 
1138
        }
 
1139
        if ( QRect( x, y, itemw, itemh ).contains( pos ) )
 
1140
            break;
 
1141
        y += itemh;
 
1142
        ++row;
 
1143
    }
 
1144
 
 
1145
    if ( mi && ( !ignoreSeparator || !mi->isSeparator() ) )
 
1146
        return row;
 
1147
    return -1;
 
1148
}
 
1149
 
 
1150
QRect PopupMenu::itemGeometry( int index )
 
1151
{
 
1152
    QMenuItem *mi;
 
1153
    QSize sz;
 
1154
    int row = 0, scrollh = 0;
 
1155
    int x = contentsRect().x();
 
1156
    int y = contentsRect().y();
 
1157
    QMenuItemListIt it( *mitems );
 
1158
    if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp) {
 
1159
        scrollh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
1160
        y += scrollh;
 
1161
        if(d->scroll.topScrollableIndex) {
 
1162
            for( ; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++)
 
1163
                ++it;
 
1164
            if(!mi) {
 
1165
                row = 0;
 
1166
                it.toFirst();
 
1167
            }
 
1168
        }
 
1169
    }
 
1170
    int itemw = contentsRect().width() / ncols;
 
1171
    while ( (mi=it.current()) ) {
 
1172
        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown &&
 
1173
           y >= contentsRect().height() - scrollh)
 
1174
            break;
 
1175
        ++it;
 
1176
        if ( !mi->isVisible() ) {
 
1177
            ++row;
 
1178
            continue;
 
1179
        }
 
1180
        int itemh = itemHeight( mi );
 
1181
 
 
1182
        sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this,
 
1183
                                      QSize(0, itemh),
 
1184
                                      QStyleOption(mi,maxPMWidth));
 
1185
        sz = sz.expandedTo(QSize(itemw, sz.height()));
 
1186
        itemw = sz.width();
 
1187
        itemh = sz.height();
 
1188
        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown &&
 
1189
           (y + itemh > contentsRect().height() - scrollh))
 
1190
            itemh -= (y + itemh) - (contentsRect().height() - scrollh);
 
1191
        if ( ncols > 1 && y + itemh > contentsRect().bottom() ) {
 
1192
            y = contentsRect().y();
 
1193
            x +=itemw;
 
1194
        }
 
1195
        if ( row == index )
 
1196
            return QRect( x,y,itemw,itemh );
 
1197
        y += itemh;
 
1198
        ++row;
 
1199
    }
 
1200
 
 
1201
    return QRect(0,0,0,0);
 
1202
}
 
1203
 
 
1204
QSize PopupMenu::updateSize(bool force_update, bool do_resize)
 
1205
{
 
1206
    polish();
 
1207
    if ( count() == 0 ) {
 
1208
        QSize ret = QSize( 50, 8 );
 
1209
        if(do_resize)
 
1210
            setFixedSize( ret );
 
1211
        badSize = TRUE;
 
1212
        return ret;
 
1213
    }
 
1214
 
 
1215
    int scrheight = 0;
 
1216
    if(d->scroll.scrollableSize) {
 
1217
        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp)
 
1218
            scrheight += style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
1219
        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown)
 
1220
            scrheight += style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
1221
    }
 
1222
 
 
1223
    if(badSize || force_update) {
 
1224
#ifndef QT_NO_ACCEL
 
1225
        updateAccel( 0 );
 
1226
#endif
 
1227
        int height = 0;
 
1228
        int max_width = 0, max_height = 0;
 
1229
        QFontMetrics fm = fontMetrics();
 
1230
        register QMenuItem *mi;
 
1231
        maxPMWidth = 0;
 
1232
        int maxWidgetWidth = 0;
 
1233
        tab = 0;
 
1234
 
 
1235
        for ( QMenuItemListIt it( *mitems ); it.current(); ++it ) {
 
1236
            mi = it.current();
 
1237
            QWidget *miw = mi->widget();
 
1238
            if (miw) {
 
1239
                if ( miw->parentWidget() != this )
 
1240
                    miw->reparent( this, QPoint(0,0), TRUE );
 
1241
                // widget items musn't propgate mouse events
 
1242
                ((PopupMenu*)miw)->setWFlags(WNoMousePropagation);
 
1243
            }
 
1244
            if ( mi->custom() )
 
1245
                mi->custom()->setFont( font() );
 
1246
            if ( mi->iconSet() != 0)
 
1247
                maxPMWidth = QMAX( maxPMWidth,
 
1248
                                   mi->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4 );
 
1249
        }
 
1250
 
 
1251
        int dh = QApplication::desktop()->height();
 
1252
        ncols = 1;
 
1253
 
 
1254
        for ( QMenuItemListIt it2( *mitems ); it2.current(); ++it2 ) {
 
1255
            mi = it2.current();
 
1256
            if ( !mi->isVisible() )
 
1257
                continue;
 
1258
            int w = 0;
 
1259
            int itemHeight = PopupMenu::itemHeight( mi );
 
1260
 
 
1261
            if ( mi->widget() ) {
 
1262
                QSize s( mi->widget()->sizeHint() );
 
1263
                s = s.expandedTo( mi->widget()->minimumSize() );
 
1264
                mi->widget()->resize( s );
 
1265
                if ( s.width()  > maxWidgetWidth )
 
1266
                    maxWidgetWidth = s.width();
 
1267
                itemHeight = s.height();
 
1268
            } else {
 
1269
                if( ! mi->isSeparator() ) {
 
1270
                    if ( mi->custom() ) {
 
1271
                        if ( mi->custom()->fullSpan() ) {
 
1272
                            maxWidgetWidth = QMAX( maxWidgetWidth,
 
1273
                                                   mi->custom()->sizeHint().width() );
 
1274
                        } else {
 
1275
                            QSize s ( mi->custom()->sizeHint() );
 
1276
                            w += s.width();
 
1277
                        }
 
1278
                    }
 
1279
 
 
1280
                    w += maxPMWidth;
 
1281
 
 
1282
                    if (! mi->text().isNull()) {
 
1283
                        QString s = mi->text();
 
1284
                        int t;
 
1285
                        if ( (t = s.find('\t')) >= 0 ) { // string contains tab
 
1286
                            w += fm.width( s, t );
 
1287
                            w -= s.contains('&') * fm.width('&');
 
1288
                            w += s.contains("&&") * fm.width('&');
 
1289
                            int tw = fm.width( s.mid(t + 1) );
 
1290
                            if ( tw > tab)
 
1291
                                tab = tw;
 
1292
                        } else {
 
1293
                            w += fm.width( s );
 
1294
                            w -= s.contains('&') * fm.width('&');
 
1295
                            w += s.contains("&&") * fm.width('&');
 
1296
                        }
 
1297
                    } else if (mi->pixmap())
 
1298
                        w += mi->pixmap()->width();
 
1299
                } else {
 
1300
                    if ( mi->custom() ) {
 
1301
                        QSize s ( mi->custom()->sizeHint() );
 
1302
                        w += s.width();
 
1303
                    } else {
 
1304
                        w = itemHeight = 2;
 
1305
                    }
 
1306
                }
 
1307
 
 
1308
                QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this,
 
1309
                                                    QSize(w, itemHeight),
 
1310
                                                    QStyleOption(mi,maxPMWidth));
 
1311
 
 
1312
                w = sz.width();
 
1313
                itemHeight = sz.height();
 
1314
 
 
1315
#if defined(QT_CHECK_NULL)
 
1316
                if ( mi->text().isNull() && !mi->pixmap() && !mi->iconSet() &&
 
1317
                     !mi->isSeparator() && !mi->widget() && !mi->custom() )
 
1318
                    qWarning( "PopupMenu: (%s) Popup has invalid menu item",
 
1319
                              name( "unnamed" ) );
 
1320
#endif
 
1321
            }
 
1322
            height += itemHeight;
 
1323
            if(style().styleHint(QStyle::SH_PopupMenu_Scrollable, this)) {
 
1324
                if(scrheight && height >= d->scroll.scrollableSize - scrheight) {
 
1325
                    height = d->scroll.scrollableSize - scrheight;
 
1326
                    break;
 
1327
                }
 
1328
            } else if( height + 2*frameWidth() >= dh ) {
 
1329
                ncols++;
 
1330
                max_height = QMAX(max_height, height - itemHeight);
 
1331
                height = itemHeight;
 
1332
            }
 
1333
            if ( w > max_width )
 
1334
                max_width = w;
 
1335
        }
 
1336
        if( ncols == 1 && !max_height )
 
1337
            max_height = height;
 
1338
 
 
1339
        if(style().styleHint(QStyle::SH_PopupMenu_Scrollable, this)) {
 
1340
            height += scrheight;
 
1341
            setMouseTracking(TRUE);
 
1342
        }
 
1343
 
 
1344
        if ( tab )
 
1345
            tab -= fontMetrics().minRightBearing();
 
1346
        else
 
1347
            max_width -= fontMetrics().minRightBearing();
 
1348
 
 
1349
        if ( max_width + tab < maxWidgetWidth )
 
1350
            max_width = maxWidgetWidth - tab;
 
1351
 
 
1352
        const int fw = frameWidth();
 
1353
        int extra_width = (fw+style().pixelMetric(QStyle::PM_PopupMenuFrameHorizontalExtra, this)) * 2,
 
1354
           extra_height = (fw+style().pixelMetric(QStyle::PM_PopupMenuFrameVerticalExtra,   this)) * 2;
 
1355
        if ( ncols == 1 )
 
1356
            d->calcSize = QSize( QMAX( minimumWidth(), max_width + tab + extra_width ),
 
1357
                              QMAX( minimumHeight() , height + extra_height ) );
 
1358
        else
 
1359
            d->calcSize = QSize( QMAX( minimumWidth(), (ncols*(max_width + tab)) + extra_width ),
 
1360
                              QMAX( minimumHeight(), QMIN( max_height + extra_height + 1, dh ) ) );
 
1361
        badSize = FALSE;
 
1362
    }
 
1363
 
 
1364
    {
 
1365
        // Position the widget items. It could be done in drawContents
 
1366
        // but this way we get less flicker.
 
1367
        QSize sz;
 
1368
        int x = contentsRect().x();
 
1369
        int y = contentsRect().y();
 
1370
        int itemw = contentsRect().width() / ncols;
 
1371
        for(QMenuItemListIt it(*mitems); it.current(); ++it) {
 
1372
            QMenuItem *mi = it.current();
 
1373
            if ( !mi->isVisible() )
 
1374
                continue;
 
1375
 
 
1376
            int itemh = itemHeight( mi );
 
1377
            
 
1378
            sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this,
 
1379
                                          QSize(0, itemh), QStyleOption(mi,maxPMWidth));
 
1380
            sz = sz.expandedTo(QSize(itemw, sz.height()));
 
1381
            itemw = sz.width();
 
1382
            itemh = sz.height();
 
1383
 
 
1384
            if ( ncols > 1 && y + itemh > contentsRect().bottom() ) {
 
1385
                y = contentsRect().y();
 
1386
                x +=itemw;
 
1387
            }
 
1388
            if ( mi->widget() ) 
 
1389
                mi->widget()->setGeometry( x, y, itemw, mi->widget()->height() );
 
1390
            y += itemh;
 
1391
        }
 
1392
    }
 
1393
 
 
1394
    if( do_resize && size() != d->calcSize ) {
 
1395
        setMaximumSize( d->calcSize );
 
1396
        d->calcSize = maximumSize(); //let the max size adjust it (virtual)
 
1397
        resize( d->calcSize );
 
1398
    }
 
1399
    return d->calcSize;
 
1400
}
 
1401
 
 
1402
#ifndef QT_NO_ACCEL
 
1403
void PopupMenu::updateAccel( QWidget *parent )
 
1404
{
 
1405
    QMenuItemListIt it(*mitems);
 
1406
    register QMenuItem *mi;
 
1407
 
 
1408
    if ( parent ) {
 
1409
        delete autoaccel;
 
1410
        autoaccel = 0;
 
1411
    } else if ( !autoaccel ) {
 
1412
        // we have no parent. Rather than ignoring any accelerators we try to find this popup's main window
 
1413
        if ( tornOff ) {
 
1414
            parent = this;
 
1415
        } else {
 
1416
            QWidget *w = (QWidget *) this;
 
1417
            parent = w->parentWidget();
 
1418
            while ( (!w->testWFlags(WType_TopLevel) || !w->testWFlags(WType_Popup)) && parent ) {
 
1419
                w = parent;
 
1420
                parent = parent->parentWidget();
 
1421
            }
 
1422
        }
 
1423
    }
 
1424
 
 
1425
    if ( parent == 0 && autoaccel == 0 )
 
1426
        return;
 
1427
 
 
1428
    if ( autoaccel )                            // build it from scratch
 
1429
        autoaccel->clear();
 
1430
    else {
 
1431
        // create an autoaccel in any case, even if we might not use
 
1432
        // it immediately. Maybe the user needs it later.
 
1433
        autoaccel = new QAccel( parent, this );
 
1434
        connect( autoaccel, SIGNAL(activated(int)),
 
1435
                 SLOT(accelActivated(int)) );
 
1436
        connect( autoaccel, SIGNAL(activatedAmbiguously(int)),
 
1437
                 SLOT(accelActivated(int)) );
 
1438
        connect( autoaccel, SIGNAL(destroyed()),
 
1439
                 SLOT(accelDestroyed()) );
 
1440
        if ( accelDisabled )
 
1441
            autoaccel->setEnabled( FALSE );
 
1442
    }
 
1443
    while ( (mi=it.current()) ) {
 
1444
        ++it;
 
1445
        QKeySequence k = mi->key();
 
1446
        if ( (int)k ) {
 
1447
            int id = autoaccel->insertItem( k, mi->id() );
 
1448
#ifndef QT_NO_WHATSTHIS
 
1449
            autoaccel->setWhatsThis( id, mi->whatsThis() );
 
1450
#endif
 
1451
        }
 
1452
        if ( !mi->text().isNull() || mi->custom() ) {
 
1453
            QString s = mi->text();
 
1454
            int i = s.find('\t');
 
1455
 
 
1456
            // Note: Only looking at the first key in the sequence!
 
1457
            if ( (int)k && (int)k != Key_unknown ) {
 
1458
                QString t = (QString)mi->key();
 
1459
                if ( i >= 0 )
 
1460
                    s.replace( i+1, s.length()-i, t );
 
1461
                else {
 
1462
                    s += '\t';
 
1463
                    s += t;
 
1464
                }
 
1465
            } else if ( !k ) {
 
1466
                if ( i >= 0 )
 
1467
                    s.truncate( i );
 
1468
            }
 
1469
            if ( s != mi->text() ) {
 
1470
                mi->setText( s );
 
1471
                badSize = TRUE;
 
1472
            }
 
1473
        }
 
1474
        if ( mi->popup() && parent ) {          // call recursively
 
1475
            // reuse
 
1476
            PopupMenu* popup = mi->popup();
 
1477
            if (!popup->avoid_circularity) {
 
1478
                popup->avoid_circularity = 1;
 
1479
                popup->updateAccel( parent );
 
1480
                popup->avoid_circularity = 0;
 
1481
            }
 
1482
        }
 
1483
    }
 
1484
}
 
1485
 
 
1486
void PopupMenu::enableAccel( bool enable )
 
1487
{
 
1488
    if ( autoaccel )
 
1489
        autoaccel->setEnabled( enable );
 
1490
    accelDisabled = !enable;            // rememeber when updateAccel
 
1491
    QMenuItemListIt it(*mitems);
 
1492
    register QMenuItem *mi;
 
1493
    while ( (mi=it.current()) ) {               // do the same for sub popups
 
1494
        ++it;
 
1495
        if ( mi->popup() )                      // call recursively
 
1496
            mi->popup()->enableAccel( enable );
 
1497
    }
 
1498
}
 
1499
#endif
 
1500
 
 
1501
void PopupMenu::setFont( const QFont &font )
 
1502
{
 
1503
    QWidget::setFont( font );
 
1504
    badSize = TRUE;
 
1505
    if ( isVisible() ) {
 
1506
        updateSize();
 
1507
        update();
 
1508
    }
 
1509
}
 
1510
 
 
1511
void PopupMenu::show()
 
1512
{
 
1513
    if ( !isPopup() && isVisible() )
 
1514
        hide();
 
1515
 
 
1516
    if ( isVisible() ) {
 
1517
        supressAboutToShow = FALSE;
 
1518
        QWidget::show();
 
1519
        return;
 
1520
    }
 
1521
    if (!supressAboutToShow)
 
1522
        emit aboutToShow();
 
1523
    else
 
1524
        supressAboutToShow = FALSE;
 
1525
    performDelayedChanges();
 
1526
    updateSize(TRUE);
 
1527
    QWidget::show();
 
1528
    popupActive = -1;
 
1529
    if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this))
 
1530
        d->mouseMoveBuffer = QRegion();
 
1531
}
 
1532
 
 
1533
void PopupMenu::hide()
 
1534
{
 
1535
    if ( syncMenu == this && qApp ) {
 
1536
        qApp->exit_loop();
 
1537
        syncMenu = 0;
 
1538
    }
 
1539
 
 
1540
    if ( !isVisible() ) {
 
1541
        QWidget::hide();
 
1542
        return;
 
1543
    }
 
1544
    emit aboutToHide();
 
1545
 
 
1546
    actItem = popupActive = -1;
 
1547
    if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this))
 
1548
        d->mouseMoveBuffer = QRegion();
 
1549
    mouseBtDn = FALSE;                          // mouse button up
 
1550
#if defined(QT_ACCESSIBILITY_SUPPORT)
 
1551
    QAccessible::updateAccessibility( this, 0, QAccessible::PopupMenuEnd );
 
1552
#endif
 
1553
    parentMenu = 0;
 
1554
    hidePopups();
 
1555
    QWidget::hide();
 
1556
}
 
1557
 
 
1558
int PopupMenu::itemHeight( int row ) const
 
1559
{
 
1560
    return itemHeight( mitems->at( row ) );
 
1561
}
 
1562
 
 
1563
int PopupMenu::itemHeight( QMenuItem *mi ) const
 
1564
{
 
1565
    if  ( mi->widget() )
 
1566
        return mi->widget()->height();
 
1567
    if ( mi->custom() && mi->custom()->fullSpan() )
 
1568
        return mi->custom()->sizeHint().height();
 
1569
 
 
1570
    QFontMetrics fm(fontMetrics());
 
1571
    int h = 0;
 
1572
    if ( mi->isSeparator() ) // separator height
 
1573
        h = 2;
 
1574
    else if ( mi->pixmap() ) // pixmap height
 
1575
        h = mi->pixmap()->height();
 
1576
    else                     // text height
 
1577
        h = fm.height();
 
1578
 
 
1579
    if ( !mi->isSeparator() && mi->iconSet() != 0 )
 
1580
        h = QMAX(h, mi->iconSet()->pixmap( QIconSet::Small,
 
1581
                                           QIconSet::Normal ).height());
 
1582
    if ( mi->custom() )
 
1583
        h = QMAX(h, mi->custom()->sizeHint().height());
 
1584
 
 
1585
    return h;
 
1586
}
 
1587
 
 
1588
void PopupMenu::drawItem( QPainter* p, int tab_, QMenuItem* mi,
 
1589
                           bool act, int x, int y, int w, int h)
 
1590
{
 
1591
    QStyle::SFlags flags = QStyle::Style_Default;
 
1592
    if (isEnabled() && mi->isEnabledAndVisible() && (!mi->popup() || mi->popup()->isEnabled()) )
 
1593
        flags |= QStyle::Style_Enabled;
 
1594
    if (act)
 
1595
        flags |= QStyle::Style_Active;
 
1596
    if (mouseBtDn)
 
1597
        flags |= QStyle::Style_Down;
 
1598
 
 
1599
    const QColorGroup &cg = ((flags&QStyle::Style_Enabled) ? colorGroup() : palette().disabled() );
 
1600
 
 
1601
    if ( mi->custom() && mi->custom()->fullSpan() ) {
 
1602
        QMenuItem dummy;
 
1603
        style().drawControl(QStyle::CE_PopupMenuItem, p, this, QRect(x, y, w, h), cg,
 
1604
                            flags, QStyleOption(&dummy,maxPMWidth,tab_));
 
1605
        mi->custom()->paint( p, cg, act, flags&QStyle::Style_Enabled, x, y, w, h );
 
1606
    } else
 
1607
        style().drawControl(QStyle::CE_PopupMenuItem, p, this, QRect(x, y, w, h), cg,
 
1608
                            flags, QStyleOption(mi,maxPMWidth,tab_));
 
1609
}
 
1610
 
 
1611
void PopupMenu::drawContents( QPainter* p )
 
1612
{
 
1613
    QMenuItemListIt it(*mitems);
 
1614
    QMenuItem *mi = 0;
 
1615
    int row = 0;
 
1616
    int x = contentsRect().x();
 
1617
    int y = contentsRect().y();
 
1618
    if(d->scroll.scrollable) {
 
1619
        if(d->scroll.topScrollableIndex) {
 
1620
            for( ; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++)
 
1621
                ++it;
 
1622
            if(!mi)
 
1623
                it.toFirst();
 
1624
        }
 
1625
        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp) {
 
1626
            QRect rect(x, y, contentsRect().width(),
 
1627
                       style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this));
 
1628
            if(!p->hasClipping() || p->clipRegion().contains(rect)) {
 
1629
                QStyle::SFlags flags = QStyle::Style_Up;
 
1630
                if (isEnabled())
 
1631
                    flags |= QStyle::Style_Enabled;
 
1632
                style().drawControl(QStyle::CE_PopupMenuScroller, p, this, rect,
 
1633
                                    colorGroup(), flags, QStyleOption(maxPMWidth));
 
1634
            }
 
1635
            y += rect.height();
 
1636
        }
 
1637
    }
 
1638
 
 
1639
    int itemw = contentsRect().width() / ncols;
 
1640
    QSize sz;
 
1641
    QStyle::SFlags flags;
 
1642
    while ( (mi=it.current()) ) {
 
1643
        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown &&
 
1644
           y >= contentsRect().height() - style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this))
 
1645
            break;
 
1646
        ++it;
 
1647
        if ( !mi->isVisible() ) {
 
1648
            ++row;
 
1649
            continue;
 
1650
        }
 
1651
        int itemh = itemHeight( mi );
 
1652
        sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this,
 
1653
                                      QSize(0, itemh),
 
1654
                                      QStyleOption(mi,maxPMWidth,0)
 
1655
                                );
 
1656
        sz = sz.expandedTo(QSize(itemw, sz.height()));
 
1657
        itemw = sz.width();
 
1658
        itemh = sz.height();
 
1659
 
 
1660
        if ( ncols > 1 && y + itemh > contentsRect().bottom() ) {
 
1661
            if ( y < contentsRect().bottom() ) {
 
1662
                QRect rect(x, y, itemw, contentsRect().bottom() - y);
 
1663
                if(!p->hasClipping() || p->clipRegion().contains(rect)) {
 
1664
                    flags = QStyle::Style_Default;
 
1665
                    if (isEnabled() && mi->isEnabledAndVisible())
 
1666
                        flags |= QStyle::Style_Enabled;
 
1667
                    style().drawControl(QStyle::CE_PopupMenuItem, p, this, rect,
 
1668
                                        colorGroup(), flags, QStyleOption((QMenuItem*)0,maxPMWidth));
 
1669
                }
 
1670
            }
 
1671
            y = contentsRect().y();
 
1672
            x +=itemw;
 
1673
        }
 
1674
        if (!mi->widget() && (!p->hasClipping() || p->clipRegion().contains(QRect(x, y, itemw, itemh))))
 
1675
            drawItem( p, tab, mi, row == actItem, x, y, itemw, itemh );
 
1676
        y += itemh;
 
1677
        ++row;
 
1678
    }
 
1679
    if ( y < contentsRect().bottom() ) {
 
1680
        QRect rect(x, y, itemw, contentsRect().bottom() - y);
 
1681
        if(!p->hasClipping() || p->clipRegion().contains(rect)) {
 
1682
            flags = QStyle::Style_Default;
 
1683
            if ( isEnabled() )
 
1684
                flags |= QStyle::Style_Enabled;
 
1685
            style().drawControl(QStyle::CE_PopupMenuItem, p, this, rect,
 
1686
                                colorGroup(), flags, QStyleOption((QMenuItem*)0,maxPMWidth));
 
1687
        }
 
1688
    }
 
1689
    if( d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown ) {
 
1690
        int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
1691
        QRect rect(x, contentsRect().height() - sh, contentsRect().width(), sh);
 
1692
        if(!p->hasClipping() || p->clipRegion().contains(rect)) {
 
1693
            QStyle::SFlags flags = QStyle::Style_Down;
 
1694
            if (isEnabled())
 
1695
                flags |= QStyle::Style_Enabled;
 
1696
            style().drawControl(QStyle::CE_PopupMenuScroller, p, this, rect,
 
1697
                                colorGroup(), flags, QStyleOption(maxPMWidth));
 
1698
        }
 
1699
    }
 
1700
#if defined( DEBUG_SLOPPY_SUBMENU )
 
1701
    if ( style().styleHint(QStyle::SH_PopupMenu_SloppySubMenus, this )) {
 
1702
        p->setClipRegion( d->mouseMoveBuffer );
 
1703
        p->fillRect( d->mouseMoveBuffer.boundingRect(), colorGroup().brush( QColorGroup::Highlight ) );
 
1704
    }
 
1705
#endif
 
1706
}
 
1707
 
 
1708
void PopupMenu::paintEvent( QPaintEvent *e )
 
1709
{
 
1710
    QFrame::paintEvent( e );
 
1711
}
 
1712
 
 
1713
void PopupMenu::closeEvent( QCloseEvent * e) {
 
1714
    e->accept();
 
1715
    byeMenuBar();
 
1716
}
 
1717
 
 
1718
void PopupMenu::mousePressEvent( QMouseEvent *e )
 
1719
{
 
1720
    int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
1721
    if (rect().contains(e->pos()) &&
 
1722
        ((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up
 
1723
         (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown &&
 
1724
             e->pos().y() >= contentsRect().height() - sh))) //down
 
1725
        return;
 
1726
 
 
1727
    mouseBtDn = TRUE;                           // mouse button down
 
1728
    int item = itemAtPos( e->pos() );
 
1729
    if ( item == -1 ) {
 
1730
        if ( !rect().contains(e->pos()) && !tryMenuBar(e) ) {
 
1731
            byeMenuBar();
 
1732
        }
 
1733
        return;
 
1734
    }
 
1735
    register QMenuItem *mi = mitems->at(item);
 
1736
    if ( item != actItem )                      // new item activated
 
1737
        setActiveItem( item );
 
1738
 
 
1739
    PopupMenu *popup = mi->popup();
 
1740
    if ( popup ) {
 
1741
        if ( popup->isVisible() ) {             // sub menu already open
 
1742
            int pactItem = popup->actItem;
 
1743
            popup->actItem = -1;
 
1744
            popup->hidePopups();
 
1745
            popup->updateRow( pactItem );
 
1746
        } else {                                // open sub menu
 
1747
            hidePopups();
 
1748
            popupSubMenuLater( 20, this );
 
1749
        }
 
1750
    } else {
 
1751
        hidePopups();
 
1752
    }
 
1753
}
 
1754
 
 
1755
void PopupMenu::mouseReleaseEvent( QMouseEvent *e )
 
1756
{
 
1757
    // do not hide a standalone context menu on press-release, unless
 
1758
    // the user moved the mouse significantly
 
1759
    if ( !parentMenu && !mouseBtDn && actItem < 0 && motion < 6 )
 
1760
        return;
 
1761
 
 
1762
    mouseBtDn = FALSE;
 
1763
 
 
1764
    // if the user released the mouse outside the menu, pass control
 
1765
    // to the menubar or our parent menu
 
1766
    int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
1767
    if ( !rect().contains( e->pos() ) && tryMenuBar(e) )
 
1768
        return;
 
1769
    else if((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up
 
1770
            (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown &&
 
1771
             e->pos().y() >= contentsRect().height() - sh)) //down
 
1772
        return;
 
1773
 
 
1774
    if ( actItem < 0 ) { // we do not have an active item
 
1775
        // if the release is inside without motion (happens with
 
1776
        // oversized popup menus on small screens), ignore it
 
1777
        if ( rect().contains( e->pos() ) && motion < 6 )
 
1778
            return;
 
1779
        else
 
1780
            byeMenuBar();
 
1781
    } else {    // selected menu item!
 
1782
        register QMenuItem *mi = mitems->at(actItem);
 
1783
        if ( mi ->widget() ) {
 
1784
            QWidget* widgetAt = QApplication::widgetAt( e->globalPos(), TRUE );
 
1785
            if ( widgetAt && widgetAt != this ) {
 
1786
                QMouseEvent me( e->type(), widgetAt->mapFromGlobal( e->globalPos() ),
 
1787
                                e->globalPos(), e->button(), e->state() );
 
1788
                QApplication::sendEvent( widgetAt, &me );
 
1789
            }
 
1790
        }
 
1791
        PopupMenu *popup = mi->popup();
 
1792
#ifndef QT_NO_WHATSTHIS
 
1793
            bool b = QWhatsThis::inWhatsThisMode();
 
1794
#else
 
1795
            const bool b = FALSE;
 
1796
#endif
 
1797
        if ( !mi->isEnabledAndVisible() ) {
 
1798
#ifndef QT_NO_WHATSTHIS
 
1799
            if ( b ) {
 
1800
                actItem = -1;
 
1801
                updateItem( mi->id() );
 
1802
                byeMenuBar();
 
1803
                actSig( mi->id(), b);
 
1804
            }
 
1805
#endif
 
1806
        } else  if ( popup ) {
 
1807
            popup->setFirstItemActive();
 
1808
        } else {                                // normal menu item
 
1809
            byeMenuBar();                       // deactivate menu bar
 
1810
            if ( mi->isEnabledAndVisible() ) {
 
1811
                actItem = -1;
 
1812
                updateItem( mi->id() );
 
1813
                active_popup_menu = this;
 
1814
                QGuardedPtr<QSignal> signal = mi->signal();
 
1815
                actSig( mi->id(), b );
 
1816
                if ( signal && !b )
 
1817
                    signal->activate();
 
1818
                active_popup_menu = 0;
 
1819
            }
 
1820
        }
 
1821
    }
 
1822
}
 
1823
 
 
1824
void PopupMenu::mouseMoveEvent( QMouseEvent *e )
 
1825
{
 
1826
    motion++;
 
1827
 
 
1828
    if ( parentMenu && parentMenu->isPopupMenu ) {
 
1829
        PopupMenu* p = (PopupMenu*)parentMenu;
 
1830
        int myIndex;
 
1831
 
 
1832
        p->findPopup( this, &myIndex );
 
1833
        QPoint pPos = p->mapFromParent( e->globalPos() );
 
1834
        if ( p->actItem != myIndex && !p->rect().contains( pPos ) )
 
1835
            p->setActiveItem( myIndex );
 
1836
 
 
1837
        if ( style().styleHint(QStyle::SH_PopupMenu_SloppySubMenus, this )) {
 
1838
            p->d->mouseMoveBuffer = QRegion();
 
1839
#ifdef DEBUG_SLOPPY_SUBMENU
 
1840
            p->repaint();
 
1841
#endif
 
1842
        }
 
1843
    }
 
1844
 
 
1845
    if ( (e->state() & Qt::MouseButtonMask) == 0 &&
 
1846
         !hasMouseTracking() )
 
1847
        return;
 
1848
 
 
1849
    if(d->scroll.scrollable && e->pos().x() >= rect().x() && e->pos().x() <= rect().width()) {
 
1850
        int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
1851
        if((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || 
 
1852
           (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && e->pos().y() >= height()-sh)) {
 
1853
            if(!d->scroll.scrolltimer) {
 
1854
                d->scroll.scrolltimer = new QTimer(this, "popup scroll timer");
 
1855
                QObject::connect( d->scroll.scrolltimer, SIGNAL(timeout()),
 
1856
                                  this, SLOT(subScrollTimer()) );
 
1857
            }
 
1858
            if(!d->scroll.scrolltimer->isActive())
 
1859
                d->scroll.scrolltimer->start(40);
 
1860
            return;
 
1861
        }
 
1862
    }
 
1863
 
 
1864
    int  item = itemAtPos( e->pos() );
 
1865
    if ( item == -1 ) {                         // no valid item
 
1866
        int lastActItem = actItem;
 
1867
        actItem = -1;
 
1868
        if ( lastActItem >= 0 )
 
1869
            updateRow( lastActItem );
 
1870
        if ( lastActItem > 0 ||
 
1871
                    ( !rect().contains( e->pos() ) && !tryMenuBar( e ) ) ) {
 
1872
            popupSubMenuLater(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay,
 
1873
                                                this), this);
 
1874
        }
 
1875
    } else {                                    // mouse on valid item
 
1876
        // but did not register mouse press
 
1877
        if ( (e->state() & Qt::MouseButtonMask) && !mouseBtDn )
 
1878
            mouseBtDn = TRUE; // so mouseReleaseEvent will pop down
 
1879
 
 
1880
        register QMenuItem *mi = mitems->at( item );
 
1881
 
 
1882
        if ( mi->widget() ) {
 
1883
            QWidget* widgetAt = QApplication::widgetAt( e->globalPos(), TRUE );
 
1884
            if ( widgetAt && widgetAt != this ) {
 
1885
                QMouseEvent me( e->type(), widgetAt->mapFromGlobal( e->globalPos() ),
 
1886
                                e->globalPos(), e->button(), e->state() );
 
1887
                QApplication::sendEvent( widgetAt, &me );
 
1888
            }
 
1889
        }
 
1890
 
 
1891
        if ( actItem == item )
 
1892
            return;
 
1893
 
 
1894
        if ( style().styleHint(QStyle::SH_PopupMenu_SloppySubMenus, this) &&
 
1895
             d->mouseMoveBuffer.contains( e->pos() ) ) {
 
1896
            actItem = item;
 
1897
            popupSubMenuLater( style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this) * 6,
 
1898
                               this );
 
1899
            return;
 
1900
        }
 
1901
 
 
1902
        if ( mi->popup() || ( popupActive >= 0 && popupActive != item ))
 
1903
            popupSubMenuLater( style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this),
 
1904
                               this );
 
1905
        else if ( singleSingleShot )
 
1906
            singleSingleShot->stop();
 
1907
 
 
1908
        if ( item != actItem )
 
1909
            setActiveItem( item );
 
1910
    }
 
1911
}
 
1912
 
 
1913
void PopupMenu::keyPressEvent( QKeyEvent *e )
 
1914
{
 
1915
    QMenuItem  *mi = 0;
 
1916
    PopupMenu *popup;
 
1917
    int dy = 0;
 
1918
    bool ok_key = TRUE;
 
1919
 
 
1920
    int key = e->key();
 
1921
    if ( QApplication::reverseLayout() ) {
 
1922
        // in reverse mode opening and closing keys for submenues are reversed
 
1923
        if ( key == Key_Left )
 
1924
            key = Key_Right;
 
1925
        else if ( key == Key_Right )
 
1926
            key = Key_Left;
 
1927
    }
 
1928
 
 
1929
    switch ( key ) {
 
1930
    case Key_Tab:
 
1931
        // ignore tab, otherwise it will be passed to the menubar
 
1932
        break;
 
1933
 
 
1934
    case Key_Up:
 
1935
        dy = -1;
 
1936
        break;
 
1937
 
 
1938
    case Key_Down:
 
1939
        dy = 1;
 
1940
        break;
 
1941
 
 
1942
    case Key_Alt:
 
1943
        if ( style().styleHint(QStyle::SH_MenuBar_AltKeyNavigation, this) )
 
1944
            byeMenuBar();
 
1945
        break;
 
1946
 
 
1947
    case Key_Escape:
 
1948
        if ( tornOff ) {
 
1949
            close();
 
1950
            return;
 
1951
        }
 
1952
        // just hide one
 
1953
        {
 
1954
            QMenuData* p = parentMenu;
 
1955
            hide();
 
1956
#ifndef QT_NO_MENUBAR
 
1957
            if ( p && p->isMenuBar )
 
1958
                ((QMenuBar*) p)->goodbye( TRUE );
 
1959
#endif
 
1960
        }
 
1961
        break;
 
1962
 
 
1963
    case Key_Left:
 
1964
        if ( ncols > 1 && actItem >= 0 ) {
 
1965
            QRect r( itemGeometry( actItem ) );
 
1966
            int newActItem = itemAtPos( QPoint( r.left() - 1, r.center().y() ) );
 
1967
            if ( newActItem >= 0 ) {
 
1968
                setActiveItem( newActItem );
 
1969
                break;
 
1970
            }
 
1971
        }
 
1972
        if ( parentMenu && parentMenu->isPopupMenu ) {
 
1973
            ((PopupMenu *)parentMenu)->hidePopups();
 
1974
            if ( singleSingleShot )
 
1975
                singleSingleShot->stop();
 
1976
            break;
 
1977
        }
 
1978
 
 
1979
        ok_key = FALSE;
 
1980
        break;
 
1981
 
 
1982
    case Key_Right:
 
1983
        if ( actItem >= 0 && ( mi=mitems->at(actItem) )->isEnabledAndVisible() && (popup=mi->popup()) ) {
 
1984
            hidePopups();
 
1985
            if ( singleSingleShot )
 
1986
                singleSingleShot->stop();
 
1987
            // ### The next two lines were switched to fix the problem with the first item of the
 
1988
            // submenu not being highlighted...any reason why they should have been the other way??
 
1989
            subMenuTimer();
 
1990
            popup->setFirstItemActive();
 
1991
            break;
 
1992
        } else if ( actItem == -1 && ( parentMenu && !parentMenu->isMenuBar )) {
 
1993
            dy = 1;
 
1994
            break;
 
1995
        }
 
1996
        if ( ncols > 1 && actItem >= 0 ) {
 
1997
            QRect r( itemGeometry( actItem ) );
 
1998
            int newActItem = itemAtPos( QPoint( r.right() + 1, r.center().y() ) );
 
1999
            if ( newActItem >= 0 ) {
 
2000
                setActiveItem( newActItem );
 
2001
                break;
 
2002
            }
 
2003
        }
 
2004
        ok_key = FALSE;
 
2005
        break;
 
2006
 
 
2007
    case Key_Space:
 
2008
        if (! style().styleHint(QStyle::SH_PopupMenu_SpaceActivatesItem, this))
 
2009
            break;
 
2010
        // for motif, fall through
 
2011
 
 
2012
    case Key_Return:
 
2013
    case Key_Enter:
 
2014
        {
 
2015
            if ( actItem < 0 )
 
2016
                break;
 
2017
#ifndef QT_NO_WHATSTHIS
 
2018
            bool b = QWhatsThis::inWhatsThisMode();
 
2019
#else
 
2020
            const bool b = FALSE;
 
2021
#endif
 
2022
            mi = mitems->at( actItem );
 
2023
            if ( !mi->isEnabled() && !b )
 
2024
                break;
 
2025
            popup = mi->popup();
 
2026
            if ( popup ) {
 
2027
                hidePopups();
 
2028
                popupSubMenuLater( 20, this );
 
2029
                popup->setFirstItemActive();
 
2030
            } else {
 
2031
                actItem = -1;
 
2032
                updateItem( mi->id() );
 
2033
                byeMenuBar();
 
2034
                if ( mi->isEnabledAndVisible() || b ) {
 
2035
                    active_popup_menu = this;
 
2036
                    QGuardedPtr<QSignal> signal = mi->signal();
 
2037
                    actSig( mi->id(), b );
 
2038
                    if ( signal && !b )
 
2039
                        signal->activate();
 
2040
                    active_popup_menu = 0;
 
2041
                }
 
2042
            }
 
2043
        }
 
2044
        break;
 
2045
#ifndef QT_NO_WHATSTHIS
 
2046
    case Key_F1:
 
2047
        if ( actItem < 0 || e->state() != ShiftButton)
 
2048
            break;
 
2049
        mi = mitems->at( actItem );
 
2050
        if ( !mi->whatsThis().isNull() ){
 
2051
            if ( !QWhatsThis::inWhatsThisMode() )
 
2052
                QWhatsThis::enterWhatsThisMode();
 
2053
            QRect r( itemGeometry( actItem) );
 
2054
            QWhatsThis::leaveWhatsThisMode( mi->whatsThis(), mapToGlobal( r.bottomLeft()) );
 
2055
        }
 
2056
        //fall-through!
 
2057
#endif
 
2058
    default:
 
2059
        ok_key = FALSE;
 
2060
 
 
2061
    }
 
2062
    if ( !ok_key &&
 
2063
         ( !e->state() || e->state() == AltButton || e->state() == ShiftButton ) &&
 
2064
         e->text().length()==1 ) {
 
2065
        QChar c = e->text()[0].upper();
 
2066
 
 
2067
        QMenuItemListIt it(*mitems);
 
2068
        QMenuItem* first = 0;
 
2069
        QMenuItem* currentSelected = 0;
 
2070
        QMenuItem* firstAfterCurrent = 0;
 
2071
 
 
2072
        register QMenuItem *m;
 
2073
        mi = 0;
 
2074
        int indx = 0;
 
2075
        int clashCount = 0;
 
2076
        while ( (m=it.current()) ) {
 
2077
            ++it;
 
2078
            QString s = m->text();
 
2079
            if ( !s.isEmpty() ) {
 
2080
                int i = s.find( '&' );
 
2081
                while ( i >= 0 && i < (int)s.length() - 1 ) {
 
2082
                    if ( s[i+1].upper() == c ) {
 
2083
                        ok_key = TRUE;
 
2084
                        clashCount++;
 
2085
                        if ( !first )
 
2086
                            first = m;
 
2087
                        if ( indx == actItem )
 
2088
                            currentSelected = m;
 
2089
                        else if ( !firstAfterCurrent && currentSelected )
 
2090
                            firstAfterCurrent = m;
 
2091
                        break;
 
2092
                    } else if ( s[i+1] == '&' ) {
 
2093
                        i = s.find( '&', i+2 );
 
2094
                    } else {
 
2095
                        break;
 
2096
                    }
 
2097
                }
 
2098
            }
 
2099
            if ( mi )
 
2100
                break;
 
2101
            indx++;
 
2102
        }
 
2103
 
 
2104
        if ( 1 == clashCount ) { // No clashes, continue with selection
 
2105
            mi = first;
 
2106
            popup = mi->popup();
 
2107
            if ( popup ) {
 
2108
                setActiveItem( indexOf(mi->id()) );
 
2109
                hidePopups();
 
2110
                popupSubMenuLater( 20, this );
 
2111
                popup->setFirstItemActive();
 
2112
            } else {
 
2113
                byeMenuBar();
 
2114
#ifndef QT_NO_WHATSTHIS
 
2115
                bool b = QWhatsThis::inWhatsThisMode();
 
2116
#else
 
2117
                const bool b = FALSE;
 
2118
#endif
 
2119
                if ( mi->isEnabledAndVisible() || b ) {
 
2120
                    active_popup_menu = this;
 
2121
                    QGuardedPtr<QSignal> signal = mi->signal();
 
2122
                    actSig( mi->id(), b );
 
2123
                    if ( signal && !b  )
 
2124
                        signal->activate();
 
2125
                    active_popup_menu = 0;
 
2126
                }
 
2127
            }
 
2128
        } else if ( clashCount > 1 ) { // Clashes, highlight next...
 
2129
            // If there's clashes and no one is selected, use first one
 
2130
            // or if there is no clashes _after_ current, use first one
 
2131
            if ( !currentSelected || (currentSelected && !firstAfterCurrent))
 
2132
                dy = indexOf( first->id() ) - actItem;
 
2133
            else
 
2134
                dy = indexOf( firstAfterCurrent->id() ) - actItem;
 
2135
        }
 
2136
    }
 
2137
#ifndef QT_NO_MENUBAR
 
2138
    if ( !ok_key ) {                            // send to menu bar
 
2139
        register QMenuData *top = this;         // find top level
 
2140
        while ( top->parentMenu )
 
2141
            top = top->parentMenu;
 
2142
        if ( top->isMenuBar ) {
 
2143
            int beforeId = top->actItem;
 
2144
            ((QMenuBar*)top)->tryKeyEvent( this, e );
 
2145
            if ( beforeId != top->actItem )
 
2146
                ok_key = TRUE;
 
2147
        }
 
2148
    }
 
2149
#endif
 
2150
    if ( actItem < 0 ) {
 
2151
        if ( dy > 0 ) {
 
2152
            setFirstItemActive();
 
2153
        } else if ( dy < 0 ) {
 
2154
            QMenuItemListIt it(*mitems);
 
2155
            it.toLast();
 
2156
            register QMenuItem *mi;
 
2157
            int ai = count() - 1;
 
2158
            while ( (mi=it.current()) ) {
 
2159
                --it;
 
2160
                if ( !mi->isSeparator() && mi->id() != QMenuData::d->aInt ) {
 
2161
                    setActiveItem( ai );
 
2162
                    return;
 
2163
                }
 
2164
                ai--;
 
2165
            }
 
2166
            actItem = -1;
 
2167
        }
 
2168
        return;
 
2169
    }
 
2170
 
 
2171
    if ( dy ) {                         // highlight next/prev
 
2172
        register int i = actItem;
 
2173
        int c = mitems->count();
 
2174
        for(int n = c; n; n--) {
 
2175
            i = i + dy;
 
2176
            if(d->scroll.scrollable) {
 
2177
                if(d->scroll.scrolltimer)
 
2178
                    d->scroll.scrolltimer->stop();
 
2179
                if(i < 0)
 
2180
                    i = 0;
 
2181
                else if(i >= c)
 
2182
                    i  = c - 1;
 
2183
            } else {
 
2184
                if ( i == c )
 
2185
                    i = 0;
 
2186
                else if ( i < 0 )
 
2187
                    i = c - 1;
 
2188
            }
 
2189
            mi = mitems->at( i );
 
2190
            if ( !mi || !mi->isVisible() )
 
2191
                continue;
 
2192
 
 
2193
            if ( !mi->isSeparator() &&
 
2194
                 ( style().styleHint(QStyle::SH_PopupMenu_AllowActiveAndDisabled, this)
 
2195
                   || mi->isEnabledAndVisible() ) )
 
2196
                break;
 
2197
        }
 
2198
        if ( i != actItem )
 
2199
            setActiveItem( i );
 
2200
        if(d->scroll.scrollable) { //need to scroll to make it visible?
 
2201
            QRect r = itemGeometry(actItem);
 
2202
            if(r.isNull() || r.height() < itemHeight(mitems->at(actItem))) {
 
2203
                bool refresh = FALSE;
 
2204
                if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && dy == -1) { //up
 
2205
                    if(d->scroll.topScrollableIndex >= 0) {
 
2206
                        d->scroll.topScrollableIndex--;
 
2207
                        refresh = TRUE;
 
2208
                    }
 
2209
                } else if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown) { //down
 
2210
                    QMenuItemListIt it(*mitems);
 
2211
                    int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
2212
                    for(int i = 0, y = ((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp) ? sh : 0); it.current(); i++, ++it) {
 
2213
                        if(i >= d->scroll.topScrollableIndex) {
 
2214
                            int itemh = itemHeight(it.current());
 
2215
                            QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this,
 
2216
                                                                QSize(0, itemh),
 
2217
                                                                QStyleOption(it.current(),maxPMWidth,0));
 
2218
                            y += sz.height();
 
2219
                            if(y > (contentsRect().height()-sh)) {
 
2220
                                if(sz.height() > sh || !it.atLast())
 
2221
                                    d->scroll.topScrollableIndex++;
 
2222
                                refresh = TRUE;
 
2223
                                break;
 
2224
                            }
 
2225
                        }
 
2226
                    }
 
2227
                }
 
2228
                if(refresh) {
 
2229
                    updateScrollerState();
 
2230
                    update();
 
2231
                }
 
2232
            }
 
2233
        }
 
2234
    }
 
2235
 
 
2236
#ifdef Q_OS_WIN32
 
2237
    if ( !ok_key &&
 
2238
        !( e->key() == Key_Control || e->key() == Key_Shift || e->key() == Key_Meta ) )
 
2239
        qApp->beep();
 
2240
#endif // Q_OS_WIN32
 
2241
}
 
2242
 
 
2243
void PopupMenu::timerEvent( QTimerEvent *e )
 
2244
{
 
2245
    QFrame::timerEvent( e );
 
2246
}
 
2247
 
 
2248
void PopupMenu::leaveEvent( QEvent * )
 
2249
{
 
2250
    if ( testWFlags( WStyle_Tool ) && style().styleHint(QStyle::SH_PopupMenu_MouseTracking, this) ) {
 
2251
        int lastActItem = actItem;
 
2252
        actItem = -1;
 
2253
        if ( lastActItem >= 0 )
 
2254
            updateRow( lastActItem );
 
2255
    }
 
2256
}
 
2257
 
 
2258
void PopupMenu::styleChange( QStyle& old )
 
2259
{
 
2260
    QFrame::styleChange( old );
 
2261
    setMouseTracking(style().styleHint(QStyle::SH_PopupMenu_MouseTracking, this));
 
2262
    style().polishPopupMenu( this );
 
2263
    updateSize(TRUE);
 
2264
}
 
2265
 
 
2266
void PopupMenu::enabledChange( bool )
 
2267
{
 
2268
    if ( QMenuData::d->aWidget ) // torn-off menu
 
2269
        QMenuData::d->aWidget->setEnabled( isEnabled() );
 
2270
}
 
2271
 
 
2272
int PopupMenu::columns() const
 
2273
{
 
2274
    return ncols;
 
2275
}
 
2276
 
 
2277
// This private slot handles the scrolling popupmenu 
 
2278
void PopupMenu::subScrollTimer() {
 
2279
    QPoint pos = QCursor::pos();
 
2280
    if(!d->scroll.scrollable || !isVisible()) {
 
2281
        if(d->scroll.scrolltimer)
 
2282
            d->scroll.scrolltimer->stop();
 
2283
        return;
 
2284
    } else if(pos.x() > x() + width() || pos.x() < x()) {
 
2285
        return;
 
2286
    }
 
2287
    int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
2288
    if(!d->scroll.lastScroll.isValid()) {
 
2289
        d->scroll.lastScroll = QTime::currentTime();
 
2290
    } else {
 
2291
        int factor=0;
 
2292
        if(pos.y() < y())
 
2293
            factor = y() - pos.y();
 
2294
        else if(pos.y() > y() + height())
 
2295
            factor = pos.y() - (y() + height());
 
2296
        int msecs = 250 - ((factor / 10) * 40);
 
2297
        if(d->scroll.lastScroll.msecsTo(QTime::currentTime()) < QMAX(0, msecs))
 
2298
            return;
 
2299
        d->scroll.lastScroll = QTime::currentTime();
 
2300
    }
 
2301
    if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && pos.y() <= y() + sh) { //up
 
2302
        if(d->scroll.topScrollableIndex > 0) {
 
2303
            d->scroll.topScrollableIndex--;
 
2304
            updateScrollerState();
 
2305
            update(contentsRect());
 
2306
        }
 
2307
    } else if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown &&
 
2308
              pos.y() >= (y() + contentsRect().height()) - sh) { //down
 
2309
        QMenuItemListIt it(*mitems);
 
2310
        for(int i = 0, y = contentsRect().y() + sh; it.current(); i++, ++it) {
 
2311
            if(i >= d->scroll.topScrollableIndex) {
 
2312
                int itemh = itemHeight(it.current());
 
2313
                QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, QSize(0, itemh),
 
2314
                                                    QStyleOption(it.current(),maxPMWidth,0));
 
2315
                y += sz.height();
 
2316
                if(y > contentsRect().height() - sh) {
 
2317
                    d->scroll.topScrollableIndex++;
 
2318
                    updateScrollerState();
 
2319
                    update(contentsRect());
 
2320
                    break;
 
2321
                }
 
2322
            }
 
2323
        }
 
2324
    }
 
2325
}
 
2326
 
 
2327
// This private slot handles the delayed submenu effects 
 
2328
 
 
2329
void PopupMenu::subMenuTimer() {
 
2330
 
 
2331
    if ( !isVisible() || (actItem < 0 && popupActive < 0) || actItem == popupActive )
 
2332
        return;
 
2333
 
 
2334
    if ( popupActive >= 0 ) {
 
2335
        hidePopups();
 
2336
        popupActive = -1;
 
2337
    }
 
2338
 
 
2339
    // hidePopups() may change actItem etc.
 
2340
    if ( !isVisible() || actItem < 0 || actItem == popupActive )
 
2341
        return;
 
2342
 
 
2343
    QMenuItem *mi = mitems->at(actItem);
 
2344
    if ( !mi || !mi->isEnabledAndVisible() )
 
2345
        return;
 
2346
 
 
2347
    PopupMenu *popup = mi->popup();
 
2348
    if ( !popup || !popup->isEnabled() )
 
2349
        return;
 
2350
 
 
2351
    //avoid circularity
 
2352
    if ( popup->isVisible() )
 
2353
        return;
 
2354
 
 
2355
    Q_ASSERT( popup->parentMenu == 0 );
 
2356
    popup->parentMenu = this;                   // set parent menu
 
2357
 
 
2358
    emit popup->aboutToShow();
 
2359
    supressAboutToShow = TRUE;
 
2360
 
 
2361
 
 
2362
    QRect r( itemGeometry( actItem ) );
 
2363
    QPoint p;
 
2364
    QSize ps = popup->sizeHint();
 
2365
    if( QApplication::reverseLayout() ) {
 
2366
        p = QPoint( r.left() + motifArrowHMargin - ps.width(), r.top() + motifArrowVMargin );
 
2367
        p = mapToGlobal( p );
 
2368
 
 
2369
        bool right = FALSE;
 
2370
        if ( ( parentMenu && parentMenu->isPopupMenu &&
 
2371
               ((PopupMenu*)parentMenu)->geometry().x() < geometry().x() ) ||
 
2372
             p.x() < 0 )
 
2373
            right = TRUE;
 
2374
        if ( right && (ps.width() > QApplication::desktop()->width() - mapToGlobal( r.topRight() ).x() ) )
 
2375
            right = FALSE;
 
2376
        if ( right )
 
2377
            p.setX( mapToGlobal( r.topRight() ).x() );
 
2378
    } else {
 
2379
        p = QPoint( r.right() - motifArrowHMargin, r.top() + motifArrowVMargin );
 
2380
        p = mapToGlobal( p );
 
2381
 
 
2382
        bool left = FALSE;
 
2383
        if ( ( parentMenu && parentMenu->isPopupMenu &&
 
2384
               ((PopupMenu*)parentMenu)->geometry().x() > geometry().x() ) ||
 
2385
             p.x() + ps.width() > QApplication::desktop()->width() )
 
2386
            left = TRUE;
 
2387
        if ( left && (ps.width() > mapToGlobal( r.topLeft() ).x() ) )
 
2388
            left = FALSE;
 
2389
        if ( left )
 
2390
            p.setX( mapToGlobal( r.topLeft() ).x() - ps.width() );
 
2391
    }
 
2392
    QRect pr = popup->itemGeometry(popup->count() - 1);
 
2393
    if (p.y() + ps.height() > QApplication::desktop()->height() &&
 
2394
        p.y() - ps.height() + (QCOORD) pr.height() >= 0)
 
2395
        p.setY( p.y() - ps.height() + (QCOORD) pr.height());
 
2396
 
 
2397
    if ( style().styleHint(QStyle::SH_PopupMenu_SloppySubMenus, this )) {
 
2398
         QPoint cur = QCursor::pos();
 
2399
         if ( r.contains( mapFromGlobal( cur ) ) ) {
 
2400
             QPoint pts[4];
 
2401
             pts[0] = QPoint( cur.x(), cur.y() - 2 );
 
2402
             pts[3] = QPoint( cur.x(), cur.y() + 2 );
 
2403
             if ( p.x() >= cur.x() )    {
 
2404
                 pts[1] = QPoint( geometry().right(), p.y() );
 
2405
                 pts[2] = QPoint( geometry().right(), p.y() + ps.height() );
 
2406
             } else {
 
2407
                 pts[1] = QPoint( p.x() + ps.width(), p.y() );
 
2408
                 pts[2] = QPoint( p.x() + ps.width(), p.y() + ps.height() );
 
2409
             }
 
2410
             QPointArray points( 4 );
 
2411
             for( int i = 0; i < 4; i++ )
 
2412
                 points.setPoint( i, mapFromGlobal( pts[i] ) );
 
2413
             d->mouseMoveBuffer = QRegion( points );
 
2414
             repaint();
 
2415
         }
 
2416
    }
 
2417
 
 
2418
    popupActive = actItem;
 
2419
    popup->popup( p );
 
2420
}
 
2421
 
 
2422
void PopupMenu::allowAnimation()
 
2423
{
 
2424
    preventAnimation = FALSE;
 
2425
}
 
2426
 
 
2427
void PopupMenu::updateRow( int row )
 
2428
{
 
2429
    if ( !isVisible() )
 
2430
        return;
 
2431
 
 
2432
    if ( badSize ) {
 
2433
        updateSize();
 
2434
        update();
 
2435
        return;
 
2436
    }
 
2437
    updateSize();
 
2438
    QRect r = itemGeometry( row );
 
2439
    if ( !r.isNull() ) // can happen via the scroller
 
2440
        repaint( r );
 
2441
}
 
2442
 
 
2443
int PopupMenu::exec( const QPoint & pos, int indexAtPoint )
 
2444
{
 
2445
    snapToMouse = TRUE;
 
2446
    if ( !qApp )
 
2447
        return -1;
 
2448
 
 
2449
    PopupMenu* priorSyncMenu = syncMenu;
 
2450
 
 
2451
    syncMenu = this;
 
2452
    syncMenuId = -1;
 
2453
 
 
2454
    QGuardedPtr<PopupMenu> that = this;
 
2455
    connectModal( that, TRUE );
 
2456
    popup( pos, indexAtPoint );
 
2457
    qApp->enter_loop();
 
2458
    connectModal( that, FALSE );
 
2459
 
 
2460
    syncMenu = priorSyncMenu;
 
2461
    return syncMenuId;
 
2462
}
 
2463
 
 
2464
 
 
2465
 
 
2466
//  Connect the popup and all its submenus to modalActivation() if
 
2467
//  \a doConnect is true, otherwise disconnect.
 
2468
void PopupMenu::connectModal( PopupMenu* receiver, bool doConnect )
 
2469
{
 
2470
    if ( !receiver )
 
2471
        return;
 
2472
 
 
2473
    connectModalRecursionSafety = doConnect;
 
2474
 
 
2475
    if ( doConnect )
 
2476
        connect( this, SIGNAL(activated(int)),
 
2477
                 receiver, SLOT(modalActivation(int)) );
 
2478
    else
 
2479
        disconnect( this, SIGNAL(activated(int)),
 
2480
                    receiver, SLOT(modalActivation(int)) );
 
2481
 
 
2482
    QMenuItemListIt it(*mitems);
 
2483
    register QMenuItem *mi;
 
2484
    while ( (mi=it.current()) ) {
 
2485
        ++it;
 
2486
        if ( mi->popup() && mi->popup() != receiver
 
2487
             && (bool)(mi->popup()->connectModalRecursionSafety) != doConnect )
 
2488
            mi->popup()->connectModal( receiver, doConnect ); //avoid circular
 
2489
    }
 
2490
}
 
2491
 
 
2492
int PopupMenu::exec()
 
2493
{
 
2494
    return exec(mapToGlobal(QPoint(0,0)));
 
2495
}
 
2496
 
 
2497
 
 
2498
//  Internal slot used for exec(). 
 
2499
 
 
2500
void PopupMenu::modalActivation( int id )
 
2501
{
 
2502
    syncMenuId = id;
 
2503
}
 
2504
 
 
2505
void PopupMenu::setActiveItem( int i )
 
2506
{
 
2507
    int lastActItem = actItem;
 
2508
    actItem = i;
 
2509
    if ( lastActItem >= 0 )
 
2510
        updateRow( lastActItem );
 
2511
    if ( i >= 0 && i != lastActItem )
 
2512
        updateRow( i );
 
2513
    QMenuItem *mi = mitems->at( actItem );
 
2514
    if ( !mi )
 
2515
        return;
 
2516
 
 
2517
    if ( mi->widget() && mi->widget()->isFocusEnabled() ) {
 
2518
        mi->widget()->setFocus();
 
2519
    } else {
 
2520
        setFocus();
 
2521
        QRect mfrect = itemGeometry( actItem );
 
2522
        setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
 
2523
    }
 
2524
    if ( mi->id() != -1 )
 
2525
        hilitSig( mi->id() );
 
2526
#ifndef QT_NO_WHATSTHIS
 
2527
    if (whatsThisItem && whatsThisItem != mi) {
 
2528
        qWhatsThisBDH();
 
2529
    }
 
2530
    whatsThisItem = mi;
 
2531
#endif
 
2532
}
 
2533
 
 
2534
QSize PopupMenu::sizeHint() const
 
2535
{
 
2536
    constPolish();
 
2537
    PopupMenu* that = (PopupMenu*) this;
 
2538
    //We do not need a resize here, just the sizeHint..
 
2539
    return that->updateSize(FALSE, FALSE).expandedTo( QApplication::globalStrut() );
 
2540
}
 
2541
 
 
2542
int PopupMenu::idAt( const QPoint& pos ) const
 
2543
{
 
2544
    return idAt( itemAtPos( pos ) );
 
2545
}
 
2546
 
 
2547
bool PopupMenu::customWhatsThis() const
 
2548
{
 
2549
    return TRUE;
 
2550
}
 
2551
 
 
2552
bool PopupMenu::focusNextPrevChild( bool next )
 
2553
{
 
2554
    register QMenuItem *mi;
 
2555
    int dy = next? 1 : -1;
 
2556
    if ( dy && actItem < 0 ) {
 
2557
        setFirstItemActive();
 
2558
    } else if ( dy ) {                          // highlight next/prev
 
2559
        register int i = actItem;
 
2560
        int c = mitems->count();
 
2561
        int n = c;
 
2562
        while ( n-- ) {
 
2563
            i = i + dy;
 
2564
            if ( i == c )
 
2565
                i = 0;
 
2566
            else if ( i < 0 )
 
2567
                i = c - 1;
 
2568
            mi = mitems->at( i );
 
2569
            if ( mi && !mi->isSeparator() &&
 
2570
                 ( ( style().styleHint(QStyle::SH_PopupMenu_AllowActiveAndDisabled, this)
 
2571
                     && mi->isVisible() )
 
2572
                   || mi->isEnabledAndVisible() ) )
 
2573
                break;
 
2574
        }
 
2575
        if ( i != actItem )
 
2576
            setActiveItem( i );
 
2577
    }
 
2578
    return TRUE;
 
2579
}
 
2580
 
 
2581
void PopupMenu::focusInEvent( QFocusEvent * )
 
2582
{
 
2583
}
 
2584
 
 
2585
void PopupMenu::focusOutEvent( QFocusEvent * )
 
2586
{
 
2587
}
 
2588
 
 
2589
class QTearOffMenuItem : public QCustomMenuItem
 
2590
{
 
2591
public:
 
2592
    QTearOffMenuItem()
 
2593
    {
 
2594
    }
 
2595
    ~QTearOffMenuItem()
 
2596
    {
 
2597
    }
 
2598
    void paint( QPainter* p, const QColorGroup& cg, bool,
 
2599
                bool, int x, int y, int w, int h )
 
2600
    {
 
2601
        p->setPen( QPen( cg.dark(), 1, DashLine ) );
 
2602
        p->drawLine( x+2, y+h/2-1, x+w-4, y+h/2-1 );
 
2603
        p->setPen( QPen( cg.light(), 1, DashLine ) );
 
2604
        p->drawLine( x+2, y+h/2, x+w-4, y+h/2 );
 
2605
    }
 
2606
    bool fullSpan() const
 
2607
    {
 
2608
        return TRUE;
 
2609
    }
 
2610
 
 
2611
    QSize sizeHint()
 
2612
    {
 
2613
        return QSize( 20, 6 );
 
2614
    }
 
2615
};
 
2616
 
 
2617
int PopupMenu::insertTearOffHandle( int id, int index )
 
2618
{
 
2619
    int myid = insertItem( new QTearOffMenuItem, id, index );
 
2620
    connectItem( myid, this, SLOT( toggleTearOff() ) );
 
2621
    QMenuData::d->aInt = myid;
 
2622
    return myid;
 
2623
}
 
2624
 
 
2625
void PopupMenu::toggleTearOff()
 
2626
{
 
2627
    if ( active_popup_menu && active_popup_menu->tornOff ) {
 
2628
        active_popup_menu->close();
 
2629
    } else  if (QMenuData::d->aWidget ) {
 
2630
        delete (QWidget*) QMenuData::d->aWidget; // delete the old one
 
2631
    } else {
 
2632
        // create a tear off menu
 
2633
        PopupMenu* p = new PopupMenu( parentWidget(), "tear off menu" );
 
2634
        connect( p, SIGNAL( activated(int) ), this, SIGNAL( activated(int) ) );
 
2635
        connect( p, SIGNAL( highlighted(int) ), this, SIGNAL( highlighted(int) ) );
 
2636
#ifndef QT_NO_WIDGET_TOPEXTRA
 
2637
        p->setCaption( caption() );
 
2638
#endif
 
2639
        p->setCheckable( isCheckable() );
 
2640
        p->reparent( parentWidget(), WType_TopLevel | WStyle_Tool |
 
2641
                     WNoAutoErase | WDestructiveClose,
 
2642
                     geometry().topLeft(), FALSE );
 
2643
        p->mitems->setAutoDelete( FALSE );
 
2644
        p->tornOff = TRUE;
 
2645
        for ( QMenuItemListIt it( *mitems ); it.current(); ++it ) {
 
2646
            if ( it.current()->id() != QMenuData::d->aInt && !it.current()->widget() )
 
2647
                p->mitems->append( it.current() );
 
2648
        }
 
2649
        p->show();
 
2650
        QMenuData::d->aWidget = p;
 
2651
    }
 
2652
}
 
2653
 
 
2654
void PopupMenu::activateItemAt( int index )
 
2655
{
 
2656
    if ( index >= 0 && index < (int) mitems->count() ) {
 
2657
        QMenuItem *mi = mitems->at( index );
 
2658
        if ( index != actItem )                 // new item activated
 
2659
            setActiveItem( index );
 
2660
        PopupMenu *popup = mi->popup();
 
2661
        if ( popup ) {
 
2662
            if ( popup->isVisible() ) {         // sub menu already open
 
2663
                int pactItem = popup->actItem;
 
2664
                popup->actItem = -1;
 
2665
                popup->hidePopups();
 
2666
                popup->updateRow( pactItem );
 
2667
            } else {                            // open sub menu
 
2668
                hidePopups();
 
2669
                actItem = index;
 
2670
                subMenuTimer();
 
2671
                popup->setFirstItemActive();
 
2672
            }
 
2673
        } else {
 
2674
            byeMenuBar();                       // deactivate menu bar
 
2675
 
 
2676
#ifndef QT_NO_WHATSTHIS
 
2677
            bool b = QWhatsThis::inWhatsThisMode();
 
2678
#else
 
2679
            const bool b = FALSE;
 
2680
#endif
 
2681
            if ( !mi->isEnabledAndVisible() ) {
 
2682
#ifndef QT_NO_WHATSTHIS
 
2683
                if ( b ) {
 
2684
                    actItem = -1;
 
2685
                    updateItem( mi->id() );
 
2686
                    byeMenuBar();
 
2687
                    actSig( mi->id(), b);
 
2688
                }
 
2689
#endif
 
2690
            } else {
 
2691
                byeMenuBar();                   // deactivate menu bar
 
2692
                if ( mi->isEnabledAndVisible() ) {
 
2693
                    actItem = -1;
 
2694
                    updateItem( mi->id() );
 
2695
                    active_popup_menu = this;
 
2696
                    QGuardedPtr<QSignal> signal = mi->signal();
 
2697
                    actSig( mi->id(), b );
 
2698
                    if ( signal && !b )
 
2699
                        signal->activate();
 
2700
                    active_popup_menu = 0;
 
2701
                }
 
2702
            }
 
2703
        }
 
2704
    } else {
 
2705
        if ( tornOff ) {
 
2706
            close();
 
2707
        } else {
 
2708
            QMenuData* p = parentMenu;
 
2709
            hide();
 
2710
#ifndef QT_NO_MENUBAR
 
2711
            if ( p && p->isMenuBar )
 
2712
                ((QMenuBar*) p)->goodbye( TRUE );
 
2713
#endif
 
2714
        }
 
2715
    }
 
2716
 
 
2717
}
 
2718
 
 
2719
void
 
2720
PopupMenu::updateScrollerState()
 
2721
{
 
2722
    uint old_scrollable = d->scroll.scrollable;
 
2723
    d->scroll.scrollable = QPopupMenuPrivate::Scroll::ScrollNone;
 
2724
    if(!style().styleHint(QStyle::SH_PopupMenu_Scrollable, this))
 
2725
        return;
 
2726
 
 
2727
    QMenuItem *mi;
 
2728
    QMenuItemListIt it( *mitems );
 
2729
    if(d->scroll.topScrollableIndex) {
 
2730
        for(int row = 0; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++)
 
2731
            ++it;
 
2732
        if(!mi)
 
2733
            it.toFirst();
 
2734
    }
 
2735
    int y = 0, sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this);
 
2736
    if(!it.atFirst()) {
 
2737
        // can't use |= because of a bug/feature in IBM xlC 5.0.2
 
2738
        d->scroll.scrollable = d->scroll.scrollable | QPopupMenuPrivate::Scroll::ScrollUp;
 
2739
        y += sh;
 
2740
    }
 
2741
    while ( (mi=it.current()) ) {
 
2742
        ++it;
 
2743
        int myheight = contentsRect().height();
 
2744
        QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this,
 
2745
                                            QSize(0, itemHeight( mi )),
 
2746
                                            QStyleOption(mi,maxPMWidth));
 
2747
        if(y + sz.height() >= myheight) {
 
2748
            d->scroll.scrollable = d->scroll.scrollable | QPopupMenuPrivate::Scroll::ScrollDown;
 
2749
            break;
 
2750
        }
 
2751
        y += sz.height();
 
2752
    }
 
2753
    if((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp) &&
 
2754
       !(old_scrollable & QPopupMenuPrivate::Scroll::ScrollUp))
 
2755
        d->scroll.topScrollableIndex++;
 
2756
}
 
2757
 
 
2758
#endif // QT_NO_POPUPMENU
 
2759
 
 
2760
*/
 
 
b'\\ No newline at end of file'