📄 menubareditor.cpp
字号:
paste( currentIndex );}// protectedbool MenuBarEditor::eventFilter( QObject * o, QEvent * e ){ if ( o == lineEdit && e->type() == QEvent::FocusOut ) { leaveEditMode(); lineEdit->hide(); update(); } else if ( e->type() == QEvent::LayoutHint ) { resize( sizeHint() ); } return QMenuBar::eventFilter( o, e );}void MenuBarEditor::paintEvent( QPaintEvent * ){ QPainter p( this ); QRect r = rect(); style().drawPrimitive( QStyle::PE_PanelMenuBar, &p, r, colorGroup() ); drawItems( p );}void MenuBarEditor::mousePressEvent( QMouseEvent * e ){ mousePressPos = e->pos(); hideItem(); lineEdit->hide(); currentIndex = findItem( mousePressPos ); showItem(); update(); e->accept();}void MenuBarEditor::mouseDoubleClickEvent( QMouseEvent * e ){ mousePressPos = e->pos(); currentIndex = findItem( mousePressPos ); lineEdit->hide(); if ( currentIndex > (int)itemList.count() ) { insertSeparator(); update(); } else { showLineEdit(); }}void MenuBarEditor::mouseMoveEvent( QMouseEvent * e ){ if ( e->state() & Qt::LeftButton ) { if ( ( e->pos() - mousePressPos ).manhattanLength() > 3 ) { bool itemCreated = FALSE; bool isSeparator = FALSE; draggedItem = item( findItem( mousePressPos ) ); if ( draggedItem == &addItem ) { draggedItem = createItem(); itemCreated = TRUE; } else if ( draggedItem == &addSeparator ) { if (hasSeparator) // we can only have one separator return; draggedItem = createItem(); draggedItem->setSeparator( TRUE ); draggedItem->setMenuText( "separator" ); isSeparator = TRUE; itemCreated = TRUE; } else { isSeparator = draggedItem->isSeparator(); } MenuBarEditorItemPtrDrag * d = new MenuBarEditorItemPtrDrag( draggedItem, this ); d->setPixmap( createTextPixmap( draggedItem->menuText() ) ); hideItem(); draggedItem->setVisible( FALSE ); update(); // If the item is dropped in the same list, // we will have two instances of the same pointer // in the list. itemList.find( draggedItem ); QLNode * node = itemList.currentNode(); dropConfirmed = FALSE; d->dragCopy(); // dragevents and stuff happens if ( draggedItem ) { // item was not dropped if ( itemCreated ) { removeItem( draggedItem ); } else { hideItem(); draggedItem->setVisible( TRUE ); draggedItem = 0; showItem(); } } else if ( dropConfirmed ) { // item was dropped dropConfirmed = FALSE; hideItem(); itemList.takeNode( node )->setVisible( TRUE ); hasSeparator = isSeparator || hasSeparator; showItem(); } else { hasSeparator = isSeparator || hasSeparator; } update(); } }}void MenuBarEditor::dragEnterEvent( QDragEnterEvent * e ){ if ( MenuBarEditorItemPtrDrag::canDecode( e ) ) { e->accept(); dropLine->show(); }}void MenuBarEditor::dragLeaveEvent( QDragLeaveEvent * ){ dropLine->hide();}void MenuBarEditor::dragMoveEvent( QDragMoveEvent * e ){ QPoint pos = e->pos(); dropLine->move( snapToItem( pos ) ); int idx = findItem( pos ); if ( currentIndex != idx ) { hideItem(); currentIndex = idx; showItem(); }}void MenuBarEditor::dropEvent( QDropEvent * e ){ MenuBarEditorItem * i = 0; if ( MenuBarEditorItemPtrDrag::decode( e, &i ) ) { draggedItem = 0; hideItem(); dropInPlace( i, e->pos() ); e->accept(); } dropLine->hide();}void MenuBarEditor::keyPressEvent( QKeyEvent * e ){ if ( lineEdit->isHidden() ) { // In navigation mode switch ( e->key() ) { case Qt::Key_Delete: hideItem(); deleteItem(); showItem(); break; case Qt::Key_Left: e->accept(); navigateLeft( e->state() & Qt::ControlButton ); return; case Qt::Key_Right: e->accept(); navigateRight( e->state() & Qt::ControlButton ); return; // no update case Qt::Key_Down: e->accept(); focusItem(); return; // no update case Qt::Key_PageUp: currentIndex = 0; break; case Qt::Key_PageDown: currentIndex = itemList.count(); break; case Qt::Key_Enter: case Qt::Key_Return: case Qt::Key_F2: e->accept(); enterEditMode(); return; // no update case Qt::Key_Up: case Qt::Key_Alt: case Qt::Key_Shift: case Qt::Key_Control: case Qt::Key_Escape: e->ignore(); setFocus(); // FIXME: this is because some other widget get the focus when CTRL is pressed return; // no update case Qt::Key_C: if ( e->state() & Qt::ControlButton && currentIndex < (int)itemList.count() ) { copy( currentIndex ); break; } case Qt::Key_X: if ( e->state() & Qt::ControlButton && currentIndex < (int)itemList.count() ) { hideItem(); cut( currentIndex ); showItem(); break; } case Qt::Key_V: if ( e->state() & Qt::ControlButton ) { hideItem(); paste( currentIndex < (int)itemList.count() ? currentIndex + 1: itemList.count() ); showItem(); break; } default: if ( e->ascii() >= 32 || e->ascii() == 0 ) { showLineEdit(); QApplication::sendEvent( lineEdit, e ); e->accept(); } else { e->ignore(); } return; } } else { // In edit mode switch ( e->key() ) { case Qt::Key_Control: e->ignore(); return; case Qt::Key_Enter: case Qt::Key_Return: leaveEditMode(); case Qt::Key_Escape: lineEdit->hide(); setFocus(); break; } } e->accept(); update();}void MenuBarEditor::focusOutEvent( QFocusEvent * e ){ QWidget * fw = qApp->focusWidget(); if ( e->lostFocus() && !::qt_cast<PopupMenuEditor*>(fw) ) hideItem(); update();}void MenuBarEditor::resizeInternals(){ dropLine->resize( 2, itemHeight ); updateGeometry();}void MenuBarEditor::drawItems( QPainter & p ){ QPoint pos( borderSize(), 0 ); uint c = 0; p.setPen( colorGroup().buttonText() ); MenuBarEditorItem * i = itemList.first(); while ( i ) { if ( i->isVisible() ) drawItem( p, i, c++, pos ); // updates x y i = itemList.next(); } p.setPen( darkBlue ); drawItem( p, &addItem, c++, pos ); if ( !hasSeparator ) drawItem( p, &addSeparator, c, pos );}void MenuBarEditor::drawItem( QPainter & p, MenuBarEditorItem * i, int idx, QPoint & pos ){ int w = itemSize( i ).width(); // If the item passes the right border, and it is not the first item on the line if ( pos.x() + w > width() && pos.x() > borderSize() ) { // wrap pos.ry() += itemHeight; pos.setX( borderSize() ); } if ( i->isSeparator() ) { drawSeparator( p, pos ); } else { int flags = QPainter::AlignLeft | QPainter::AlignVCenter | Qt::ShowPrefix | Qt::SingleLine; p.drawText( pos.x() + borderSize(), pos.y(), w - borderSize(), itemHeight, flags, i->menuText() ); } if ( hasFocus() && idx == currentIndex && !draggedItem ) p.drawWinFocusRect( pos.x(), pos.y() + 1, w, itemHeight - 2 ); pos.rx() += w;}void MenuBarEditor::drawSeparator( QPainter & p, QPoint & pos ){ p.save(); p.setPen( darkBlue ); int left = pos.x(); int top = pos.y() + 2; int right = left + separatorWidth - 1; int bottom = pos.y() + itemHeight - 4; p.drawLine( left, top, left, bottom ); p.drawLine( right, top, right, bottom ); p.fillRect( left, pos.y() + borderSize() * 2, separatorWidth - 1, itemHeight - borderSize() * 4, QBrush( darkBlue, Qt::Dense5Pattern ) ); p.restore();}QSize MenuBarEditor::itemSize( MenuBarEditorItem * i ){ if ( i->isSeparator() ) return QSize( separatorWidth, itemHeight ); QRect r = fontMetrics().boundingRect( i->menuText().remove( "&") ); return QSize( r.width() + borderSize() * 2, r.height() + borderSize() * 4 );}void MenuBarEditor::addItemSizeToCoords( MenuBarEditorItem * i, int & x, int & y, int w ){ int dx = itemSize( i ).width(); if ( x + dx > w && x > borderSize() ) { y += itemHeight; x = borderSize(); } x += dx;}QPoint MenuBarEditor::itemPos( int index ){ int x = borderSize(); int y = 0; int w = width(); int dx = 0; int c = 0; MenuBarEditorItem * i = itemList.first(); while ( i ) { if ( i->isVisible() ) { dx = itemSize( i ).width(); if ( x + dx > w && x > borderSize() ) { y += itemHeight; x = borderSize(); } if ( c == index ) return QPoint( x, y ); x += dx; c++; } i = itemList.next(); } dx = itemSize( &addItem ).width(); if ( x + dx > width() && x > borderSize() ) { y += itemHeight; x = borderSize(); } return QPoint( x, y );}QPoint MenuBarEditor::snapToItem( const QPoint & pos ){ int x = borderSize(); int y = 0; int dx = 0; MenuBarEditorItem * n = itemList.first(); while ( n ) { if ( n->isVisible() ) { dx = itemSize( n ).width(); if ( x + dx > width() && x > borderSize() ) { y += itemHeight; x = borderSize(); } if ( pos.y() > y && pos.y() < y + itemHeight && pos.x() < x + dx / 2 ) { return QPoint( x, y ); } x += dx; } n = itemList.next(); } return QPoint( x, y );}void MenuBarEditor::dropInPlace( MenuBarEditorItem * i, const QPoint & pos ){ int x = borderSize(); int y = 0; int dx = 0; int idx = 0; MenuBarEditorItem * n = itemList.first(); while ( n ) { if ( n->isVisible() ) { dx = itemSize( n ).width(); if ( x + dx > width() && x > borderSize() ) { y += itemHeight; x = borderSize(); } if ( pos.y() > y && pos.y() < y + itemHeight && pos.x() < x + dx / 2 ) break; x += dx; } n = itemList.next(); idx++; } hideItem(); Command * cmd = 0; int iidx = itemList.findRef( i ); if ( iidx != -1 ) { // internal dnd cmd = new MoveMenuCommand( "Item Dragged", formWnd, this, iidx, idx ); item( iidx )->setVisible( TRUE ); } else { cmd = new AddMenuCommand( "Add Menu", formWnd, this, i, idx ); dropConfirmed = TRUE; // let mouseMoveEvent set the item visible } formWnd->commandHistory()->addCommand( cmd ); cmd->execute(); currentIndex = ( iidx >= 0 && iidx < idx ) ? idx - 1 : idx; showItem();}void MenuBarEditor::safeDec(){ do { currentIndex--; } while ( currentIndex > 0 && !( item( currentIndex )->isVisible() ) );}void MenuBarEditor::safeInc(){ int max = (int)itemList.count(); if ( !hasSeparator ) max += 1; if ( currentIndex < max ) { do { currentIndex++; // skip invisible items } while ( currentIndex < max && !( item( currentIndex )->isVisible() ) ); }}void MenuBarEditor::navigateLeft( bool ctrl ){ // FIXME: handle invisible items if ( currentIndex > 0 ) { hideItem(); if ( ctrl ) { ExchangeMenuCommand * cmd = new ExchangeMenuCommand( "Move Menu Left", formWnd, this, currentIndex, currentIndex - 1 ); formWnd->commandHistory()->addCommand( cmd ); cmd->execute(); safeDec(); } else { safeDec(); } showItem(); } update();}void MenuBarEditor::navigateRight( bool ctrl ){// FIXME: handle invisible items hideItem(); if ( ctrl ) { if ( currentIndex < ( (int)itemList.count() - 1 ) ) { ExchangeMenuCommand * cmd = new ExchangeMenuCommand( "Move Menu Right", formWnd, this, currentIndex, currentIndex + 1 ); formWnd->commandHistory()->addCommand( cmd ); cmd->execute(); safeInc(); } } else { safeInc(); } showItem(); update();}void MenuBarEditor::enterEditMode(){ if ( currentIndex > (int)itemList.count() ) { insertSeparator(); } else { showLineEdit(); }}void MenuBarEditor::leaveEditMode(){ MenuBarEditorItem * i = 0; if ( currentIndex >= (int)itemList.count() ) { i = createItem(); // do not put rename on cmd stack RenameMenuCommand rename( "Rename Menu", formWnd, this, lineEdit->text(), i ); rename.execute(); } else { i = itemList.at( currentIndex ); RenameMenuCommand * cmd = new RenameMenuCommand( "Rename Menu", formWnd, this, lineEdit->text(), i ); formWnd->commandHistory()->addCommand( cmd ); cmd->execute(); } showItem();}QPixmap MenuBarEditor::createTextPixmap( const QString &text ){ QSize sz( fontMetrics().boundingRect( text ).size() ); QPixmap pix( sz.width() + 20, sz.height() * 2 ); pix.fill( white ); QPainter p( &pix, this ); p.drawText( 2, 0, pix.width(), pix.height(), 0, text ); p.end(); QBitmap bm( pix.size() ); bm.fill( color0 ); p.begin( &bm ); p.setPen( color1 ); p.drawText( 2, 0, pix.width(), pix.height(), 0, text ); p.end(); pix.setMask( bm ); return pix;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -