diff options
| author | Tim E. Real <termtech@rogers.com> | 2010-11-06 08:04:38 +0000 | 
|---|---|---|
| committer | Tim E. Real <termtech@rogers.com> | 2010-11-06 08:04:38 +0000 | 
| commit | 3a459a08c7bac364ab4454adb5bcfded8d79c6a8 (patch) | |
| tree | 1543f065052bf4101d3f01c48c6e333ed27e9f14 /muse2/muse | |
| parent | 2428f541f4a60ade9dc402ac6bec1bb362b768b4 (diff) | |
The return of the 'stay open' popup menu! (WIP)
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/app.cpp | 554 | ||||
| -rw-r--r-- | muse2/muse/app.h | 6 | ||||
| -rw-r--r-- | muse2/muse/arranger/arranger.h | 6 | ||||
| -rw-r--r-- | muse2/muse/arranger/trackinfo.cpp | 41 | ||||
| -rw-r--r-- | muse2/muse/synth.cpp | 3 | ||||
| -rw-r--r-- | muse2/muse/widgets/popupmenu.cpp | 2811 | ||||
| -rw-r--r-- | muse2/muse/widgets/popupmenu.h | 298 | 
7 files changed, 541 insertions, 3178 deletions
| diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index f9087051..6ce85950 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -36,6 +36,7 @@  #include <QStyle>  #include <QSplashScreen>  #include <QObject> +#include <QAction>  //Added by qt3to4:  #include <QTimerEvent>  #include <Q3CString> @@ -845,6 +846,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow()        watchdogThread        = 0;        editInstrument        = 0;        routingPopupMenu      = 0; +      routingPopupView      = 0;        appName               = QString("MusE"); @@ -1913,6 +1915,13 @@ void MusE::closeEvent(QCloseEvent*)        // Make sure to clear the menu, which deletes any sub menus.        if(routingPopupMenu)          routingPopupMenu->clear(); +      #if 0 +      if(routingPopupView) +      { +        routingPopupView->clear(); +        delete routingPopupView; +      }   +      #endif        // Changed by Tim. p3.3.14        //SynthIList* sl = song->syntis(); @@ -2038,53 +2047,33 @@ PopupMenu* MusE::getRoutingPopupMenu()  //   updateRouteMenus  //--------------------------------------------------------- -//void MusE::updateRouteMenus(Track* track) -void MusE::updateRouteMenus(Track* track, QObject* master)    // p3.3.50 +void MusE::updateRouteMenus(Track* track, QObject* master)      { +      // NOTE: The puropse of this routine is to make sure the items actually reflect +      //  the routing status. And with MusE-1 QT3, it was also required to actually +      //  check the items since QT3 didn't do it for us. +      // But now with MusE-2 and QT4, QT4 checks an item when it is clicked. +      // So this routine is less important now, since 99% of the time, the items +      //  will be in the right checked state. +      // But we still need this in case for some reason a route could not be +      //  added (or removed). Then the item will be properly un-checked (or checked) here. +              //if(!track || track != gRoutingPopupMenuMaster || track->type() == Track::AUDIO_AUX)        //if(!track || track->type() == Track::AUDIO_AUX)        if(!track || gRoutingPopupMenuMaster != master)  // p3.3.50          return; -      //QPopupMenu* pup = muse->getORoutesPopup();        PopupMenu* pup = getRoutingPopupMenu(); -      if(pup->count() == 0) +      if(pup->actions().size() == 0)          return; -      // p4.0.1 Protection since reverting to regular (self-extinguishing) menu behaviour here in muse2.        if(!pup->isVisible()) -      { -        //printf("MusE::updateRouteMenus menu is not visible\n");          return; -      }        //AudioTrack* t = (AudioTrack*)track;        RouteList* rl = gIsOutRoutingPopupMenu ? track->outRoutes() : track->inRoutes(); -      /* -      iRoute iorl = orl->begin(); -      for(; iorl != orl->end(); ++iorl)  -      { -        iRouteMenuMap imm = ormm->begin(); -        for(; imm != ormm->end(); ++imm)  -        { -          if(*iorl == imm->second) -          { -            orpup->setItemChecked(imm->first, true); -            break; -          } -        } -        //if(imm == ormm->end())  -        //{ -        //} -         -      } -      //if (iorl == orl->end())  -      //{ -      //} -      */      -                   iRouteMenuMap imm = gRoutingMenuMap.begin();        for(; imm != gRoutingMenuMap.end(); ++imm)         { @@ -2114,11 +2103,14 @@ void MusE::updateRouteMenus(Track* track, QObject* master)    // p3.3.50            }          }          //pup->setItemChecked(imm->first, found); -        pup->setItemChecked(imm->first, irl != rl->end()); +        //printf("MusE::updateRouteMenus setItemChecked\n"); +        // TODO: MusE-2: Convert this, fastest way is to change the routing map, otherwise this requires a lookup. +        //if(pup->isItemChecked(imm->first) != (irl != rl->end())) +        //  pup->setItemChecked(imm->first, irl != rl->end()); +        QAction* act = pup->findActionFromData(imm->first);   +        if(act && act->isChecked() != (irl != rl->end())) +          act->setChecked(irl != rl->end());        } -       -       -      return;  }        //--------------------------------------------------------- @@ -2135,128 +2127,66 @@ void MusE::routingPopupMenuActivated(Track* track, int n)        {          PopupMenu* pup = getRoutingPopupMenu(); -        //printf("MusE::routingPopupMenuActivated midi n:%d count:%d\n", n, pup->count()); -         -        if(pup->count() == 0) +        if(pup->actions().size() == 0)            return;          //MidiTrack* t = (MidiTrack*)track;          RouteList* rl = gIsOutRoutingPopupMenu ? track->outRoutes() : track->inRoutes();          if(n == -1)  -        { -          //printf("MusE::routingPopupMenuActivated midi n = -1\n"); -          ///delete pup; -          ///pup = 0;            return; -        } -        else -        { -          //int mdidx = n / MIDI_CHANNELS; -          //int ch = n % MIDI_CHANNELS; -          //int chbit = 1 << ch;              // p3.3.50 -          //int chmask = 0;                    -           -          //if(n >= MIDI_PORTS * MIDI_CHANNELS)   // p3.3.50  Toggle channels. -          //{     -            //for (int i = 0; i < MIDI_CHANNELS; i++) -              //muse->routingPopupMenuActivated(selected, i + MIDI_CHANNELS * (n-1000)); -              //muse->routingPopupMenuActivated(selected, i + MIDI_CHANNELS * (n - MIDI_PORTS * MIDI_CHANNELS));   // p3.3.50 -          //  chbit = (1 << MIDI_CHANNELS) - 1; -          //} -          //if(debugMsg) -            //printf("MusE::routingPopupMenuActivated mdidx:%d ch:%d\n", mdidx, ch); -             -          // p3.3.50 -          iRouteMenuMap imm = gRoutingMenuMap.find(n); -          if(imm == gRoutingMenuMap.end()) -            return; -          if(imm->second.type != Route::MIDI_PORT_ROUTE) -            return; -          Route &aRoute = imm->second; -          int chbit = aRoute.channel; -          Route bRoute(track, chbit); -          int mdidx = aRoute.midiPort; - -          MidiPort* mp = &midiPorts[mdidx]; -          MidiDevice* md = mp->device(); -          if(!md) -          { -            ///delete pup; -            return; -          } -           -          //if(!(md->rwFlags() & 2)) -          if(!(md->rwFlags() & (gIsOutRoutingPopupMenu ? 1 : 2))) -          { -            ///delete pup; -            return; -          }   -           -          //QString s(pup->text(n)); -          //QT_TR_NOOP(md->name()) -           -          //Route srcRoute(s, false, -1); -           -          //Route aRoute(md, ch); -          //Route aRoute(mdidx, ch);      // p3.3.49 -          //Route aRoute(mdidx, chbit);     // p3.3.50 In accordance with new channel mask, use the bit position. -           -          //Route srcRoute(md, -1); -          //Route dstRoute(track, -1); -          //Route bRoute(track, ch); -          //Route bRoute(track, chbit);     // p3.3.50  +         +        iRouteMenuMap imm = gRoutingMenuMap.find(n); +        if(imm == gRoutingMenuMap.end()) +          return; +        if(imm->second.type != Route::MIDI_PORT_ROUTE) +          return; +        Route &aRoute = imm->second; +        int chbit = aRoute.channel; +        Route bRoute(track, chbit); +        int mdidx = aRoute.midiPort; -          //if (track->type() == Track::AUDIO_INPUT) -          //      srcRoute.channel = dstRoute.channel = n & 0xf; -           -          int chmask = 0;                    -          iRoute iir = rl->begin(); -          for (; iir != rl->end(); ++iir)  -          { -            //if(*iir == (dst ? bRoute : aRoute)) -            //if(*iir == aRoute) -            if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == mdidx)    // p3.3.50 Is there already a route to this port? -            { -                  chmask = iir->channel;  // p3.3.50 Grab the channel mask. -                  break; -            }       -          } -          //if (iir != rl->end())  -          if ((chmask & chbit) == chbit)             // p3.3.50 Is the channel's bit(s) set? -          { -            // disconnect -            if(gIsOutRoutingPopupMenu) -            { -              //printf("MusE::routingPopupMenuActivated removing route src track name: %s dst device name: %s\n", track->name().latin1(), md->name().latin1()); -              audio->msgRemoveRoute(bRoute, aRoute); -            } -            else -            { -              //printf("MusE::routingPopupMenuActivated removing route src device name: %s dst track name: %s\n", md->name().latin1(), track->name().latin1()); -              audio->msgRemoveRoute(aRoute, bRoute); -            } -          } -          else  +        MidiPort* mp = &midiPorts[mdidx]; +        MidiDevice* md = mp->device(); +        if(!md) +          return; +         +        //if(!(md->rwFlags() & 2)) +        if(!(md->rwFlags() & (gIsOutRoutingPopupMenu ? 1 : 2))) +          return; +         +        int chmask = 0;                    +        iRoute iir = rl->begin(); +        for (; iir != rl->end(); ++iir)  +        { +          //if(*iir == (dst ? bRoute : aRoute)) +          //if(*iir == aRoute) +          if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == mdidx)    // p3.3.50 Is there already a route to this port?            { -            // connect -            if(gIsOutRoutingPopupMenu) -            { -              //printf("MusE::routingPopupMenuActivated adding route src track name: %s dst device name: %s\n", track->name().latin1(), md->name().latin1()); -              audio->msgAddRoute(bRoute, aRoute); -            } -            else -            { -              //printf("MusE::routingPopupMenuActivated adding route src device name: %s dst track name: %s\n", md->name().latin1(), track->name().latin1()); -              audio->msgAddRoute(aRoute, bRoute); -            }   -          } -           -          //printf("MusE::routingPopupMenuActivated calling msgUpdateSoloStates\n"); -          audio->msgUpdateSoloStates(); -          //printf("MusE::routingPopupMenuActivated calling song->update\n"); -          song->update(SC_ROUTE); +                chmask = iir->channel;  // p3.3.50 Grab the channel mask. +                break; +          }                } +        //if (iir != rl->end())  +        if ((chmask & chbit) == chbit)             // p3.3.50 Is the channel's bit(s) set? +        { +          // disconnect +          if(gIsOutRoutingPopupMenu) +            audio->msgRemoveRoute(bRoute, aRoute); +          else +            audio->msgRemoveRoute(aRoute, bRoute); +        } +        else  +        { +          // connect +          if(gIsOutRoutingPopupMenu) +            audio->msgAddRoute(bRoute, aRoute); +          else +            audio->msgAddRoute(aRoute, bRoute); +        } +         +        audio->msgUpdateSoloStates(); +        song->update(SC_ROUTE);        }        else        { @@ -2485,9 +2415,6 @@ void MusE::routingPopupMenuActivated(Track* track, int n)        //else        //{        //} -             -      ///delete pup; -      //oR->setDown(false);       }  //--------------------------------------------------------- @@ -2496,23 +2423,13 @@ void MusE::routingPopupMenuActivated(Track* track, int n)  void MusE::routingPopupMenuAboutToHide()  { -      // p3.3.47 -      //printf("MusE::routingPopupMenuAboutToHide\n"); -      //if(track) -      //  printf("%s", track->name().latin1()); -      //printf("\n"); -              // Hmm, can't do this? Sub-menus stay open with this. Re-arranged, testing... Nope.        //PopupMenu* pup = muse->getRoutingPopupMenu();        //pup->disconnect();        //pup->clear(); -      // p4.0.1 Removed. IIRC These lines were not strictly necessary in muse-1,  -      //  and here in muse-2 we reverted back to regular Q3PopupMenu behaviour for now,  -      //  which is self-extinguishing, so these lines cannot be enabled -  -      //  gRoutingPopupMenuMaster and gRoutingMenuMap are required for routingPopupMenuActivated(). -      //gRoutingMenuMap.clear(); -      //gRoutingPopupMenuMaster = 0; +      gRoutingMenuMap.clear(); +      gRoutingPopupMenuMaster = 0;  }  //--------------------------------------------------------- @@ -2541,14 +2458,295 @@ PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)        RouteList* rl = dst ? track->outRoutes() : track->inRoutes();        //Route dst(track, -1); -      ///QPopupMenu* pup = new QPopupMenu(parent); -              PopupMenu* pup = getRoutingPopupMenu();        pup->disconnect();        //connect(pup, SIGNAL(activated(int)), SLOT(routingPopupMenuActivated(int)));        //connect(pup, SIGNAL(aboutToHide()), SLOT(routingPopupMenuAboutToHide())); +      int gid = 0; +      //int n;     +      QAction* act = 0; +       +    // Routes can't be re-read until the message sent from msgAddRoute1()  +    //  has had time to be sent and actually affected the routes. +    ///_redisplay: +       +      pup->clear(); +      gRoutingMenuMap.clear(); +      gid = 0; +       +      //MidiInPortList* tl = song->midiInPorts(); +      //for(iMidiInPort i = tl->begin();i != tl->end(); ++i)  +      for(int i = 0; i < MIDI_PORTS; ++i) +      { +        //MidiInPort* track = *i; +        // NOTE: Could possibly list all devices, bypassing ports, but no, let's stick with ports. +        MidiPort* mp = &midiPorts[i]; +        MidiDevice* md = mp->device(); +        if(!md) +          continue; +         +        if(!(md->rwFlags() & (dst ? 1 : 2))) +          continue; +           +        //printf("MusE::prepareRoutingPopupMenu adding submenu portnum:%d\n", i); +         +        //QMenu* m = menu->addMenu(track->name()); +        //QPopupMenu* subp = new QPopupMenu(parent); +        //PopupMenu* subp = new PopupMenu(this); +        //PopupMenu* subp = new PopupMenu(); +        PopupMenu* subp = new PopupMenu(pup); +        subp->setTitle(md->name());  +         +        // MusE-2: Check this - needed with QMenu? Help says no. No - verified, it actually causes double triggers! +        //connect(subp, SIGNAL(triggered(QAction*)), pup, SIGNAL(triggered(QAction*))); +        //connect(subp, SIGNAL(aboutToHide()), pup, SIGNAL(aboutToHide())); +         +        int chanmask = 0; +        // p3.3.50 To reduce number of routes required, from one per channel to just one containing a channel mask.  +        // Look for the first route to this midi port. There should always be only a single route for each midi port, now. +        for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)    +        { +          if(ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == i)  +          { +            // We have a route to the midi port. Grab the channel mask. +            chanmask = ir->channel; +            break; +          } +        } +         +        for(int ch = 0; ch < MIDI_CHANNELS; ++ch)  +        { +          //QAction* a = m->addAction(QString("Channel %1").arg(ch+1)); +          //subp->insertItem(QT_TR_NOOP(QString("Channel %1").arg(ch+1)), i * MIDI_CHANNELS + ch); +          gid = i * MIDI_CHANNELS + ch; +           +          //printf("MusE::prepareRoutingPopupMenu inserting gid:%d\n", gid); +           +          act = subp->addAction(QString("Channel %1").arg(ch+1)); +          act->setCheckable(true); +          act->setData(gid); +          //a->setCheckable(true); +          //Route src(track, ch, RouteNode::TRACK); +          //Route src(md, ch); +          //Route r = Route(src, dst); +          //a->setData(QVariant::fromValue(r)); +          //a->setChecked(rl->indexOf(r) != -1); +           +          //Route srcRoute(md, ch); +          //Route srcRoute(i, ch);     // p3.3.49 New: Midi port route. +          int chbit = 1 << ch; +          Route srcRoute(i, chbit);    // p3.3.50 In accordance with new channel mask, use the bit position. +           +          gRoutingMenuMap.insert( pRouteMenuMap(gid, srcRoute) ); +           +          //for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)   // p3.3.50 Removed. +          //{ +            //if(*ir == dst)  +          //  if(*ir == srcRoute)  +          //  { +          //    subp->setItemChecked(id, true); +          //    break; +          //  } +          //} +          if(chanmask & chbit)                  // p3.3.50 Is the channel already set? Show item check mark. +            act->setChecked(true); +        } +        //subp->insertItem(QString("Toggle all"), 1000+i); +        // p3.3.50 One route with all channel bits set. +        gid = MIDI_PORTS * MIDI_CHANNELS + i;           // Make sure each 'toggle' item gets a unique id. +        act = subp->addAction(QString("Toggle all")); +        //act->setCheckable(true); +        act->setData(gid); +        Route togRoute(i, (1 << MIDI_CHANNELS) - 1);    // Set all channel bits. +        gRoutingMenuMap.insert( pRouteMenuMap(gid, togRoute) ); +         +        pup->addMenu(subp); +      } +           +      /* +      QPopupMenu* pup = new QPopupMenu(iR);        pup->setCheckable(true); +      //MidiTrack* t = (MidiTrack*)track; +      RouteList* irl = track->inRoutes(); +   +      MidiTrack* t = (MidiTrack*)track; +      int gid = 0; +      for (int i = 0; i < channel; ++i)  +      { +            char buffer[128]; +            snprintf(buffer, 128, "%s %d", tr("Channel").latin1(), i+1); +            MenuTitleItem* titel = new MenuTitleItem(QString(buffer)); +            pup->insertItem(titel); +   +            if (!checkAudioDevice()) return; +            std::list<QString> ol = audioDevice->outputPorts(); +            for (std::list<QString>::iterator ip = ol.begin(); ip != ol.end(); ++ip) { +                  int id = pup->insertItem(*ip, (gid * 16) + i); +                  Route dst(*ip, true, i); +                  ++gid; +                  for (iRoute ir = irl->begin(); ir != irl->end(); ++ir) { +                        if (*ir == dst) { +                              pup->setItemChecked(id, true); +                              break; +                              } +                        } +                  } +            if (i+1 != channel) +                  pup->insertSeparator(); +      } +      */ +       +      if(pup->actions().size() == 0) +      { +        gRoutingPopupMenuMaster = 0; +        //pup->clear(); +        //pup->disconnect(); +        gRoutingMenuMap.clear(); +        //oR->setDown(false);      +        return 0; +      } +       +      gIsOutRoutingPopupMenu = dst; +      return pup; +    } +     +    return 0; +} + +#if 0 +//--------------------------------------------------------- +//   getRoutingPopupView +//--------------------------------------------------------- + +PopupView* MusE::getRoutingPopupView() +{ +  if(!routingPopupView) +    //routingPopupView = new PopupView(this); +    routingPopupView = new PopupView(); +  return routingPopupView; +} + +//--------------------------------------------------------- +//   routingPopupViewActivated +//--------------------------------------------------------- + +void MusE::routingPopupViewActivated(Track* track, int n) +{ +      //if(!track || (track != gRoutingPopupMenuMaster)) +      if(!track) +        return; +         +      if(track->isMidiTrack()) +      { +        PopupView* pup = getRoutingPopupView(); +         +        //printf("MusE::routingPopupMenuActivated midi n:%d count:%d\n", n, pup->count()); +         +        if(pup->model()->rowCount() == 0) +          return; +           +        //MidiTrack* t = (MidiTrack*)track; +        RouteList* rl = gIsOutRoutingPopupMenu ? track->outRoutes() : track->inRoutes(); +         +        if(n == -1)  +          return; +           +        iRouteMenuMap imm = gRoutingMenuMap.find(n); +        if(imm == gRoutingMenuMap.end()) +          return; +        if(imm->second.type != Route::MIDI_PORT_ROUTE) +          return; +        Route &aRoute = imm->second; +        int chbit = aRoute.channel; +        Route bRoute(track, chbit); +        int mdidx = aRoute.midiPort; + +        MidiPort* mp = &midiPorts[mdidx]; +        MidiDevice* md = mp->device(); +        if(!md) +          return; +         +        //if(!(md->rwFlags() & 2)) +        if(!(md->rwFlags() & (gIsOutRoutingPopupMenu ? 1 : 2))) +          return; +         +        int chmask = 0;                    +        iRoute iir = rl->begin(); +        for (; iir != rl->end(); ++iir)  +        { +          //if(*iir == (dst ? bRoute : aRoute)) +          //if(*iir == aRoute) +          if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == mdidx)    // p3.3.50 Is there already a route to this port? +          { +                chmask = iir->channel;  // p3.3.50 Grab the channel mask. +                break; +          }       +        } +        //if (iir != rl->end())  +        if ((chmask & chbit) == chbit)             // p3.3.50 Is the channel's bit(s) set? +        { +          // disconnect +          if(gIsOutRoutingPopupMenu) +            audio->msgRemoveRoute(bRoute, aRoute); +          else +            audio->msgRemoveRoute(aRoute, bRoute); +        } +        else  +        { +          // connect +          if(gIsOutRoutingPopupMenu) +            audio->msgAddRoute(bRoute, aRoute); +          else +            audio->msgAddRoute(aRoute, bRoute); +        } +         +        audio->msgUpdateSoloStates(); +        song->update(SC_ROUTE); +      } +      else +      { +        // TODO: Try to move code from AudioStrip::routingPopupMenuActivated into here. +      } +      //else +      //{ +      //} +} + +//--------------------------------------------------------- +//   prepareRoutingPopupView +//--------------------------------------------------------- + +PopupView* MusE::prepareRoutingPopupView(Track* track, bool dst) +{ +  if(!track) +    return 0; +     +  //QPoint ppt = QCursor::pos(); +   +  if(track->isMidiTrack()) +  { +   +    //QPoint ppt = parent->rect().bottomLeft(); +       +    //if(dst) +    //{ +      // TODO  +       +    //} +    //else +    //{ +      RouteList* rl = dst ? track->outRoutes() : track->inRoutes(); +      //Route dst(track, -1); +     +      ///QPopupMenu* pup = new QPopupMenu(parent); +       +      PopupView* pup = getRoutingPopupView(); +      pup->disconnect(); +      //connect(pup, SIGNAL(activated(int)), SLOT(routingPopupMenuActivated(int))); +      //connect(pup, SIGNAL(aboutToHide()), SLOT(routingPopupMenuAboutToHide())); +         +      ///pup->setCheckable(true);        int gid = 0;        //int n;     @@ -2580,8 +2778,8 @@ PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)          //QMenu* m = menu->addMenu(track->name());          //QPopupMenu* subp = new QPopupMenu(parent);          //PopupMenu* subp = new PopupMenu(this); -        PopupMenu* subp = new PopupMenu(); -        connect(subp, SIGNAL(activated(int)), pup, SIGNAL(activated(int))); +        QStandardItem* subp = new QStandardItem(QT_TR_NOOP(md->name())); +///        connect(subp, SIGNAL(activated(int)), pup, SIGNAL(activated(int)));          //connect(subp, SIGNAL(aboutToHide()), pup, SIGNAL(aboutToHide()));          int chanmask = 0; @@ -2605,7 +2803,12 @@ PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)            //printf("MusE::prepareRoutingPopupMenu inserting gid:%d\n", gid); -          subp->insertItem(QString("Channel %1").arg(ch+1), gid); +///          subp->insertItem(QString("Channel %1").arg(ch+1), gid); +          QStandardItem* sti = new QStandardItem(QString("Channel %1").arg(ch+1)); +          sti->setCheckable(true); +          sti->setData(gid); +          subp->appendRow(sti); +                      //a->setCheckable(true);            //Route src(track, ch, RouteNode::TRACK);            //Route src(md, ch); @@ -2630,16 +2833,23 @@ PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)            //  }            //}            if(chanmask & chbit)                  // p3.3.50 Is the channel already set? Show item check mark. -            subp->setItemChecked(gid, true); +///            subp->setItemChecked(gid, true); +            sti->setCheckState(Qt::Checked);          }          //subp->insertItem(QString("Toggle all"), 1000+i);          // p3.3.50 One route with all channel bits set.          gid = MIDI_PORTS * MIDI_CHANNELS + i;           // Make sure each 'toggle' item gets a unique id. -        subp->insertItem(QString("Toggle all"), gid);       +///        subp->insertItem(QString("Toggle all"), gid);       +        QStandardItem* sti = new QStandardItem(QString("Toggle all")); +        sti->setData(gid); +        subp->appendRow(sti); +                  Route togRoute(i, (1 << MIDI_CHANNELS) - 1);    // Set all channel bits.          gRoutingMenuMap.insert( pRouteMenuMap(gid, togRoute) ); -        pup->insertItem(QT_TR_NOOP(md->name()), subp); +///        pup->insertItem(QT_TR_NOOP(md->name()), subp); +        pup->model()->appendRow(subp); +        pup->updateView();        }        /* @@ -2675,7 +2885,8 @@ PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)        }        */ -      if(pup->count() == 0) +///      if(pup->count() == 0) +      if(pup->model()->rowCount() == 0)        {          ///delete pup;          gRoutingPopupMenuMaster = 0; @@ -2692,6 +2903,7 @@ PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)      return 0;  } +#endif  //---------------------------------------------------------  //   saveAs diff --git a/muse2/muse/app.h b/muse2/muse/app.h index 4728f74f..b13c38a3 100644 --- a/muse2/muse/app.h +++ b/muse2/muse/app.h @@ -37,6 +37,7 @@ class Q3ListViewItem;  class QPoint;  class QToolButton;  class PopupMenu; +class PopupView;  class Track;  class PrinterConfig;  class MidiSyncConfig; @@ -116,6 +117,7 @@ class MusE : public QMainWindow        // Special 'stay-open' menu for routes.        PopupMenu* routingPopupMenu;  +      PopupView* routingPopupView;         int aid1a, aid1b, aid2, aid3, autoId;        int tr_id, bt_id, mr_id; @@ -318,6 +320,10 @@ class MusE : public QMainWindow        PopupMenu* prepareRoutingPopupMenu(Track* /*track*/, bool /*dst*/);        void routingPopupMenuActivated(Track* /*track*/, int /*id*/);        void updateRouteMenus(Track* /*track*/, QObject* /*master*/); +      // Testing... +      //PopupView* getRoutingPopupView(); +      //PopupView* prepareRoutingPopupView(Track* /*track*/, bool /*dst*/); +      //void routingPopupViewActivated(Track* /*track*/, int /*id*/);  #ifdef HAVE_LASH        void lash_idle_cb (); diff --git a/muse2/muse/arranger/arranger.h b/muse2/muse/arranger/arranger.h index 37b4c55e..34aa5c68 100644 --- a/muse2/muse/arranger/arranger.h +++ b/muse2/muse/arranger/arranger.h @@ -41,6 +41,9 @@ class TLLayout;  class WidgetStack;  class AudioStrip;  class SpinBox; +class QAction; +//class QModelIndex; +  //---------------------------------------------------------  //   TWhatsThis  //--------------------------------------------------------- @@ -172,7 +175,8 @@ class Arranger : public QWidget {        void verticalScrollSetYpos(unsigned);        void inRoutesPressed();        void outRoutesPressed(); -      void routingPopupMenuActivated(int /*id*/); +      void routingPopupMenuActivated(QAction*); +      //void routingPopupViewActivated(const QModelIndex&);     signals:        void redirectWheelEvent(QWheelEvent*); diff --git a/muse2/muse/arranger/trackinfo.cpp b/muse2/muse/arranger/trackinfo.cpp index 382ef1e0..b23cead8 100644 --- a/muse2/muse/arranger/trackinfo.cpp +++ b/muse2/muse/arranger/trackinfo.cpp @@ -9,7 +9,7 @@  #include <qcombobox.h>  #include <qtoolbutton.h>  #include <qlabel.h> -#include <q3popupmenu.h> +#include <QMenu>  #include <qmessagebox.h>  //#include <q3hbox.h>  #include <qcheckbox.h> @@ -17,6 +17,7 @@  //#include <q3widgetstack.h>  #include <qlineedit.h>  #include <qtimer.h> +#include <QModelIndex>  //Added by qt3to4:  #include <QPixmap>  #include <math.h> @@ -573,7 +574,8 @@ void Arranger::iInputPortChanged(const QString& s)  //   routingPopupMenuActivated  //--------------------------------------------------------- -void Arranger::routingPopupMenuActivated(int n) +//void Arranger::routingPopupMenuActivated(int n) +void Arranger::routingPopupMenuActivated(QAction* act)  {    //if(gRoutingPopupMenuMaster != this || !track || !track->isMidiTrack())    if(!midiTrackInfo || gRoutingPopupMenuMaster != midiTrackInfo || !selected || !selected->isMidiTrack()) @@ -585,10 +587,34 @@ void Arranger::routingPopupMenuActivated(int n)    //    muse->routingPopupMenuActivated(selected, i + MIDI_CHANNELS * (n - MIDI_PORTS * MIDI_CHANNELS));   // p3.3.50    //}    //else { -    muse->routingPopupMenuActivated(selected, n); +    ///muse->routingPopupMenuActivated(selected, n); +    muse->routingPopupMenuActivated(selected, act->data().toInt());    //}  } +#if 0 +//--------------------------------------------------------- +//   routingPopupViewActivated +//--------------------------------------------------------- + +void Arranger::routingPopupViewActivated(const QModelIndex& mdi) +{ +  //if(gRoutingPopupMenuMaster != this || !track || !track->isMidiTrack()) +  if(!midiTrackInfo || gRoutingPopupMenuMaster != midiTrackInfo || !selected || !selected->isMidiTrack()) +    return; +  //if (n > 999) { +  //if (n >= MIDI_PORTS * MIDI_CHANNELS) {    // p3.3.50 +  //  for (int i = 0; i < MIDI_CHANNELS; i++) +      //muse->routingPopupMenuActivated(selected, i + MIDI_CHANNELS * (n-1000)); +  //    muse->routingPopupMenuActivated(selected, i + MIDI_CHANNELS * (n - MIDI_PORTS * MIDI_CHANNELS));   // p3.3.50 +  //} +  //else { +///    muse->routingPopupMenuActivated(selected, n); +    muse->routingPopupMenuActivated(selected, mdi.data().toInt()); +  //} +} +#endif +  //---------------------------------------------------------  //   inRoutesPressed  //--------------------------------------------------------- @@ -605,16 +631,21 @@ void Arranger::inRoutesPressed()    //song->chooseMidiRoutes(iR, (MidiTrack*)track, false);    PopupMenu* pup = muse->prepareRoutingPopupMenu(selected, false); +  //PopupView* pup = muse->prepareRoutingPopupView(selected, false);    if(!pup)      return;    //pup->disconnect();    //gRoutingPopupMenuMaster = this;    gRoutingPopupMenuMaster = midiTrackInfo; -  connect(pup, SIGNAL(activated(int)), SLOT(routingPopupMenuActivated(int))); +  //connect(pup, SIGNAL(activated(int)), SLOT(routingPopupMenuActivated(int))); +  connect(pup, SIGNAL(triggered(QAction*)), SLOT(routingPopupMenuActivated(QAction*))); +  //connect(pup, SIGNAL(activated(const QModelIndex&)), SLOT(routingPopupViewActivated(const QModelIndex&)));    // Nope, can't clear menu and mm list in there, sub-menus stay open. Never mind for now...    connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupMenuAboutToHide())); -  pup->popup(QCursor::pos(), 0); +  //connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupViewAboutToHide())); +  pup->popup(QCursor::pos()); +  //pup->setVisible(true);    midiTrackInfo->iRButton->setDown(false);         return;  } diff --git a/muse2/muse/synth.cpp b/muse2/muse/synth.cpp index a9685706..b6e06e65 100644 --- a/muse2/muse/synth.cpp +++ b/muse2/muse/synth.cpp @@ -36,9 +36,6 @@  #include "midictrl.h"  //#include "stringparam.h" -// REMOVE Tim. -#include "plugin.h" -  std::vector<Synth*> synthis;  // array of available synthis  extern void connectNodes(AudioTrack*, AudioTrack*); diff --git a/muse2/muse/widgets/popupmenu.cpp b/muse2/muse/widgets/popupmenu.cpp index 59951375..e2344d32 100644 --- a/muse2/muse/widgets/popupmenu.cpp +++ b/muse2/muse/widgets/popupmenu.cpp @@ -5,2774 +5,131 @@  //  //  (C) Copyright 1999-2010 Werner Schweer (ws@seh.de)  // -//  PopupMenu sub-class of QPopupMenu created by Tim. +//  PopupMenu sub-class of QMenu created by Tim.  //========================================================= - - -//========================================================= -// -// NOTICE: This sub-class of QPopupMenu *automatically* deletes -//          and *clears* any sub popup menus, when clear() is called. -//         Therefore a parent widget is *not* necessary when  -//          creating sub popup menus to add to the popup. -// -//========================================================= - - - -// MusE: want no menu bar here. Can't use, not needed for now anyway. -#define QT_NO_MENUBAR -#define QT_NO_WHATSTHIS - -#include <qapplication.h> -//#include <qtimer.h> -#include <qpointer.h> -//Added by qt3to4: -#include <Q3Signal>  #include <QMouseEvent> -#include <Q3PopupMenu> -//#include <qmenubar.h> -//#include <qstyle.h> -//#include <qdatetime.h> +#include <QAction> +//#include <QStandardItemModel>  #include "popupmenu.h" -  -// used to provide ONE single-shot timer -//static QTimer * singleSingleShot = 0; -//static bool preventAnimation = FALSE; -// Used to detect motion prior to mouse-release -static int motion; -static PopupMenu* active_popup_menu = 0; - -/* -static void cleanup() -{ -    delete singleSingleShot; -    singleSingleShot = 0; -} - -static void popupSubMenuLater( int msec, QPopupMenu * receiver ) { -//static void popupSubMenuLater( int msec, PopupMenu * receiver ) { -    if ( !singleSingleShot ) { -        singleSingleShot = new QTimer( qApp, "popup submenu timer" ); -        qAddPostRoutine( cleanup ); -    } - -    singleSingleShot->disconnect( SIGNAL(timeout()) ); -    QObject::connect( singleSingleShot, SIGNAL(timeout()), -                      receiver, SLOT(subMenuTimer()) ); -    singleSingleShot->start( msec, TRUE ); -} -*/ - -/* -//====================== -// MenuDataData -//====================== - -class QMenuDataData { -public: -    QMenuDataData(); -    QGuardedPtr<QWidget> aWidget; -    int aInt; -}; - -//====================== -// QPopupMenuPrivate -//====================== - -class QPopupMenuPrivate { -public: -    struct Scroll { -        enum { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 }; -        uint scrollable : 2; -        uint direction : 1; -        int topScrollableIndex, scrollableSize; -        QTime lastScroll; -        QTimer *scrolltimer; -    } scroll; -    QSize calcSize; -    QRegion mouseMoveBuffer; -}; -*/ -  //======================  // PopupMenu  //====================== -PopupMenu::PopupMenu(QWidget* parent, const char* name)  -          : Q3PopupMenu(parent, name) +PopupMenu::PopupMenu(QWidget* parent)  +          : QMenu(parent)  { -  // It's too bad QPopupMenu::d is private.  -  // It will be redundant and this will be our own private member. -  //d = new QPopupMenuPrivate; -  //d->scroll.scrollableSize = d->scroll.topScrollableIndex = 0; -  //d->scroll.scrollable = QPopupMenuPrivate::Scroll::ScrollNone; -  //d->scroll.scrolltimer = 0; +  // Menus will trigger! Set to make sure our trigger handlers ignore menus. +  menuAction()->setData(-1);  }  PopupMenu::~PopupMenu()  { -  //if(d->scroll.scrolltimer) -  //  delete d->scroll.scrolltimer; - -  //preventAnimation = FALSE; -  //delete d; -   -  // Make sure to clear the popup so that any child popups are also deleted ! -  //popup->clear(); +  printf("PopupMenu::~PopupMenu\n");  // REMOVE Tim.  } - - -#if 0     // p4.0.1 - -void PopupMenu::menuDelPopup(Q3PopupMenu *popup) +void PopupMenu::clear()  { -  //printf("PopupMenu::menuDelPopup deleting popup...\n"); -   -  // Make sure to clear the popup so that any child popups are also deleted ! -  // Tested OK. All the popups are deleted. -  popup->clear(); -   -  popup->disconnect( SIGNAL(activatedRedirect(int)) ); -  popup->disconnect( SIGNAL(highlightedRedirect(int)) ); -  disconnect( popup, SIGNAL(destroyed(QObject*)), -              this, SLOT(popupDestroyed(QObject*)) ); -  delete popup; -} - -/* -void PopupMenu::setFirstItemActive() -{ -    QMenuItemListIt it(*QPopupMenu::mitems); -    register QMenuItem *mi; -    int ai = 0; -    //if(d->scroll.scrollable) -    //    ai = d->scroll.topScrollableIndex; -    while ( (mi=it.current()) )  +  QList<QAction*> list = actions(); +  for(int i = 0; i < list.size(); ++i) +  { +    QAction* act = list[i]; +    QMenu* menu = act->menu(); +    if(menu)      { -        ++it; -        if(!mi->isSeparator() && mi->id() != QMenuData::d->aInt && -           (style().styleHint(QStyle::SH_PopupMenu_AllowActiveAndDisabled, this) || mi->isEnabledAndVisible()))  -        { -          setActiveItem( ai ); -          return; -        } -        ai++; -    } -    QPopupMenu::actItem = -1; -} -*/ - -/* -void PopupMenu::hideAllPopups() -{ -    //register QMenuData *top = this;             // find top level popup -    register MenuData *top = this;             // find top level popup -    if ( !preventAnimation ) -        QTimer::singleShot( 10, this, SLOT(allowAnimation()) ); -    preventAnimation = TRUE; - -    if ( !isPopup() ) -        return; // nothing to do - -    //while ( top->parentMenu && top->parentMenu->isPopupMenu -    while ( top->parentMenu && ((MenuData*)top->parentMenu)->isPopupMenu -            //&& ((QPopupMenu*)top->parentMenu)->isPopup() ) -            && ((PopupMenu*)((MenuData*)top->parentMenu))->isPopup() ) -        //top = top->parentMenu; -        top = (MenuData*)top->parentMenu; -    //((QPopupMenu*)top)->hide();                 // cascade from top level -    ((PopupMenu*)top)->hide();                 // cascade from top level - -#ifndef QT_NO_WHATSTHIS -    if (whatsThisItem) { -        qWhatsThisBDH(); -        whatsThisItem = 0; -    } -#endif - -} -*/ - -/* -void PopupMenu::hidePopups() -{ -    if ( !preventAnimation ) -        QTimer::singleShot( 10, this, SLOT(allowAnimation()) ); -    preventAnimation = TRUE; - -    //QMenuItemListIt it(*mitems); -    QMenuItemListIt it(*MenuData::mitems); -    register QMenuItem *mi; -    while ( (mi=it.current()) ) { -        ++it; -        if ( mi->popup() && mi->popup()->parentMenu == this ) //avoid circularity -            mi->popup()->hide(); +      menu->clear(); +      act->setMenu(0);  // CHECK: Is this OK? +      delete menu;      } -    popupActive = -1;                           // no active sub menu -    if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this)) -        d->mouseMoveBuffer = QRegion(); - -    QRect mfrect = itemGeometry( actItem ); -    setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE ); -} -*/ - -bool PopupMenu::tryMenuBar( QMouseEvent *e ) -{ -#if 0 // ddskrjo -    register QMenuData *top = this;             // find top level -    //register PopupMenu *top = this;             // find top level -    //while ( top->parentMenu ) -    while ( ((PopupMenu*)top)->parentMenu ) -        //top = top->parentMenu; -        //top = (MenuData*)top->parentMenu; -        top = ((PopupMenu*)top)->parentMenu; -#ifndef QT_NO_MENUBAR -    return top->isMenuBar ? -        ((QMenuBar *)top)->tryMouseEvent( this, e ) : -                              ((Q3PopupMenu*)top)->tryMouseEvent(this, e ); -#else -    //return ((QPopupMenu*)top)->tryMouseEvent(this, e ); -    return ((PopupMenu*)top)->tryMouseEvent(this, e ); -#endif - -#endif -    return false; // ddskrjo -} - -//bool PopupMenu::tryMouseEvent( QPopupMenu *p, QMouseEvent * e) -bool PopupMenu::tryMouseEvent( PopupMenu *p, QMouseEvent * e) -{ -    if ( p == this ) -        return FALSE; -    QPoint pos = mapFromGlobal( e->globalPos() ); -    if ( !rect().contains( pos ) )              // outside -        return FALSE; -    QMouseEvent ee( e->type(), pos, e->globalPos(), e->button(), e->state() ); -    event( &ee ); -    return TRUE; -} - -/* -void PopupMenu::byeMenuBar() -{ -#ifndef QT_NO_MENUBAR -    //register QMenuData *top = this;             // find top level -    register MenuData *top = this;             // find top level -    while ( top->parentMenu ) -        top = top->parentMenu; -#endif -    hideAllPopups(); -#ifndef QT_NO_MENUBAR -    if ( top->isMenuBar ) -        ((QMenuBar *)top)->goodbye(); -#endif +  } +   +  // Now let QT remove and delete this menu's actions. +  QMenu::clear();  } -*/ -void PopupMenu::actSig(int id, bool inwhatsthis) +QAction* PopupMenu::findActionFromData(QVariant v)  { -    if(!inwhatsthis)  +  QList<QAction*> list = actions(); +  for(int i = 0; i < list.size(); ++i) +  { +    QAction* act = list[i]; +    PopupMenu* menu = (PopupMenu*)act->menu(); +    if(menu)      { -      emit activated( id ); -#if defined(QT_ACCESSIBILITY_SUPPORT) -      if(!fromAccel) -        QAccessible::updateAccessibility(this, indexOf(id)+1, QAccessible::MenuCommand); -#endif -    }  -    else  -    { -#ifndef QT_NO_WHATSTHIS -      QRect r(itemGeometry(indexOf(id))); -      QPoint p(r.center().x(), r.bottom()); -      QString whatsThis = findItem(id)->whatsThis(); -      if(whatsThis.isNull()) -        whatsThis = Q3WhatsThis::textFor(this, p); -      Q3WhatsThis::leaveWhatsThisMode(whatsThis, mapToGlobal(p), this); -#endif +      if(QAction* actm = menu->findActionFromData(v)) +        return actm;      } - -    //emit activatedRedirect(id); ddskrjo +    if(act->data() == v) +      return act; +  } +  return 0;  } - -/* -void PopupMenu::mousePressEvent(QMouseEvent *e) -{ -    printf("PopupMenu::mousePressEvent\n"); -     -    //int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -    //if (rect().contains(e->pos()) && -    //    ((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up -    //     (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && -    //         e->pos().y() >= contentsRect().height() - sh))) //down +void PopupMenu::mouseReleaseEvent(QMouseEvent *e) +{ +    //Q_D(QMenu); +    //if (d->mouseEventTaken(e))      //    return; -     -    mouseBtDn = TRUE;                           // mouse button down -    int item = itemAtPos( e->pos() ); -    if ( item == -1 ) { -        //if ( !rect().contains(e->pos()) && !tryMenuBar(e) ) { -        //    byeMenuBar(); -        //} -        return; -    } -    register QMenuItem *mi = mitems->at(item); -    ///if ( item != actItem )                      // new item activated -    ///    setActiveItem( item ); -    QPopupMenu *popup = mi->popup(); -    if(popup)  -    { -        if(popup->isVisible())              // sub menu already open -        {     -            //int pactItem = popup->actItem; -            //popup->actItem = -1; -            //popup->hidePopups(); -            //popup->updateRow( pactItem ); -        }  -        else                                 // open sub menu -        {     -            //hidePopups(); -            popupSubMenuLater( 20, this ); -        } -    }  -    else  +    //d->mouseDown = false; +    //QAction *action = d->actionAt(e->pos()); +    QAction *action = actionAt(e->pos()); +     +    //for(QWidget *caused = this; caused;) { +    //    if (QMenu *m = qobject_cast<QMenu*>(caused)) { +    //        QAction *currentAction = d->currentAction; +    //        if(currentAction && (!currentAction->isEnabled() || currentAction->menu() || currentAction->isSeparator())) +    //            currentAction = 0; +    //        caused = m->d_func()->causedPopup.widget; +    //        if (m->d_func()->eventLoop) +    //            m->d_func()->syncAction = currentAction; // synchronous operation +    //    } else { +    //        break; +    //    } +    //} +     +    //if (action && action == d->currentAction) { +    if (action && action == activeAction() && !action->isSeparator() && action->isEnabled())       { -        //hidePopups(); +        //if (action->menu()) +        //    action->menu()->d_func()->setFirstActionActive(); +        //else +            //d->activateAction(action, QAction::Trigger); +            action->activate(QAction::Trigger);      } -} -*/ - -void PopupMenu::mouseReleaseEvent(QMouseEvent *e) -{ -#if 0 // ddskrjo -    // do not hide a standalone context menu on press-release, unless -    // the user moved the mouse significantly -    //if(!parentMenu && !mouseBtDn && actItem < 0 && motion < 6) -    //  return; - -    //mouseBtDn = FALSE; -    //MenuData::mouseBtDn = FALSE; -    Q3PopupMenu::mouseBtDn = FALSE; - -    // if the user released the mouse outside the menu, pass control -    // to the menubar or our parent menu -    //int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -    if(!rect().contains(e->pos()) && tryMenuBar(e)) -      return; -    //else  -    //if((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up -    //   (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && -    //    e->pos().y() >= contentsRect().height() - sh)) //down -    //  return; - -    if(Q3PopupMenu::actItem < 0)  -    {  -      // we do not have an active item -      // if the release is inside without motion (happens with -      // oversized popup menus on small screens), ignore it -      if(rect().contains(e->pos()) && motion < 6) -        return; -      ///else -      ///  byeMenuBar(); -    }       else  -    {  -      // selected menu item! -      register QMenuItem *mi = Q3PopupMenu::mitems->at(Q3PopupMenu::actItem); -      if(mi->widget())  -      { -        QWidget* widgetAt = QApplication::widgetAt(e->globalPos(), TRUE); -        if(widgetAt && widgetAt != this)  -        { -          QMouseEvent me(e->type(), widgetAt->mapFromGlobal(e->globalPos()), -                         e->globalPos(), e->button(), e->state()); -          QApplication::sendEvent( widgetAt, &me ); -        } -      } -      //QPopupMenu *popup = mi->popup(); -      PopupMenu *popup = (PopupMenu*)mi->popup(); -#ifndef QT_NO_WHATSTHIS -      bool b = Q3WhatsThis::inWhatsThisMode(); -#else -      const bool b = FALSE; -#endif -      if(!mi->isEnabledAndVisible())  -      { -#ifndef QT_NO_WHATSTHIS -        if(b)  -        { -          actItem = -1; -          updateItem(mi->id()); -          byeMenuBar(); -          actSig(mi->id(), b); -        } -#endif -      }  -      else   -      if(popup)  -      { -        //popup->setFirstItemActive(); -      }  -      else  -      {                                 -        // normal menu item -        ///byeMenuBar();       // deactivate menu bar -        if(mi->isEnabledAndVisible())  -        { -          ///QPopupMenu::actItem = -1; -          Q3PopupMenu::updateItem(mi->id()); -          active_popup_menu = this; -          QPointer<Q3Signal> signal = mi->signal(); -          actSig(mi->id(), b); -          if(signal && !b) -            signal->activate(); -          active_popup_menu = 0; -        } -      } -    } -#endif +    //if (d->motions > 6) { +    //    d->hideUpToMenuBar(); +    //  } +      QMenu::mouseReleaseEvent(e);  } - - -#endif      // p4.0.1 - - - - -/**************************************************************************** -** -** Implementation of QPopupMenu class -** -** Created : 941128 -** -** Copyright (C) 1992-2008 Trolltech ASA.  All rights reserved. -** -** This file is part of the widgets module of the Qt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free Qt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.QPL -** included in the packaging of this file.  Licensees holding valid Qt -** Commercial licenses may use this file in accordance with the Qt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ -  /* -#include "popupmenu.h" -#ifndef QT_NO_POPUPMENU -#include <qmenubar.h> -#include <qaccel.h> -#include <qpainter.h> -#include <qdrawutil.h> -#include <qapplication.h> -#include <qpixmap.h> -#include <qpixmapcache.h> -#include <qtimer.h> -#include <qwhatsthis.h> -#include <qobjectlist.h> -#include <qguardedptr.h> -//#include <qeffects_p.h> -#include <qcursor.h> -#include <qstyle.h> -#include <qtimer.h> -#include <qdatetime.h> -#if defined(QT_ACCESSIBILITY_SUPPORT) -#include <qaccessible.h> -#endif - -//#define ANIMATED_POPUP -//#define BLEND_POPUP - -// Motif style parameters - -static const int motifArrowHMargin      = 6;    // arrow horizontal margin -static const int motifArrowVMargin      = 2;    // arrow vertical margin - -#if 0 -# define DEBUG_SLOPPY_SUBMENU -#endif - -// used for internal communication -static PopupMenu * syncMenu = 0; -static int syncMenuId = 0; - -// Used to detect motion prior to mouse-release -static int motion; - -// used to provide ONE single-shot timer -static QTimer * singleSingleShot = 0; - -static bool supressAboutToShow = FALSE; - -static void cleanup() -{ -    delete singleSingleShot; -    singleSingleShot = 0; -} - -static void popupSubMenuLater( int msec, PopupMenu * receiver ) { -    if ( !singleSingleShot ) { -        singleSingleShot = new QTimer( qApp, "popup submenu timer" ); -        qAddPostRoutine( cleanup ); -    } - -    singleSingleShot->disconnect( SIGNAL(timeout()) ); -    QObject::connect( singleSingleShot, SIGNAL(timeout()), -                      receiver, SLOT(subMenuTimer()) ); -    singleSingleShot->start( msec, TRUE ); -} - -static bool preventAnimation = FALSE; - -#ifndef QT_NO_WHATSTHIS -extern void qWhatsThisBDH(); -static QMenuItem* whatsThisItem = 0; -#endif - -class QMenuDataData { -    // attention: also defined in qmenudata.cpp -public: -    QMenuDataData(); -    QGuardedPtr<QWidget> aWidget; -    int aInt; -}; - -class QPopupMenuPrivate { -public: -    struct Scroll { -        enum { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 }; -        uint scrollable : 2; -        uint direction : 1; -        int topScrollableIndex, scrollableSize; -        QTime lastScroll; -        QTimer *scrolltimer; -    } scroll; -    QSize calcSize; -    QRegion mouseMoveBuffer; -}; - -static PopupMenu* active_popup_menu = 0; - -PopupMenu::PopupMenu( QWidget *parent, const char *name ) -    : QFrame( parent, name, WType_Popup  | WNoAutoErase ) -{ -    d = new QPopupMenuPrivate; -    d->scroll.scrollableSize = d->scroll.topScrollableIndex = 0; -    d->scroll.scrollable = QPopupMenuPrivate::Scroll::ScrollNone; -    d->scroll.scrolltimer = 0; -    isPopupMenu   = TRUE; -#ifndef QT_NO_ACCEL -    autoaccel     = 0; -    accelDisabled = FALSE; -#endif -    popupActive   = -1; -    snapToMouse   = TRUE; -    tab = 0; -    checkable = 0; -    tornOff = 0; -    pendingDelayedContentsChanges = 0; -    pendingDelayedStateChanges = 0; -    maxPMWidth = 0; - -    tab = 0; -    ncols = 1; -    setFrameStyle( QFrame::PopupPanel | QFrame::Raised ); -    setMouseTracking(style().styleHint(QStyle::SH_PopupMenu_MouseTracking, this)); -    //style().polishPopupMenu( this ); -    style().polishPopupMenu( (QPopupMenu*)this ); -    setBackgroundMode( PaletteButton ); -    connectModalRecursionSafety = 0; - -    setFocusPolicy( StrongFocus ); -} - -PopupMenu::~PopupMenu() -{ -    if ( syncMenu == this && qApp ) { -        qApp->exit_loop(); -        syncMenu = 0; -    } - -    if(d->scroll.scrolltimer) -        delete d->scroll.scrolltimer; - -    if ( isVisible() ) { -        parentMenu = 0; -        hidePopups(); -    } - -    delete (QWidget*) QMenuData::d->aWidget;  // tear-off menu - -    preventAnimation = FALSE; -    delete d; -} - - -void PopupMenu::updateItem( int id )           // update popup menu item -{ -    updateRow( indexOf(id) ); -} - - -void PopupMenu::setCheckable( bool enable ) -{ -    if ( isCheckable() != enable ) { -        checkable = enable; -        badSize = TRUE; -        if ( QMenuData::d->aWidget ) -            ( (PopupMenu*)(QWidget*)QMenuData::d->aWidget)->setCheckable( enable ); -    } -} - -bool PopupMenu::isCheckable() const -{ -    return checkable; -} - -void PopupMenu::menuContentsChanged() -{ -    // here the part that can't be delayed -    QMenuData::menuContentsChanged(); -    badSize = TRUE;                             // might change the size -#if defined(Q_WS_MAC) && !defined(QMAC_QMENUBAR_NO_NATIVE) -    mac_dirty_popup = 1; -#endif -    if( pendingDelayedContentsChanges ) -        return; -    pendingDelayedContentsChanges = 1; -    if( !pendingDelayedStateChanges ) // if the timer hasn't been started yet -        QTimer::singleShot( 0, this, SLOT(performDelayedChanges())); -} - -void PopupMenu::performDelayedContentsChanged() -{ -    pendingDelayedContentsChanges = 0; -    // here the part the can be delayed -#ifndef QT_NO_ACCEL -    // if performDelayedStateChanged() will be called too, -    // it will call updateAccel() too, no need to do it twice -    if( !pendingDelayedStateChanges ) -        updateAccel( 0 ); -#endif -    if ( isVisible() ) { -        if ( tornOff ) -            return; -        updateSize(TRUE); -        update(); -    } -    PopupMenu* p = (PopupMenu*)(QWidget*)QMenuData::d->aWidget; -    if ( p && p->isVisible() ) { -        p->updateSize(TRUE); -        p->update(); -    } -#if defined(Q_WS_MAC) && !defined(QMAC_QMENUBAR_NO_NATIVE) -    mac_dirty_popup = 1; -#endif -} - - -void PopupMenu::menuStateChanged() -{ -    // here the part that can't be delayed -    if( pendingDelayedStateChanges ) -        return; -    pendingDelayedStateChanges = 1; -    if( !pendingDelayedContentsChanges ) // if the timer hasn't been started yet -        QTimer::singleShot( 0, this, SLOT(performDelayedChanges())); -} - -void PopupMenu::performDelayedStateChanged() -{ -    pendingDelayedStateChanges = 0; -    // here the part that can be delayed -#ifndef QT_NO_ACCEL -    updateAccel( 0 ); // ### when we have a good solution for the accel vs. focus widget problem, remove that. That is only a workaround -    // if you remove this, see performDelayedContentsChanged() -#endif -    update(); -    if ( QMenuData::d->aWidget ) -        QMenuData::d->aWidget->update(); -} - -void PopupMenu::performDelayedChanges() -{ -    if( pendingDelayedContentsChanges ) -        performDelayedContentsChanged(); -    if( pendingDelayedStateChanges ) -        performDelayedStateChanged(); -} - -void PopupMenu::menuInsPopup( PopupMenu *popup ) -{ -    connect( popup, SIGNAL(activatedRedirect(int)), -             SLOT(subActivated(int)) ); -    connect( popup, SIGNAL(highlightedRedirect(int)), -             SLOT(subHighlighted(int)) ); -    connect( popup, SIGNAL(destroyed(QObject*)), -             this, SLOT(popupDestroyed(QObject*)) ); -} - -void PopupMenu::menuDelPopup( PopupMenu *popup ) -{ -    popup->disconnect( SIGNAL(activatedRedirect(int)) ); -    popup->disconnect( SIGNAL(highlightedRedirect(int)) ); -    disconnect( popup, SIGNAL(destroyed(QObject*)), -                this, SLOT(popupDestroyed(QObject*)) ); -} - - -void PopupMenu::frameChanged() -{ -    menuContentsChanged(); -} - -void PopupMenu::popup( const QPoint &pos, int indexAtPoint ) -{ -    if ( !isPopup() && isVisible() ) -        hide(); - -    //avoid circularity -    if ( isVisible() || !isEnabled() ) -        return; - -#if defined(Q_WS_MAC) && !defined(QMAC_QMENUBAR_NO_NATIVE) -    if( macPopupMenu(pos, indexAtPoint )) -        return; -#endif - -#if (QT_VERSION-0 >= 0x040000) -#error "Fix this now" -    // #### should move to QWidget - anything might need this functionality, -    // #### since anything can have WType_Popup window flag. -    // #### This includes stuff in QPushButton and some stuff for setting -    // #### the geometry of QDialog. -    // QPopupMenu -    // ::exec() -    // ::popup() -    // QPushButton (shouldn't require QMenuPopup) -    // ::popupPressed -    // Some stuff in qwidget.cpp for dialogs... can't remember exactly. -    // Also the code here indicatets the parameter should be a rect, not a -    // point. -#endif - -    if(d->scroll.scrollable) { -        d->scroll.scrollable = QPopupMenuPrivate::Scroll::ScrollNone; -        d->scroll.topScrollableIndex = d->scroll.scrollableSize = 0; -        badSize = TRUE; -    } -    updateSize(); - -    QPoint mouse = QCursor::pos(); -    snapToMouse = pos == mouse; - -    // have to emit here as a menu might be setup in a slot connected -    // to aboutToShow which will change the size of the menu -    bool s = supressAboutToShow; -    supressAboutToShow = TRUE; -    if ( !s) { -        emit aboutToShow(); -        updateSize(TRUE); -    } - -    int screen_num; -    if (QApplication::desktop()->isVirtualDesktop()) -        screen_num = -            QApplication::desktop()->screenNumber( QApplication::reverseLayout() ? -                                                   pos+QPoint(width(),0) : pos ); -    else -        screen_num = QApplication::desktop()->screenNumber( this ); -#ifdef Q_WS_MAC -    QRect screen = QApplication::desktop()->availableGeometry( screen_num ); -#else -    QRect screen = QApplication::desktop()->screenGeometry( screen_num ); -#endif -    int sw = screen.width();                    // screen width -    int sh = screen.height();                   // screen height -    int sx = screen.x();                        // screen pos -    int sy = screen.y(); -    int x  = pos.x(); -    int y  = pos.y(); -    if ( indexAtPoint >= 0 )                    // don't subtract when < 0 -        y -= itemGeometry( indexAtPoint ).y();          // (would subtract 2 pixels!) -    int w  = width(); -    int h  = height(); - -    if ( snapToMouse ) { -        if ( qApp->reverseLayout() ) -            x -= w; -        if ( x+w > sx+sw ) -            x = mouse.x()-w; -        if ( y+h > sy+sh ) -            y = mouse.y()-h; -        if ( x < sx ) -            x = mouse.x(); -        if ( y < sy ) -            y = sy; -    } - -    if ( x+w > sx+sw )                          // the complete widget must -        x = sx+sw - w;                          //   be visible -    if ( y+h > sy+sh ) -        y = sy+sh - h; -    if ( x < sx ) -        x = sx; -    if ( y < sy ) -        y = sy; - -    if(style().styleHint(QStyle::SH_PopupMenu_Scrollable, this)) { -        int off_top = 0, off_bottom = 0; -        if(y+h > sy+sh) -            off_bottom = (y+h) - (sy+sh); -        if(y < sy) -            off_top = sy - y; -        if(off_bottom || off_top) { -            int ch = updateSize().height(); //store the old height, before setting scrollable --Sam -            const int vextra = style().pixelMetric(QStyle::PM_PopupMenuFrameVerticalExtra, this); -            d->scroll.scrollableSize = h - off_top - off_bottom - 2*vextra; -            if(off_top) { -                move( x, y = sy ); -                d->scroll.scrollable = d->scroll.scrollable | QPopupMenuPrivate::Scroll::ScrollUp; -            } -            if( off_bottom ) -                d->scroll.scrollable = d->scroll.scrollable | QPopupMenuPrivate::Scroll::ScrollDown; -            if( off_top != off_bottom && indexAtPoint >= 0 ) { -                ch -= (vextra * 2); -                if(ch > sh) //no bigger than the screen! -                    ch = sh; -                if( ch > d->scroll.scrollableSize )  -                    d->scroll.scrollableSize = ch; -            } - -            updateSize(TRUE); //now set the size using the scrollable/scrollableSize as above -            w = width(); -            h = height(); -            if(indexAtPoint >= 0) {  -                if(off_top) { //scroll to it -                    register QMenuItem *mi = NULL; -                    QMenuItemListIt it(*mitems); -                    for(int tmp_y = 0; tmp_y < off_top && (mi=it.current()); ) { -                        QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, -                                                            QSize(0, itemHeight( mi )), -                                                            QStyleOption(mi,maxPMWidth,0)); -                        tmp_y += sz.height(); -                        d->scroll.topScrollableIndex++; -                    } -                }  -            } -        } -    } -    move( x, y ); -    motion=0; -    actItem = -1; - -#ifndef QT_NO_EFFECTS -    int hGuess = qApp->reverseLayout() ? QEffects::LeftScroll : QEffects::RightScroll; -    int vGuess = QEffects::DownScroll; -    if ( qApp->reverseLayout() ) { -        if ( snapToMouse && ( x + w/2 > mouse.x() ) || -            ( parentMenu && parentMenu->isPopupMenu && -            ( x + w/2 > ((PopupMenu*)parentMenu)->x() ) ) ) -            hGuess = QEffects::RightScroll; -    } else { -        if ( snapToMouse && ( x + w/2 < mouse.x() ) || -            ( parentMenu && parentMenu->isPopupMenu && -            ( x + w/2 < ((PopupMenu*)parentMenu)->x() ) ) ) -            hGuess = QEffects::LeftScroll; -    } - -#ifndef QT_NO_MENUBAR -    if ( snapToMouse && ( y + h/2 < mouse.y() ) || -        ( parentMenu && parentMenu->isMenuBar && -        ( y + h/2 < ((QMenuBar*)parentMenu)->mapToGlobal( ((QMenuBar*)parentMenu)->pos() ).y() ) ) ) -        vGuess = QEffects::UpScroll; -#endif - -    if ( QApplication::isEffectEnabled( UI_AnimateMenu ) && -         preventAnimation == FALSE ) { -        if ( QApplication::isEffectEnabled( UI_FadeMenu ) ) -            qFadeEffect( this ); -        else if ( parentMenu ) -            qScrollEffect( this, parentMenu->isPopupMenu ? hGuess : vGuess ); -        else -            qScrollEffect( this, hGuess | vGuess ); -    } else -#endif -    { -        show(); -    } -#if defined(QT_ACCESSIBILITY_SUPPORT) -    QAccessible::updateAccessibility( this, 0, QAccessible::PopupMenuStart ); -#endif -} - -void PopupMenu::subActivated( int id ) -{ -    emit activatedRedirect( id ); -} - -void PopupMenu::subHighlighted( int id ) -{ -    emit highlightedRedirect( id ); -} - -static bool fromAccel = FALSE; - -#ifndef QT_NO_ACCEL -void PopupMenu::accelActivated( int id ) -{ -    QMenuItem *mi = findItem( id ); -    if ( mi && mi->isEnabledAndVisible() ) { -        QGuardedPtr<QSignal> signal = mi->signal(); -        fromAccel = TRUE; -        actSig( mi->id() ); -        fromAccel = FALSE; -        if ( signal ) -            signal->activate(); -    } -} - -void PopupMenu::accelDestroyed()               // accel about to be deleted -{ -    autoaccel = 0;                              // don't delete it twice! -} -#endif //QT_NO_ACCEL - -void PopupMenu::popupDestroyed( QObject *o ) -{ -    removePopup( (PopupMenu*)o ); -} - -void PopupMenu::actSig( int id, bool inwhatsthis ) -{ -    if ( !inwhatsthis ) { -        emit activated( id ); -#if defined(QT_ACCESSIBILITY_SUPPORT) -        if ( !fromAccel ) -            QAccessible::updateAccessibility( this, indexOf(id)+1, QAccessible::MenuCommand ); -#endif -    } else { -#ifndef QT_NO_WHATSTHIS -        QRect r( itemGeometry( indexOf( id ) ) ); -        QPoint p( r.center().x(), r.bottom() ); -        QString whatsThis = findItem( id )->whatsThis(); -        if ( whatsThis.isNull() ) -            whatsThis = QWhatsThis::textFor( this, p ); -        QWhatsThis::leaveWhatsThisMode( whatsThis, mapToGlobal( p ), this ); -#endif -    } - -    emit activatedRedirect( id ); -} - -void PopupMenu::hilitSig( int id ) -{ -    emit highlighted( id ); -    emit highlightedRedirect( id ); - -#if defined(QT_ACCESSIBILITY_SUPPORT) -    QAccessible::updateAccessibility( this, indexOf(id)+1, QAccessible::Focus ); -    QAccessible::updateAccessibility( this, indexOf(id)+1, QAccessible::Selection ); -#endif -} - -void PopupMenu::setFirstItemActive() -{ -    QMenuItemListIt it(*mitems); -    register QMenuItem *mi; -    int ai = 0; -    if(d->scroll.scrollable) -        ai = d->scroll.topScrollableIndex; -    while ( (mi=it.current()) ) { -        ++it; -        if ( !mi->isSeparator() && mi->id() != QMenuData::d->aInt && -             ( style().styleHint( QStyle::SH_PopupMenu_AllowActiveAndDisabled, this ) || mi->isEnabledAndVisible() )) { -            setActiveItem( ai ); -            return; -        } -        ai++; -    } -    actItem = -1; -} - -void PopupMenu::hideAllPopups() -{ -    register QMenuData *top = this;             // find top level popup -    if ( !preventAnimation ) -        QTimer::singleShot( 10, this, SLOT(allowAnimation()) ); -    preventAnimation = TRUE; - -    if ( !isPopup() ) -        return; // nothing to do - -    while ( top->parentMenu && top->parentMenu->isPopupMenu -            && ((PopupMenu*)top->parentMenu)->isPopup() ) -        top = top->parentMenu; -    ((PopupMenu*)top)->hide();                 // cascade from top level - -#ifndef QT_NO_WHATSTHIS -    if (whatsThisItem) { -        qWhatsThisBDH(); -        whatsThisItem = 0; -    } -#endif - -} - -void PopupMenu::hidePopups() -{ -    if ( !preventAnimation ) -        QTimer::singleShot( 10, this, SLOT(allowAnimation()) ); -    preventAnimation = TRUE; - -    QMenuItemListIt it(*mitems); -    register QMenuItem *mi; -    while ( (mi=it.current()) ) { -        ++it; -        if ( mi->popup() && mi->popup()->parentMenu == this ) //avoid circularity -            mi->popup()->hide(); -    } -    popupActive = -1;                           // no active sub menu -    if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this)) -        d->mouseMoveBuffer = QRegion(); - -    QRect mfrect = itemGeometry( actItem ); -    setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE ); -} - -bool PopupMenu::tryMenuBar( QMouseEvent *e ) -{ -    register QMenuData *top = this;             // find top level -    while ( top->parentMenu ) -        top = top->parentMenu; -#ifndef QT_NO_MENUBAR -    return top->isMenuBar ? -        ((QMenuBar *)top)->tryMouseEvent( this, e ) : -                              ((PopupMenu*)top)->tryMouseEvent(this, e ); -#else -    return ((PopupMenu*)top)->tryMouseEvent(this, e ); -#endif -} - -bool PopupMenu::tryMouseEvent( PopupMenu *p, QMouseEvent * e) -{ -    if ( p == this ) -        return FALSE; -    QPoint pos = mapFromGlobal( e->globalPos() ); -    if ( !rect().contains( pos ) )              // outside -        return FALSE; -    QMouseEvent ee( e->type(), pos, e->globalPos(), e->button(), e->state() ); -    event( &ee ); -    return TRUE; -} - -void PopupMenu::byeMenuBar() -{ -#ifndef QT_NO_MENUBAR -    register QMenuData *top = this;             // find top level -    while ( top->parentMenu ) -        top = top->parentMenu; -#endif -    hideAllPopups(); -#ifndef QT_NO_MENUBAR -    if ( top->isMenuBar ) -        ((QMenuBar *)top)->goodbye(); -#endif -} - -int PopupMenu::itemAtPos( const QPoint &pos, bool ignoreSeparator ) const -{ -    if ( !contentsRect().contains(pos) ) -        return -1; - -    int row = 0; -    int x = contentsRect().x(); -    int y = contentsRect().y(); -    QMenuItem *mi; -    QMenuItemListIt it( *mitems ); -    if(d->scroll.scrollable) { -        if(d->scroll.topScrollableIndex) { -            for( ; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++) -                ++it; -            if(!mi) { -                row = 0; -                it.toFirst(); -            } -            y += style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -        } -    } -    int itemw = contentsRect().width() / ncols; -    QSize sz; -    while ( (mi=it.current()) ) { -        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && -           y >= contentsRect().height() - style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this)) -            return -1; -        ++it; -        if ( !mi->isVisible() ) { -            ++row; -            continue; -        } -        int itemh = itemHeight( mi ); - -        sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, -                                      QSize(0, itemh), -                                      QStyleOption(mi,maxPMWidth)); -        sz = sz.expandedTo(QSize(itemw, sz.height())); -        itemw = sz.width(); -        itemh = sz.height(); - -        if ( ncols > 1 && y + itemh > contentsRect().bottom() ) { -            y = contentsRect().y(); -            x +=itemw; -        } -        if ( QRect( x, y, itemw, itemh ).contains( pos ) ) -            break; -        y += itemh; -        ++row; -    } - -    if ( mi && ( !ignoreSeparator || !mi->isSeparator() ) ) -        return row; -    return -1; -} - -QRect PopupMenu::itemGeometry( int index ) -{ -    QMenuItem *mi; -    QSize sz; -    int row = 0, scrollh = 0; -    int x = contentsRect().x(); -    int y = contentsRect().y(); -    QMenuItemListIt it( *mitems ); -    if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp) { -        scrollh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -        y += scrollh; -        if(d->scroll.topScrollableIndex) { -            for( ; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++) -                ++it; -            if(!mi) { -                row = 0; -                it.toFirst(); -            } -        } -    } -    int itemw = contentsRect().width() / ncols; -    while ( (mi=it.current()) ) { -        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && -           y >= contentsRect().height() - scrollh) -            break; -        ++it; -        if ( !mi->isVisible() ) { -            ++row; -            continue; -        } -        int itemh = itemHeight( mi ); - -        sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, -                                      QSize(0, itemh), -                                      QStyleOption(mi,maxPMWidth)); -        sz = sz.expandedTo(QSize(itemw, sz.height())); -        itemw = sz.width(); -        itemh = sz.height(); -        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && -           (y + itemh > contentsRect().height() - scrollh)) -            itemh -= (y + itemh) - (contentsRect().height() - scrollh); -        if ( ncols > 1 && y + itemh > contentsRect().bottom() ) { -            y = contentsRect().y(); -            x +=itemw; -        } -        if ( row == index ) -            return QRect( x,y,itemw,itemh ); -        y += itemh; -        ++row; -    } - -    return QRect(0,0,0,0); -} - -QSize PopupMenu::updateSize(bool force_update, bool do_resize) -{ -    polish(); -    if ( count() == 0 ) { -        QSize ret = QSize( 50, 8 ); -        if(do_resize) -            setFixedSize( ret ); -        badSize = TRUE; -        return ret; -    } - -    int scrheight = 0; -    if(d->scroll.scrollableSize) { -        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp) -            scrheight += style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown) -            scrheight += style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -    } - -    if(badSize || force_update) { -#ifndef QT_NO_ACCEL -        updateAccel( 0 ); -#endif -        int height = 0; -        int max_width = 0, max_height = 0; -        QFontMetrics fm = fontMetrics(); -        register QMenuItem *mi; -        maxPMWidth = 0; -        int maxWidgetWidth = 0; -        tab = 0; - -        for ( QMenuItemListIt it( *mitems ); it.current(); ++it ) { -            mi = it.current(); -            QWidget *miw = mi->widget(); -            if (miw) { -                if ( miw->parentWidget() != this ) -                    miw->reparent( this, QPoint(0,0), TRUE ); -                // widget items musn't propgate mouse events -                ((PopupMenu*)miw)->setWFlags(WNoMousePropagation); -            } -            if ( mi->custom() ) -                mi->custom()->setFont( font() ); -            if ( mi->iconSet() != 0) -                maxPMWidth = QMAX( maxPMWidth, -                                   mi->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4 ); -        } - -        int dh = QApplication::desktop()->height(); -        ncols = 1; - -        for ( QMenuItemListIt it2( *mitems ); it2.current(); ++it2 ) { -            mi = it2.current(); -            if ( !mi->isVisible() ) -                continue; -            int w = 0; -            int itemHeight = PopupMenu::itemHeight( mi ); - -            if ( mi->widget() ) { -                QSize s( mi->widget()->sizeHint() ); -                s = s.expandedTo( mi->widget()->minimumSize() ); -                mi->widget()->resize( s ); -                if ( s.width()  > maxWidgetWidth ) -                    maxWidgetWidth = s.width(); -                itemHeight = s.height(); -            } else { -                if( ! mi->isSeparator() ) { -                    if ( mi->custom() ) { -                        if ( mi->custom()->fullSpan() ) { -                            maxWidgetWidth = QMAX( maxWidgetWidth, -                                                   mi->custom()->sizeHint().width() ); -                        } else { -                            QSize s ( mi->custom()->sizeHint() ); -                            w += s.width(); -                        } -                    } - -                    w += maxPMWidth; - -                    if (! mi->text().isNull()) { -                        QString s = mi->text(); -                        int t; -                        if ( (t = s.find('\t')) >= 0 ) { // string contains tab -                            w += fm.width( s, t ); -                            w -= s.contains('&') * fm.width('&'); -                            w += s.contains("&&") * fm.width('&'); -                            int tw = fm.width( s.mid(t + 1) ); -                            if ( tw > tab) -                                tab = tw; -                        } else { -                            w += fm.width( s ); -                            w -= s.contains('&') * fm.width('&'); -                            w += s.contains("&&") * fm.width('&'); -                        } -                    } else if (mi->pixmap()) -                        w += mi->pixmap()->width(); -                } else { -                    if ( mi->custom() ) { -                        QSize s ( mi->custom()->sizeHint() ); -                        w += s.width(); -                    } else { -                        w = itemHeight = 2; -                    } -                } - -                QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, -                                                    QSize(w, itemHeight), -                                                    QStyleOption(mi,maxPMWidth)); - -                w = sz.width(); -                itemHeight = sz.height(); - -#if defined(QT_CHECK_NULL) -                if ( mi->text().isNull() && !mi->pixmap() && !mi->iconSet() && -                     !mi->isSeparator() && !mi->widget() && !mi->custom() ) -                    qWarning( "PopupMenu: (%s) Popup has invalid menu item", -                              name( "unnamed" ) ); -#endif -            } -            height += itemHeight; -            if(style().styleHint(QStyle::SH_PopupMenu_Scrollable, this)) { -                if(scrheight && height >= d->scroll.scrollableSize - scrheight) { -                    height = d->scroll.scrollableSize - scrheight; -                    break; -                } -            } else if( height + 2*frameWidth() >= dh ) { -                ncols++; -                max_height = QMAX(max_height, height - itemHeight); -                height = itemHeight; -            } -            if ( w > max_width ) -                max_width = w; -        } -        if( ncols == 1 && !max_height ) -            max_height = height; - -        if(style().styleHint(QStyle::SH_PopupMenu_Scrollable, this)) { -            height += scrheight; -            setMouseTracking(TRUE); -        } - -        if ( tab ) -            tab -= fontMetrics().minRightBearing(); -        else -            max_width -= fontMetrics().minRightBearing(); - -        if ( max_width + tab < maxWidgetWidth ) -            max_width = maxWidgetWidth - tab; - -        const int fw = frameWidth(); -        int extra_width = (fw+style().pixelMetric(QStyle::PM_PopupMenuFrameHorizontalExtra, this)) * 2, -           extra_height = (fw+style().pixelMetric(QStyle::PM_PopupMenuFrameVerticalExtra,   this)) * 2; -        if ( ncols == 1 ) -            d->calcSize = QSize( QMAX( minimumWidth(), max_width + tab + extra_width ), -                              QMAX( minimumHeight() , height + extra_height ) ); -        else -            d->calcSize = QSize( QMAX( minimumWidth(), (ncols*(max_width + tab)) + extra_width ), -                              QMAX( minimumHeight(), QMIN( max_height + extra_height + 1, dh ) ) ); -        badSize = FALSE; -    } - -    { -        // Position the widget items. It could be done in drawContents -        // but this way we get less flicker. -        QSize sz; -        int x = contentsRect().x(); -        int y = contentsRect().y(); -        int itemw = contentsRect().width() / ncols; -        for(QMenuItemListIt it(*mitems); it.current(); ++it) { -            QMenuItem *mi = it.current(); -            if ( !mi->isVisible() ) -                continue; - -            int itemh = itemHeight( mi ); -             -            sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, -                                          QSize(0, itemh), QStyleOption(mi,maxPMWidth)); -            sz = sz.expandedTo(QSize(itemw, sz.height())); -            itemw = sz.width(); -            itemh = sz.height(); - -            if ( ncols > 1 && y + itemh > contentsRect().bottom() ) { -                y = contentsRect().y(); -                x +=itemw; -            } -            if ( mi->widget() )  -                mi->widget()->setGeometry( x, y, itemw, mi->widget()->height() ); -            y += itemh; -        } -    } - -    if( do_resize && size() != d->calcSize ) { -        setMaximumSize( d->calcSize ); -        d->calcSize = maximumSize(); //let the max size adjust it (virtual) -        resize( d->calcSize ); -    } -    return d->calcSize; -} - -#ifndef QT_NO_ACCEL -void PopupMenu::updateAccel( QWidget *parent ) -{ -    QMenuItemListIt it(*mitems); -    register QMenuItem *mi; - -    if ( parent ) { -        delete autoaccel; -        autoaccel = 0; -    } else if ( !autoaccel ) { -        // we have no parent. Rather than ignoring any accelerators we try to find this popup's main window -        if ( tornOff ) { -            parent = this; -        } else { -            QWidget *w = (QWidget *) this; -            parent = w->parentWidget(); -            while ( (!w->testWFlags(WType_TopLevel) || !w->testWFlags(WType_Popup)) && parent ) { -                w = parent; -                parent = parent->parentWidget(); -            } -        } -    } - -    if ( parent == 0 && autoaccel == 0 ) -        return; - -    if ( autoaccel )                            // build it from scratch -        autoaccel->clear(); -    else { -        // create an autoaccel in any case, even if we might not use -        // it immediately. Maybe the user needs it later. -        autoaccel = new QAccel( parent, this ); -        connect( autoaccel, SIGNAL(activated(int)), -                 SLOT(accelActivated(int)) ); -        connect( autoaccel, SIGNAL(activatedAmbiguously(int)), -                 SLOT(accelActivated(int)) ); -        connect( autoaccel, SIGNAL(destroyed()), -                 SLOT(accelDestroyed()) ); -        if ( accelDisabled ) -            autoaccel->setEnabled( FALSE ); -    } -    while ( (mi=it.current()) ) { -        ++it; -        QKeySequence k = mi->key(); -        if ( (int)k ) { -            int id = autoaccel->insertItem( k, mi->id() ); -#ifndef QT_NO_WHATSTHIS -            autoaccel->setWhatsThis( id, mi->whatsThis() ); -#endif -        } -        if ( !mi->text().isNull() || mi->custom() ) { -            QString s = mi->text(); -            int i = s.find('\t'); - -            // Note: Only looking at the first key in the sequence! -            if ( (int)k && (int)k != Key_unknown ) { -                QString t = (QString)mi->key(); -                if ( i >= 0 ) -                    s.replace( i+1, s.length()-i, t ); -                else { -                    s += '\t'; -                    s += t; -                } -            } else if ( !k ) { -                if ( i >= 0 ) -                    s.truncate( i ); -            } -            if ( s != mi->text() ) { -                mi->setText( s ); -                badSize = TRUE; -            } -        } -        if ( mi->popup() && parent ) {          // call recursively -            // reuse -            PopupMenu* popup = mi->popup(); -            if (!popup->avoid_circularity) { -                popup->avoid_circularity = 1; -                popup->updateAccel( parent ); -                popup->avoid_circularity = 0; -            } -        } -    } -} - -void PopupMenu::enableAccel( bool enable ) -{ -    if ( autoaccel ) -        autoaccel->setEnabled( enable ); -    accelDisabled = !enable;            // rememeber when updateAccel -    QMenuItemListIt it(*mitems); -    register QMenuItem *mi; -    while ( (mi=it.current()) ) {               // do the same for sub popups -        ++it; -        if ( mi->popup() )                      // call recursively -            mi->popup()->enableAccel( enable ); -    } -} -#endif - -void PopupMenu::setFont( const QFont &font ) -{ -    QWidget::setFont( font ); -    badSize = TRUE; -    if ( isVisible() ) { -        updateSize(); -        update(); -    } -} - -void PopupMenu::show() -{ -    if ( !isPopup() && isVisible() ) -        hide(); - -    if ( isVisible() ) { -        supressAboutToShow = FALSE; -        QWidget::show(); -        return; -    } -    if (!supressAboutToShow) -        emit aboutToShow(); -    else -        supressAboutToShow = FALSE; -    performDelayedChanges(); -    updateSize(TRUE); -    QWidget::show(); -    popupActive = -1; -    if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this)) -        d->mouseMoveBuffer = QRegion(); -} - -void PopupMenu::hide() -{ -    if ( syncMenu == this && qApp ) { -        qApp->exit_loop(); -        syncMenu = 0; -    } - -    if ( !isVisible() ) { -        QWidget::hide(); -        return; -    } -    emit aboutToHide(); - -    actItem = popupActive = -1; -    if(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this)) -        d->mouseMoveBuffer = QRegion(); -    mouseBtDn = FALSE;                          // mouse button up -#if defined(QT_ACCESSIBILITY_SUPPORT) -    QAccessible::updateAccessibility( this, 0, QAccessible::PopupMenuEnd ); -#endif -    parentMenu = 0; -    hidePopups(); -    QWidget::hide(); -} - -int PopupMenu::itemHeight( int row ) const -{ -    return itemHeight( mitems->at( row ) ); -} - -int PopupMenu::itemHeight( QMenuItem *mi ) const -{ -    if  ( mi->widget() ) -        return mi->widget()->height(); -    if ( mi->custom() && mi->custom()->fullSpan() ) -        return mi->custom()->sizeHint().height(); - -    QFontMetrics fm(fontMetrics()); -    int h = 0; -    if ( mi->isSeparator() ) // separator height -        h = 2; -    else if ( mi->pixmap() ) // pixmap height -        h = mi->pixmap()->height(); -    else                     // text height -        h = fm.height(); - -    if ( !mi->isSeparator() && mi->iconSet() != 0 ) -        h = QMAX(h, mi->iconSet()->pixmap( QIconSet::Small, -                                           QIconSet::Normal ).height()); -    if ( mi->custom() ) -        h = QMAX(h, mi->custom()->sizeHint().height()); - -    return h; -} - -void PopupMenu::drawItem( QPainter* p, int tab_, QMenuItem* mi, -                           bool act, int x, int y, int w, int h) -{ -    QStyle::SFlags flags = QStyle::Style_Default; -    if (isEnabled() && mi->isEnabledAndVisible() && (!mi->popup() || mi->popup()->isEnabled()) ) -        flags |= QStyle::Style_Enabled; -    if (act) -        flags |= QStyle::Style_Active; -    if (mouseBtDn) -        flags |= QStyle::Style_Down; - -    const QColorGroup &cg = ((flags&QStyle::Style_Enabled) ? colorGroup() : palette().disabled() ); - -    if ( mi->custom() && mi->custom()->fullSpan() ) { -        QMenuItem dummy; -        style().drawControl(QStyle::CE_PopupMenuItem, p, this, QRect(x, y, w, h), cg, -                            flags, QStyleOption(&dummy,maxPMWidth,tab_)); -        mi->custom()->paint( p, cg, act, flags&QStyle::Style_Enabled, x, y, w, h ); -    } else -        style().drawControl(QStyle::CE_PopupMenuItem, p, this, QRect(x, y, w, h), cg, -                            flags, QStyleOption(mi,maxPMWidth,tab_)); -} - -void PopupMenu::drawContents( QPainter* p ) -{ -    QMenuItemListIt it(*mitems); -    QMenuItem *mi = 0; -    int row = 0; -    int x = contentsRect().x(); -    int y = contentsRect().y(); -    if(d->scroll.scrollable) { -        if(d->scroll.topScrollableIndex) { -            for( ; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++) -                ++it; -            if(!mi) -                it.toFirst(); -        } -        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp) { -            QRect rect(x, y, contentsRect().width(), -                       style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this)); -            if(!p->hasClipping() || p->clipRegion().contains(rect)) { -                QStyle::SFlags flags = QStyle::Style_Up; -                if (isEnabled()) -                    flags |= QStyle::Style_Enabled; -                style().drawControl(QStyle::CE_PopupMenuScroller, p, this, rect, -                                    colorGroup(), flags, QStyleOption(maxPMWidth)); -            } -            y += rect.height(); -        } -    } - -    int itemw = contentsRect().width() / ncols; -    QSize sz; -    QStyle::SFlags flags; -    while ( (mi=it.current()) ) { -        if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && -           y >= contentsRect().height() - style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this)) -            break; -        ++it; -        if ( !mi->isVisible() ) { -            ++row; -            continue; -        } -        int itemh = itemHeight( mi ); -        sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, -                                      QSize(0, itemh), -                                      QStyleOption(mi,maxPMWidth,0) -                                ); -        sz = sz.expandedTo(QSize(itemw, sz.height())); -        itemw = sz.width(); -        itemh = sz.height(); - -        if ( ncols > 1 && y + itemh > contentsRect().bottom() ) { -            if ( y < contentsRect().bottom() ) { -                QRect rect(x, y, itemw, contentsRect().bottom() - y); -                if(!p->hasClipping() || p->clipRegion().contains(rect)) { -                    flags = QStyle::Style_Default; -                    if (isEnabled() && mi->isEnabledAndVisible()) -                        flags |= QStyle::Style_Enabled; -                    style().drawControl(QStyle::CE_PopupMenuItem, p, this, rect, -                                        colorGroup(), flags, QStyleOption((QMenuItem*)0,maxPMWidth)); -                } -            } -            y = contentsRect().y(); -            x +=itemw; -        } -        if (!mi->widget() && (!p->hasClipping() || p->clipRegion().contains(QRect(x, y, itemw, itemh)))) -            drawItem( p, tab, mi, row == actItem, x, y, itemw, itemh ); -        y += itemh; -        ++row; -    } -    if ( y < contentsRect().bottom() ) { -        QRect rect(x, y, itemw, contentsRect().bottom() - y); -        if(!p->hasClipping() || p->clipRegion().contains(rect)) { -            flags = QStyle::Style_Default; -            if ( isEnabled() ) -                flags |= QStyle::Style_Enabled; -            style().drawControl(QStyle::CE_PopupMenuItem, p, this, rect, -                                colorGroup(), flags, QStyleOption((QMenuItem*)0,maxPMWidth)); -        } -    } -    if( d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown ) { -        int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -        QRect rect(x, contentsRect().height() - sh, contentsRect().width(), sh); -        if(!p->hasClipping() || p->clipRegion().contains(rect)) { -            QStyle::SFlags flags = QStyle::Style_Down; -            if (isEnabled()) -                flags |= QStyle::Style_Enabled; -            style().drawControl(QStyle::CE_PopupMenuScroller, p, this, rect, -                                colorGroup(), flags, QStyleOption(maxPMWidth)); -        } -    } -#if defined( DEBUG_SLOPPY_SUBMENU ) -    if ( style().styleHint(QStyle::SH_PopupMenu_SloppySubMenus, this )) { -        p->setClipRegion( d->mouseMoveBuffer ); -        p->fillRect( d->mouseMoveBuffer.boundingRect(), colorGroup().brush( QColorGroup::Highlight ) ); -    } -#endif -} - -void PopupMenu::paintEvent( QPaintEvent *e ) -{ -    QFrame::paintEvent( e ); -} - -void PopupMenu::closeEvent( QCloseEvent * e) { -    e->accept(); -    byeMenuBar(); -} - -void PopupMenu::mousePressEvent( QMouseEvent *e ) -{ -    int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -    if (rect().contains(e->pos()) && -        ((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up -         (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && -             e->pos().y() >= contentsRect().height() - sh))) //down -        return; - -    mouseBtDn = TRUE;                           // mouse button down -    int item = itemAtPos( e->pos() ); -    if ( item == -1 ) { -        if ( !rect().contains(e->pos()) && !tryMenuBar(e) ) { -            byeMenuBar(); -        } -        return; -    } -    register QMenuItem *mi = mitems->at(item); -    if ( item != actItem )                      // new item activated -        setActiveItem( item ); - -    PopupMenu *popup = mi->popup(); -    if ( popup ) { -        if ( popup->isVisible() ) {             // sub menu already open -            int pactItem = popup->actItem; -            popup->actItem = -1; -            popup->hidePopups(); -            popup->updateRow( pactItem ); -        } else {                                // open sub menu -            hidePopups(); -            popupSubMenuLater( 20, this ); -        } -    } else { -        hidePopups(); -    } -} - -void PopupMenu::mouseReleaseEvent( QMouseEvent *e ) -{ -    // do not hide a standalone context menu on press-release, unless -    // the user moved the mouse significantly -    if ( !parentMenu && !mouseBtDn && actItem < 0 && motion < 6 ) -        return; - -    mouseBtDn = FALSE; - -    // if the user released the mouse outside the menu, pass control -    // to the menubar or our parent menu -    int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -    if ( !rect().contains( e->pos() ) && tryMenuBar(e) ) -        return; -    else if((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up -            (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && -             e->pos().y() >= contentsRect().height() - sh)) //down -        return; - -    if ( actItem < 0 ) { // we do not have an active item -        // if the release is inside without motion (happens with -        // oversized popup menus on small screens), ignore it -        if ( rect().contains( e->pos() ) && motion < 6 ) -            return; -        else -            byeMenuBar(); -    } else {    // selected menu item! -        register QMenuItem *mi = mitems->at(actItem); -        if ( mi ->widget() ) { -            QWidget* widgetAt = QApplication::widgetAt( e->globalPos(), TRUE ); -            if ( widgetAt && widgetAt != this ) { -                QMouseEvent me( e->type(), widgetAt->mapFromGlobal( e->globalPos() ), -                                e->globalPos(), e->button(), e->state() ); -                QApplication::sendEvent( widgetAt, &me ); -            } -        } -        PopupMenu *popup = mi->popup(); -#ifndef QT_NO_WHATSTHIS -            bool b = QWhatsThis::inWhatsThisMode(); -#else -            const bool b = FALSE; -#endif -        if ( !mi->isEnabledAndVisible() ) { -#ifndef QT_NO_WHATSTHIS -            if ( b ) { -                actItem = -1; -                updateItem( mi->id() ); -                byeMenuBar(); -                actSig( mi->id(), b); -            } -#endif -        } else  if ( popup ) { -            popup->setFirstItemActive(); -        } else {                                // normal menu item -            byeMenuBar();                       // deactivate menu bar -            if ( mi->isEnabledAndVisible() ) { -                actItem = -1; -                updateItem( mi->id() ); -                active_popup_menu = this; -                QGuardedPtr<QSignal> signal = mi->signal(); -                actSig( mi->id(), b ); -                if ( signal && !b ) -                    signal->activate(); -                active_popup_menu = 0; -            } -        } -    } -} - -void PopupMenu::mouseMoveEvent( QMouseEvent *e ) -{ -    motion++; - -    if ( parentMenu && parentMenu->isPopupMenu ) { -        PopupMenu* p = (PopupMenu*)parentMenu; -        int myIndex; - -        p->findPopup( this, &myIndex ); -        QPoint pPos = p->mapFromParent( e->globalPos() ); -        if ( p->actItem != myIndex && !p->rect().contains( pPos ) ) -            p->setActiveItem( myIndex ); - -        if ( style().styleHint(QStyle::SH_PopupMenu_SloppySubMenus, this )) { -            p->d->mouseMoveBuffer = QRegion(); -#ifdef DEBUG_SLOPPY_SUBMENU -            p->repaint(); -#endif -        } -    } - -    if ( (e->state() & Qt::MouseButtonMask) == 0 && -         !hasMouseTracking() ) -        return; - -    if(d->scroll.scrollable && e->pos().x() >= rect().x() && e->pos().x() <= rect().width()) { -        int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -        if((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) ||  -           (d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && e->pos().y() >= height()-sh)) { -            if(!d->scroll.scrolltimer) { -                d->scroll.scrolltimer = new QTimer(this, "popup scroll timer"); -                QObject::connect( d->scroll.scrolltimer, SIGNAL(timeout()), -                                  this, SLOT(subScrollTimer()) ); -            } -            if(!d->scroll.scrolltimer->isActive()) -                d->scroll.scrolltimer->start(40); -            return; -        } -    } - -    int  item = itemAtPos( e->pos() ); -    if ( item == -1 ) {                         // no valid item -        int lastActItem = actItem; -        actItem = -1; -        if ( lastActItem >= 0 ) -            updateRow( lastActItem ); -        if ( lastActItem > 0 || -                    ( !rect().contains( e->pos() ) && !tryMenuBar( e ) ) ) { -            popupSubMenuLater(style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, -                                                this), this); -        } -    } else {                                    // mouse on valid item -        // but did not register mouse press -        if ( (e->state() & Qt::MouseButtonMask) && !mouseBtDn ) -            mouseBtDn = TRUE; // so mouseReleaseEvent will pop down - -        register QMenuItem *mi = mitems->at( item ); - -        if ( mi->widget() ) { -            QWidget* widgetAt = QApplication::widgetAt( e->globalPos(), TRUE ); -            if ( widgetAt && widgetAt != this ) { -                QMouseEvent me( e->type(), widgetAt->mapFromGlobal( e->globalPos() ), -                                e->globalPos(), e->button(), e->state() ); -                QApplication::sendEvent( widgetAt, &me ); -            } -        } - -        if ( actItem == item ) -            return; - -        if ( style().styleHint(QStyle::SH_PopupMenu_SloppySubMenus, this) && -             d->mouseMoveBuffer.contains( e->pos() ) ) { -            actItem = item; -            popupSubMenuLater( style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this) * 6, -                               this ); -            return; -        } - -        if ( mi->popup() || ( popupActive >= 0 && popupActive != item )) -            popupSubMenuLater( style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay, this), -                               this ); -        else if ( singleSingleShot ) -            singleSingleShot->stop(); - -        if ( item != actItem ) -            setActiveItem( item ); -    } -} - -void PopupMenu::keyPressEvent( QKeyEvent *e ) -{ -    QMenuItem  *mi = 0; -    PopupMenu *popup; -    int dy = 0; -    bool ok_key = TRUE; - -    int key = e->key(); -    if ( QApplication::reverseLayout() ) { -        // in reverse mode opening and closing keys for submenues are reversed -        if ( key == Key_Left ) -            key = Key_Right; -        else if ( key == Key_Right ) -            key = Key_Left; -    } - -    switch ( key ) { -    case Key_Tab: -        // ignore tab, otherwise it will be passed to the menubar -        break; - -    case Key_Up: -        dy = -1; -        break; - -    case Key_Down: -        dy = 1; -        break; - -    case Key_Alt: -        if ( style().styleHint(QStyle::SH_MenuBar_AltKeyNavigation, this) ) -            byeMenuBar(); -        break; - -    case Key_Escape: -        if ( tornOff ) { -            close(); -            return; -        } -        // just hide one -        { -            QMenuData* p = parentMenu; -            hide(); -#ifndef QT_NO_MENUBAR -            if ( p && p->isMenuBar ) -                ((QMenuBar*) p)->goodbye( TRUE ); -#endif -        } -        break; - -    case Key_Left: -        if ( ncols > 1 && actItem >= 0 ) { -            QRect r( itemGeometry( actItem ) ); -            int newActItem = itemAtPos( QPoint( r.left() - 1, r.center().y() ) ); -            if ( newActItem >= 0 ) { -                setActiveItem( newActItem ); -                break; -            } -        } -        if ( parentMenu && parentMenu->isPopupMenu ) { -            ((PopupMenu *)parentMenu)->hidePopups(); -            if ( singleSingleShot ) -                singleSingleShot->stop(); -            break; -        } - -        ok_key = FALSE; -        break; - -    case Key_Right: -        if ( actItem >= 0 && ( mi=mitems->at(actItem) )->isEnabledAndVisible() && (popup=mi->popup()) ) { -            hidePopups(); -            if ( singleSingleShot ) -                singleSingleShot->stop(); -            // ### The next two lines were switched to fix the problem with the first item of the -            // submenu not being highlighted...any reason why they should have been the other way?? -            subMenuTimer(); -            popup->setFirstItemActive(); -            break; -        } else if ( actItem == -1 && ( parentMenu && !parentMenu->isMenuBar )) { -            dy = 1; -            break; -        } -        if ( ncols > 1 && actItem >= 0 ) { -            QRect r( itemGeometry( actItem ) ); -            int newActItem = itemAtPos( QPoint( r.right() + 1, r.center().y() ) ); -            if ( newActItem >= 0 ) { -                setActiveItem( newActItem ); -                break; -            } -        } -        ok_key = FALSE; -        break; - -    case Key_Space: -        if (! style().styleHint(QStyle::SH_PopupMenu_SpaceActivatesItem, this)) -            break; -        // for motif, fall through - -    case Key_Return: -    case Key_Enter: -        { -            if ( actItem < 0 ) -                break; -#ifndef QT_NO_WHATSTHIS -            bool b = QWhatsThis::inWhatsThisMode(); -#else -            const bool b = FALSE; -#endif -            mi = mitems->at( actItem ); -            if ( !mi->isEnabled() && !b ) -                break; -            popup = mi->popup(); -            if ( popup ) { -                hidePopups(); -                popupSubMenuLater( 20, this ); -                popup->setFirstItemActive(); -            } else { -                actItem = -1; -                updateItem( mi->id() ); -                byeMenuBar(); -                if ( mi->isEnabledAndVisible() || b ) { -                    active_popup_menu = this; -                    QGuardedPtr<QSignal> signal = mi->signal(); -                    actSig( mi->id(), b ); -                    if ( signal && !b ) -                        signal->activate(); -                    active_popup_menu = 0; -                } -            } -        } -        break; -#ifndef QT_NO_WHATSTHIS -    case Key_F1: -        if ( actItem < 0 || e->state() != ShiftButton) -            break; -        mi = mitems->at( actItem ); -        if ( !mi->whatsThis().isNull() ){ -            if ( !QWhatsThis::inWhatsThisMode() ) -                QWhatsThis::enterWhatsThisMode(); -            QRect r( itemGeometry( actItem) ); -            QWhatsThis::leaveWhatsThisMode( mi->whatsThis(), mapToGlobal( r.bottomLeft()) ); -        } -        //fall-through! -#endif -    default: -        ok_key = FALSE; - -    } -    if ( !ok_key && -         ( !e->state() || e->state() == AltButton || e->state() == ShiftButton ) && -         e->text().length()==1 ) { -        QChar c = e->text()[0].upper(); - -        QMenuItemListIt it(*mitems); -        QMenuItem* first = 0; -        QMenuItem* currentSelected = 0; -        QMenuItem* firstAfterCurrent = 0; - -        register QMenuItem *m; -        mi = 0; -        int indx = 0; -        int clashCount = 0; -        while ( (m=it.current()) ) { -            ++it; -            QString s = m->text(); -            if ( !s.isEmpty() ) { -                int i = s.find( '&' ); -                while ( i >= 0 && i < (int)s.length() - 1 ) { -                    if ( s[i+1].upper() == c ) { -                        ok_key = TRUE; -                        clashCount++; -                        if ( !first ) -                            first = m; -                        if ( indx == actItem ) -                            currentSelected = m; -                        else if ( !firstAfterCurrent && currentSelected ) -                            firstAfterCurrent = m; -                        break; -                    } else if ( s[i+1] == '&' ) { -                        i = s.find( '&', i+2 ); -                    } else { -                        break; -                    } -                } -            } -            if ( mi ) -                break; -            indx++; -        } - -        if ( 1 == clashCount ) { // No clashes, continue with selection -            mi = first; -            popup = mi->popup(); -            if ( popup ) { -                setActiveItem( indexOf(mi->id()) ); -                hidePopups(); -                popupSubMenuLater( 20, this ); -                popup->setFirstItemActive(); -            } else { -                byeMenuBar(); -#ifndef QT_NO_WHATSTHIS -                bool b = QWhatsThis::inWhatsThisMode(); -#else -                const bool b = FALSE; -#endif -                if ( mi->isEnabledAndVisible() || b ) { -                    active_popup_menu = this; -                    QGuardedPtr<QSignal> signal = mi->signal(); -                    actSig( mi->id(), b ); -                    if ( signal && !b  ) -                        signal->activate(); -                    active_popup_menu = 0; -                } -            } -        } else if ( clashCount > 1 ) { // Clashes, highlight next... -            // If there's clashes and no one is selected, use first one -            // or if there is no clashes _after_ current, use first one -            if ( !currentSelected || (currentSelected && !firstAfterCurrent)) -                dy = indexOf( first->id() ) - actItem; -            else -                dy = indexOf( firstAfterCurrent->id() ) - actItem; -        } -    } -#ifndef QT_NO_MENUBAR -    if ( !ok_key ) {                            // send to menu bar -        register QMenuData *top = this;         // find top level -        while ( top->parentMenu ) -            top = top->parentMenu; -        if ( top->isMenuBar ) { -            int beforeId = top->actItem; -            ((QMenuBar*)top)->tryKeyEvent( this, e ); -            if ( beforeId != top->actItem ) -                ok_key = TRUE; -        } -    } -#endif -    if ( actItem < 0 ) { -        if ( dy > 0 ) { -            setFirstItemActive(); -        } else if ( dy < 0 ) { -            QMenuItemListIt it(*mitems); -            it.toLast(); -            register QMenuItem *mi; -            int ai = count() - 1; -            while ( (mi=it.current()) ) { -                --it; -                if ( !mi->isSeparator() && mi->id() != QMenuData::d->aInt ) { -                    setActiveItem( ai ); -                    return; -                } -                ai--; -            } -            actItem = -1; -        } -        return; -    } - -    if ( dy ) {                         // highlight next/prev -        register int i = actItem; -        int c = mitems->count(); -        for(int n = c; n; n--) { -            i = i + dy; -            if(d->scroll.scrollable) { -                if(d->scroll.scrolltimer) -                    d->scroll.scrolltimer->stop(); -                if(i < 0) -                    i = 0; -                else if(i >= c) -                    i  = c - 1; -            } else { -                if ( i == c ) -                    i = 0; -                else if ( i < 0 ) -                    i = c - 1; -            } -            mi = mitems->at( i ); -            if ( !mi || !mi->isVisible() ) -                continue; - -            if ( !mi->isSeparator() && -                 ( style().styleHint(QStyle::SH_PopupMenu_AllowActiveAndDisabled, this) -                   || mi->isEnabledAndVisible() ) ) -                break; -        } -        if ( i != actItem ) -            setActiveItem( i ); -        if(d->scroll.scrollable) { //need to scroll to make it visible? -            QRect r = itemGeometry(actItem); -            if(r.isNull() || r.height() < itemHeight(mitems->at(actItem))) { -                bool refresh = FALSE; -                if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && dy == -1) { //up -                    if(d->scroll.topScrollableIndex >= 0) { -                        d->scroll.topScrollableIndex--; -                        refresh = TRUE; -                    } -                } else if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown) { //down -                    QMenuItemListIt it(*mitems); -                    int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -                    for(int i = 0, y = ((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp) ? sh : 0); it.current(); i++, ++it) { -                        if(i >= d->scroll.topScrollableIndex) { -                            int itemh = itemHeight(it.current()); -                            QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, -                                                                QSize(0, itemh), -                                                                QStyleOption(it.current(),maxPMWidth,0)); -                            y += sz.height(); -                            if(y > (contentsRect().height()-sh)) { -                                if(sz.height() > sh || !it.atLast()) -                                    d->scroll.topScrollableIndex++; -                                refresh = TRUE; -                                break; -                            } -                        } -                    } -                } -                if(refresh) { -                    updateScrollerState(); -                    update(); -                } -            } -        } -    } - -#ifdef Q_OS_WIN32 -    if ( !ok_key && -        !( e->key() == Key_Control || e->key() == Key_Shift || e->key() == Key_Meta ) ) -        qApp->beep(); -#endif // Q_OS_WIN32 -} - -void PopupMenu::timerEvent( QTimerEvent *e ) -{ -    QFrame::timerEvent( e ); -} - -void PopupMenu::leaveEvent( QEvent * ) -{ -    if ( testWFlags( WStyle_Tool ) && style().styleHint(QStyle::SH_PopupMenu_MouseTracking, this) ) { -        int lastActItem = actItem; -        actItem = -1; -        if ( lastActItem >= 0 ) -            updateRow( lastActItem ); -    } -} - -void PopupMenu::styleChange( QStyle& old ) -{ -    QFrame::styleChange( old ); -    setMouseTracking(style().styleHint(QStyle::SH_PopupMenu_MouseTracking, this)); -    style().polishPopupMenu( this ); -    updateSize(TRUE); -} - -void PopupMenu::enabledChange( bool ) -{ -    if ( QMenuData::d->aWidget ) // torn-off menu -        QMenuData::d->aWidget->setEnabled( isEnabled() ); -} - -int PopupMenu::columns() const -{ -    return ncols; -} - -// This private slot handles the scrolling popupmenu  -void PopupMenu::subScrollTimer() { -    QPoint pos = QCursor::pos(); -    if(!d->scroll.scrollable || !isVisible()) { -        if(d->scroll.scrolltimer) -            d->scroll.scrolltimer->stop(); -        return; -    } else if(pos.x() > x() + width() || pos.x() < x()) { -        return; -    } -    int sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -    if(!d->scroll.lastScroll.isValid()) { -        d->scroll.lastScroll = QTime::currentTime(); -    } else { -        int factor=0; -        if(pos.y() < y()) -            factor = y() - pos.y(); -        else if(pos.y() > y() + height()) -            factor = pos.y() - (y() + height()); -        int msecs = 250 - ((factor / 10) * 40); -        if(d->scroll.lastScroll.msecsTo(QTime::currentTime()) < QMAX(0, msecs)) -            return; -        d->scroll.lastScroll = QTime::currentTime(); -    } -    if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp && pos.y() <= y() + sh) { //up -        if(d->scroll.topScrollableIndex > 0) { -            d->scroll.topScrollableIndex--; -            updateScrollerState(); -            update(contentsRect()); -        } -    } else if(d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollDown && -              pos.y() >= (y() + contentsRect().height()) - sh) { //down -        QMenuItemListIt it(*mitems); -        for(int i = 0, y = contentsRect().y() + sh; it.current(); i++, ++it) { -            if(i >= d->scroll.topScrollableIndex) { -                int itemh = itemHeight(it.current()); -                QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, QSize(0, itemh), -                                                    QStyleOption(it.current(),maxPMWidth,0)); -                y += sz.height(); -                if(y > contentsRect().height() - sh) { -                    d->scroll.topScrollableIndex++; -                    updateScrollerState(); -                    update(contentsRect()); -                    break; -                } -            } -        } -    } -} - -// This private slot handles the delayed submenu effects  - -void PopupMenu::subMenuTimer() { - -    if ( !isVisible() || (actItem < 0 && popupActive < 0) || actItem == popupActive ) -        return; - -    if ( popupActive >= 0 ) { -        hidePopups(); -        popupActive = -1; -    } - -    // hidePopups() may change actItem etc. -    if ( !isVisible() || actItem < 0 || actItem == popupActive ) -        return; - -    QMenuItem *mi = mitems->at(actItem); -    if ( !mi || !mi->isEnabledAndVisible() ) -        return; - -    PopupMenu *popup = mi->popup(); -    if ( !popup || !popup->isEnabled() ) -        return; - -    //avoid circularity -    if ( popup->isVisible() ) -        return; - -    Q_ASSERT( popup->parentMenu == 0 ); -    popup->parentMenu = this;                   // set parent menu - -    emit popup->aboutToShow(); -    supressAboutToShow = TRUE; - - -    QRect r( itemGeometry( actItem ) ); -    QPoint p; -    QSize ps = popup->sizeHint(); -    if( QApplication::reverseLayout() ) { -        p = QPoint( r.left() + motifArrowHMargin - ps.width(), r.top() + motifArrowVMargin ); -        p = mapToGlobal( p ); - -        bool right = FALSE; -        if ( ( parentMenu && parentMenu->isPopupMenu && -               ((PopupMenu*)parentMenu)->geometry().x() < geometry().x() ) || -             p.x() < 0 ) -            right = TRUE; -        if ( right && (ps.width() > QApplication::desktop()->width() - mapToGlobal( r.topRight() ).x() ) ) -            right = FALSE; -        if ( right ) -            p.setX( mapToGlobal( r.topRight() ).x() ); -    } else { -        p = QPoint( r.right() - motifArrowHMargin, r.top() + motifArrowVMargin ); -        p = mapToGlobal( p ); - -        bool left = FALSE; -        if ( ( parentMenu && parentMenu->isPopupMenu && -               ((PopupMenu*)parentMenu)->geometry().x() > geometry().x() ) || -             p.x() + ps.width() > QApplication::desktop()->width() ) -            left = TRUE; -        if ( left && (ps.width() > mapToGlobal( r.topLeft() ).x() ) ) -            left = FALSE; -        if ( left ) -            p.setX( mapToGlobal( r.topLeft() ).x() - ps.width() ); -    } -    QRect pr = popup->itemGeometry(popup->count() - 1); -    if (p.y() + ps.height() > QApplication::desktop()->height() && -        p.y() - ps.height() + (QCOORD) pr.height() >= 0) -        p.setY( p.y() - ps.height() + (QCOORD) pr.height()); - -    if ( style().styleHint(QStyle::SH_PopupMenu_SloppySubMenus, this )) { -         QPoint cur = QCursor::pos(); -         if ( r.contains( mapFromGlobal( cur ) ) ) { -             QPoint pts[4]; -             pts[0] = QPoint( cur.x(), cur.y() - 2 ); -             pts[3] = QPoint( cur.x(), cur.y() + 2 ); -             if ( p.x() >= cur.x() )    { -                 pts[1] = QPoint( geometry().right(), p.y() ); -                 pts[2] = QPoint( geometry().right(), p.y() + ps.height() ); -             } else { -                 pts[1] = QPoint( p.x() + ps.width(), p.y() ); -                 pts[2] = QPoint( p.x() + ps.width(), p.y() + ps.height() ); -             } -             QPointArray points( 4 ); -             for( int i = 0; i < 4; i++ ) -                 points.setPoint( i, mapFromGlobal( pts[i] ) ); -             d->mouseMoveBuffer = QRegion( points ); -             repaint(); -         } -    } - -    popupActive = actItem; -    popup->popup( p ); -} - -void PopupMenu::allowAnimation() -{ -    preventAnimation = FALSE; -} - -void PopupMenu::updateRow( int row ) -{ -    if ( !isVisible() ) -        return; - -    if ( badSize ) { -        updateSize(); -        update(); -        return; -    } -    updateSize(); -    QRect r = itemGeometry( row ); -    if ( !r.isNull() ) // can happen via the scroller -        repaint( r ); -} - -int PopupMenu::exec( const QPoint & pos, int indexAtPoint ) -{ -    snapToMouse = TRUE; -    if ( !qApp ) -        return -1; - -    PopupMenu* priorSyncMenu = syncMenu; - -    syncMenu = this; -    syncMenuId = -1; - -    QGuardedPtr<PopupMenu> that = this; -    connectModal( that, TRUE ); -    popup( pos, indexAtPoint ); -    qApp->enter_loop(); -    connectModal( that, FALSE ); - -    syncMenu = priorSyncMenu; -    return syncMenuId; -} - - - -//  Connect the popup and all its submenus to modalActivation() if -//  \a doConnect is true, otherwise disconnect. -void PopupMenu::connectModal( PopupMenu* receiver, bool doConnect ) -{ -    if ( !receiver ) -        return; - -    connectModalRecursionSafety = doConnect; - -    if ( doConnect ) -        connect( this, SIGNAL(activated(int)), -                 receiver, SLOT(modalActivation(int)) ); -    else -        disconnect( this, SIGNAL(activated(int)), -                    receiver, SLOT(modalActivation(int)) ); - -    QMenuItemListIt it(*mitems); -    register QMenuItem *mi; -    while ( (mi=it.current()) ) { -        ++it; -        if ( mi->popup() && mi->popup() != receiver -             && (bool)(mi->popup()->connectModalRecursionSafety) != doConnect ) -            mi->popup()->connectModal( receiver, doConnect ); //avoid circular -    } -} - -int PopupMenu::exec() -{ -    return exec(mapToGlobal(QPoint(0,0))); -} - - -//  Internal slot used for exec().  - -void PopupMenu::modalActivation( int id ) -{ -    syncMenuId = id; -} - -void PopupMenu::setActiveItem( int i ) -{ -    int lastActItem = actItem; -    actItem = i; -    if ( lastActItem >= 0 ) -        updateRow( lastActItem ); -    if ( i >= 0 && i != lastActItem ) -        updateRow( i ); -    QMenuItem *mi = mitems->at( actItem ); -    if ( !mi ) -        return; - -    if ( mi->widget() && mi->widget()->isFocusEnabled() ) { -        mi->widget()->setFocus(); -    } else { -        setFocus(); -        QRect mfrect = itemGeometry( actItem ); -        setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE ); -    } -    if ( mi->id() != -1 ) -        hilitSig( mi->id() ); -#ifndef QT_NO_WHATSTHIS -    if (whatsThisItem && whatsThisItem != mi) { -        qWhatsThisBDH(); -    } -    whatsThisItem = mi; -#endif -} - -QSize PopupMenu::sizeHint() const -{ -    constPolish(); -    PopupMenu* that = (PopupMenu*) this; -    //We do not need a resize here, just the sizeHint.. -    return that->updateSize(FALSE, FALSE).expandedTo( QApplication::globalStrut() ); -} - -int PopupMenu::idAt( const QPoint& pos ) const -{ -    return idAt( itemAtPos( pos ) ); -} - -bool PopupMenu::customWhatsThis() const -{ -    return TRUE; -} - -bool PopupMenu::focusNextPrevChild( bool next ) -{ -    register QMenuItem *mi; -    int dy = next? 1 : -1; -    if ( dy && actItem < 0 ) { -        setFirstItemActive(); -    } else if ( dy ) {                          // highlight next/prev -        register int i = actItem; -        int c = mitems->count(); -        int n = c; -        while ( n-- ) { -            i = i + dy; -            if ( i == c ) -                i = 0; -            else if ( i < 0 ) -                i = c - 1; -            mi = mitems->at( i ); -            if ( mi && !mi->isSeparator() && -                 ( ( style().styleHint(QStyle::SH_PopupMenu_AllowActiveAndDisabled, this) -                     && mi->isVisible() ) -                   || mi->isEnabledAndVisible() ) ) -                break; -        } -        if ( i != actItem ) -            setActiveItem( i ); -    } -    return TRUE; -} - -void PopupMenu::focusInEvent( QFocusEvent * ) -{ -} - -void PopupMenu::focusOutEvent( QFocusEvent * ) -{ -} - -class QTearOffMenuItem : public QCustomMenuItem -{ -public: -    QTearOffMenuItem() -    { -    } -    ~QTearOffMenuItem() -    { -    } -    void paint( QPainter* p, const QColorGroup& cg, bool, -                bool, int x, int y, int w, int h ) -    { -        p->setPen( QPen( cg.dark(), 1, DashLine ) ); -        p->drawLine( x+2, y+h/2-1, x+w-4, y+h/2-1 ); -        p->setPen( QPen( cg.light(), 1, DashLine ) ); -        p->drawLine( x+2, y+h/2, x+w-4, y+h/2 ); -    } -    bool fullSpan() const -    { -        return TRUE; -    } - -    QSize sizeHint() -    { -        return QSize( 20, 6 ); -    } -}; - -int PopupMenu::insertTearOffHandle( int id, int index ) -{ -    int myid = insertItem( new QTearOffMenuItem, id, index ); -    connectItem( myid, this, SLOT( toggleTearOff() ) ); -    QMenuData::d->aInt = myid; -    return myid; -} +//====================== +// PopupView +//====================== -void PopupMenu::toggleTearOff() +PopupView::PopupView(QWidget* parent)  +          : QColumnView(parent)  { -    if ( active_popup_menu && active_popup_menu->tornOff ) { -        active_popup_menu->close(); -    } else  if (QMenuData::d->aWidget ) { -        delete (QWidget*) QMenuData::d->aWidget; // delete the old one -    } else { -        // create a tear off menu -        PopupMenu* p = new PopupMenu( parentWidget(), "tear off menu" ); -        connect( p, SIGNAL( activated(int) ), this, SIGNAL( activated(int) ) ); -        connect( p, SIGNAL( highlighted(int) ), this, SIGNAL( highlighted(int) ) ); -#ifndef QT_NO_WIDGET_TOPEXTRA -        p->setCaption( caption() ); -#endif -        p->setCheckable( isCheckable() ); -        p->reparent( parentWidget(), WType_TopLevel | WStyle_Tool | -                     WNoAutoErase | WDestructiveClose, -                     geometry().topLeft(), FALSE ); -        p->mitems->setAutoDelete( FALSE ); -        p->tornOff = TRUE; -        for ( QMenuItemListIt it( *mitems ); it.current(); ++it ) { -            if ( it.current()->id() != QMenuData::d->aInt && !it.current()->widget() ) -                p->mitems->append( it.current() ); -        } -        p->show(); -        QMenuData::d->aWidget = p; -    } +  _model= new QStandardItemModel(this);  +  // FIXME: After clearing, then re-filling, no items seen.  +  // But if setModel is called FOR THE FIRST TIME after clearing the model, +  //  then it works. Calling setModel any time after that does not work. +  setModel(_model);  } -void PopupMenu::activateItemAt( int index ) +PopupView::~PopupView()  { -    if ( index >= 0 && index < (int) mitems->count() ) { -        QMenuItem *mi = mitems->at( index ); -        if ( index != actItem )                 // new item activated -            setActiveItem( index ); -        PopupMenu *popup = mi->popup(); -        if ( popup ) { -            if ( popup->isVisible() ) {         // sub menu already open -                int pactItem = popup->actItem; -                popup->actItem = -1; -                popup->hidePopups(); -                popup->updateRow( pactItem ); -            } else {                            // open sub menu -                hidePopups(); -                actItem = index; -                subMenuTimer(); -                popup->setFirstItemActive(); -            } -        } else { -            byeMenuBar();                       // deactivate menu bar - -#ifndef QT_NO_WHATSTHIS -            bool b = QWhatsThis::inWhatsThisMode(); -#else -            const bool b = FALSE; -#endif -            if ( !mi->isEnabledAndVisible() ) { -#ifndef QT_NO_WHATSTHIS -                if ( b ) { -                    actItem = -1; -                    updateItem( mi->id() ); -                    byeMenuBar(); -                    actSig( mi->id(), b); -                } -#endif -            } else { -                byeMenuBar();                   // deactivate menu bar -                if ( mi->isEnabledAndVisible() ) { -                    actItem = -1; -                    updateItem( mi->id() ); -                    active_popup_menu = this; -                    QGuardedPtr<QSignal> signal = mi->signal(); -                    actSig( mi->id(), b ); -                    if ( signal && !b ) -                        signal->activate(); -                    active_popup_menu = 0; -                } -            } -        } -    } else { -        if ( tornOff ) { -            close(); -        } else { -            QMenuData* p = parentMenu; -            hide(); -#ifndef QT_NO_MENUBAR -            if ( p && p->isMenuBar ) -                ((QMenuBar*) p)->goodbye( TRUE ); -#endif -        } -    } - +  // Make sure to clear the popup so that any child popups are also deleted ! +  //popup->clear();  } -void -PopupMenu::updateScrollerState() +void PopupView::clear()  { -    uint old_scrollable = d->scroll.scrollable; -    d->scroll.scrollable = QPopupMenuPrivate::Scroll::ScrollNone; -    if(!style().styleHint(QStyle::SH_PopupMenu_Scrollable, this)) -        return; - -    QMenuItem *mi; -    QMenuItemListIt it( *mitems ); -    if(d->scroll.topScrollableIndex) { -        for(int row = 0; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++) -            ++it; -        if(!mi) -            it.toFirst(); -    } -    int y = 0, sh = style().pixelMetric(QStyle::PM_PopupMenuScrollerHeight, this); -    if(!it.atFirst()) { -        // can't use |= because of a bug/feature in IBM xlC 5.0.2 -        d->scroll.scrollable = d->scroll.scrollable | QPopupMenuPrivate::Scroll::ScrollUp; -        y += sh; -    } -    while ( (mi=it.current()) ) { -        ++it; -        int myheight = contentsRect().height(); -        QSize sz = style().sizeFromContents(QStyle::CT_PopupMenuItem, this, -                                            QSize(0, itemHeight( mi )), -                                            QStyleOption(mi,maxPMWidth)); -        if(y + sz.height() >= myheight) { -            d->scroll.scrollable = d->scroll.scrollable | QPopupMenuPrivate::Scroll::ScrollDown; -            break; -        } -        y += sz.height(); -    } -    if((d->scroll.scrollable & QPopupMenuPrivate::Scroll::ScrollUp) && -       !(old_scrollable & QPopupMenuPrivate::Scroll::ScrollUp)) -        d->scroll.topScrollableIndex++; +  _model->clear();  } - -#endif // QT_NO_POPUPMENU - -*/ +*/  +  diff --git a/muse2/muse/widgets/popupmenu.h b/muse2/muse/widgets/popupmenu.h index bea30f1d..c06d51f4 100644 --- a/muse2/muse/widgets/popupmenu.h +++ b/muse2/muse/widgets/popupmenu.h @@ -5,299 +5,55 @@  //  //  (C) Copyright 1999-2010 Werner Schweer (ws@seh.de)  // -//  PopupMenu sub-class of QPopupMenu created by Tim. +//  PopupMenu sub-class of QMenu created by Tim.  //========================================================= - - -//========================================================= -// -// NOTICE: This sub-class of QPopupMenu *automatically* deletes -//          and *clears* any sub popup menus, when clear() is called. -//         Therefore a parent widget is *not* necessary when  -//          creating sub popup menus to add to the popup. -// -//========================================================= - - -  #ifndef __POPUPMENU_H__  #define __POPUPMENU_H__ -#include <q3popupmenu.h> -//Added by qt3to4: -#include <QMouseEvent> -//#include <qmenudata.h> +#include <QMenu> +//#include <QMouseEvent> +//#include <QColumnView>  class QWidget;  class QMouseEvent; +class QVariant; +class QAction; +//class QStandardItemModel; -//class MenuData : public QMenuData -//{ -  //friend class QMenuBar; -//  friend class QPopupMenu; -//  friend class PopupMenu; -   -//  Q_OBJECT -  //private:   -//}; - -/* -// Internal class to get access to protected QMenuData members. -class MenuData : public QMenuData +class PopupMenu : public QMenu  { -    friend class QPopupMenu; -    friend class QMenuData; -    friend class PopupMenu; -     -private:     - -public: -    MenuData() : QMenuData() { } -    virtual ~MenuData() { } -}; -*/ - -//class Q_EXPORT PopupMenu : public QPopupMenu -class PopupMenu : public Q3PopupMenu -//class PopupMenu : public QPopupMenu, public MenuData -{ -  friend class QMenuData; -  //friend class QMenuBar; -  friend class Q3PopupMenu; -  friend class QMenuBar; -  //friend class MenuData; -      Q_OBJECT -  private:   -    // QPopupMenu::d is private, so this is our own private. -    //QPopupMenuPrivate *d; -     -    //virtual void setFirstItemActive(); -    //void hideAllPopups(); -    //void hidePopups(); -///    bool tryMenuBar(QMouseEvent *); -    //bool tryMouseEvent(QPopupMenu *, QMouseEvent *); -///    bool tryMouseEvent(PopupMenu *, QMouseEvent *); -    //void byeMenuBar(); -///    void actSig(int, bool = FALSE); -///    virtual void menuDelPopup(Q3PopupMenu *);    protected: -    //int            actItem; -     -    //void mousePressEvent(QMouseEvent *); -///    void mouseReleaseEvent(QMouseEvent *); +    void mouseReleaseEvent(QMouseEvent *);    public: -    PopupMenu(QWidget* parent=0, const char* name=0); +    PopupMenu(QWidget* parent=0);      ~PopupMenu(); +    void clear(); +    QAction* findActionFromData(QVariant);  }; -#endif - - - - -/**************************************************************************** -** -** Definition of QPopupMenu class -** -** Created : 941128 -** -** Copyright (C) 1992-2008 Trolltech ASA.  All rights reserved. -** -** This file is part of the widgets module of the Qt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free Qt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.QPL -** included in the packaging of this file.  Licensees holding valid Qt -** Commercial licenses may use this file in accordance with the Qt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/  /* -#ifndef __POPUPMENU_H__ -#define __POPUPMENU_H__ - -#ifndef QT_H -#include <qframe.h> -#include <qmenudata.h> -#endif // QT_H - -#ifndef QT_NO_POPUPMENU -class QPopupMenuPrivate; - -class Q_EXPORT PopupMenu : public QFrame, public QMenuData +class PopupView : public QColumnView  { -    Q_OBJECT -    Q_PROPERTY( bool checkable READ isCheckable WRITE setCheckable ) -public: -    PopupMenu( QWidget* parent=0, const char* name=0 ); -    ~PopupMenu(); - -    void        popup( const QPoint & pos, int indexAtPoint = -1 ); // open -    void        updateItem( int id ); - -    virtual void        setCheckable( bool ); -    bool        isCheckable() const; - -    void        setFont( const QFont & ); -    void        show(); -    void        hide(); - -    int         exec(); -    int         exec( const QPoint & pos, int indexAtPoint = 0 ); // modal - -    virtual void        setActiveItem( int ); -    QSize       sizeHint() const; - -    int         idAt( int index ) const { return QMenuData::idAt( index ); } -    int         idAt( const QPoint& pos ) const; - -    bool        customWhatsThis() const; - -    int         insertTearOffHandle( int id=-1, int index=-1 ); - -    void        activateItemAt( int index ); -    QRect       itemGeometry( int index ); - - -signals: -    void        activated( int itemId ); -    void        highlighted( int itemId ); -    void        activatedRedirect( int itemId ); // to parent menu -    void        highlightedRedirect( int itemId ); -    void        aboutToShow(); -    void        aboutToHide(); - -protected: -    int         itemHeight( int ) const; -    int         itemHeight( QMenuItem* mi ) const; -    void        drawItem( QPainter* p, int tab, QMenuItem* mi, -                   bool act, int x, int y, int w, int h); - -    void        drawContents( QPainter * ); - -    void        closeEvent( QCloseEvent *e ); -    void        paintEvent( QPaintEvent * ); -    void        mousePressEvent( QMouseEvent * ); -    void        mouseReleaseEvent( QMouseEvent * ); -    void        mouseMoveEvent( QMouseEvent * ); -    void        keyPressEvent( QKeyEvent * ); -    void        focusInEvent( QFocusEvent * ); -    void        focusOutEvent( QFocusEvent * ); -    void        timerEvent( QTimerEvent * ); -    void        leaveEvent( QEvent * ); -    void        styleChange( QStyle& ); -    void        enabledChange( bool ); -    int         columns() const; - -    bool        focusNextPrevChild( bool next ); - -    int         itemAtPos( const QPoint &, bool ignoreSeparator = TRUE ) const; - -private slots: -    void        subActivated( int itemId ); -    void        subHighlighted( int itemId ); -#ifndef QT_NO_ACCEL -    void        accelActivated( int itemId ); -    void        accelDestroyed(); -#endif -    void        popupDestroyed( QObject* ); -    void        modalActivation( int ); - -    void        subMenuTimer(); -    void        subScrollTimer(); -    void        allowAnimation(); -    void     toggleTearOff(); - -    void        performDelayedChanges(); - -private: -    void        updateScrollerState(); -    void        menuContentsChanged(); -    void        menuStateChanged(); -    void        performDelayedContentsChanged(); -    void        performDelayedStateChanged(); -    void        menuInsPopup( PopupMenu * ); -    void        menuDelPopup( PopupMenu * ); -    void        frameChanged(); - -    void        actSig( int, bool = FALSE ); -    void        hilitSig( int ); -    virtual void setFirstItemActive(); -    void        hideAllPopups(); -    void        hidePopups(); -    bool        tryMenuBar( QMouseEvent * ); -    void        byeMenuBar(); - -    QSize       updateSize(bool force_recalc=FALSE, bool do_resize=TRUE); -    void        updateRow( int row ); -#ifndef QT_NO_ACCEL -    void        updateAccel( QWidget * ); -    void        enableAccel( bool ); -#endif -    QPopupMenuPrivate  *d; -#ifndef QT_NO_ACCEL -    QAccel     *autoaccel; -#endif - -#if defined(Q_WS_MAC) && !defined(QMAC_QMENUBAR_NO_NATIVE) -    bool macPopupMenu(const QPoint &, int); -    uint mac_dirty_popup : 1; -#endif - -    int popupActive; -    int tab; -    uint accelDisabled : 1; -    uint checkable : 1; -    uint connectModalRecursionSafety : 1; -    uint tornOff : 1; -    uint pendingDelayedContentsChanges : 1; -    uint pendingDelayedStateChanges : 1; -    int maxPMWidth; -    int ncols; -    bool        snapToMouse; -    bool        tryMouseEvent( PopupMenu *, QMouseEvent * ); - -    friend class QMenuData; -    friend class QMenuBar; - -    void connectModal(PopupMenu* receiver, bool doConnect); - -private:        // Disabled copy constructor and operator= -#if defined(Q_DISABLE_COPY) -    PopupMenu( const PopupMenu & ); -    PopupMenu &operator=( const PopupMenu & ); -#endif +  Q_OBJECT +  private:   +    QStandardItemModel* _model; +     +  protected: +   +  public: +    PopupView(QWidget* parent=0); +    ~PopupView(); +     +    void clear(); +    QStandardItemModel* model() { return _model; }  }; +*/ -#endif // QT_NO_POPUPMENU +#endif -#endif // QPOPUPMENU_H -*/
\ No newline at end of file | 
