⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qmultilineedit.cpp

📁 基于qt2的电子书
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/************************************************************************ $Id: qt/src/widgets/qmultilineedit.cpp   2.3.7   edited 2003-01-16 $**** Implementation of QMultiLineEdit widget class**** Created : 961005**** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.**** This file is part of the widgets module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for**   information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qmultilineedit.h"#ifndef QT_NO_MULTILINEEDIT#include "qpainter.h"#include "qscrollbar.h"#include "qclipboard.h"#include "qpixmap.h"#include "qregexp.h"#include "qapplication.h"#include "qdragobject.h"#include "qpopupmenu.h"#include "qtimer.h"#include "qdict.h"#include <ctype.h>#ifdef _WS_QWS_#include <qwsdisplay_qws.h>#endifclass QMultiLineEditCommand{public:    enum Commands { Invalid, Begin, End, Insert, Delete };    virtual ~QMultiLineEditCommand() {};    virtual Commands type() { return Invalid; };    virtual int terminator() { return 0; }    virtual bool merge( QMultiLineEditCommand* ) { return FALSE;}};class QBeginCommand : public QMultiLineEditCommand{public:    QBeginCommand() {}    int terminator() { return 1; }    Commands type() { return Begin; };};class QEndCommand : public QMultiLineEditCommand{public:    QEndCommand() {}    int terminator() { return -1; }    Commands type() { return End; };};// QMultiLineEditUndoRedo methodsclass QDelTextCmd : public QMultiLineEditCommand{public:    int mOffset;    QString mStr;    // have to handle deletion of current selection    QDelTextCmd(int offset, const QString &str )	: mOffset( offset ),	  mStr ( str )    {    }    Commands type() { return Delete; };    bool merge( QMultiLineEditCommand* other)    {	if ( other->type() == type() ) {	    QDelTextCmd* o = (QDelTextCmd*) other;	    if ( mOffset + int(mStr.length()) == o->mOffset ) {		o->mStr.prepend( mStr );		o->mOffset = mOffset;		return TRUE;	    }	}	return FALSE;    }};class QInsTextCmd : public QDelTextCmd{public:    QInsTextCmd(int offset,const QString &str )	: QDelTextCmd( offset, str )    {    }    Commands type() { return Insert; };    bool merge( QMultiLineEditCommand* other)    {	if ( other->type() == type() ) {	    QInsTextCmd* o = (QInsTextCmd*) other;	    if ( mOffset == o->mOffset + int(o->mStr.length()) ) {		o->mStr += mStr;		return TRUE;	    }	}	return FALSE;    }};// NOT REVISED/*!  \class QMultiLineEdit qmultilineedit.h  \brief The QMultiLineEdit widget is a simple editor for inputting text.  \ingroup advanced  The QMultiLineEdit widget provides multiple line text input and display.  It is intended for moderate amounts of text. There are no arbitrary  limitations, but if you try to handle megabytes of data, performance  will suffer.  Per default, the edit widget does not perform any word  wrapping. This can be adjusted by calling setWordWrap(). Both  dynamic wrapping according to the visible width or a fixed number of  character or pixels is supported.  The widget can be used to display text by calling setReadOnly(TRUE)  The default key bindings are described in keyPressEvent(); they cannot  be customized except by inheriting the class.  <img src=qmlined-m.png> <img src=qmlined-w.png>*/static const char * const arrow_xpm[] = {    "     8     8        2            1",    ". c None",    "# c #000000",    "........",    "..####..",    "..#####.",    ".....##.",    ".#..###.",    ".#####..",    ".####...",    ".#####.."};enum {    IdUndo,    IdRedo,#ifndef QT_NO_CLIPBOARD    IdCut,    IdCopy,    IdPaste,    IdPasteSpecial,#endif    IdClear,    IdSelectAll,    IdCount};struct QMultiLineData{    QMultiLineData() :	isHandlingEvent(FALSE),	edited(FALSE),	maxLineWidth(0),	align(Qt::AlignLeft),	maxlines(-1),	maxlinelen(-1),	maxlen(-1),	wordwrap( QMultiLineEdit::NoWrap ),	wrapcol( -1 ),	wrappolicy( QMultiLineEdit::AtWhiteSpace ),	// This doesn't use font bearings, as textWidthWithTabs does that.	// This is just an aesthetics value.	// It should probably be QMAX(0,3-fontMetrics().minLeftBearing()) though,	// as bearings give some border anyway.	lr_marg(3),	marg_extra(0),	echomode(QMultiLineEdit::Normal),	val(0),	dnd_primed(FALSE),	dnd_forcecursor(FALSE),	undo( TRUE ),	undodepth( 256 )    {#ifndef QT_NO_QWS_IM		preeditStartY = -1;#endif	undoList.setAutoDelete( TRUE );	redoList.setAutoDelete( TRUE );	clearChartable();    }    bool isHandlingEvent;    bool edited;    int  maxLineWidth;    int	 scrollTime;    int	 scrollAccel;    int  align;    int  numlines;    int  maxlines;    int  maxlinelen;    int  maxlen;    QMultiLineEdit::WordWrap wordwrap;    int wrapcol;    QMultiLineEdit::WrapPolicy wrappolicy;    int lr_marg;    int marg_extra;    QMultiLineEdit::EchoMode echomode;    const QValidator* val;    bool dnd_primed; // If TRUE, user has pressed    bool dnd_forcecursor; // If TRUE show cursor for DND feedback,    // even if !hasFocus()    QList<QMultiLineEditCommand> undoList;    QList<QMultiLineEditCommand> redoList;    bool undo;    int undodepth;    short chartable[256];    void clearChartable()    {	int i = 256;	while ( i )	    chartable[--i] = 0;    }    QPixmap arrow;    QPoint dnd_startpos;    QTimer *blinkTimer, *scrollTimer;#ifndef QT_NO_QWS_IM    int preeditStartX, preeditStartY, preeditEndX, preeditEndY;    int preeditCPos, preeditLength, preeditSelLen;#endif#ifndef QT_NO_DRAGANDDROP    QTimer *dnd_timer;#endif};#ifndef QT_NO_QWS_IMbool QMultiLineEdit::composeMode() const{    return  d->preeditStartY >= 0;}#endifstatic bool inBlinkTimer = FALSE;#ifndef QT_NO_QWS_IMextern QBrush *qt_im_compose_background;#endif#define CLEAR_UNDO {d->undoList.clear(); emit undoAvailable( FALSE );\    d->redoList.clear(); emit redoAvailable( FALSE );}void QMultiLineEdit::addUndoCmd(QMultiLineEditCommand* c){    if ( d->undoList.isEmpty() )	emit undoAvailable(TRUE);    else if ( c->merge( d->undoList.last() ) ) {	delete c;	return;    }    if ( int(d->undoList.count()) >= d->undodepth )	d->undoList.removeFirst();    d->undoList.append(c);    if ( !d->redoList.isEmpty() ) {	d->redoList.clear();	emit redoAvailable( FALSE );    }}void QMultiLineEdit::addRedoCmd(QMultiLineEditCommand* c){    if ( d->redoList.isEmpty() )	emit redoAvailable(TRUE);    d->redoList.append(c);}static const int initialScrollTime = 50; // mark text scroll timestatic const int initialScrollAccel = 5; // mark text scroll accel (0=fastest)static const int scroll_margin = 16;     // auto-scroll edge in DND#define WORD_WRAP ( d->wordwrap != QMultiLineEdit::NoWrap )#define DYNAMIC_WRAP ( d->wordwrap == QMultiLineEdit::WidgetWidth )#define FIXED_WIDTH_WRAP ( d->wordwrap == QMultiLineEdit::FixedPixelWidth )#define FIXED_COLUMN_WRAP ( d->wordwrap == QMultiLineEdit::FixedColumnWidth )#define BREAK_WITHIN_WORDS ( d->wrappolicy == QMultiLineEdit::Anywhere )static int defTabStop = 8;static int tabStopDist( const QFontMetrics &fm ){    int dist;    dist = fm.width( QChar('x' ));    if( dist == 0 )       dist = fm.maxWidth();    return defTabStop*dist;}/*!  Sets the distance between tab stops for all QMultiLineEdit instances  to \a ex, which is measured in multiples of the width of a lower case 'x'  in the widget's font. The initial value is 8.  \warning This function does not cause a redraw. It is best to call  it before any QMultiLineEdit widgets are shown.  \sa defaultTabStop()*/void QMultiLineEdit::setDefaultTabStop( int ex ){    defTabStop = ex;}/*!  Returns the distance between tab stops.  \sa setDefaultTabStop();*/int QMultiLineEdit::defaultTabStop(){    return defTabStop;}static int textWidthWithTabs( const QFontMetrics &fm, const QString &s, uint start, uint nChars, int align ){    if ( s.isEmpty() )	return 0;    int dist = -fm.leftBearing( s[(int)start] );    int i = start;    int tabDist = -1; // lazy eval    while ( (uint)i < s.length() && (uint)i < start+nChars ) {	if ( s[i] == '\t' && align == Qt::AlignLeft ) {	    if ( tabDist<0 )		tabDist = tabStopDist(fm);	    dist = ( (dist+tabDist+1)/tabDist ) * tabDist;	    i++;	} else {	    int ii = i;	    while ( (uint)i < s.length() && (uint)i < start + nChars && ( align != Qt::AlignLeft || s[i] != '\t' ) )		i++;	    dist += fm.width( s.mid(ii,i-ii) );	}    }    return dist;}static int xPosToCursorPos( const QString &s, const QFontMetrics &fm,			    int xPos, int width, int align ){    int i = 0;    int	  dist;    int tabDist;    if ( s.isEmpty() )	return 0;    if ( xPos > width )	xPos = width;    if ( xPos <= 0 )	return 0;    dist    = -fm.leftBearing( s[0] );    if ( align == Qt::AlignCenter || align == Qt::AlignHCenter )	dist = ( width - textWidthWithTabs( fm, s, 0, s.length(), align ) ) / 2;    else if ( align == Qt::AlignRight )	dist = width - textWidthWithTabs( fm, s, 0, s.length(), align );    int     distBeforeLastTab = dist;    tabDist = tabStopDist(fm);    while ( (uint)i < s.length() && dist < xPos ) {	if ( s[i] == '\t' && align == Qt::AlignLeft ) {	    distBeforeLastTab = dist;	    dist = (dist/tabDist + 1) * tabDist;	} else {	    dist += fm.width( s[i] );	}	i++;    }    if ( dist > xPos ) {	if ( dist > width ) {	    i--;	} else {	    if ( s[i-1] == '\t' && align == Qt::AlignLeft ) { // dist equals a tab stop position		if ( xPos - distBeforeLastTab < (dist - distBeforeLastTab)/2 )		    i--;	    } else {		if ( fm.width(s[i-1])/2 < dist-xPos )		    i--;	    }	}    }    return i;}/*!  Constructs a new, empty, QMultiLineEdit.*/QMultiLineEdit::QMultiLineEdit( QWidget *parent , const char *name )    :QTableView( parent, name, WNorthWestGravity | WRepaintNoErase ){    d = new QMultiLineData;    QFontMetrics fm( font() );    setCellHeight( fm.lineSpacing() );    setNumCols( 1 );    contents = new QList<QMultiLineEditRow>;    contents->setAutoDelete( TRUE );    cursorX = 0; cursorY = 0;    curXPos = 0;    setTableFlags( Tbl_clipCellPainting ); /*Tbl_autoVScrollBar|Tbl_autoHScrollBar|Tbl_smoothVScrolling |*/		       setFrameStyle( QFrame::WinPanel | QFrame::Sunken );    setBackgroundMode( PaletteBase );    setWFlags( WResizeNoErase );    setKeyCompression( TRUE );    setFocusPolicy( WheelFocus );#ifndef QT_NO_CURSOR    setCursor( ibeamCursor );    verticalScrollBar()->setCursor( arrowCursor );    horizontalScrollBar()->setCursor( arrowCursor );#endif    readOnly 	   = FALSE;    cursorOn	   = FALSE;    markIsOn	   = FALSE;    dragScrolling  = FALSE;    dragMarking    = FALSE;    textDirty	   = FALSE;    wordMark	   = FALSE;    overWrite	   = FALSE;    markAnchorX    = 0;    markAnchorY    = 0;    markDragX      = 0;    markDragY      = 0;    d->blinkTimer = new QTimer( this );    connect( d->blinkTimer, SIGNAL( timeout() ),	     this, SLOT( blinkTimerTimeout() ) );    d->scrollTimer = new QTimer( this );    connect( d->scrollTimer, SIGNAL( timeout() ),	     this, SLOT( scrollTimerTimeout() ) );#ifndef QT_NO_DRAGANDDROP    d->dnd_timer = new QTimer( this );    connect( d->dnd_timer, SIGNAL( timeout() ),	     this, SLOT( dndTimeout() ) );#endif    d->scrollTime = 0;    dummy = TRUE;    int w  = textWidth( QString::fromLatin1("") );    contents->append( new QMultiLineEditRow(QString::fromLatin1(""), w) );    (void)setNumRowsAndTruncate();    setWidth( w );    setAcceptDrops(TRUE);    if ( d->maxlines >= 0 && d->maxlines <= 6 ) {	setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );    } else {	setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );    }}/*! \fn int QMultiLineEdit::numLines() const  Returns the number of lines in the editor. The count includes any  empty lines at top and bottom, so for an empty editor this method  will return 1.*//*! \fn bool QMultiLineEdit::atEnd() const  Returns TRUE if the cursor is placed at the end of the text.*//*! \fn bool QMultiLineEdit::atBeginning() const  Returns TRUE if the cursor is placed at the beginning of the text.*//*!  \fn int QMultiLineEdit::lineLength( int line ) const  Returns the number of characters at line number \a line.*//*! \fn QString *QMultiLineEdit::getString( int line ) const  Returns a pointer to the text at line \a line.*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -