📄 qmultilineedit.cpp
字号:
/*! \fn void QMultiLineEdit::textChanged() This signal is emitted when the text is changed by an event or by a slot. Note that the signal is not emitted when you call a non-slot function such as insertLine(). \sa returnPressed()*//*! \fn void QMultiLineEdit::returnPressed() This signal is emitted when the user presses the return or enter key. It is not emitted if isReadOnly() is TRUE. \sa textChanged()*//*! \fn void QMultiLineEdit::undoAvailable (bool yes) This signal is emitted when the availability of undo changes. If \a yes is TRUE, then undo() will work until undoAvailable( FALSE ) is next emitted.*//*! \fn void QMultiLineEdit::redoAvailable (bool yes) This signal is emitted when the availability of redo changes. If \a yes is TRUE, then redo() will work until redoAvailable( FALSE ) is next emitted.*//*! \fn void QMultiLineEdit::copyAvailable (bool yes) This signal is emitted when the availability of cut/copy changes. If \a yes is TRUE, then cut() and copy() will work until copyAvailable( FALSE ) is next emitted.*//*! \fn bool QMultiLineEdit::isReadOnly() const Returns FALSE if this multi line edit accepts text input. Scrolling and cursor movements are accepted in any case. \sa setReadOnly() QWidget::isEnabled()*//*! \fn bool QMultiLineEdit::isOverwriteMode() const Returns TRUE if this multi line edit is in overwrite mode, i.e. if characters typed replace characters in the editor. \sa setOverwriteMode()*//*! \fn void QMultiLineEdit::setOverwriteMode( bool on ) Sets overwrite mode if \a on is TRUE. Overwrite mode means that characters typed replace characters in the editor. \sa isOverwriteMode()*//*! If \a on is FALSE, this multi line edit accepts text input. Scrolling and cursor movements are accepted in any case. \sa isReadOnly() QWidget::setEnabled()*/void QMultiLineEdit::setReadOnly( bool on ){ if ( readOnly != on ) { readOnly = on;#ifndef QT_NO_CURSOR setCursor( on ? arrowCursor : ibeamCursor );#endif }}/*! Returns the width in pixels of the longest text line in this editor.*/int QMultiLineEdit::maxLineWidth() const{ return d->maxLineWidth;}/*! Destroys the QMultiLineEdit*/QMultiLineEdit::~QMultiLineEdit(){ delete contents; delete d;}static QPixmap *buffer = 0;static void cleanupMLBuffer(){ delete buffer; buffer = 0;}static QPixmap *getCacheBuffer( QSize sz ){ if ( !buffer ) { qAddPostRoutine( cleanupMLBuffer ); buffer = new QPixmap; } if ( buffer->width() < sz.width() || buffer->height() < sz.height() ) buffer->resize( sz ); return buffer;}/*! Implements the basic drawing logic.*/void QMultiLineEdit::paintCell( QPainter *painter, int row, int ){ const QColorGroup & g = colorGroup(); QFontMetrics fm( painter->font() ); QString s = stringShown(row); if ( s.isNull() ) { qWarning( "QMultiLineEdit::paintCell: (%s) no text at line %d", name( "unnamed" ), row ); return; } QRect updateR = cellUpdateRect(); QPixmap *buffer = getCacheBuffer( updateR.size() ); ASSERT(buffer); buffer->fill ( g.base() ); QPainter p( buffer ); p.setFont( painter->font() ); p.translate( -updateR.left(), -updateR.top() ); p.setTabStops( tabStopDist(fm) ); int yPos = 0; int markX1, markX2; // in x-coordinate pixels markX1 = markX2 = 0; // avoid gcc warning if ( markIsOn ) { int markBeginX, markBeginY; int markEndX, markEndY; getMarkedRegion( &markBeginY, &markBeginX, &markEndY, &markEndX ); if ( row >= markBeginY && row <= markEndY ) { if ( row == markBeginY ) { markX1 = markBeginX; if ( row == markEndY ) // both marks on same row markX2 = markEndX; else markX2 = s.length(); // mark till end of line } else { if ( row == markEndY ) { markX1 = 0; markX2 = markEndX; } else { markX1 = 0; // whole line is marked markX2 = s.length(); // whole line is marked } } } }#ifndef QT_NO_QWS_IM else if ( composeMode() ) { if ( row >= d->preeditStartY && row <= d->preeditEndY ) { int sLength = s.length(); int preX1 = (row == d->preeditStartY) ? d->preeditStartX : 0; int preX2 = (row == d->preeditEndY) ? d->preeditEndX : sLength; int prexpos1 = mapToView( preX1, row ); int prexpos2 = mapToView( preX2, row ); if ( !qt_im_compose_background ) { p.setPen( g.text() ); p.drawLine( prexpos1, cellHeight()-2, prexpos2, cellHeight()-2 ); } else { if ( markX1 == 0 ) prexpos1 -= 2; if ( markX2 == sLength ) prexpos2 += 3; p.fillRect( prexpos1, 0, prexpos2 - prexpos1, cellHeight(row), *qt_im_compose_background ); } } //### abusing mark anchor if ( ( markAnchorY < markDragY || markAnchorY == markDragY && markAnchorX < markDragX) && row >= markAnchorY && row <= markDragY) { markX1 = row == markAnchorY ? markAnchorX : 0; markX2 = row == markDragY ? markDragX : s.length(); } }#endif //QT_NO_QWS_IM p.setPen( g.text() ); QMultiLineEditRow* r = contents->at( row ); int wcell = cellWidth() - 2*d->lr_marg;// - d->marg_extra; int wrow = r->w; int x = d->lr_marg - p.fontMetrics().leftBearing(s[0]); if ( d->align == Qt::AlignCenter || d->align == Qt::AlignHCenter ) x += (wcell - wrow) / 2; else if ( d->align == Qt::AlignRight ) x += wcell - wrow; p.drawText( x, yPos, cellWidth()-d->lr_marg-x, cellHeight(), d->align == AlignLeft?ExpandTabs:0, s ); if ( !r->newline && BREAK_WITHIN_WORDS ) p.drawPixmap( x + wrow - d->lr_marg - d->marg_extra, yPos, d->arrow );#if 0 if ( r->newline ) p.drawLine( d->lr_marg, yPos+cellHeight()-2, cellWidth() - d->lr_marg, yPos+cellHeight()-2);#endif if ( markX1 != markX2 ) { int sLength = s.length(); int xpos1 = mapToView( markX1, row ); int xpos2 = mapToView( markX2, row ); int fillxpos1 = xpos1; int fillxpos2 = xpos2; if ( markX1 == 0 ) fillxpos1 -= 2; if ( markX2 == sLength ) fillxpos2 += 3; p.setClipping( TRUE ); p.setClipRect( fillxpos1 - updateR.left(), 0, fillxpos2 - fillxpos1, cellHeight(row) ); p.fillRect( fillxpos1, 0, fillxpos2 - fillxpos1, cellHeight(row), g.brush( QColorGroup::Highlight ) ); p.setPen( g.highlightedText() ); p.drawText( x, yPos, cellWidth()-d->lr_marg-x, cellHeight(), d->align == AlignLeft?ExpandTabs:0, s ); p.setClipping( FALSE ); } if ( row == cursorY && cursorOn && !readOnly ) { int cursorPos = QMIN( (int)s.length(), cursorX ); int cXPos = QMAX( mapToView( cursorPos, row ), 0 ); int cYPos = 0; if ( hasFocus() || d->dnd_forcecursor ) { p.setPen( g.text() ); /* styled? p.drawLine( cXPos - 2, cYPos, cXPos + 2, cYPos ); */#ifndef QT_NO_QWS_IM if ( !( composeMode() && markX1 != markX2) )#endif p.drawLine( cXPos, cYPos, cXPos, cYPos + fm.height() - 2); /* styled? p.drawLine( cXPos - 2, cYPos + fm.height() - 2, cXPos + 2, cYPos + fm.height() - 2); */#ifndef QT_NO_TRANSFORMATIONS // TODO: set it other times, eg. when scrollbar moves view QWMatrix wm = painter->worldMatrix(); if ( !inBlinkTimer ) setMicroFocusHint( int(wm.dx()+cXPos), int (wm.dy()+cYPos), 1, fm.height() );#else int xxpos,yypos; if ( !inBlinkTimer && colXPos( 0, &xxpos ) && rowYPos( row, &yypos ) ) setMicroFocusHint( cXPos+xxpos, cYPos+yypos, 1, fm.height() );#endif } } p.end(); painter->drawPixmap( updateR.left(), updateR.top(), *buffer, 0, 0, updateR.width(), updateR.height() );}/*! Returns the width in pixels of the string \a s. NOTE: only appropriate for whole lines.*/int QMultiLineEdit::textWidth( const QString &s ){ int w = 0; if ( !s.isNull() ) { w = textWidthWithTabs( QFontMetrics( font() ), s, 0, s.length(), d->align ); } return w + 2 * d->lr_marg + d->marg_extra;}/*! Returns the width in pixels of the text at line \a line.*/int QMultiLineEdit::textWidth( int line ){ if ( d->echomode == Password) { QString s = stringShown(line); return textWidth( s ); } QMultiLineEditRow* r = contents->at(line); return r?r->w:0;}/*! Starts the cursor blinking.*/void QMultiLineEdit::focusInEvent( QFocusEvent * ){ stopAutoScroll(); if ( !d->blinkTimer->isActive() ) d->blinkTimer->start( QApplication::cursorFlashTime() / 2, FALSE ); cursorOn = TRUE; updateCell( cursorY, 0, FALSE );}/*!\reimp*/void QMultiLineEdit::leaveEvent( QEvent * ){}/*!\reimp*/void QMultiLineEdit::focusOutEvent( QFocusEvent * ){ stopAutoScroll(); d->blinkTimer->stop(); if ( cursorOn ) { cursorOn = FALSE; updateCell( cursorY, 0, FALSE ); }}/*! \reimp Present for binary compatibility only!*/void QMultiLineEdit::timerEvent( QTimerEvent * ){ // ############ Remove in 3.0!!!!!!!!}#ifndef QT_NO_DRAGANDDROPvoid QMultiLineEdit::doDrag(){ if ( d->dnd_timer ) { d->dnd_timer->stop(); } QDragObject *drag_text = new QTextDrag(markedText(), this); if ( readOnly ) { drag_text->dragCopy(); } else { if ( drag_text->drag() && QDragObject::target() != this ) { del(); if ( textDirty && !d->isHandlingEvent ) emit textChanged(); } } d->dnd_primed = FALSE;}#endif/*! If there is marked text, sets \a line1, \a col1, \a line2 and \a col2 to the start and end of the marked region and returns TRUE. Returns FALSE if there is no marked text. */bool QMultiLineEdit::getMarkedRegion( int *line1, int *col1, int *line2, int *col2 ) const{ if ( !markIsOn || !line1 || !line2 || !col1 || !col2 ) return FALSE; if ( markAnchorY < markDragY || markAnchorY == markDragY && markAnchorX < markDragX) { *line1 = markAnchorY; *col1 = markAnchorX; *line2 = markDragY; *col2 = markDragX; if ( *line2 > numLines() - 1 ) { *line2 = numLines() - 1; *col2 = lineLength( *line2 ); } } else { *line1 = markDragY; *col1 = markDragX; *line2 = markAnchorY; *col2 = markAnchorX; if ( *line2 > numLines() - 1 ) { *line2 = numLines() - 1; *col2 = lineLength( *line2 ); } } return markIsOn;}/*! Returns TRUE if there is marked text.*/bool QMultiLineEdit::hasMarkedText() const{ return markIsOn;}/*! Returns a copy of the marked text.*/QString QMultiLineEdit::markedText() const{ int markBeginX, markBeginY; int markEndX, markEndY; if ( !getMarkedRegion( &markBeginY, &markBeginX, &markEndY, &markEndX ) ) return QString(); if ( markBeginY == markEndY ) { //just one line QString *s = getString( markBeginY ); return s->mid( markBeginX, markEndX - markBeginX ); } else { //multiline QString *firstS, *lastS; firstS = getString( markBeginY ); lastS = getString( markEndY ); int i; QString tmp; if ( firstS ) tmp += firstS->mid(markBeginX); if ( contents->at( markBeginY )->newline ) tmp += '\n'; for( i = markBeginY + 1; i < markEndY ; i++ ) { tmp += *getString(i); if ( contents->at( i )->newline ) tmp += '\n'; } if ( lastS ) { tmp += lastS->left(markEndX); } else { tmp.truncate(tmp.length()-1); } return tmp; }}/*! Returns the text at line number \a line (possibly the empty string), or a \link QString::operator!() null string\endlink if \a line is invalid.*/QString QMultiLineEdit::textLine( int line ) const{ QString *s = getString(line); if ( s ) { if ( s->isNull() ) return QString::fromLatin1(""); else return *s; } else return QString::null;}/*! Returns a copy of the whole text. If the multi line edit contains no text, a \link QString::operator!() null string\endlink is returned.*/QString QMultiLineEdit::text() const{ QString tmp; for( int i = 0 ; i < (int)contents->count() ; i++ ) { tmp += *getString(i); if ( i+1 < (int)contents->count() && contents->at(i)->newline ) tmp += '\n'; } return tmp;}/*! Selects all text without moving the cursor.*/void QMultiLineEdit::selectAll(){ markAnchorX = 0; markAnchorY = 0; markDragY = numLines() - 1; markDragX = lineLength( markDragY ); turnMark( markDragX != markAnchorX || markDragY != markAnchorY ); if ( autoUpdate() ) update();}/*! Deselects all text (i.e. removes marking) and leaves the cursor at the current position.*/void QMultiLineEdit::deselect(){ turnMark( FALSE );}/*! Sets the text to \a s, removing old text, if any.*/void QMultiLineEdit::setText( const QString &s )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -