📄 popupmenueditor.cpp
字号:
int idx = ( index == -1 ? currentIndex : index ); PopupMenuEditorItem * i = 0; QAction * a = 0; if ( idx < (int)itemList.count() ) { i = itemList.at( idx ); a = i->action(); } else { createItem(); } hide(); // qChoosePixmap hides the menu QIconSet icons( qChoosePixmap( 0, formWnd, 0, 0 ) ); SetActionIconsCommand * cmd = new SetActionIconsCommand( "Set icon", formWnd, a, this, icons ); formWnd->commandHistory()->addCommand( cmd ); cmd->execute(); show(); setFocus();}void PopupMenuEditor::showLineEdit( int index ){ int idx = ( index == -1 ? currentIndex : index ); PopupMenuEditorItem * i = 0; if ( idx >= (int)itemList.count() ) i = &addItem; else i = itemList.at( idx ); // open edit currentField for item name lineEdit->setText( i->action()->menuText() ); lineEdit->selectAll(); lineEdit->setGeometry( borderSize + iconWidth, borderSize + itemPos( i ), textWidth, itemHeight( i ) ); lineEdit->show(); lineEdit->setFocus();}void PopupMenuEditor::setAccelerator( int key, Qt::ButtonState state, int index ){ // FIXME: make this a command int idx = ( index == -1 ? currentIndex : index ); if ( key == Qt::Key_Shift || key == Qt::Key_Control || key == Qt::Key_Alt || key == Qt::Key_Meta || key == Qt::Key_unknown ) return; // ignore these keys when they are pressed PopupMenuEditorItem * i = 0; if ( idx >= (int)itemList.count() ) i = createItem(); else i = itemList.at( idx ); int shift = ( state & Qt::ShiftButton ? Qt::SHIFT : 0 ); int ctrl = ( state & Qt::ControlButton ? Qt::CTRL : 0 ); int alt = ( state & Qt::AltButton ? Qt::ALT : 0 ); int meta = ( state & Qt::MetaButton ? Qt::META : 0 ); QAction * a = i->action(); QKeySequence ks = a->accel(); int keys[4] = { ks[0], ks[1], ks[2], ks[3] }; int n = 0; while ( n < 4 && ks[n++] ); n--; if ( n < 4 ) keys[n] = key | shift | ctrl | alt | meta; a->setAccel( QKeySequence( keys[0], keys[1], keys[2], keys[3] ) ); MetaDataBase::setPropertyChanged( a, "accel", TRUE ); resizeToContents();}void PopupMenuEditor::resizeToContents(){ QSize s = contentsSize(); dropLine->resize( s.width(), 2 ); s.rwidth() += borderSize * 2; s.rheight() += borderSize * 2; resize( s );}void PopupMenuEditor::showSubMenu(){ if ( currentIndex < (int)itemList.count() ) { itemList.at( currentIndex )->showMenu( pos().x() + width() - borderSize * 3, pos().y() + itemPos( at( currentIndex ) ) + borderSize * 2 ); setFocus(); // Keep focus in this widget }}void PopupMenuEditor::hideSubMenu(){ if ( currentIndex < (int)itemList.count() ) itemList.at( currentIndex )->hideMenu();}void PopupMenuEditor::focusOnSubMenu(){ if ( currentIndex < (int)itemList.count() ) itemList.at( currentIndex )->focusOnMenu();}// This function has no undo. It is only here to remove an item when its action was// removed from the action editor.// Use removeItem to put the command on the command stack.void PopupMenuEditor::remove( int index ){ int idx = ( index == -1 ? currentIndex : index ); PopupMenuEditorItem * i = itemList.at( idx ); if ( i && i->isRemovable() ) { itemList.remove( idx ); int n = itemList.count() + 1; if ( currentIndex >= n ) currentIndex = itemList.count() + 1; emit removed( i->action() ); resizeToContents(); }}PopupMenuEditorItem * PopupMenuEditor::createItem( QAction * a ){ ActionEditor * ae = (ActionEditor *) formWindow()->mainWindow()->child( 0, "ActionEditor" ); if ( !a ) a = ae->newActionEx(); PopupMenuEditorItem * i = new PopupMenuEditorItem( a, this ); QString n = QString( a->name() ) + "Item"; formWindow()->unify( i, n, FALSE ); i->setName( n ); AddActionToPopupCommand * cmd = new AddActionToPopupCommand( "Add Item", formWnd, this, i ); formWnd->commandHistory()->addCommand( cmd ); cmd->execute(); return i;}void PopupMenuEditor::removeItem( int index ){ int idx = ( index == -1 ? currentIndex : index ); if ( idx < (int)itemList.count() ) { RemoveActionFromPopupCommand * cmd = new RemoveActionFromPopupCommand( "Remove Item", formWnd, this, idx ); formWnd->commandHistory()->addCommand( cmd ); cmd->execute(); if ( itemList.count() == 0 && parentMenu ) parentMenu->update(); resizeToContents(); }}PopupMenuEditorItem * PopupMenuEditor::currentItem(){ int count = itemList.count(); if ( currentIndex < count ) return itemList.at( currentIndex ); else if ( currentIndex == count ) return &addItem; return &addSeparator;}PopupMenuEditorItem * PopupMenuEditor::itemAt( int y ){ PopupMenuEditorItem * i = itemList.first(); int iy = 0; while ( i ) { iy += itemHeight( i ); if ( iy > y ) return i; i = itemList.next(); } iy += itemHeight( &addItem ); if ( iy > y ) return &addItem; return &addSeparator;}void PopupMenuEditor::setFocusAt( const QPoint & pos ){ hideSubMenu(); lineEdit->hide(); currentIndex = 0; int iy = 0; PopupMenuEditorItem * i = itemList.first(); while ( i ) { iy += itemHeight( i ); if ( iy > pos.y() ) break; i = itemList.next(); currentIndex++; } iy += itemHeight( &addItem ); if ( iy <= pos.y() ) currentIndex++; if ( currentIndex < (int)itemList.count() ) { if ( pos.x() < iconWidth ) currentField = 0; else if ( pos.x() < iconWidth + textWidth ) currentField = 1; else currentField = 2; } else { currentField = 1; } showSubMenu();}bool PopupMenuEditor::eventFilter( QObject * o, QEvent * e ){ if ( o == lineEdit && e->type() == QEvent::FocusOut ) { leaveEditMode( 0 ); update(); } return QWidget::eventFilter( o, e );}void PopupMenuEditor::paintEvent( QPaintEvent * ){ QPainter p( this ); p.save(); QRegion reg( rect() ); QRegion mid( borderSize, borderSize, rect().width() - borderSize * 2, rect().height() - borderSize * 2 ); reg -= mid; p.setClipRegion( reg ); style().drawPrimitive( QStyle::PE_PanelPopup, &p, rect(), colorGroup() ); p.restore(); drawItems( &p );}void PopupMenuEditor::mousePressEvent( QMouseEvent * e ){ mousePressPos = e->pos(); setFocusAt( mousePressPos ); e->accept(); update();}void PopupMenuEditor::mouseDoubleClickEvent( QMouseEvent * ){ setFocusAt( mousePressPos ); if ( currentItem() == &addSeparator ) { PopupMenuEditorItem * i = createItem( new QSeparatorAction( 0 ) ); i->setSeparator( TRUE ); return; } if ( currentField == 0 ) { choosePixmap(); resizeToContents(); } else if ( currentField == 1 ) { showLineEdit(); }}void PopupMenuEditor::mouseMoveEvent( QMouseEvent * e ){ if ( e->state() & Qt::LeftButton ) { if ( ( e->pos() - mousePressPos ).manhattanLength() > 3 ) { draggedItem = itemAt( mousePressPos.y() ); if ( draggedItem == &addItem ) { draggedItem = createItem(); RenameActionCommand cmd( "Rename Item", formWnd, draggedItem->action(), this, "Unnamed" ); cmd.execute(); // FIXME: start rename after drop } else if ( draggedItem == &addSeparator ) { draggedItem = createItem( new QSeparatorAction( 0 ) ); draggedItem->setSeparator( TRUE ); } PopupMenuEditorItemPtrDrag * d = new PopupMenuEditorItemPtrDrag( draggedItem, this ); hideSubMenu(); draggedItem->setVisible( FALSE ); resizeToContents(); // If the item is dropped in the same list, // we will have two instances of the same pointer // in the list. We use node instead. int idx = itemList.find( draggedItem ); QLNode * node = itemList.currentNode(); d->dragCopy(); // dragevents and stuff happens if ( draggedItem ) { // item was not dropped draggedItem->setVisible( TRUE ); draggedItem = 0; if ( hasFocus() ) { hideSubMenu(); resizeToContents(); showSubMenu(); } } else { // item was dropped itemList.takeNode( node )->setVisible( TRUE ); if ( currentIndex > 0 && currentIndex > idx ) --currentIndex; // the drop might happen in another menu, so we'll resize // and show the submenu there } } }}void PopupMenuEditor::dragEnterEvent( QDragEnterEvent * e ){ if ( e->provides( "qt/popupmenueditoritemptr" ) || e->provides( "application/x-designer-actions" ) || e->provides( "application/x-designer-actiongroup" ) ) { e->accept(); dropLine->show(); }}void PopupMenuEditor::dragLeaveEvent( QDragLeaveEvent * ){ dropLine->hide();}void PopupMenuEditor::dragMoveEvent( QDragMoveEvent * e ){ QPoint pos = e->pos(); dropLine->move( borderSize, snapToItem( pos.y() ) ); if ( currentItem() != itemAt( pos.y() ) ) { hideSubMenu(); setFocusAt( pos ); showSubMenu(); }}void PopupMenuEditor::dropEvent( QDropEvent * e ){ if ( !( e->provides( "qt/popupmenueditoritemptr" ) || e->provides( "application/x-designer-actions" ) || e->provides( "application/x-designer-actiongroup" ) ) ) return; // Hide the sub menu of the current item, but do it later if ( currentIndex < (int)itemList.count() ) { PopupMenuEditor *s = itemList.at( currentIndex )->s; QTimer::singleShot( 0, s, SLOT( hide() ) ); } draggedItem = 0; PopupMenuEditorItem * i = 0; if ( e->provides( "qt/popupmenueditoritemptr" ) ) { PopupMenuEditorItemPtrDrag::decode( e, &i ); } else { if ( e->provides( "application/x-designer-actiongroup" ) ) { QActionGroup * g = ::qt_cast<QDesignerActionGroup*>(ActionDrag::action()); if ( g->usesDropDown() ) { i = new PopupMenuEditorItem( g, this ); QString n = QString( g->name() ) + "Item"; formWindow()->unify( i, n, FALSE ); i->setName( n ); QObjectList *l = g->queryList( "QAction", 0, FALSE, FALSE ); QObjectListIterator it( *l ); for ( ; it.current(); ++it ) { g = ::qt_cast<QActionGroup*>(it.current()); if ( g ) i->s->insert( g ); else i->s->insert( (QAction*)it.current() ); } delete l; } else { dropInPlace( g, e->pos().y() ); } } else if ( e->provides( "application/x-designer-actions" ) ) { QAction *a = ::qt_cast<QDesignerAction*>(ActionDrag::action()); i = new PopupMenuEditorItem( a, this ); } } if ( i ) { dropInPlace( i, e->pos().y() ); QTimer::singleShot( 0, this, SLOT( resizeToContents() ) ); } QTimer::singleShot( 0, this, SLOT( showSubMenu() ) ); QTimer::singleShot( 0, this, SLOT( setFocus() ) ); dropLine->hide(); e->accept();}void PopupMenuEditor::keyPressEvent( QKeyEvent * e ){ if ( lineEdit->isHidden() ) { // In navigation mode switch ( e->key() ) { case Qt::Key_Delete: hideSubMenu(); removeItem(); showSubMenu(); break; case Qt::Key_Backspace: clearCurrentField(); break; case Qt::Key_Up: navigateUp( e->state() & Qt::ControlButton ); break; case Qt::Key_Down: navigateDown( e->state() & Qt::ControlButton ); break; case Qt::Key_Left: navigateLeft(); break; case Qt::Key_Right: navigateRight(); break; 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: enterEditMode( e ); // move on case Qt::Key_Alt: case Qt::Key_Shift: case Qt::Key_Control: // do nothing return; case Qt::Key_Escape: currentField = 0; navigateLeft(); break; 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() ) { hideSubMenu(); cut( currentIndex ); showSubMenu(); break; } case Qt::Key_V: if ( e->state() & Qt::ControlButton ) { hideSubMenu(); paste( currentIndex < (int)itemList.count() ? currentIndex + 1: itemList.count() ); showSubMenu(); break; } default: if ( currentItem()->isSeparator() ) return; if ( currentField == 1 ) { showLineEdit(); QApplication::sendEvent( lineEdit, e ); e->accept();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -