?? qpopupmenu.cpp
字號:
several items to a single slot (most often if the user selects from an array). This signal is handy in such cases. \sa activated(), QMenuData::insertItem()*//*! \fn void QPopupMenu::highlightedRedirect( int id ) \internal Used internally to connect submenus to their parents.*//*! \fn void QPopupMenu::activatedRedirect( int id ) \internal Used internally to connect submenus to their parents.*/void QPopupMenu::subActivated( int id ){ emit activatedRedirect( id );}void QPopupMenu::subHighlighted( int id ){ emit highlightedRedirect( id );}#ifndef QT_NO_ACCELvoid QPopupMenu::accelActivated( int id ){ QMenuItem *mi = findItem( id ); if ( mi && mi->isEnabled() ) { actSig( mi->id() ); if ( mi->signal() ) mi->signal()->activate(); }}void QPopupMenu::accelDestroyed() // accel about to be deleted{ autoaccel = 0; // don't delete it twice!}#endif //QT_NO_ACCELvoid QPopupMenu::actSig( int id, bool inwhatsthis ){ bool sync = FALSE; QPopupMenu * p = this; while( p && !sync ) { if ( p == syncMenu ) sync = TRUE; else if ( p->parentMenu && p->parentMenu->isPopupMenu ) p = (QPopupMenu*)(p->parentMenu); else p = 0; } if ( sync && qApp ) { qApp->exit_loop(); syncMenu = 0; } if ( !inwhatsthis ) emit activated( id ); else { QRect r( itemGeometry( indexOf( id ) ) );#ifndef QT_NO_WHATSTHIS QWhatsThis::leaveWhatsThisMode( findItem( id )->whatsThis(), mapToGlobal( r.bottomLeft() ) );#endif } emit activatedRedirect( id );}void QPopupMenu::hilitSig( int id ){ emit highlighted( id ); emit highlightedRedirect( id );}void QPopupMenu::setFirstItemActive(){ QMenuItemListIt it(*mitems); register QMenuItem *mi; int ai = 0; while ( (mi=it.current()) ) { ++it; if ( !mi->isSeparator() && mi->id() != QMenuData::d->aInt#ifdef QT_KEYPAD_MODE && mi->isEnabled()#endif ) { setActiveItem( ai ); return; } ai++; } actItem = -1;}/*! \internal Hides all popup menus (in this menu tree) that are currently open.*/void QPopupMenu::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 && ((QPopupMenu*)top->parentMenu)->isPopup() ) top = top->parentMenu; ((QPopupMenu*)top)->hide(); // cascade from top level}/*! \internal Hides all popup sub-menus.*/void QPopupMenu::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}/*! \internal Sends the event to the menu bar.*/bool QPopupMenu::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 ) : ((QPopupMenu*)top)->tryMouseEvent(this, e );#else return ((QPopupMenu*)top)->tryMouseEvent(this, e );#endif}/*! \internal*/bool QPopupMenu::tryMouseEvent( QPopupMenu *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;}/*! \internal Tells the menu bar to go back to idle state.*/void QPopupMenu::byeMenuBar(){ hideAllPopups();#ifndef QT_NO_MENUBAR register QMenuData *top = this; // find top level while ( top->parentMenu ) top = top->parentMenu; if ( top->isMenuBar ) ((QMenuBar *)top)->goodbye();#endif}/*! \internal Return the item at \e pos, or -1 if there is no item there, or if it is a separator item.*/int QPopupMenu::itemAtPos( const QPoint &pos ) const{ if ( !contentsRect().contains(pos) ) return -1; int row = 0; int x = contentsRect().x(); int y = contentsRect().y(); int itemw = contentsRect().width() / ncols; QMenuItem *mi; QMenuItemListIt it( *mitems ); while ( (mi=it.current()) ) { ++it; int itemh = itemHeight( row ); 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 && !mi->isSeparator() ) return row; return -1;}/*! \internal Returns the geometry of item number \e index.*/QRect QPopupMenu::itemGeometry( int index ){ QMenuItem *mi; int row = 0; int x = contentsRect().x(); int y = contentsRect().y(); int itemw = contentsRect().width() / ncols; QMenuItemListIt it( *mitems ); while ( (mi=it.current()) ) { ++it; int itemh = itemHeight( mi ); 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);}/*! \internal Calculates and sets the size of the popup menu, based on the size of the items.*/void QPopupMenu::updateSize(){ polish();#ifndef QT_NO_ACCEL updateAccel( 0 );#endif int height = 0; int max_width = 0; QFontMetrics fm = fontMetrics(); register QMenuItem *mi; maxPMWidth = 0; int maxWidgetWidth = 0; tab = 0; int arrow_width = style().popupSubmenuIndicatorWidth( fm ); bool hasWidgetItems = FALSE; for ( QMenuItemListIt it( *mitems ); it.current(); ++it ) { mi = it.current(); if ( mi->widget() && mi->widget()->parentWidget() != this ) { mi->widget()->reparent( this, QPoint(0,0), TRUE ); } 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; QMenuItemListIt it2( *mitems ); while( it2.current() ) { mi = it2.current(); int w = 0; int itemHeight = QPopupMenu::itemHeight( mi ); bool incr = TRUE; if ( mi->widget() ) { hasWidgetItems = TRUE; QSize s( mi->widget()->sizeHint() ); s.expandedTo( mi->widget()->minimumSize() ); mi->widget()->resize( s ); if ( s.width() > maxWidgetWidth ) maxWidgetWidth = s.width(); itemHeight = s.height(); } else { if ( mi->custom() ) { if ( mi->custom()->fullSpan() ) { maxWidgetWidth = QMAX( maxWidgetWidth, mi->custom()->sizeHint().width() ); } else { QSize s ( mi->custom()->sizeHint() ); w += s.width(); } } if ( !mi->text().isNull() && !mi->isSeparator() ) { 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('&'); } } } w += style().extraPopupMenuItemWidth( checkable, maxPMWidth, mi, fm ); if ( mi->popup() ) { // submenu indicator belong in the right tab area if ( arrow_width > tab ) tab = arrow_width; }#if defined(CHECK_NULL) if ( mi->text().isNull() && !mi->pixmap() && !mi->isSeparator() && !mi->widget() && !mi->custom() ) qWarning( "QPopupMenu: (%s) Popup has invalid menu item", name( "unnamed" ) );#endif height += itemHeight; if ( height + 2*frameWidth() >= dh ) { ncols++; height = 0; incr = FALSE; } if ( w > max_width ) max_width = w; if( incr ) ++it2; } if ( tab ) tab -= fontMetrics().minRightBearing(); else max_width -= fontMetrics().minRightBearing(); if ( max_width + tab < maxWidgetWidth ) max_width = maxWidgetWidth - tab; if ( ncols == 1 ) { setFixedSize( max_width + tab + 2*frameWidth(), height + 2*frameWidth() ); } else { setFixedSize( (ncols*(max_width + tab)) + 2*frameWidth(), dh ); } badSize = FALSE; if ( hasWidgetItems ) { // Position the widget items. It could be done in drawContents // but this way we get less flicker. QMenuItemListIt it(*mitems); QMenuItem *mi; int row = 0; int x = contentsRect().x(); int y = contentsRect().y(); int itemw = contentsRect().width() / ncols; while ( (mi=it.current()) ) { ++it; int itemh = itemHeight( row ); 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; ++row; } }}#ifndef QT_NO_ACCEL/*! \internal The \e parent is 0 when it is updated when a menu item has changed a state, or it is something else if called from the menu bar.*/void QPopupMenu::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 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(destroyed()), SLOT(accelDestroyed()) ); if ( accelDisabled ) autoaccel->setEnabled( FALSE ); } while ( (mi=it.current()) ) { ++it; if ( !mi->isEnabled() ) // ### when we have a good solution for the accel vs. focus widget problem, remove that. That is only a workaround continue; int k = mi->key(); if ( 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'); if ( k && k != Key_unknown ) { QString t = QAccel::keyToString( k ); 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 QPopupMenu* popup = mi->popup(); if ( !popup->avoid_circularity ) { popup->avoid_circularity = 1; if (popup->parentMenu) popup->parentMenu->menuDelPopup(popup); menuInsPopup(popup); popup->updateAccel( parent ); popup->avoid_circularity = 0; } } }}/*! \internal It would be better to check in the slot.*/void QPopupMenu::enableAccel( bool enable ){ if ( autoaccel ) autoaccel->setEnabled( enable ); else accelDisabled = TRUE; // 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/*!\reimp*/void QPopupMenu::setFont( const QFont &font ){ QWidget::setFont( font ); badSize = TRUE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -