📄 qmultilineedit.cpp
字号:
int id[ (int)IdCount ]; id[ IdUndo ] = popup->insertItem( tr( "Undo" ) ); id[ IdRedo ] = popup->insertItem( tr( "Redo" ) ); popup->insertSeparator();#ifndef QT_NO_CLIPBOARD id[ IdCut ] = popup->insertItem( tr( "Cut" ) ); id[ IdCopy ] = popup->insertItem( tr( "Copy" ) ); id[ IdPaste ] = popup->insertItem( tr( "Paste" ) );#ifndef QT_NO_MIMECLIPBOARD id[ IdPasteSpecial ] = popup->insertItem( tr( "Paste special..." ) );#endif#endif id[ IdClear ] = popup->insertItem( tr( "Clear" ) ); popup->insertSeparator(); id[ IdSelectAll ] = popup->insertItem( tr( "Select All" ) ); popup->setItemEnabled( id[ IdUndo ], !this->d->undoList.isEmpty() ); popup->setItemEnabled( id[ IdRedo ], !this->d->redoList.isEmpty() );#ifndef QT_NO_CLIPBOARD popup->setItemEnabled( id[ IdCut ], !isReadOnly() && hasMarkedText() ); popup->setItemEnabled( id[ IdCopy ], hasMarkedText() ); popup->setItemEnabled( id[ IdPaste ], !isReadOnly() && (bool)QApplication::clipboard()->text().length() );#ifndef QT_NO_MIMECLIPBOARD // Any non-plain types? QMimeSource* ms = QApplication::clipboard()->data(); bool ps = FALSE; if ( ms ) { if ( !isReadOnly() ) { const char* fmt; for (int i=0; !ps && (fmt=ms->format(i)); i++) { ps = qstrnicmp(fmt,"text/",5)==0 && qstrnicmp(fmt+5,"plain",5)!=0; } } } popup->setItemEnabled( id[ IdPasteSpecial ], ps );#endif#endif popup->setItemEnabled( id[ IdClear ], !isReadOnly() && (bool)text().length() ); int allSelected = markIsOn && markAnchorX == 0 && markAnchorY == 0 && markDragY == numLines() - 1 && markDragX == lineLength( markDragY ); popup->setItemEnabled( id[ IdSelectAll ], (bool)text().length() && !allSelected ); int r = popup->exec( e->globalPos() ); delete popup; if ( r == id[ IdUndo ] ) undo(); else if ( r == id[ IdRedo ] ) redo();#ifndef QT_NO_CLIPBOARD else if ( r == id[ IdCut ] ) cut(); else if ( r == id[ IdCopy ] ) copy(); else if ( r == id[ IdPaste ] ) paste();# ifndef QT_NO_MIMECLIPBOARD else if ( r == id[ IdPasteSpecial ] ) pasteSpecial(QCursor::pos());# endif#endif else if ( r == id[ IdClear ] ) clear(); else if ( r == id[ IdSelectAll ] ) selectAll(); return; } if ( e->button() != MidButton && e->button() != LeftButton) return; int newX, newY; pixelPosToCursorPos( e->pos(), &newX, &newY ); if ( e->state() & ShiftButton ) { wordMark = FALSE; dragMarking = TRUE; setCursorPosition( newY, newX, TRUE); return; }#ifndef QT_NO_DRAGANDDROP if ( inMark(newX, newY) // Click on highlighted text && echoMode() == Normal // No DnD of passwords, etc. && e->pos().y() < totalHeight() // Click past the end is not dragging ) { // The user might be trying to drag d->dnd_primed = TRUE; d->dnd_timer->start( QApplication::startDragTime(), FALSE ); } else#endif { wordMark = FALSE; dragMarking = TRUE; setCursorPixelPosition(e->pos()); }}void QMultiLineEdit::pixelPosToCursorPos(QPoint p, int* x, int* y) const{ *y = findRow( p.y() ); if ( *y < 0 ) { if ( p.y() < lineWidth() ) { *y = topCell(); } else { *y = lastRowVisible(); p.setX(cellWidth()); } } *y = QMIN( (int)contents->count() - 1, *y ); QFontMetrics fm( font() ); *x = xPosToCursorPos( stringShown( *y ), fm, p.x() - d->lr_marg + xOffset(), cellWidth() - 2 * d->lr_marg - d->marg_extra, d->align ); QMultiLineEditRow* r = contents->at( *y ); if (r && !r->newline && ((unsigned int)*x == r->s.length()) && (*x > 0)) --*x;}void QMultiLineEdit::setCursorPixelPosition(QPoint p, bool clear_mark){ int newY; pixelPosToCursorPos( p, &cursorX, &newY ); curXPos = 0; if ( clear_mark ) { markAnchorX = cursorX; markAnchorY = newY; bool markWasOn = markIsOn; turnMark( FALSE ); if ( markWasOn ) { cursorY = newY; update(); d->isHandlingEvent = FALSE; return; } } if ( cursorY != newY ) { int oldY = cursorY; cursorY = newY; updateCell( oldY, 0, FALSE ); } updateCell( cursorY, 0, FALSE ); // ###}void QMultiLineEdit::startAutoScroll(){ if ( !dragScrolling ) { d->scrollTime = initialScrollTime; d->scrollAccel = initialScrollAccel; d->scrollTimer->start( d->scrollTime, FALSE ); dragScrolling = TRUE; }}void QMultiLineEdit::stopAutoScroll(){ if ( dragScrolling ) { d->scrollTimer->stop(); dragScrolling = FALSE; }}/*!\reimp*/void QMultiLineEdit::mouseMoveEvent( QMouseEvent *e ){#ifndef QT_NO_QWS_IM if ( composeMode() ) { return; }#endif#ifndef QT_NO_DRAGANDDROP d->dnd_timer->stop(); if ( d->dnd_primed && ( d->dnd_startpos - e->pos() ).manhattanLength() > QApplication::startDragDistance() ) { doDrag(); return; }#endif if ( !dragMarking ) return; if ( rect().contains( e->pos() ) ) { stopAutoScroll(); } else if ( !dragScrolling ) { startAutoScroll(); } int newX, newY; pixelPosToCursorPos(e->pos(), &newX, &newY); if ( wordMark ) { extendSelectionWord( newX, newY); } if ( markDragX == newX && markDragY == newY ) return; int oldY = markDragY; newMark( newX, newY, FALSE ); for ( int i = QMIN(oldY,newY); i <= QMAX(oldY,newY); i++ ) updateCell( i, 0, FALSE );}void QMultiLineEdit::extendSelectionWord( int &newX, int&newY){ QString s = stringShown( newY ); int lim = s.length(); if ( newX >= 0 && newX < lim ) { int i = newX; int startclass = charClass(s.at(i)); if ( markAnchorY < markDragY || ( markAnchorY == markDragY && markAnchorX < markDragX ) ) { // going right while ( i < lim && charClass(s.at(i)) == startclass ) i++; } else { // going left while ( i >= 0 && charClass(s.at(i)) == startclass ) i--; i++; } newX = i; }}/*!\reimp*/void QMultiLineEdit::mouseReleaseEvent( QMouseEvent *e ){#ifndef QT_NO_QWS_IM if ( composeMode() ) {#if defined (_WS_QWS_) QPaintDevice::qwsDisplay()->sendIMMouseEvent( pixelPosToIMPos( e->pos() ), FALSE ); #endif return; }#endif stopAutoScroll();#ifndef QT_NO_DRAGANDDROP if ( d->dnd_timer->isActive() ) { d->dnd_timer->stop(); d->dnd_primed = FALSE; setCursorPixelPosition(e->pos()); }#endif wordMark = FALSE; dragMarking = FALSE; textDirty = FALSE; d->isHandlingEvent = TRUE; if ( markAnchorY == markDragY && markAnchorX == markDragX ) turnMark( FALSE );#ifndef QT_NO_CLIPBOARD#if defined(_WS_X11_) else if ( echoMode() == Normal ) copy();#endif if ( e->button() == MidButton && !readOnly ) {#if defined(_WS_X11_) paste(); // Will repaint the cursor line.#else if ( style() == MotifStyle ) paste();#endif }#endif d->isHandlingEvent = FALSE; if ( !readOnly && textDirty ) emit textChanged();}/*!\reimp*/void QMultiLineEdit::mouseDoubleClickEvent( QMouseEvent *m ){#ifndef QT_NO_QWS_IM if ( composeMode() ) { return; }#endif if ( m->button() == LeftButton ) { if ( m->state() & ShiftButton ) { int newX = cursorX; int newY = cursorY; extendSelectionWord( newX, newY); newMark( newX, newY, FALSE ); } else { markWord( cursorX, cursorY ); } dragMarking = TRUE; wordMark = TRUE; updateCell( cursorY, 0, FALSE ); }}#ifndef QT_NO_DRAGANDDROP/*! \reimp*/void QMultiLineEdit::dragEnterEvent( QDragEnterEvent * ){ cursorOn = TRUE; updateCell( cursorY, 0, FALSE );}/*!\reimp*/void QMultiLineEdit::dragMoveEvent( QDragMoveEvent* event ){ if ( readOnly ) return; event->accept( QTextDrag::canDecode(event) ); d->dnd_forcecursor = TRUE; setCursorPixelPosition(event->pos(), FALSE); d->dnd_forcecursor = FALSE; QRect inside_margin(scroll_margin, scroll_margin, width()-scroll_margin*2, height()-scroll_margin*2); if ( !inside_margin.contains(event->pos()) ) { startAutoScroll(); } if ( event->source() == this && event->action() == QDropEvent::Move ) event->acceptAction();}/*!\reimp*/void QMultiLineEdit::dragLeaveEvent( QDragLeaveEvent* ){ if ( cursorOn ) { cursorOn = FALSE; updateCell( cursorY, 0, FALSE ); } stopAutoScroll();}/*!\reimp*/void QMultiLineEdit::dropEvent( QDropEvent* event ){ if ( readOnly ) return; QString text; QCString fmt = pickSpecial(event,FALSE,event->pos()); if ( QTextDrag::decode(event, text, fmt) ) { int i = -1; while ( ( i = text.find( '\r' ) ) != -1 ) text.replace( i,1,"" ); if ( event->source() == this && event->action() == QDropEvent::Move ) { event->acceptAction(); // Careful not to tread on my own feet int newX, newY; pixelPosToCursorPos( event->pos(), &newX, &newY ); if ( afterMark( newX, newY ) ) { // The tricky case int x1, y1, x2, y2; getMarkedRegion( &y1, &x1, &y2, &x2 ); if ( newY == y2 ) { newY = y1; newX = x1 + newX - x2; } else { newY -= y2 - y1; } addUndoCmd( new QBeginCommand ); del(); setCursorPosition(newY, newX); insert(text, TRUE); addUndoCmd( new QEndCommand ); } else if ( beforeMark( newX, newY ) ) { // Easy addUndoCmd( new QBeginCommand ); del(); setCursorPosition(newY, newX); insert(text, TRUE); addUndoCmd( new QEndCommand ); } else { // Do nothing. } } else { setCursorPixelPosition(event->pos()); insert(text, TRUE); } update(); emit textChanged(); }}#endif // QT_NO_DRAGANDDROP/*! Returns TRUE if line \a line is invisible or partially invisible.*/bool QMultiLineEdit::partiallyInvisible( int line ){ int y; if ( !rowYPos( line, &y ) ) return TRUE; if ( y < 0 ) return TRUE; else if ( y + cellHeight() - 2 > viewHeight() ) return TRUE; return FALSE;}/*! Scrolls such that the cursor is visible*/void QMultiLineEdit::makeVisible(){ if ( !autoUpdate() ) return; if ( partiallyInvisible( cursorY ) ) { if ( cursorY >= lastRowVisible() ) setBottomCell( cursorY ); else setTopCell( cursorY ); } int xPos = mapToView( cursorX, cursorY ); if ( xPos < xOffset() ) { int of = xPos - 10; //### setXOffset( of ); } else if ( xPos > xOffset() + viewWidth() ) { int of = xPos - viewWidth() + 10; //### setXOffset( of ); }}/*! Computes the character position in line \a line which corresponds to pixel \a xPos*/int QMultiLineEdit::mapFromView( int xPos, int line ){ QString s = stringShown( line ); if ( !s ) return 0; QFontMetrics fm( font() ); int index = xPosToCursorPos( s, fm, xPos - d->lr_marg, cellWidth() - 2 * d->lr_marg - d->marg_extra, d->align ); QMultiLineEditRow* r = contents->at( line ); if (r && !r->newline && ((unsigned int)index == r->s.length()) && (index > 0)) --index; return index;}/*! Computes the pixel position in line \a line which corresponds to character position \a xIndex*/int QMultiLineEdit::mapToView( int xIndex, int line ){ QString s = stringShown( line ); xIndex = QMIN( (int)s.length(), xIndex ); QFontMetrics fm( font() ); int wcell = cellWidth() - 2 * d->lr_marg;// - d->marg_extra; int wrow = contents->at( line )->w; int w = textWidthWithTabs( fm, s, 0, xIndex, d->align ) - 1; if ( d->align == Qt::AlignCenter || d->align == Qt::AlignHCenter ) w += (wcell - wrow) / 2; else if ( d->align == Qt::AlignRight ) w += wcell - wrow; return d->lr_marg + w;}/*! Traverses the list and finds an item with the maximum width, and updates the internal list box structures accordingly.*/void QMultiLineEdit::updateCellWidth(){ QMultiLineEditRow* r = contents->first(); int maxW = 0; int w; switch ( d->echomode ) { case Normal: while ( r ) { w = r->w; if ( w > maxW ) maxW = w; r = contents->next(); } break; case Password: { uint l = 0; while ( r ) { l = QMAX(l, r->s.length() ); r = contents->next(); } QString t; t.fill(QChar('*'), l); maxW = textWidth(t); } break; case NoEcho: maxW = textWidth(QString::fromLatin1("")); } setWidth( maxW );}/*! Sets the bottommost visible line to \a line.*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -