diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2019-04-21 23:22:20 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2019-04-21 23:22:20 +0900 |
commit | dba036816b279bc1539a9f3894fbc414665d2bce (patch) | |
tree | 29e4bf00bafe515e7afdd02168d65a47a3f9fbc0 /tqtinterface/qt4/src/attic/qtmultilineedit.cpp | |
parent | 6f1b4f0c7505a049d992a33f6e409b7c75732d4b (diff) | |
download | experimental-dba036816b279bc1539a9f3894fbc414665d2bce.tar.gz experimental-dba036816b279bc1539a9f3894fbc414665d2bce.zip |
Removed unnecessary and/or TDE-unrelated code.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
Diffstat (limited to 'tqtinterface/qt4/src/attic/qtmultilineedit.cpp')
-rw-r--r-- | tqtinterface/qt4/src/attic/qtmultilineedit.cpp | 4236 |
1 files changed, 0 insertions, 4236 deletions
diff --git a/tqtinterface/qt4/src/attic/qtmultilineedit.cpp b/tqtinterface/qt4/src/attic/qtmultilineedit.cpp deleted file mode 100644 index 104ff60..0000000 --- a/tqtinterface/qt4/src/attic/qtmultilineedit.cpp +++ /dev/null @@ -1,4236 +0,0 @@ -/********************************************************************** -** -** Implementation of TQtMultiLineEdit widget class -** -** Created : 961005 -** -** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. -** -** This file contains a class moved out of the TQt GUI Toolkit API. It -** may be used, distributed and modified without limitation. -** -**********************************************************************/ - -#include "tqtmultilineedit.h" -#ifndef TQT_NO_TQTMULTILINEEDIT -#include "tqpainter.h" -#include "tqscrollbar.h" -#include "tqclipboard.h" -#include "tqpixmap.h" -#include "tqregexp.h" -#include "tqapplication.h" -#include "tqdragobject.h" -#include "tqpopupmenu.h" -#include "tqtimer.h" -#include "tqdict.h" -#include "tqcursor.h" -#ifndef TQT_NO_COMPAT -#include "tqstyle.h" -#endif - - -class TQtMultiLineEditCommand -{ -public: - enum Commands { Invalid, Begin, End, Insert, Delete }; - virtual ~TQtMultiLineEditCommand() {}; - virtual Commands type() { return Invalid; }; - virtual int terminator() { return 0; } - - virtual bool merge( TQtMultiLineEditCommand* ) { return FALSE;} -}; - -class TQBeginCommand : public TQtMultiLineEditCommand -{ - -public: - TQBeginCommand() {} - int terminator() { return 1; } - Commands type() { return Begin; }; -}; - -class TQEndCommand : public TQtMultiLineEditCommand -{ -public: - TQEndCommand() {} - int terminator() { return -1; } - Commands type() { return End; }; -}; - -// TQtMultiLineEditUndoRedo methods -class TQDelTextCmd : public TQtMultiLineEditCommand -{ -public: - int mOffset; - TQString mStr; - - // have to handle deletion of current selection - TQDelTextCmd(int offset, const TQString &str ) - : mOffset( offset ), - mStr ( str ) - { - } - Commands type() { return Delete; }; - - bool merge( TQtMultiLineEditCommand* other) - { - if ( other->type() == type() ) { - TQDelTextCmd* o = (TQDelTextCmd*) other; - if ( mOffset + int(mStr.length()) == o->mOffset ) { - o->mStr.prepend( mStr ); - o->mOffset = mOffset; - return TRUE; - } - } - return FALSE; - } - - -}; - -class TQInsTextCmd : public TQDelTextCmd -{ - -public: - TQInsTextCmd(int offset,const TQString &str ) - : TQDelTextCmd( offset, str ) - { - } - - Commands type() { return Insert; }; - - bool merge( TQtMultiLineEditCommand* other) - { - if ( other->type() == type() ) { - TQInsTextCmd* o = (TQInsTextCmd*) other; - if ( mOffset == o->mOffset + int(o->mStr.length()) ) { - o->mStr += mStr; - return TRUE; - } - } - return FALSE; - } -}; - - -/* - \class TQtMultiLineEdit qtmultilineedit.h - - \brief The TQtMultiLineEdit widget is a simple editor for inputting text. - - \obsolete - - The TQtMultiLineEdit 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> -*/ - -/* - \property TQtMultiLineEdit::numLines - \brief the number of lines in the multi-line edit - - numLines() 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. -*/ -/* - \property TQtMultiLineEdit::atBeginning - \brief whether the cursor is at the beginning - - atBeginning() returns TRUE if the cursor is placed at the - beginning of the text. -*/ -/* - \property TQtMultiLineEdit::atEnd - \brief whether the cursor is at the end - - atEnd() returns TRUE if the cursor is placed at the end of the text. -*/ -/* - \property TQtMultiLineEdit::maxLineWidth - \brief the maximum line width in pixels - Returns the width in pixels of the longest text line in this editor. -*/ -/* - \property TQtMultiLineEdit::tqalignment - \brief the tqalignment - - Possible values are \c AlignLeft, \c Align(H)Center and \c - AlignRight. - \sa TQt::AlignmentFlags -*/ -/* - \property TQtMultiLineEdit::edited - \brief whether the text had been edited - -edited() returns the edited flag of the line edit. If this returns FALSE, -the contents has not been changed since the construction of the -TQtMultiLineEdit (or the last call to setEdited( FALSE ), if any). If -it returns TRUE, the contents have been edited, or setEdited( TRUE ) -has been called. - -setEdited() sets the edited flag of this line edit to \e e. The -edited flag is never read by TQtMultiLineEdit, but is changed to TRUE -whenever the user changes its contents. - -This is useful e.g. for things that need to provide a default value, -but cannot find the default at once. Just open the widget without the -best default and when the default is known, check the edited() return -value and set the line edit's contents if the user has not started -editing the line edit. Another example is to detect whether the -contents need saving. - -*/ -/* - \property TQtMultiLineEdit::echoMode - \brief the echo mode -*/ -/* - \property TQtMultiLineEdit::maxLength - \brief the maximum length of the text - - The currently set text length limit, or -1 if there is - no limit (this is the default). - -*/ -/* - \property TQtMultiLineEdit::maxLines - \brief the maximum number of lines - The currently set line limit, or -1 if there is - no limit (the default). - - Note that excess lines are deleted from the \e bottom of the - lines. If you want teletype behaviour with lines disappearing - from the \e top as the limit is exceed, you probably just want - to use removeLine(0) prior to adding an excess line. - -*/ -/* - \property TQtMultiLineEdit::hMargin - \brief the horizontal margin - The horizontal margin current set. The default is 3. -*/ -/* - \property TQtMultiLineEdit::wordWrap - \brief the word wrap mode - - By default, wrapping keeps words intact. To allow breaking within - words, set the wrap policy to \c Anywhere (see setWrapPolicy() ). - - The default wrap mode is \c NoWrap. - - \sa wordWrap(), setWrapColumnOrWidth(), setWrapPolicy() -*/ -/* - \property TQtMultiLineEdit::wrapColumnOrWidth - \brief the wrap width in columns or pixels - The wrap column or wrap width, depending on the word wrap - mode. - \sa setWordWrap(), setWrapColumnOrWidth() -*/ -/* - \property TQtMultiLineEdit::wrapPolicy - \brief the wrap policy mode - The default is \c AtWhiteSpace. - -*/ -/* - \property TQtMultiLineEdit::autoUpdate - \brief whether auto update is enabled - - autoUpdate() returns TRUE if the view updates itself automatically - whenever it is changed in some way. - - If autoUpdate() is TRUE (this is the default) then the editor updates - itself automatically whenever it has changed in some way (generally, - when text has been inserted or deleted). - - If autoUpdate() is FALSE, the view does NOT tqrepaint itself, or update - its internal state variables itself when it is changed. This can be - useful to avoid flicker during large changes, and is singularly - useless otherwise: Disable auto-update, do the changes, re-enable - auto-update, and call tqrepaint(). - - \warning Do not leave the view in this state for a long time - (i.e. between events ). If, for example, the user interacts with the - view when auto-update is off, strange things can happen. - - Setting auto-update to TRUE does not tqrepaint the view, you must call - tqrepaint() to do this (preferable tqrepaint(FALSE) to avoid flicker). - - \sa autoUpdate() tqrepaint() - -*/ -/* - \property TQtMultiLineEdit::undoEnabled - \brief whether undo is enabled -*/ -/* - \property TQtMultiLineEdit::undoDepth - \brief the undo depth - - The maximum number of operations that can be stored on the undo stack. - - \sa setUndoDepth() -*/ -/* - \property TQtMultiLineEdit::readOnly - \brief whether the multi-line edit is read-only -*/ -/* - \property TQtMultiLineEdit::overWriteMode - \brief the overwrite mode -*/ -/* - \property TQtMultiLineEdit::text - \brief the multi-line edit's text -*/ -/* - \property TQtMultiLineEdit::length - \brief the length of the text -*/ - -static const char * const arrow_xpm[] = { - " 8 8 2 1", - ". c None", - "# c #000000", - "........", - "..####..", - "..#####.", - ".....##.", - ".#..###.", - ".#####..", - ".####...", - ".#####.." -}; - -enum { - IdUndo, - IdRedo, -#ifndef TQT_NO_CLIPBOARD - IdCut, - IdCopy, - IdPaste, - IdPasteSpecial, -#endif - IdClear, - IdSelectAll, - IdCount -}; - -struct TQtMultiLineData -{ - TQtMultiLineData() : - isHandlingEvent(FALSE), - edited(FALSE), - maxLineWidth(0), - align(TQt::AlignLeft), - maxlines(-1), - maxlinelen(-1), - maxlen(-1), - wordwrap( TQtMultiLineEdit::NoWrap ), - wrapcol( -1 ), - wrappolicy( TQtMultiLineEdit::AtWhiteSpace ), - // This doesn't use font bearings, as textWidthWithTabs does that. - // This is just an aesthetics value. - // It should probably be TQMAX(0,3-fontMetrics().minLeftBearing()) though, - // as bearings give some border anyway. - lr_marg(3), - marg_extra(0), - echomode(TQtMultiLineEdit::Normal), - val(0), - dnd_primed(FALSE), - dnd_forcecursor(FALSE), - undo( TRUE ), - undodepth( 256 ) - { - 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; - TQtMultiLineEdit::WordWrap wordwrap; - int wrapcol; - TQtMultiLineEdit::WrapPolicy wrappolicy; - int lr_marg; - int marg_extra; - TQtMultiLineEdit::EchoMode echomode; - const TQValidator* val; - - bool dnd_primed; // If TRUE, user has pressed - bool dnd_forcecursor; // If TRUE show cursor for DND feedback, - // even if !hasFocus() - TQPtrList<TQtMultiLineEditCommand> undoList; - TQPtrList<TQtMultiLineEditCommand> redoList; - bool undo; - int undodepth; - short chartable[256]; - void clearChartable() - { - int i = 256; - while ( i ) - chartable[--i] = 0; - } - TQPixmap arrow; - TQPoint dnd_startpos; - TQTimer *blinkTimer, *scrollTimer; -#ifndef TQT_NO_DRAGANDDROP - TQTimer *dnd_timer; -#endif -}; - - -#define CLEAR_UNDO {d->undoList.clear(); emit undoAvailable( FALSE );\ - d->redoList.clear(); emit redoAvailable( FALSE );} - -void TQtMultiLineEdit::addUndoCmd(TQtMultiLineEditCommand* 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 TQtMultiLineEdit::addRedoCmd(TQtMultiLineEditCommand* c) -{ - if ( d->redoList.isEmpty() ) - emit redoAvailable(TRUE); - d->redoList.append(c); -} - -static const int initialScrollTime = 50; // mark text scroll time -static 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 != TQtMultiLineEdit::NoWrap ) -#define DYNAMIC_WRAP ( d->wordwrap == TQtMultiLineEdit::WidgetWidth ) -#define FIXED_WIDTH_WRAP ( d->wordwrap == TQtMultiLineEdit::FixedPixelWidth ) -#define FIXED_COLUMN_WRAP ( d->wordwrap == TQtMultiLineEdit::FixedColumnWidth ) -#define BREAK_WITHIN_WORDS ( d->wrappolicy == TQtMultiLineEdit::Anywhere ) - -static int defTabStop = 8; - -static int tabStopDist( const TQFontMetrics &fm ) -{ - int dist; - dist = fm.width( TQChar('x' )); - if( dist == 0 ) - dist = fm.maxWidth(); - return defTabStop*dist; -} - - -/* - Sets the distance between tab stops for all TQtMultiLineEdit 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 TQtMultiLineEdit widgets are shown. - - \sa defaultTabStop() -*/ - -void TQtMultiLineEdit::setDefaultTabStop( int ex ) -{ - defTabStop = ex; -} - - - -/* - Returns the distance between tab stops. - - \sa setDefaultTabStop(); -*/ - -int TQtMultiLineEdit::defaultTabStop() -{ - return defTabStop; -} - - - - -static int textWidthWithTabs( const TQFontMetrics &fm, const TQString &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 == TQt::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 != TQt::AlignLeft || s[i] != '\t' ) ) - i++; - dist += fm.width( s.mid(ii,i-ii) ); - } - } - return dist; -} - -static int xPosToCursorPos( const TQString &s, const TQFontMetrics &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 == TQt::AlignCenter || align == TQt::AlignHCenter ) - dist = ( width - textWidthWithTabs( fm, s, 0, s.length(), align ) ) / 2; - else if ( align == TQt::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 == TQt::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 == TQt::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, TQtMultiLineEdit with parent \a parent and - called \a name. -*/ - -TQtMultiLineEdit::TQtMultiLineEdit( TQWidget *parent , const char *name ) - :TQtTableView( parent, name, WStaticContents | WRepaintNoErase ) -{ - d = new TQtMultiLineData; - TQFontMetrics fm( font() ); - setCellHeight( fm.lineSpacing() ); - setNumCols( 1 ); - - contents = new TQPtrList<TQtMultiLineEditRow>; - contents->setAutoDelete( TRUE ); - - cursorX = 0; cursorY = 0; - curXPos = 0; - - setTableFlags( Tbl_autoVScrollBar|Tbl_autoHScrollBar| - Tbl_smoothVScrolling | - Tbl_clipCellPainting - ); - setFrameStyle( TQFrame::WinPanel | TQFrame::Sunken ); - setBackgroundMode( PaletteBase ); - setWFlags( WResizeNoErase ); - setKeyCompression( TRUE ); - setFocusPolicy( WheelFocus ); -#ifndef TQT_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 TQTimer( this ); - connect( d->blinkTimer, TQT_SIGNAL( timeout() ), - this, TQT_SLOT( blinkTimerTimeout() ) ); - d->scrollTimer = new TQTimer( this ); - connect( d->scrollTimer, TQT_SIGNAL( timeout() ), - this, TQT_SLOT( scrollTimerTimeout() ) ); -#ifndef TQT_NO_DRAGANDDROP - d->dnd_timer = new TQTimer( this ); - connect( d->dnd_timer, TQT_SIGNAL( timeout() ), - this, TQT_SLOT( dndTimeout() ) ); -#endif - d->scrollTime = 0; - - dummy = TRUE; - - int w = textWidth( TQString::tqfromLatin1("") ); - contents->append( new TQtMultiLineEditRow(TQString::tqfromLatin1(""), w) ); - (void)setNumRowsAndTruncate(); - setWidth( w ); - setAcceptDrops(TRUE); - if ( d->maxlines >= 0 && d->maxlines <= 6 ) { - tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) ); - } else { - tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) ); - } -} - -/* - \fn int TQtMultiLineEdit::lineLength( int line ) const - Returns the number of characters at line number \a line. -*/ - -/* \fn TQString *TQtMultiLineEdit::getString( int line ) const - - Returns a pointer to the text at line \a line. -*/ - -/* \fn void TQtMultiLineEdit::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 TQtMultiLineEdit::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 TQtMultiLineEdit::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 TQtMultiLineEdit::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 TQtMultiLineEdit::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. -*/ - - -/* - If \a on is FALSE, this multi line edit accepts text input. - Scrolling and cursor movements are accepted in any case. - - \sa isReadOnly() TQWidget::setEnabled() -*/ - -void TQtMultiLineEdit::setReadOnly( bool on ) -{ - if ( readOnly != on ) { - readOnly = on; -#ifndef TQT_NO_CURSOR - setCursor( on ? arrowCursor : ibeamCursor ); -#endif - } -} - -/* -*/ -int TQtMultiLineEdit::maxLineWidth() const -{ - return d->maxLineWidth; -} - -/* - Destroys the TQtMultiLineEdit -*/ - -TQtMultiLineEdit::~TQtMultiLineEdit() -{ - delete contents; - delete d; -} - -static TQPixmap *buffer = 0; - -static void cleanupMLBuffer() -{ - delete buffer; - buffer = 0; -} - -static TQPixmap *getCacheBuffer( TQSize sz ) -{ - if ( !buffer ) { - qAddPostRoutine( cleanupMLBuffer ); - buffer = new TQPixmap; - } - - if ( buffer->width() < sz.width() || buffer->height() < sz.height() ) - buffer->resize( sz ); - return buffer; -} - -/* - Implements the basic drawing logic. Paints the line at row \a row - using painter \a painter. The \a col parameter is ignored. -*/ -void TQtMultiLineEdit::paintCell( TQPainter *painter, int row, int ) -{ - const TQColorGroup & g = tqcolorGroup(); - TQFontMetrics fm( painter->font() ); - TQString s = stringShown(row); - if ( s.isNull() ) { - qWarning( "TQtMultiLineEdit::paintCell: (%s) no text at line %d", - name( "unnamed" ), row ); - return; - } - TQRect updateR = cellUpdateRect(); - TQPixmap *buffer = getCacheBuffer( updateR.size() ); - ASSERT(buffer); - buffer->fill ( g.base() ); - - TQPainter 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 - } - } - } - } - p.setPen( g.text() ); - TQtMultiLineEditRow* 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 == TQt::AlignCenter || d->align == TQt::AlignHCenter ) - x += (wcell - wrow) / 2; - else if ( d->align == TQt::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( TQColorGroup::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 = TQMIN( (int)s.length(), cursorX ); - int cXPos = TQMAX( 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 ); - */ - 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 TQT_NO_TRANSFORMATIONS - // TODO: set it other times, eg. when scrollbar moves view - TQWMatrix wm = painter->tqworldMatrix(); - setMicroFocusHint( int(wm.dx()+cXPos), - int (wm.dy()+cYPos), - 1, fm.ascent() ); -#else - setMicroFocusHint( cXPos, - cYPos, - 1, fm.ascent() ); -#endif - } - } - p.end(); - painter->drawPixmap( updateR.left(), updateR.top(), *buffer, - 0, 0, updateR.width(), updateR.height() ); -} - - -/* - \overload - Returns the width in pixels of the string \a s. - NOTE: only appropriate for whole lines. -*/ - -int TQtMultiLineEdit::textWidth( const TQString &s ) -{ - int w = 0; - if ( !s.isNull() ) { - w = textWidthWithTabs( TQFontMetrics( 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 TQtMultiLineEdit::textWidth( int line ) -{ - if ( d->echomode == Password) { - TQString s = stringShown(line); - return textWidth( s ); - } - TQtMultiLineEditRow* r = contents->at(line); - return r?r->w:0; -} - -/* - Starts the cursor blinking. -*/ - -void TQtMultiLineEdit::focusInEvent( TQFocusEvent * ) -{ - stopAutoScroll(); - if ( !d->blinkTimer->isActive() ) - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); - cursorOn = TRUE; - updateCell( cursorY, 0, FALSE ); -} - - -/*\reimp -*/ -void TQtMultiLineEdit::leaveEvent( TQEvent * ) -{ -} - - -/*\reimp -*/ -void TQtMultiLineEdit::focusOutEvent( TQFocusEvent * ) -{ - stopAutoScroll(); - d->blinkTimer->stop(); - if ( cursorOn ) { - cursorOn = FALSE; - updateCell( cursorY, 0, FALSE ); - } -} - - -/* - \reimp - Present for binary compatibility only! -*/ - -void TQtMultiLineEdit::timerEvent( TQTimerEvent * ) -{ - // ############ Remove in 3.0!!!!!!!! -} - -#ifndef TQT_NO_DRAGANDDROP -void TQtMultiLineEdit::doDrag() -{ - if ( d->dnd_timer ) { - d->dnd_timer->stop(); - } - TQDragObject *drag_text = new TQTextDrag(markedText(), this); - if ( readOnly ) { - drag_text->dragCopy(); - } else { - if ( drag_text->drag() && TQDragObject::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 TQtMultiLineEdit::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 TQtMultiLineEdit::hasMarkedText() const -{ - return markIsOn; -} - - -/* - Returns a copy of the marked text. -*/ - -TQString TQtMultiLineEdit::markedText() const -{ - int markBeginX, markBeginY; - int markEndX, markEndY; - if ( !getMarkedRegion( &markBeginY, &markBeginX, &markEndY, &markEndX ) ) - return TQString(); - if ( markBeginY == markEndY ) { //just one line - TQString *s = getString( markBeginY ); - return s->mid( markBeginX, markEndX - markBeginX ); - } else { //multiline - TQString *firstS, *lastS; - firstS = getString( markBeginY ); - lastS = getString( markEndY ); - int i; - TQString 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 TQString::operator!() null string\endlink if \a line is invalid. -*/ - -TQString TQtMultiLineEdit::textLine( int line ) const -{ - TQString *s = getString(line); - if ( s ) { - if ( s->isNull() ) - return TQString::tqfromLatin1(""); - else - return *s; - } else - return TQString::null; -} - - -/* - Returns a copy of the whole text. If the multi line edit contains no - text, a - \link TQString::operator!() null string\endlink - is returned. -*/ - -TQString TQtMultiLineEdit::text() const -{ - TQString 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 TQtMultiLineEdit::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 TQtMultiLineEdit::deselect() -{ - turnMark( FALSE ); -} - - -/* - Sets the text to \a s, removing old text, if any. -*/ - -void TQtMultiLineEdit::setText( const TQString &s ) -{ - bool oldUndo = isUndoEnabled(); - setUndoEnabled( FALSE ); - bool oldAuto = autoUpdate(); - setAutoUpdate( FALSE ); - bool b = tqsignalsBlocked(); - blockSignals( TRUE ); - clear(); - CLEAR_UNDO - blockSignals( b ); - insertLine( s, -1 ); - emit textChanged(); - setAutoUpdate(oldAuto); - if ( autoUpdate() ) - update(); - setUndoEnabled( oldUndo ); -} - - -/* - Appends \a s to the text. -*/ - -void TQtMultiLineEdit::append( const TQString &s ) -{ - bool oldUndo = isUndoEnabled(); - setUndoEnabled( FALSE ); - insertLine( s, -1 ); - setUndoEnabled( oldUndo ); - emit textChanged(); -} - -/* \reimp -Passes wheel events to the vertical scrollbar. -*/ -void TQtMultiLineEdit::wheelEvent( TQWheelEvent *e ){ - TQApplication::sendEvent( verticalScrollBar(), e); -} - - -/* - The key press event handler converts a key press in event \a e to - some line editor action. - - Here are the default key bindings when isReadOnly() is FALSE: - \list - \i <i> Left Arrow </i> Move the cursor one character leftwards - \i <i> Right Arrow </i> Move the cursor one character rightwards - \i <i> Up Arrow </i> Move the cursor one line upwards - \i <i> Down Arrow </i> Move the cursor one line downwards - \i <i> Page Up </i> Move the cursor one page upwards - \i <i> Page Down </i> Move the cursor one page downwards - \i <i> Backspace </i> Delete the character to the left of the cursor - \i <i> Home </i> Move the cursor to the beginning of the line - \i <i> End </i> Move the cursor to the end of the line - \i <i> Delete </i> Delete the character to the right of the cursor - \i <i> Shift - Left Arrow </i> Mark text one character leftwards - \i <i> Shift - Right Arrow </i> Mark text one character rightwards - \i <i> Control-A </i> Move the cursor to the beginning of the line - \i <i> Control-B </i> Move the cursor one character leftwards - \i <i> Control-C </i> Copy the marked text to the clipboard - \i <i> Control-D </i> Delete the character to the right of the cursor - \i <i> Control-E </i> Move the cursor to the end of the line - \i <i> Control-F </i> Move the cursor one character rightwards - \i <i> Control-H </i> Delete the character to the left of the cursor - \i <i> Control-K </i> Delete to end of line - \i <i> Control-N </i> Move the cursor one line downwards - \i <i> Control-P </i> Move the cursor one line upwards - \i <i> Control-V </i> Paste the clipboard text into line edit - \i <i> Control-X </i> Cut the marked text, copy to clipboard - \i <i> Control-Z </i> Undo the last operation - \i <i> Control-Y </i> Redo the last operation - \i <i> Control - Left Arrow </i> Move the cursor one word leftwards - \i <i> Control - Right Arrow </i> Move the cursor one word rightwards - \i <i> Control - Up Arrow </i> Move the cursor one word upwards - \i <i> Control - Down Arrow </i> Move the cursor one word downwards - \i <i> Control - Home Arrow </i> Move the cursor to the beginning of the text - \i <i> Control - End Arrow </i> Move the cursor to the end of the text - \endlist - In addition, the following key bindings are used on Windows: - \list - \i <i> Shift - Delete </i> Cut the marked text, copy to clipboard - \i <i> Shift - Insert </i> Paste the clipboard text into line edit - \i <i> Control - Insert </i> Copy the marked text to the clipboard - \endlist - All other keys with valid ASCII codes insert themselves into the line. - - Here are the default key bindings when isReadOnly() is TRUE: - \list - \i <i> Left Arrow </i> Scrolls the table rightwards - \i <i> Right Arrow </i> Scrolls the table rightwards - \i <i> Up Arrow </i> Scrolls the table one line downwards - \i <i> Down Arrow </i> Scrolls the table one line upwards - \i <i> Page Up </i> Scrolls the table one page downwards - \i <i> Page Down </i> Scrolls the table one page upwards - \i <i> Control-C </i> Copy the marked text to the clipboard - \endlist - -*/ - -void TQtMultiLineEdit::keyPressEvent( TQKeyEvent *e ) -{ - textDirty = FALSE; - d->isHandlingEvent = TRUE; - int unknown = 0; - if ( readOnly ) { - int pageSize = viewHeight() / cellHeight(); - - switch ( e->key() ) { - case Key_Left: - setXOffset( xOffset() - viewWidth()/10 ); - break; - case Key_Right: - setXOffset( xOffset() + viewWidth()/10 ); - break; - case Key_Up: - setTopCell( topCell() - 1 ); - break; - case Key_Down: - setTopCell( topCell() + 1 ); - break; - case Key_Home: - setCursorPosition(0,0, e->state() & ShiftButton ); - break; - case Key_End: - setCursorPosition( numLines()-1, lineLength( numLines()-1 ), - e->state() & ShiftButton ); - break; - case Key_Next: - setTopCell( topCell() + pageSize ); - break; - case Key_Prior: - setTopCell( TQMAX( topCell() - pageSize, 0 ) ); - break; -#ifndef TQT_NO_CLIPBOARD - case Key_C: - if ( echoMode() == Normal && (e->state()&ControlButton) ) - copy(); - else - unknown++; - break; - case Key_F16: // Copy key on Sun keyboards - if ( echoMode() == Normal ) - copy(); - else - unknown++; - break; -#endif - default: - unknown++; - } - if ( unknown ) - e->ignore(); - d->isHandlingEvent = FALSE; - return; - } - if ( e->text().length() && - e->key() != Key_Return && - e->key() != Key_Enter && - e->key() != Key_Delete && - e->key() != Key_Backspace && - (!e->ascii() || e->ascii()>=32) - ) { - insert( e->text() ); - //TQApplication::sendPostedEvents( this, TQEvent::Paint ); - if ( textDirty ) - emit textChanged(); - d->isHandlingEvent = FALSE; - return; - } - if ( e->state() & ControlButton ) { - switch ( e->key() ) { - case Key_A: - home( e->state() & ShiftButton ); - break; - case Key_B: - cursorLeft( e->state() & ShiftButton ); - break; -#ifndef TQT_NO_CLIPBOARD - case Key_C: - if ( echoMode() == Normal ) - copy(); - break; -#endif - case Key_D: - del(); - break; - case Key_E: - end( e->state() & ShiftButton ); - break; - case Key_Left: - cursorWordBackward( e->state() & ShiftButton ); - break; - case Key_Right: - cursorWordForward( e->state() & ShiftButton ); - break; - case Key_Up: - cursorUp( e->state() & ShiftButton ); - break; - case Key_Down: - cursorDown( e->state() & ShiftButton ); - break; - case Key_Home: - setCursorPosition(0,0, e->state() & ShiftButton ); - break; - case Key_End: - setCursorPosition( numLines()-1, lineLength( numLines()-1 ), - e->state() & ShiftButton ); - break; - case Key_F: - cursorRight( e->state() & ShiftButton ); - break; - case Key_H: - backspace(); - break; - case Key_K: - killLine(); - break; - case Key_N: - cursorDown( e->state() & ShiftButton ); - break; - case Key_P: - cursorUp( e->state() & ShiftButton ); - break; -#ifndef TQT_NO_CLIPBOARD - case Key_V: - paste(); - break; - case Key_X: - cut(); - break; -#endif - case Key_Z: - undo(); - break; - case Key_Y: - redo(); - break; -#if defined (_WS_WIN_) - case Key_Insert: - copy(); -#endif - default: - unknown++; - } - } else { - switch ( e->key() ) { - case Key_Left: - cursorLeft( e->state() & ShiftButton ); - break; - case Key_Right: - cursorRight( e->state() & ShiftButton ); - break; - case Key_Up: - cursorUp( e->state() & ShiftButton ); - break; - case Key_Down: - cursorDown( e->state() & ShiftButton ); - break; - case Key_Backspace: - backspace(); - break; - case Key_Home: - home( e->state() & ShiftButton ); - break; - case Key_End: - end( e->state() & ShiftButton ); - break; - case Key_Delete: -#if defined (_WS_WIN_) - if ( e->state() & ShiftButton ) { - cut(); - break; - } -#endif - del(); - break; - case Key_Next: - pageDown( e->state() & ShiftButton ); - break; - case Key_Prior: - pageUp( e->state() & ShiftButton ); - break; - case Key_Enter: - case Key_Return: - newLine(); - emit returnPressed(); - break; - case Key_Tab: - insert( e->text() ); - break; -#if defined (_WS_WIN_) - case Key_Insert: - if ( e->state() & ShiftButton ) - paste(); - else - unknown++; - break; -#endif - case Key_F14: // Undo key on Sun keyboards - undo(); - break; -#ifndef TQT_NO_CLIPBOARD - case Key_F16: // Copy key on Sun keyboards - if ( echoMode() == Normal ) - copy(); - break; - case Key_F18: // Paste key on Sun keyboards - paste(); - break; - case Key_F20: // Paste key on Sun keyboards - cut(); - break; -#endif - default: - unknown++; - } - } - if ( textDirty ) - emit textChanged(); - - if ( unknown ) // unknown key - e->ignore(); - - d->isHandlingEvent = FALSE; -} - - -/* - Moves the cursor one page down. If \a mark is TRUE, the text - is marked. -*/ - -void TQtMultiLineEdit::pageDown( bool mark ) -{ - bool oldAuto = autoUpdate(); - if ( mark ) - setAutoUpdate( FALSE ); - - if ( partiallyInvisible( cursorY ) ) - cursorY = topCell(); - int delta = cursorY - topCell(); - int pageSize = viewHeight() / cellHeight(); - int newTopCell = TQMIN( topCell() + pageSize, numLines() - 1 - pageSize ); - - if ( pageSize >= numLines() ) { // quick fix to handle small texts - newTopCell = topCell(); - } - if ( !curXPos ) - curXPos = mapToView( cursorX, cursorY ); - int oldY = cursorY; - - if ( mark && !hasMarkedText() ) { - markAnchorX = cursorX; - markAnchorY = cursorY; - } - if ( newTopCell != topCell() ) { - cursorY = newTopCell + delta; - cursorX = mapFromView( curXPos, cursorY ); - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - setTopCell( newTopCell ); - } else if ( cursorY != (int)contents->count() - 1) { // just move the cursor - cursorY = TQMIN( cursorY + pageSize, numLines() - 1); - cursorX = mapFromView( curXPos, cursorY ); - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - makeVisible(); - } - if ( oldAuto ) - if ( mark ) { - setAutoUpdate( TRUE ); - update(); - } else { - updateCell( oldY, 0, FALSE ); - } - if ( !mark ) - turnMark( FALSE ); -} - - -/* - Moves the cursor one page up. If \a mark is TRUE, the text - is marked. -*/ - -void TQtMultiLineEdit::pageUp( bool mark ) -{ - bool oldAuto = autoUpdate(); - if ( mark ) - setAutoUpdate( FALSE ); - if ( partiallyInvisible( cursorY ) ) - cursorY = topCell(); - int delta = cursorY - topCell(); - int pageSize = viewHeight() / cellHeight(); - bool partial = delta == pageSize && viewHeight() != pageSize * cellHeight(); - int newTopCell = TQMAX( topCell() - pageSize, 0 ); - if ( pageSize > numLines() ) { // quick fix to handle small texts - newTopCell = 0; - delta = 0; - } - if ( mark && !hasMarkedText() ) { - markAnchorX = cursorX; - markAnchorY = cursorY; - } - if ( !curXPos ) - curXPos = mapToView( cursorX, cursorY ); - int oldY = cursorY; - if ( newTopCell != topCell() ) { - cursorY = TQMIN( newTopCell + delta, numLines() - 1 ); - if ( partial ) - cursorY--; - cursorX = mapFromView( curXPos, cursorY ); - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - setTopCell( newTopCell ); - } else { // just move the cursor - cursorY = TQMAX( cursorY - pageSize, 0 ); - cursorX = mapFromView( curXPos, cursorY ); - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - } - if ( oldAuto ) - if ( mark ) { - setAutoUpdate( TRUE ); - update(); - } else { - updateCell( oldY, 0, FALSE ); - } - if ( !mark ) - turnMark( FALSE ); -} - -// THE CORE INSERTION FUNCTION -void TQtMultiLineEdit::insertAtAux( const TQString &txt, int line, int col, bool mark ) -{ - dummy = FALSE; - d->blinkTimer->stop(); - cursorOn = TRUE; - int oldw = contentsRect().width(); - - line = TQMAX( TQMIN( line, numLines() - 1), 0 ); - col = TQMAX( TQMIN( col, lineLength( line )), 0 ); - - TQString itxt = txt; - TQtMultiLineEditRow *row = contents->at( line ); - if ( d->maxlen >= 0 && length() + int(txt.length()) > d->maxlen ) - itxt.truncate( d->maxlen - length() ); - - row->s.insert( uint(col), itxt ); - - if ( mark ) { - markAnchorX = col; - markAnchorY = line; - } - if ( cursorX == col && cursorY == line ) { - cursorX += itxt.length(); - } - TQFontMetrics fm( font() ); - if ( !WORD_WRAP || ( col == 0 && itxt.contains('\n') == int(itxt.length())) ) - wrapLine( line, 0 ); - else if ( WORD_WRAP && itxt.find('\n')<0 && itxt.find('\t')<0 - && ( - ( DYNAMIC_WRAP && fm.width( itxt ) + row->w < contentsRect().width() - 2*d->lr_marg - d->marg_extra ) - || - ( FIXED_WIDTH_WRAP && ( d->wrapcol < 0 || fm.width( itxt ) + row->w < d->wrapcol ) ) - || - ( FIXED_COLUMN_WRAP && ( d->wrapcol < 0 || int(row->s.length()) < d->wrapcol ) ) - ) - && ( itxt.find(' ') < 0 || row->s.find(' ') >= 0 && row->s.find(' ') < col ) ){ - row->w = textWidth( row->s ); - setWidth( TQMAX( maxLineWidth(), row->w) ); - updateCell( line, 0, FALSE ); - } - else { - if ( line > 0 && !contents->at( line-1)->newline ) - rebreakParagraph( line-1 ); - else - rebreakParagraph( line ); - } - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - - setNumRowsAndTruncate(); - - textDirty = TRUE; - d->edited = TRUE; - if ( autoUpdate() ) { - makeVisible(); - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); - if ( DYNAMIC_WRAP && oldw != contentsRect().width() ) { - setAutoUpdate( FALSE ); - rebreakAll(); - setAutoUpdate( TRUE ); - update(); - } - } -} - - -/* - Inserts \a txt at line number \a line. If \a line is less than zero, - or larger than the number of rows, the new text is put at the end. - If \a txt contains newline characters, several lines are inserted. - - The cursor position is not changed. -*/ - -void TQtMultiLineEdit::insertLine( const TQString &txt, int line ) -{ - TQString s = txt; - int oldXPos = cursorX; - int oldYPos = cursorY; - if ( line < 0 || line >= int( contents->count() ) ) { - if ( !dummy ) - contents->append( new TQtMultiLineEditRow(TQString::tqfromLatin1(""), 0) ); - insertAt( s, numLines()-1, 0 ); - } else { - s.append('\n'); - insertAt( s, line, 0 ); - } - cursorX = oldXPos; - cursorY = oldYPos; -} - -/* - Deletes the line at line number \a line. If \a - line is less than zero, or larger than the number of lines, - no line is deleted. -*/ - -void TQtMultiLineEdit::removeLine( int line ) -{ - CLEAR_UNDO - if ( line >= numLines() ) - return; - if ( cursorY >= line && cursorY > 0 ) - cursorY--; - bool updt = autoUpdate() && rowIsVisible( line ); - TQtMultiLineEditRow* r = contents->at( line ); - ASSERT( r ); - bool recalc = r->w == maxLineWidth(); - contents->remove( line ); - if ( contents->count() == 0 ) { - int w = textWidth( TQString::tqfromLatin1("") ); - contents->append( new TQtMultiLineEditRow(TQString::tqfromLatin1(""), w) ); - setWidth( w ); - dummy = TRUE; - } - if ( setNumRowsAndTruncate() ) - recalc = updt = FALSE; - if ( recalc ) - updateCellWidth(); - makeVisible(); - if (updt) - update(); - textDirty = TRUE; - d->edited = TRUE; -} - -/* - Inserts \a s at the current cursor position. -*/ -void TQtMultiLineEdit::insert( const TQString& s ) -{ - insert( s, FALSE ); -} - -/* - Inserts \a c at the current cursor position. - (this function is provided for backward compatibility - - it simply calls insert()). -*/ -void TQtMultiLineEdit::insertChar( TQChar c ) -{ - insert(c); -} - -/* - \overload - Inserts string \a str at the current cursor position. If \a mark is - TRUE the string is marked. -*/ - -void TQtMultiLineEdit::insert( const TQString& str, bool mark ) -{ - dummy = FALSE; - bool wasMarkedText = hasMarkedText(); - if ( wasMarkedText ) - addUndoCmd( new TQBeginCommand ); - if ( wasMarkedText ) - del(); // ## Will flicker - TQString *s = getString( cursorY ); - if ( cursorX > (int)s->length() ) - cursorX = s->length(); - else if ( overWrite && !wasMarkedText && cursorX < (int)s->length() ) - del(); // ## Will flicker - insertAt(str, cursorY, cursorX, mark ); - makeVisible(); - - if ( wasMarkedText ) - addUndoCmd( new TQEndCommand() ); -} - -/* - Makes a line break at the current cursor position. -*/ - -void TQtMultiLineEdit::newLine() -{ - insert("\n"); -} - -/* - Deletes text from the current cursor position to the end of the line. -*/ - -void TQtMultiLineEdit::killLineAux() -{ - deselect(); // -sanders Don't let del() delete marked region - TQtMultiLineEditRow* r = contents->at( cursorY ); - if ( cursorX == (int)r->s.length() ) { - // if (r->newline) // -sanders Only del newlines! - del(); - return; - } else { - bool recalc = r->w == maxLineWidth(); - r->s.remove( cursorX, r->s.length() ); - r->w = textWidth( r->s ); - updateCell( cursorY, 0, FALSE ); - if ( recalc ) - updateCellWidth(); - rebreakParagraph( cursorY ); // -sanders - textDirty = TRUE; - d->edited = TRUE; - } - curXPos = 0; - makeVisible(); - turnMark( FALSE ); -} - - -/* - Moves the cursor one character to the left. If \a mark is TRUE, the text - is marked. If \a wrap is TRUE, the cursor moves to the end of the - previous line if it is placed at the beginning of the current line. - - \sa cursorRight() cursorUp() cursorDown() -*/ - -void TQtMultiLineEdit::cursorLeft( bool mark, bool wrap ) -{ - cursorLeft(mark,!mark,wrap); -} -void TQtMultiLineEdit::cursorLeft( bool mark, bool clear_mark, bool wrap ) -{ - if ( cursorX != 0 || cursorY != 0 && wrap ) { - if ( mark && !hasMarkedText() ) { - markAnchorX = cursorX; - markAnchorY = cursorY; - } - d->blinkTimer->stop(); - int ll = lineLength( cursorY ); - if ( cursorX > ll ) - cursorX = ll; - cursorOn = TRUE; - cursorX--; - if ( cursorX < 0 ) { - int oldY = cursorY; - if ( cursorY > 0 ) { - cursorY--; - cursorX = lineLength( cursorY ); - if ( cursorX > 1 && !isEndOfParagraph( cursorY ) ) - cursorX--; - } else { - cursorY = 0; //### ? - cursorX = 0; - } - updateCell( oldY, 0, FALSE ); - } - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); - updateCell( cursorY, 0, FALSE ); - } - curXPos = 0; - makeVisible(); - if ( clear_mark ) - turnMark( FALSE ); -} - -/* - Moves the cursor one character to the right. If \a mark is TRUE, the text - is marked. If \a wrap is TRUE, the cursor moves to the beginning of the next - line if it is placed at the end of the current line. - \sa cursorLeft() cursorUp() cursorDown() -*/ - -void TQtMultiLineEdit::cursorRight( bool mark, bool wrap ) -{ - cursorRight(mark,!mark,wrap); -} -void TQtMultiLineEdit::cursorRight( bool mark, bool clear_mark, bool wrap ) -{ - int strl = lineLength( cursorY ); - if ( strl > 1 && !isEndOfParagraph( cursorY ) ) - strl--; - if ( cursorX < strl || cursorY < (int)contents->count() - 1 && wrap ) { - if ( mark && !hasMarkedText() ) { - markAnchorX = cursorX; - markAnchorY = cursorY; - } - d->blinkTimer->stop(); - cursorOn = TRUE; - cursorX++; - if ( cursorX > strl ) { - int oldY = cursorY; - if ( cursorY < (int) contents->count() - 1 ) { - cursorY++; - cursorX = 0; - } else { - cursorX = lineLength( cursorY ); - } - updateCell( oldY, 0, FALSE ); - } - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - updateCell( cursorY, 0, FALSE ); - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); - } - curXPos = 0; - makeVisible(); - if ( clear_mark ) - turnMark( FALSE ); -} - -/* - Moves the cursor up one line. If \a mark is TRUE, the text - is marked. - \sa cursorDown() cursorLeft() cursorRight() -*/ - -void TQtMultiLineEdit::cursorUp( bool mark ) -{ - cursorUp(mark,!mark); -} -void TQtMultiLineEdit::cursorUp( bool mark, bool clear_mark ) -{ - if ( cursorY != 0 ) { - if ( mark && !hasMarkedText() ) { - markAnchorX = cursorX; - markAnchorY = cursorY; - } - if ( !curXPos ) - curXPos = mapToView( cursorX, cursorY ); - int oldY = cursorY; - d->blinkTimer->stop(); - cursorOn = TRUE; - cursorY--; - if ( cursorY < 0 ) { - cursorY = 0; - } - cursorX = mapFromView( curXPos, cursorY ); - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - updateCell( oldY, 0, FALSE ); - updateCell( cursorY, 0, FALSE ); - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); - } - makeVisible(); - if ( clear_mark ) - turnMark( FALSE ); -} - -/* - Moves the cursor one line down. If \a mark is TRUE, the text - is marked. - \sa cursorUp() cursorLeft() cursorRight() -*/ - -void TQtMultiLineEdit::cursorDown( bool mark ) -{ - cursorDown(mark,!mark); -} -void TQtMultiLineEdit::cursorDown( bool mark, bool clear_mark ) -{ - int lastLin = contents->count() - 1; - if ( cursorY != lastLin ) { - if ( mark && !hasMarkedText() ) { - markAnchorX = cursorX; - markAnchorY = cursorY; - } - if ( !curXPos ) - curXPos = mapToView( cursorX, cursorY ); - int oldY = cursorY; - d->blinkTimer->stop(); - cursorOn = TRUE; - cursorY++; - if ( cursorY > lastLin ) { - cursorY = lastLin; - } - cursorX = mapFromView( curXPos, cursorY ); - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - updateCell( oldY, 0, FALSE ); - updateCell( cursorY, 0, FALSE ); - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); - } - makeVisible(); - if ( clear_mark ) - turnMark( FALSE ); -} - -/* - Turns off marked text -*/ -void TQtMultiLineEdit::turnMark( bool on ) -{ - if ( on != markIsOn ) { - markIsOn = on; - if ( echoMode() == Normal ) - emit copyAvailable( on ); - update(); - } -} - - - - -/* - Deletes the character on the left side of the text cursor and moves - the cursor one position to the left. If a text has been marked by - the user (e.g. by clicking and dragging) the cursor is put at the - beginning of the marked text and the marked text is removed. - \sa del() -*/ - -void TQtMultiLineEdit::backspace() -{ - if ( hasMarkedText() ) { - del(); - } else { - if ( !atBeginning() ) { - cursorLeft( FALSE ); - del(); - } - } - makeVisible(); -} - -void TQtMultiLineEdit::delAux() -{ - int markBeginX, markBeginY; - int markEndX, markEndY; - TQRect oldContents = contentsRect(); - if ( getMarkedRegion( &markBeginY, &markBeginX, &markEndY, &markEndX ) ) { - turnMark( FALSE ); - textDirty = TRUE; - d->edited = TRUE; - if ( markBeginY == markEndY ) { //just one line - TQtMultiLineEditRow *r = contents->at( markBeginY ); - ASSERT(r); - bool recalc = r->w == maxLineWidth(); - r->s.remove( markBeginX, markEndX - markBeginX ); - r->w = textWidth( r->s ); - cursorX = markBeginX; - cursorY = markBeginY; - - if (autoUpdate() ) - updateCell( cursorY, 0, FALSE ); - if ( recalc ) - updateCellWidth(); - } else { //multiline - bool oldAuto = autoUpdate(); - setAutoUpdate( FALSE ); - ASSERT( markBeginY >= 0); - ASSERT( markEndY < (int)contents->count() ); - - TQtMultiLineEditRow *firstR, *lastR; - firstR = contents->at( markBeginY ); - lastR = contents->at( markEndY ); - ASSERT( firstR != lastR ); - firstR->s.remove( markBeginX, firstR->s.length() - markBeginX ); - lastR->s.remove( 0, markEndX ); - firstR->s.append( lastR->s ); // lastS will be removed in loop below - firstR->newline = lastR->newline; // Don't forget this -sanders - firstR->w = textWidth( firstR->s ); - - for( int i = markBeginY + 1 ; i <= markEndY ; i++ ) - contents->remove( markBeginY + 1 ); - - if ( contents->isEmpty() ) - insertLine( TQString::tqfromLatin1(""), -1 ); - - cursorX = markBeginX; - cursorY = markBeginY; - curXPos = 0; - - setNumRowsAndTruncate(); - updateCellWidth(); - setAutoUpdate( oldAuto ); - if ( autoUpdate() ) - update(); - } - markAnchorY = markDragY = cursorY; - markAnchorX = markDragX = cursorX; - } else { - if ( !atEnd() ) { - textDirty = TRUE; - d->edited = TRUE; - TQtMultiLineEditRow *r = contents->at( cursorY ); - if ( cursorX == (int) r->s.length() ) { // remove newline - TQtMultiLineEditRow* other = contents->at( cursorY + 1 ); - if ( ! r->newline && cursorX ) - r->s.truncate( r->s.length()-1 ); - - bool needBreak = !r->s.isEmpty(); - r->s += other->s; - r->newline = other->newline; - contents->remove( cursorY + 1 ); - if ( needBreak ) - rebreakParagraph( cursorY, 1 ); - else - wrapLine( cursorY, 1 ); - } else { - bool recalc = r->w == maxLineWidth(); - r->s.remove( cursorX, 1 ); - rebreakParagraph( cursorY ); - if ( recalc ) - updateCellWidth(); - } - } - } - if ( DYNAMIC_WRAP && oldContents != contentsRect() ) { - if ( oldContents.width() != contentsRect().width() ) { - bool oldAuto = autoUpdate(); - setAutoUpdate( FALSE ); - rebreakAll(); - setAutoUpdate( oldAuto ); - } - if ( autoUpdate() ) - update(); - } - curXPos = 0; - makeVisible(); -} - -/* - Moves the text cursor to the left end of the line. If \a mark is - TRUE, text is marked towards the first position. If it is FALSE and - the cursor is moved, all marked text is unmarked. - - \sa end() -*/ - -void TQtMultiLineEdit::home( bool mark ) -{ - if ( cursorX != 0 ) { - if ( mark && !hasMarkedText() ) { - markAnchorX = cursorX; - markAnchorY = cursorY; - } - d->blinkTimer->stop(); - cursorX = 0; - cursorOn = TRUE; - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - updateCell( cursorY, 0, FALSE ); - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); - } - curXPos = 0; - if ( !mark ) - turnMark( FALSE ); - makeVisible(); -} - -/* - Moves the text cursor to the right end of the line. If \a mark is TRUE - text is marked towards the last position. If it is FALSE and the - cursor is moved, all marked text is unmarked. - - \sa home() -*/ - -void TQtMultiLineEdit::end( bool mark ) -{ - int tlen = lineLength( cursorY ); - if ( cursorX != tlen ) { - if ( mark && !hasMarkedText() ) { - markAnchorX = cursorX; - markAnchorY = cursorY; - } - d->blinkTimer->stop(); - cursorX = tlen; - cursorOn = TRUE; - if ( mark ) - newMark( cursorX, cursorY, FALSE ); - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); - updateCell( cursorY, 0, FALSE ); - } - curXPos = 0; - makeVisible(); - if ( !mark ) - turnMark( FALSE ); -} - -/*\reimp -*/ -void TQtMultiLineEdit::mousePressEvent( TQMouseEvent *e ) -{ - stopAutoScroll(); - d->dnd_startpos = e->pos(); - - if ( e->button() == RightButton ) { - TQPopupMenu *popup = new TQPopupMenu( this ); - int id[ (int)IdCount ]; - id[ IdUndo ] = popup->insertItem( tr( "Undo" ) ); - id[ IdRedo ] = popup->insertItem( tr( "Redo" ) ); - popup->insertSeparator(); -#ifndef TQT_NO_CLIPBOARD - id[ IdCut ] = popup->insertItem( tr( "Cut" ) ); - id[ IdCopy ] = popup->insertItem( tr( "Copy" ) ); - id[ IdPaste ] = popup->insertItem( tr( "Paste" ) ); -#ifndef TQT_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 TQT_NO_CLIPBOARD - popup->setItemEnabled( id[ IdCut ], - !isReadOnly() && hasMarkedText() ); - popup->setItemEnabled( id[ IdCopy ], hasMarkedText() ); - popup->setItemEnabled( id[ IdPaste ], - !isReadOnly() && (bool)TQApplication::clipboard()->text().length() ); -#ifndef TQT_NO_MIMECLIPBOARD - // Any non-plain types? - TQMimeSource* ms = TQApplication::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 TQT_NO_CLIPBOARD - else if ( r == id[ IdCut ] ) - cut(); - else if ( r == id[ IdCopy ] ) - copy(); - else if ( r == id[ IdPaste ] ) - paste(); -# ifndef TQT_NO_MIMECLIPBOARD - else if ( r == id[ IdPasteSpecial ] ) - pasteSpecial(TQCursor::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 TQT_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( TQApplication::startDragTime(), FALSE ); - } else -#endif - { - wordMark = FALSE; - dragMarking = TRUE; - setCursorPixelPosition(e->pos()); - } -} - -void TQtMultiLineEdit::pixelPosToCursorPos(TQPoint 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 = TQMIN( (int)contents->count() - 1, *y ); - TQFontMetrics fm( font() ); - *x = xPosToCursorPos( stringShown( *y ), fm, - p.x() - d->lr_marg + xOffset(), - cellWidth() - 2 * d->lr_marg - d->marg_extra, - d->align ); - TQtMultiLineEditRow* r = contents->at( *y ); - if (r && !r->newline && ((unsigned int)*x == r->s.length()) && (*x > 0)) - --*x; -} - -void TQtMultiLineEdit::setCursorPixelPosition(TQPoint 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 TQtMultiLineEdit::startAutoScroll() -{ - if ( !dragScrolling ) { - d->scrollTime = initialScrollTime; - d->scrollAccel = initialScrollAccel; - d->scrollTimer->start( d->scrollTime, FALSE ); - dragScrolling = TRUE; - } -} - -void TQtMultiLineEdit::stopAutoScroll() -{ - if ( dragScrolling ) { - d->scrollTimer->stop(); - dragScrolling = FALSE; - } -} - -/*\reimp -*/ -void TQtMultiLineEdit::mouseMoveEvent( TQMouseEvent *e ) -{ -#ifndef TQT_NO_DRAGANDDROP - d->dnd_timer->stop(); - if ( d->dnd_primed && - ( d->dnd_startpos - e->pos() ).manhattanLength() > TQApplication::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 = TQMIN(oldY,newY); i <= TQMAX(oldY,newY); i++ ) - updateCell( i, 0, FALSE ); -} - -void TQtMultiLineEdit::extendSelectionWord( int &newX, int&newY) -{ - TQString 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 TQtMultiLineEdit::mouseReleaseEvent( TQMouseEvent *e ) -{ - stopAutoScroll(); -#ifndef TQT_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 TQT_NO_CLIPBOARD -#if defined(_WS_X11_) - else if ( echoMode() == Normal ) - copy(); -#endif - - if ( e->button() == MidButton && !readOnly ) { -#if defined(_WS_X11_) - paste(); // Will tqrepaint the cursor line. -#else -#ifndef TQT_NO_COMPAT - if ( style().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle ) - paste(); -#endif -#endif - } -#endif - - d->isHandlingEvent = FALSE; - - if ( !readOnly && textDirty ) - emit textChanged(); -} - - -/*\reimp -*/ -void TQtMultiLineEdit::mouseDoubleClickEvent( TQMouseEvent *m ) -{ - 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 TQT_NO_DRAGANDDROP - -/* - \reimp -*/ - -void TQtMultiLineEdit::dragEnterEvent( TQDragEnterEvent * ) -{ - cursorOn = TRUE; - updateCell( cursorY, 0, FALSE ); -} - -/*\reimp -*/ -void TQtMultiLineEdit::dragMoveEvent( TQDragMoveEvent* event ) -{ - if ( readOnly ) return; - event->accept( TQTextDrag::canDecode(event) ); - d->dnd_forcecursor = TRUE; - setCursorPixelPosition(event->pos(), FALSE); - d->dnd_forcecursor = FALSE; - TQRect 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() == TQDropEvent::Move ) - event->acceptAction(); -} - -/*\reimp -*/ -void TQtMultiLineEdit::dragLeaveEvent( TQDragLeaveEvent* ) -{ - if ( cursorOn ) { - cursorOn = FALSE; - updateCell( cursorY, 0, FALSE ); - } - stopAutoScroll(); -} - -/*\reimp -*/ -void TQtMultiLineEdit::dropEvent( TQDropEvent* event ) -{ - if ( readOnly ) return; - TQString text; - TQCString fmt = pickSpecial(event,FALSE,event->pos()); - if ( TQTextDrag::decode(event, text, fmt) ) { - int i = -1; - while ( ( i = text.find( '\r' ) ) != -1 ) - text.replace( i,1,"" ); - if ( event->source() == this && event->action() == TQDropEvent::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 TQBeginCommand ); - del(); - setCursorPosition(newY, newX); - insert(text, TRUE); - addUndoCmd( new TQEndCommand ); - } else if ( beforeMark( newX, newY ) ) { - // Easy - addUndoCmd( new TQBeginCommand ); - del(); - setCursorPosition(newY, newX); - insert(text, TRUE); - addUndoCmd( new TQEndCommand ); - } else { - // Do nothing. - } - } else { - setCursorPixelPosition(event->pos()); - insert(text, TRUE); - } - update(); - emit textChanged(); - } -} - -#endif // TQT_NO_DRAGANDDROP - - -/* - Returns TRUE if line \a line is invisible or partially invisible. -*/ - -bool TQtMultiLineEdit::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 TQtMultiLineEdit::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 TQtMultiLineEdit::mapFromView( int xPos, int line ) -{ - TQString s = stringShown( line ); - if ( !s ) - return 0; - TQFontMetrics fm( font() ); - int index = xPosToCursorPos( s, fm, - xPos - d->lr_marg, - cellWidth() - 2 * d->lr_marg - d->marg_extra, - d->align ); - TQtMultiLineEditRow* 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 TQtMultiLineEdit::mapToView( int xIndex, int line ) -{ - TQString s = stringShown( line ); - xIndex = TQMIN( (int)s.length(), xIndex ); - TQFontMetrics 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 == TQt::AlignCenter || d->align == TQt::AlignHCenter ) - w += (wcell - wrow) / 2; - else if ( d->align == TQt::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 TQtMultiLineEdit::updateCellWidth() -{ - TQtMultiLineEditRow* 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 = TQMAX(l, r->s.length() ); - r = contents->next(); - } - TQString t; - t.fill(TQChar('*'), l); - maxW = textWidth(t); - } - break; - case NoEcho: - maxW = textWidth(TQString::tqfromLatin1("")); - } - setWidth( maxW ); -} - - -/* - Sets the bottommost visible line to \a line. -*/ - -void TQtMultiLineEdit::setBottomCell( int line ) -{ - int rowY = cellHeight() * line; - int newYPos = rowY + cellHeight() - viewHeight(); - setYOffset( TQMAX( newYPos, 0 ) ); -} - -#ifndef TQT_NO_CLIPBOARD - -/* - Copies text in MIME subtype \a subtype from the clipboard onto the current - cursor position. - Any marked text is first deleted. -*/ -void TQtMultiLineEdit::pasteSubType(const TQCString& subtype) -{ - TQCString st = subtype; - addUndoCmd( new TQBeginCommand ); - - if ( hasMarkedText() ) - del(); - TQString t = TQApplication::clipboard()->text(st); - if ( !t.isEmpty() ) { - if ( hasMarkedText() ) - turnMark( FALSE ); - -#if defined(_OS_WIN32_) - // Need to convert CRLF to NL - t.replace( "\r\n", "\n" ); -#endif - - for (int i=0; (uint)i<t.length(); i++) { - if ( t[i] < ' ' && t[i] != '\n' && t[i] != '\t' ) - t[i] = ' '; - } - insertAt( t, cursorY, cursorX ); - turnMark( FALSE ); - curXPos = 0; - makeVisible(); - } - if ( textDirty && !d->isHandlingEvent ) - emit textChanged(); - - addUndoCmd( new TQEndCommand ); -} - -/* - Copies plain text from the clipboard onto the current cursor position. - Any marked text is first deleted. -*/ -void TQtMultiLineEdit::paste() -{ - pasteSubType("plain"); -} - -#ifndef TQT_NO_MIMECLIPBOARD -/* - Prompts the user for a type from a list of text types available, - Then copies text from the clipboard onto the current cursor position. - Any marked text is first deleted. -*/ -void TQtMultiLineEdit::pasteSpecial(const TQPoint& pt) -{ - TQCString st = pickSpecial(TQApplication::clipboard()->data(),TRUE,pt); - if ( !st.isEmpty() ) - pasteSubType(st); -} -#endif -#ifndef TQT_NO_MIME -TQCString TQtMultiLineEdit::pickSpecial(TQMimeSource* ms, bool always_ask, const TQPoint& pt) -{ - if ( ms ) { - TQPopupMenu popup(this); - TQString fmt; - int n=0; - TQDict<void> done; - for (int i=0; !(fmt=ms->format(i)).isNull(); i++) { - int semi=fmt.find(";"); - if ( semi >= 0 ) - fmt = fmt.left(semi); - if ( fmt.left(5) == "text/" ) { - fmt = fmt.mid(5); - if ( !done.find(fmt) ) { - done.insert(fmt,(void*)1); - popup.insertItem(fmt,i); - n++; - } - } - } - if ( n ) { - int i = n==1 && !always_ask ? popup.idAt(0) : popup.exec(pt); - if ( i >= 0 ) - return popup.text(i).latin1(); - } - } - return TQCString(); -} -#endif // TQT_NO_MIME -#endif // TQT_NO_CLIPBOARD - - -/* - Removes all text. -*/ - -void TQtMultiLineEdit::clear() -{ - addUndoCmd( new TQDelTextCmd( 0, text() ) ); - setEdited( TRUE ); - contents->clear(); - cursorX = cursorY = 0; - int w = textWidth( TQString::tqfromLatin1("") ); - contents->append( new TQtMultiLineEditRow(TQString::tqfromLatin1(""), w) ); - setNumRowsAndTruncate(); - setWidth( w ); - dummy = TRUE; - turnMark( FALSE ); - if ( autoUpdate() ) - update(); - if ( !d->isHandlingEvent ) //# && not already empty - emit textChanged(); - update(); -} - - -/*\reimp -*/ - -void TQtMultiLineEdit::setFont( const TQFont &font ) -{ - TQWidget::setFont( font ); - d->clearChartable(); - TQFontMetrics fm( font ); - setCellHeight( fm.lineSpacing() ); - for ( TQtMultiLineEditRow* r = contents->first(); r; r = contents->next() ) - r->w = textWidth( r->s ); - rebreakAll(); - updateCellWidth(); -} - -/* - Sets a new marked text limit, does not tqrepaint the widget. -*/ - -void TQtMultiLineEdit::newMark( int posx, int posy, bool /*copy*/ ) -{ - if ( markIsOn && markDragX == posx && markDragY == posy && - cursorX == posx && cursorY == posy ) - return; - markDragX = posx; - markDragY = posy; - cursorX = posx; - cursorY = posy; - turnMark( markDragX != markAnchorX || markDragY != markAnchorY ); -} - -bool TQtMultiLineEdit::beforeMark( int posx, int posy ) const -{ - int x1, y1, x2, y2; - if ( !getMarkedRegion( &y1, &x1, &y2, &x2 ) ) - return FALSE; - return - (y1 > posy || y1 == posy && x1 > posx) - && (y2 > posy || y2 == posy && x2 > posx); -} - -bool TQtMultiLineEdit::afterMark( int posx, int posy ) const -{ - int x1, y1, x2, y2; - if ( !getMarkedRegion( &y1, &x1, &y2, &x2 ) ) - return FALSE; - return - (y1 < posy || y1 == posy && x1 < posx) - && (y2 < posy || y2 == posy && x2 < posx); -} - -bool TQtMultiLineEdit::inMark( int posx, int posy ) const -{ - int x1, y1, x2, y2; - if ( !getMarkedRegion( &y1, &x1, &y2, &x2 ) ) - return FALSE; - return - (y1 < posy || y1 == posy && x1 <= posx) - && (y2 > posy || y2 == posy && x2 >= posx); -} - -/* - Marks the word at character position \a posx, \a posy. - */ -void TQtMultiLineEdit::markWord( int posx, int posy ) -{ - TQString& s = contents->at( posy )->s; - - int i = posx - 1; - while ( i >= 0 && s[i].isPrint() && !s[i].isSpace() ) - i--; - i++; - markAnchorY = posy; - markAnchorX = i; - - while ( s[i].isPrint() && !s[i].isSpace() ) - i++; - markDragX = i; - markDragY = posy; - turnMark( markDragX != markAnchorX || markDragY != markAnchorY ); - -#ifndef TQT_NO_CLIPBOARD -#if defined(_WS_X11_) - if ( echoMode() == Normal ) - copy(); -#endif -#endif -} - -/* - This may become a protected virtual member in a future TQt. - This implementation is an example of a useful classification - that aids selection of common units like filenames and URLs. -*/ -int TQtMultiLineEdit::charClass( TQChar ch ) -{ - if ( !ch.isPrint() || ch.isSpace() ) return 1; - else if ( ch.isLetter() || ch=='-' || ch=='+' || ch==':' - || ch=='.' || ch=='/' || ch=='\\' - || ch=='@' || ch=='$' || ch=='~' ) return 2; - else return 3; -} - -#ifndef TQT_NO_CLIPBOARD -/* - Copies the marked text to the clipboard. Will copy only - if echoMode() is Normal. -*/ - -void TQtMultiLineEdit::copy() const -{ - TQString t = markedText(); - if ( !t.isEmpty() && echoMode() == Normal ) { -#if defined(_WS_X11_) - disconnect( TQApplication::clipboard(), TQT_SIGNAL(dataChanged()), this, 0); -#endif -#if defined(_OS_WIN32_) - // Need to convert NL to CRLF - t.replace( "\n", "\r\n" ); -#endif - TQApplication::clipboard()->setText( t ); -#if defined(_WS_X11_) - connect( TQApplication::clipboard(), TQT_SIGNAL(dataChanged()), - this, TQT_SLOT(clipboardChanged()) ); -#endif - } -} - -/* \obsolete - - Backward compatibility. -*/ -void TQtMultiLineEdit::copyText() const -{ - copy(); -} - -/* - Copies the selected text to the clipboard and deletes the selected text. -*/ - -void TQtMultiLineEdit::cut() -{ - if ( hasMarkedText() ) { - if ( echoMode() == Normal ) - copy(); - del(); - if ( textDirty && !d->isHandlingEvent ) - emit textChanged(); - } -} - -#endif - -/* - This private slot is activated when this line edit owns the clipboard and - some other widget/application takes over the clipboard. (X11 only) -*/ - -void TQtMultiLineEdit::clipboardChanged() -{ -#if defined(_WS_X11_) - disconnect( TQApplication::clipboard(), TQT_SIGNAL(dataChanged()), - this, TQT_SLOT(clipboardChanged()) ); - turnMark( FALSE ); - update(); -#endif -} - - -/* - Sets maxLineWidth() and maybe cellWidth() to \a w without updating the entire widget. - */ - -void TQtMultiLineEdit::setWidth( int w ) -{ - if ( w ==d->maxLineWidth ) - return; - bool u = autoUpdate(); - setAutoUpdate( FALSE ); - d->maxLineWidth = w; - if ( d->align == AlignLeft ) - setCellWidth( w ); - else - setCellWidth( TQMAX( w, contentsRect().width() ) ); - setAutoUpdate( u ); - if ( autoUpdate() && d->align != AlignLeft ) - update(); -} - - -/* - Sets the cursor position to character number \a col in line number \a line. - The parameters are adjusted to lie within the legal range. - - If \a mark is FALSE, the selection is cleared. otherwise it is extended - - \sa cursorPosition() -*/ - -void TQtMultiLineEdit::setCursorPosition( int line, int col, bool mark ) -{ - if ( mark && !hasMarkedText() ) { - markAnchorX = cursorX; - markAnchorY = cursorY; - } - int oldY = cursorY; - cursorY = TQMAX( TQMIN( line, numLines() - 1), 0 ); - cursorX = TQMAX( TQMIN( col, lineLength( cursorY )), 0 ); - curXPos = 0; - makeVisible(); - if ( mark ) { - newMark( cursorX, cursorY, FALSE ); - for ( int i = TQMIN(oldY,cursorY); i <= TQMAX(oldY,cursorY); i++ ) - updateCell( i, 0, FALSE ); - } else { - updateCell( oldY, 0, FALSE ); - turnMark( FALSE ); - } -} - - - -/* \obsolete - - Use getCursorPosition() instead. -*/ - -void TQtMultiLineEdit::cursorPosition( int *line, int *col ) const -{ - getCursorPosition(line,col); -} - - -/* - Returns the current line and character - position within that line, in the variables pointed to - by \a line and \a col respectively. - - \sa setCursorPosition() -*/ - -void TQtMultiLineEdit::getCursorPosition( int *line, int *col ) const -{ - if ( line ) - *line = cursorY; - if ( col ) - *col = cursorX; -} - - -/* - \sa setAutoUpdate() -*/ - -bool TQtMultiLineEdit::autoUpdate() const -{ - return TQtTableView::autoUpdate(); -} - - -/* - Sets the auto-update option of multi-line editor to \a enable. - -*/ - -void TQtMultiLineEdit::setAutoUpdate( bool enable ) -{ - TQtTableView::setAutoUpdate( enable ); -} - -/* - Sets the fixed height of the TQtMultiLineEdit so that \a lines text lines - are visible given the current font. - - \sa setMaxLines(), setFixedHeight() - */ -void TQtMultiLineEdit::setFixedVisibleLines( int lines ) -{ - int ls = fontMetrics().lineSpacing(); - setFixedHeight( frameWidth()*2 + ls*lines ); - return; -} - - - -/* - Returns the top center point where the cursor is drawn -*/ - -TQPoint TQtMultiLineEdit::cursorPoint() const -{ - TQPoint cp( 0, 0 ); - - TQFontMetrics fm( font() ); - int col, row; - col = row = 0; - cursorPosition( &row, &col ); - TQString line = textLine( row ); - ASSERT( line ); - cp.setX( d->lr_marg + textWidthWithTabs( fm, line, 0, col, d->align ) - 1 ); - cp.setY( (row * cellHeight()) + viewRect().y() ); - return cp; -} - - -/* \reimp -*/ -TQSizePolicy TQtMultiLineEdit::sizePolicy() const -{ - //### removeme 3.0 - return TQWidget::sizePolicy(); -} - - -/*\reimp -*/ -TQSize TQtMultiLineEdit::tqsizeHint() const -{ - constPolish(); - int expected_lines; - if ( d->maxlines >= 0 && d->maxlines <= 6 ) { - expected_lines = d->maxlines; - } else { - expected_lines = 6; - } - TQFontMetrics fm( font() ); - int h = fm.lineSpacing()*(expected_lines-1)+fm.height() + frameWidth()*2; - int w = fm.width('x')*35; - - int maxh = tqmaximumSize().height(); - if ( maxh < TQWIDGETSIZE_MAX ) - h = maxh; - - return TQSize( w, h ).expandedTo( TQApplication::globalStrut() ); -} - - -/* - Returns a size sufficient for one character, and scroll bars. -*/ - -TQSize TQtMultiLineEdit::tqminimumSizeHint() const -{ - constPolish(); - TQFontMetrics fm( font() ); - int h = fm.lineSpacing() + frameWidth()*2; - int w = fm.maxWidth(); - h += frameWidth(); - w += frameWidth(); - if ( testTableFlags(Tbl_hScrollBar|Tbl_autoHScrollBar) ) - w += verticalScrollBar()->tqsizeHint().width(); - if ( testTableFlags(Tbl_vScrollBar|Tbl_autoVScrollBar) ) - h += horizontalScrollBar()->tqsizeHint().height(); - return TQSize(w,h); -} - - - -/*\reimp -*/ - -void TQtMultiLineEdit::resizeEvent( TQResizeEvent *e ) -{ - int oldw = contentsRect().width(); - TQtTableView::resizeEvent( e ); - if ( DYNAMIC_WRAP - && (e->oldSize().width() != width() - || oldw != contentsRect().width() ) ) { - bool oldAuto = autoUpdate(); - setAutoUpdate( FALSE ); - rebreakAll(); - if ( oldw != contentsRect().width() ) - rebreakAll(); - setAutoUpdate( oldAuto ); - if ( autoUpdate() ) - tqrepaint( FALSE ); - } else if ( d->align != AlignLeft ) { - d->maxLineWidth = 0; // trigger update - updateCellWidth(); - } - if ( isVisible() ) - deselect(); -} - -/* - Sets the tqalignment to \a flags. Possible values are \c AlignLeft, \c - Align(H)Center and \c AlignRight. - - \sa tqalignment(), TQt::AlignmentFlags -*/ -void TQtMultiLineEdit::tqsetAlignment( int flags ) -{ - if ( d->align != flags ) { - d->align = flags; - update(); - } -} - -/* - Returns the tqalignment. - -*/ -int TQtMultiLineEdit::tqalignment() const -{ - return d->align; -} - - -/* - Not supported at this time. - \a v is the validator to set. -*/ -void TQtMultiLineEdit::setValidator( const TQValidator *v ) -{ - d->val = v; - // #### validate text now -} - -/* - Not supported at this time. -*/ -const TQValidator * TQtMultiLineEdit::validator() const -{ - return d->val; -} - -/* \sa edited() -*/ -void TQtMultiLineEdit::setEdited( bool e ) -{ - d->edited = e; -} - -/* \sa setEdited() -*/ -bool TQtMultiLineEdit::edited() const -{ - return d->edited; -} - -/* \enum TQtMultiLineEdit::EchoMode - - This enum type describes the ways in which TQLineEdit can display its - contents. The currently defined values are: \list - - \i Normal - display characters as they are entered. This is - the default. - - \i NoEcho - do not display anything. - - \i Password - display asterisks instead of the characters - actually entered. - - \endlist - - \sa setEchoMode() echoMode() TQLineEdit::EchoMode -*/ - - -/* - Sets the echo mode to \a em. The default is \c Normal. - - The display is updated according. - - \sa setEchoMode() -*/ -void TQtMultiLineEdit::setEchoMode( EchoMode em ) -{ - if ( d->echomode != em ) { - d->echomode = em; - updateCellWidth(); - update(); - } -} - -/* - Returns the currently set echo mode. - - \sa setEchoMode() -*/ -TQtMultiLineEdit::EchoMode TQtMultiLineEdit::echoMode() const -{ - return d->echomode; -} - - -/* - Returns the string shown at line \a row, including - processing of the echoMode(). -*/ - -TQString TQtMultiLineEdit::stringShown(int row) const -{ - TQString* s = getString(row); - if ( !s ) return TQString::null; - switch ( d->echomode ) { - case Normal: - if (!*s) return TQString::tqfromLatin1(""); - return *s; - case Password: - { - TQString r; - r.fill(TQChar('*'), (int)s->length()); - if ( !r ) r = TQString::tqfromLatin1(""); - return r; - } - case NoEcho: - return TQString::tqfromLatin1(""); - } - return TQString::tqfromLatin1(""); -} - -/* - - \sa maxLength() -*/ -void TQtMultiLineEdit::setMaxLength(int m) -{ - d->maxlen = m; -} - -/* - \sa setMaxLength() -*/ -int TQtMultiLineEdit::maxLength() const -{ - return d->maxlen; -} - - -/* - Returns the length of the current text. - - \sa setMaxLength() - */ -int TQtMultiLineEdit::length() const -{ - int l = 0; - for ( TQtMultiLineEditRow* r = contents->first(); r; r = contents->next() ) { - l += r->s.length(); - if ( r->newline ) - ++l; - } - return l-1; -} - - -/* - Sets the maximum length of lines to \a m. Use -1 for unlimited - (the default). Existing long lines will be truncated. - - \sa maxLineLength() -*/ -void TQtMultiLineEdit::setMaxLineLength(int m) -{ - bool trunc = d->maxlinelen < 0 || m < d->maxlinelen; - d->maxlinelen = m; - if ( trunc ) { - TQtMultiLineEditRow* r = contents->first(); - while ( r ) { - r->s.truncate( m ); - r = contents->next(); - } - if ( cursorX > m ) cursorX = m; - if ( markAnchorX > m ) markAnchorX = m; - if ( markDragX > m ) markDragX = m; - update(); - updateCellWidth(); - } -} - -/* - Returns the currently set line length limit, or -1 if there is - no limit (this is the default). - - \sa setMaxLineLength() -*/ -int TQtMultiLineEdit::maxLineLength() const -{ - return d->maxlinelen; -} - -/* - Sets the maximum number of lines to \a m. Use -1 for unlimited - (the default). Existing excess lines will be deleted. - - \sa maxLines(), numLines() -*/ -void TQtMultiLineEdit::setMaxLines(int m) -{ - if ( m == 0 ) // bad value - m = -1; - d->maxlines = m; - if ( d->maxlines >= 0 && d->maxlines <= 6 ) { - tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) ); - } else { - tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) ); - } - if ( setNumRowsAndTruncate() ) { - updateCellWidth(); - update(); - } -} - -/* - \sa setMaxLines() -*/ -int TQtMultiLineEdit::maxLines() const -{ - return d->maxlines; -} - -/* - Sets the horizontal margin to \a m. - - \sa hMargin() -*/ -void TQtMultiLineEdit::setHMargin(int m) -{ - if ( m != d->lr_marg ) { - d->lr_marg = m; - updateCellWidth(); - update(); - } -} - -/* - - \sa setHMargin() -*/ -int TQtMultiLineEdit::hMargin() const -{ - return d->lr_marg; -} - -/* - Marks the text starting at \a row_from, \a col_from and ending - at \a row_to, \a col_to. -*/ -void TQtMultiLineEdit::setSelection( int row_from, int col_from, - int row_to, int col_to ) -{ - setCursorPosition( row_from, col_from, FALSE ); - setCursorPosition( row_to, col_to, TRUE ); -} - - -/* - Moves the cursor one word to the right. If \a mark is TRUE, the text - is marked. - \sa cursorWordBackward() -*/ -void TQtMultiLineEdit::cursorWordForward( bool mark ) -{ - int x = cursorX; - int y = cursorY; - - if ( x == lineLength( y ) || textLine(y).at(x).isSpace() ) { - while ( x < lineLength( y ) && textLine(y).at(x).isSpace() ) - ++x; - if ( x == lineLength( y ) ) { - if ( y < (int)contents->count() - 1) { - ++y; - x = 0; - while ( x < lineLength( y ) && textLine(y).at(x).isSpace() ) - ++x; - } - } - } - else { - while ( x < lineLength( y ) && !textLine(y).at(x).isSpace() ) - ++x; - int xspace = x; - while ( xspace < lineLength( y ) && textLine(y).at(xspace).isSpace() ) - ++xspace; - if ( xspace < lineLength( y ) ) - x = xspace; - } - cursorOn = TRUE; - int oldY = cursorY; - setCursorPosition( y, x, mark ); - if ( oldY != cursorY ) - updateCell( oldY, 0, FALSE ); - updateCell( cursorY, 0, FALSE ); - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); -} - -/* - Moves the cursor one word to the left. If \a mark is TRUE, the text - is marked. - \sa cursorWordForward() -*/ -void TQtMultiLineEdit::cursorWordBackward( bool mark ) -{ - int x = cursorX; - int y = cursorY; - - while ( x > 0 && textLine(y).at(x-1).isSpace() ) - --x; - - if ( x == 0 ) { - if ( y > 0 ) { - --y; - x = lineLength( y ); - while ( x > 0 && textLine(y).at(x-1).isSpace() ) - --x; - } - } - else { - while ( x > 0 && !textLine(y).at(x-1).isSpace() ) - --x; - } - cursorOn = TRUE; - int oldY = cursorY; - setCursorPosition( y, x, mark ); - if ( oldY != cursorY ) - updateCell( oldY, 0, FALSE ); - updateCell( cursorY, 0, FALSE ); - d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE ); -} - -#define DO_BREAK {doBreak = TRUE; if ( lastSpace > a ) { \ -i = lastSpace; \ -linew = lastw; \ -} \ -else \ -i = TQMAX( a, i-1 );} - -void TQtMultiLineEdit::wrapLine( int line, int removed ) -{ - TQtMultiLineEditRow* r = contents->at( line ); - int yPos; - (void) rowYPos( line, &yPos ); - TQFontMetrics fm( font() ); - int i = 0; - TQString s = r->s; - int a = 0; - int l = line; - int w = 0; - int nlines = 0; - int lastSpace = -1; - bool doBreak = FALSE; - int linew = 0; - int lastw = 0; - int tabDist = -1; // lazy eval - while ( i < int(s.length()) ) { - doBreak = FALSE; - if ( s[i] == '\t' && d->align == TQt::AlignLeft ) { - if ( tabDist<0 ) - tabDist = tabStopDist(fm); - linew = ( linew/tabDist + 1 ) * tabDist; - } else if ( s[i] != '\n' ) { - char c = s[i].latin1(); - if ( c > 0 ) { - if ( !d->chartable[c] ) - d->chartable[c] = fm.width( s[i] ); - linew += d->chartable[c]; - } else { - linew += fm.width( s[i] ); - } - } - if ( WORD_WRAP && - lastSpace >= a && s[i] != '\n' ) { - if ( DYNAMIC_WRAP ) { - if (linew >= contentsRect().width() - 2*d->lr_marg - d->marg_extra) { - DO_BREAK - } - } else if ( FIXED_COLUMN_WRAP ) { - if ( d->wrapcol >= 0 && i-a >= d->wrapcol ) { - DO_BREAK - } - } else if ( FIXED_WIDTH_WRAP ) { - if ( d->wrapcol >= 0 && linew > d->wrapcol - d->marg_extra ) { - DO_BREAK - } - } - } - if ( s[i] == '\n' || doBreak ) { - r->s = s.mid( a, i - a + (doBreak?1:0) ); - r->w = linew - fm.leftBearing(r->s[0]) + 2 * d->lr_marg + d->marg_extra; - if ( r->w > w ) - w = r->w; - if ( cursorY > l ) - ++cursorY; - else if ( cursorY == line && cursorX >=a && cursorX <= i + (doBreak?1:0)) { - cursorY = l; - cursorX -= a; - } - if ( markAnchorY > l ) - ++markAnchorY; - else if ( markAnchorY == line && markAnchorX >=a && markAnchorX <= i + (doBreak?1:0)) { - markAnchorY = l; - markAnchorX -= a; - } - a = i + 1; - lastSpace = a; - linew = 0; - bool oldnewline = r->newline; - r->newline = !doBreak; - r = new TQtMultiLineEditRow( TQString::null, 0, oldnewline ); - ++nlines; - contents->insert( l + 1, r ); - ++l; - } - if ( s[i].isSpace() || BREAK_WITHIN_WORDS ) { - lastSpace = i; - lastw = linew; - } - if ( lastSpace <= a ) - lastw = linew; - - ++i; - } - if ( a < int(s.length()) ){ - r->s = s.mid( a, i - a ); - r->w = linew - fm.leftBearing( r->s[0] ) + 2 * d->lr_marg + d->marg_extra; - } - if ( cursorY == line && cursorX >= a ) { - cursorY = l; - cursorX -= a; - } - if ( markAnchorY == line && markAnchorX >= a ) { - markAnchorY = l; - markAnchorX -= a; - } - if ( r->w > w ) - w = r->w; - - setWidth( TQMAX( maxLineWidth(), w ) ); - bool oldAuto = autoUpdate(); - setAutoUpdate( FALSE ); - (void)setNumRowsAndTruncate(); - setAutoUpdate( oldAuto ); - - yPos += (nlines+1) * cellHeight(); - int sh = (nlines-removed) * cellHeight(); - if ( autoUpdate() ) { - if ( sh && yPos >= contentsRect().top() && yPos < contentsRect().bottom() ) { - int h = contentsRect().bottom() - yPos + 1; - if ( d->maxlines >= 0 ) { - int maxy; - if ( rowYPos( d->maxlines-1, &maxy ) ) { - maxy += cellHeight(); - if ( maxy < contentsRect().bottom() && maxy > yPos ) - h = maxy - yPos + 1; - } - } - TQWidget::scroll( 0, sh, TQRect( contentsRect().left(), yPos, - contentsRect().width(), - h ) ); - } - for (int ul = 0; ul <= nlines; ++ul ) - updateCell( line + ul, 0, FALSE ); - } -} - -void TQtMultiLineEdit::rebreakParagraph( int line, int removed ) -{ - TQtMultiLineEditRow* r = contents->at( line ); - if ( WORD_WRAP ) { - TQtMultiLineEditRow* other = 0; - while (line < int(contents->count())-1 && !r->newline ) { - other = contents->at( line + 1 ); - if ( cursorY > line ) { - --cursorY; - if ( cursorY == line ) { - cursorX += r->s.length(); - } - } - if ( markAnchorY > line ) { - --markAnchorY; - if ( markAnchorY == line ) { - markAnchorX += r->s.length(); - } - } - r->s.append( other->s ); - r->newline = other->newline; - contents->remove( line + 1 ); - ++removed; - } - } - wrapLine( line, removed ); -} - -void TQtMultiLineEdit::rebreakAll() -{ - if ( !WORD_WRAP ) - return; - d->maxLineWidth = 0; - for (int i = 0; i < int(contents->count()); ++i ) { - if ( contents->at( i )->newline && - contents->at( i )->w < contentsRect().width() - 2*d->lr_marg - d->marg_extra ) { - setWidth( TQMAX( d->maxLineWidth, contents->at( i )->w ) ); - continue; - } - rebreakParagraph( i ); - while ( i < int(contents->count() ) - && !contents->at( i )->newline ) - ++i; - } -} - - -/* \enum TQtMultiLineEdit::WordWrap - - This enum describes the multiline edit's word wrap mode. - - The following values are valid: - \list - \i NoWrap - no word wrap at all. - \i WidgetWidth - word wrap depending on the current - width of the editor widget - \i FixedPixelWidth - wrap according to a fix amount - of pixels ( see wrapColumnOrWidth() ) - \i FixedColumnWidth - wrap according to a fix character - column. This is useful whenever you need formatted text that - can also be displayed gracefully on tqdevices with monospaced - fonts, for example a standard VT100 terminal. In that case - wrapColumnOrWidth() should typically be set to 80. - \endlist - - \sa setWordWrap() -*/ - -/* - Sets the word wrap mode to \a mode. - - */ -void TQtMultiLineEdit::setWordWrap( WordWrap mode ) -{ - if ( mode == d->wordwrap ) - return; - d->wordwrap = mode; - - if ( BREAK_WITHIN_WORDS ) { - d->arrow = TQPixmap( (const char **)arrow_xpm ); - d->marg_extra = 8; - if ( DYNAMIC_WRAP ) - clearTableFlags( Tbl_autoHScrollBar ); - else - setTableFlags( Tbl_autoHScrollBar ); - } else { - d->marg_extra = 0; - setTableFlags( Tbl_autoHScrollBar ); - } - if ( !text().isEmpty() ) - setText( text() ); -} - -/* - Returns the current word wrap mode. - - \sa setWordWrap() - */ -TQtMultiLineEdit::WordWrap TQtMultiLineEdit::wordWrap() const -{ - return d->wordwrap; -} - -/* - Sets the wrap column or wrap width to \a value, depending on the - word wrap mode. - - \sa setWordWrap() - */ -void TQtMultiLineEdit::setWrapColumnOrWidth( int value ) -{ - if ( value == d->wrapcol ) - return; - d->wrapcol = value; - if ( wordWrap() != NoWrap ) - setText( text() ); -} - -/* - */ -int TQtMultiLineEdit::wrapColumnOrWidth() const -{ - return d->wrapcol; -} - - -/* \enum TQtMultiLineEdit::WrapPolicy - - Defines where text can be wrapped in word wrap mode. - - The following values are valid: - \list - \i AtWhiteSpace - break only after whitespace - \i Anywhere - break anywhere - \endlist - - \sa setWrapPolicy() -*/ - -/* - Sets the wrap \a policy, i.e. where text can be wrapped in word wrap - mode. - - \sa setWordWrap(), wrapPolicy() - */ -void TQtMultiLineEdit::setWrapPolicy( WrapPolicy policy ) -{ - if ( d->wrappolicy == policy ) - return; - d->wrappolicy = policy; - WordWrap m = d->wordwrap; - if ( m != NoWrap ) { // trigger update - d->wordwrap = NoWrap; - setWordWrap( m ); - } -} - -/* - - Returns the current word wrap policy. - - \sa setWrapPolicy() - */ -TQtMultiLineEdit::WrapPolicy TQtMultiLineEdit::wrapPolicy() const -{ - return d->wrappolicy; -} - -/* - Returns wether \a row is the last row in a paragraph. - - This function is only interesting in word wrap mode, otherwise its - return value is always TRUE. - - \sa setWordWrap() - */ -bool TQtMultiLineEdit::isEndOfParagraph( int row ) const -{ - return contents->at( row )->newline; -} - -int TQtMultiLineEdit::positionToOffsetInternal( int row, int col ) const -{ - row = TQMAX( TQMIN( row, numLines() - 1), 0 ); // Sanity check - col = TQMAX( TQMIN( col, lineLength( row )), 0 ); // Sanity check - if ( row == 0 ) - return TQMIN( col, lineLength( 0 )); - else { - int lastI; - lastI = lineLength( row ); - int i, tmp = 0; - - for( i = 0; i < row ; i++ ) { - tmp += lineLength( i ); - if ( contents->at( i )->newline ) - ++tmp; - } - - tmp += TQMIN( lastI, col ); - - return tmp; - } - -} - -// if position is <0 = returns row 0, col 0, if position >= amount of text -// returns pointer to end of text. -void TQtMultiLineEdit::offsetToPositionInternal( int position, - int *row, int *col ) const -{ - if (position <= 0) { - *row = 0; - *col = 0; - return; - } - else { - int charsLeft = position; - int i; - - for( i = 0; contents->at( i ); ++i ) { - if (lineLength( i ) < charsLeft) - charsLeft -= lineLength( i ); - else { - *row = i; - *col = charsLeft; - return; - } - if ( contents->at( i )->newline ) - --charsLeft; - } - - if (contents->at( i - 1) && !contents->at( i - 1 )->newline) { - *row = i - 1; - *col = lineLength( i - 1 ); - } - else { - *row = i; - *col = 0; - } - return; - } -} - - -/* - Processes an undo/redo command \a cmd, depending on \a undo. - */ -void TQtMultiLineEdit::processCmd( TQtMultiLineEditCommand* cmd, bool undo) -{ - TQDelTextCmd* delcmd = (TQDelTextCmd*) cmd; - bool ins = TRUE; - if (cmd->type() == TQtMultiLineEditCommand::Delete ) - ins = undo; - else if (cmd->type() == TQtMultiLineEditCommand::Insert ) - ins = !undo; - else - return; - - if ( ins ) { - int row, col; - offsetToPositionInternal( delcmd->mOffset, &row, &col ); - setCursorPosition( row, col, FALSE ); - insertAt( delcmd->mStr, row, col, FALSE ); - offsetToPositionInternal( delcmd->mOffset+delcmd->mStr.length(), &row, &col ); - setCursorPosition( row, col, FALSE ); - } else { // del - int row, col, rowEnd, colEnd; - offsetToPositionInternal( delcmd->mOffset, &row, &col ); - offsetToPositionInternal( delcmd->mOffset + delcmd->mStr.length(), &rowEnd, &colEnd ); - markAnchorY = row; - markAnchorX = col; - setCursorPosition( rowEnd, colEnd, FALSE ); - markDragY = rowEnd; - markDragX = colEnd; - turnMark( TRUE ); - del(); - } -} - -/* - Undoes the last text operation. - */ -void TQtMultiLineEdit::undo() -{ - if ( d->undoList.isEmpty() || isReadOnly() ) - return; - textDirty = FALSE; - int macroLevel = 0; - bool before = d->undo; - d->undo = FALSE; - do { - TQtMultiLineEditCommand *command = d->undoList.take(); - if ( !command ) - break; - processCmd( command, TRUE ); - macroLevel += command->terminator(); - if ( d->undoList.isEmpty() ) - emit undoAvailable( FALSE ); - addRedoCmd( command ); - } while (macroLevel != 0); - d->undo = before; - if ( textDirty ) - emit textChanged(); - textDirty = FALSE; -} - -/* - Redoes the last text operation. - */ -void TQtMultiLineEdit::redo() -{ - if ( d->redoList.isEmpty() || isReadOnly() ) - return; - textDirty = FALSE; - int macroLevel = 0; - bool before = d->undo; - d->undo = FALSE; - do { - TQtMultiLineEditCommand *command = d->redoList.take(); - if ( !command ) - break; - processCmd( command, FALSE ); - macroLevel += command->terminator(); - if ( d->redoList.isEmpty() ) - emit redoAvailable( FALSE ); - if ( d->undoList.isEmpty() ) - emit undoAvailable(TRUE); - d->undoList.append( command ); - } while (macroLevel != 0); - d->undo = before; - if ( textDirty ) - emit textChanged(); - textDirty = FALSE; -} - -/* - Inserts \a s at line number \a line, after character number \a col - in the line. - If \a s contains newline characters, new lines are inserted. - If \a mark is TRUE the inserted text is selected. - - The cursor position is adjusted. If the insertion position is equal to - the cursor position, the cursor is placed after the end of the new text. - - */ - -void TQtMultiLineEdit::insertAt( const TQString &s, int line, int col, bool mark ) -{ - if ( d->undo ) { - d->undo = FALSE; - TQString itxt = s; - int offset = positionToOffsetInternal( line, col ); - if ( d->maxlen >= 0 && length() + int(s.length()) > d->maxlen ) - itxt.truncate( d->maxlen - length() ); - addUndoCmd( new TQInsTextCmd( offset, itxt ) ); - insertAtAux( s, line, col, mark ); // may perform del op - d->undo = TRUE; - } - else - insertAtAux( s, line, col, mark ); // may perform del op -} - -void TQtMultiLineEdit::deleteNextChar( int offset, int row, int col ) -{ - int row2, col2; - setCursorPosition( row, col, FALSE ); - offsetToPositionInternal( offset + 1, &row2, &col2 ); - setCursorPosition( row2, col2, TRUE ); - - TQString str = markedText(); - addUndoCmd( new TQDelTextCmd( offset, str ) ); - - setCursorPosition( row, col, FALSE ); -} - -/* - Deletes text from the current cursor position to the end of the line. -*/ - -void TQtMultiLineEdit::killLine() -{ - if ( d->undo ) { - d->undo = FALSE; - int curY, curX; - cursorPosition( &curY, &curX ); - int offset = positionToOffsetInternal( curY, curX ); - TQtMultiLineEditRow* r = contents->at( curY ); - deselect(); - - addUndoCmd( new TQBeginCommand ); - if (curX == (int)r->s.length()) { - if ( ! atEnd() && r->newline ) - deleteNextChar( offset, curY, curX ); - } - else { - TQString str = r->s.mid( curX, r->s.length() ); - addUndoCmd( new TQDelTextCmd( offset, str ) ); - } - - addUndoCmd( new TQEndCommand ); - killLineAux(); - d->undo = TRUE; - } - else - killLineAux(); -} - -/* - Deletes the character on the right side of the text cursor. If a - text has been marked by the user (e.g. by clicking and dragging) the - cursor is put at the beginning of the marked text and the marked - text is removed. \sa backspace() -*/ - -void TQtMultiLineEdit::del() -{ - if (d->undo ) { - d->undo = FALSE; - bool oldAuto = autoUpdate(); - setAutoUpdate( FALSE ); - int markBeginX, markBeginY; - int markEndX, markEndY; - - if ( getMarkedRegion( &markBeginY, &markBeginX, &markEndY, &markEndX ) ) { - addUndoCmd( new TQBeginCommand ); - int offset = positionToOffsetInternal( markBeginY, markBeginX ); - TQString str = markedText(); - d->undoList.append( new TQDelTextCmd( offset, str ) ); - addUndoCmd( new TQEndCommand ); - } - else if ( ! atEnd() ) { - int crsorY, crsorX; - cursorPosition( &crsorY, &crsorX ); - int offset = positionToOffsetInternal( crsorY, crsorX ); - TQtMultiLineEditRow* r = contents->at( crsorY ); - if (r) { - if (crsorX != (int)r->s.length()) - deleteNextChar( offset, crsorY, crsorX ); - else if (r->newline) - deleteNextChar( offset, crsorY, crsorX ); - // else noop - } - } - setAutoUpdate( oldAuto ); - delAux(); - d->undo = TRUE; - } - else - delAux(); -} - -/* - Sets undo enabled to \a enable. - - \sa isUndoEnabled() -*/ -void TQtMultiLineEdit::setUndoEnabled( bool enable ) -{ - if ( d->undo == enable ) - return; - d->undo = enable; - if ( !enable ) { - CLEAR_UNDO - } -} - - -/* - Returns whether the multilineedit is currently undo enabled or not. - - \sa setUndoEnabled() - */ -bool TQtMultiLineEdit::isUndoEnabled() const -{ - return d->undo; -} - - -/* - Sets the maximum number of operations that can be stored on the undo - stack to \a depth. - - \sa undoDepth() - */ -void TQtMultiLineEdit::setUndoDepth( int depth ) -{ - d->undodepth = depth; -} - - -/* - */ -int TQtMultiLineEdit::undoDepth() const -{ - return d->undodepth; -} - -void TQtMultiLineEdit::blinkTimerTimeout() -{ - cursorOn = !cursorOn; - updateCell( cursorY, 0, FALSE ); -} - -void TQtMultiLineEdit::scrollTimerTimeout() -{ - TQPoint p = mapFromGlobal( TQCursor::pos() ); - if ( d->scrollAccel-- <= 0 && d->scrollTime ) { - d->scrollAccel = initialScrollAccel; - d->scrollTime--; - d->scrollTimer->stop(); - d->scrollTimer->start( d->scrollTime ); - } - int l = TQMAX(1,(initialScrollTime-d->scrollTime)/5); - - // auto scrolling is dual-use - for highlighting and DND - int margin = d->dnd_primed ? scroll_margin : 0; - bool mark = !d->dnd_primed; - bool clear_mark = d->dnd_primed ? FALSE : !mark; - - for (int i=0; i<l; i++) { - if ( p.y() < margin ) { - cursorUp( mark, clear_mark ); - } else if ( p.y() > height()-margin ) { - cursorDown( mark, clear_mark ); - } else if ( p.x() < margin ) { - cursorLeft( mark, clear_mark, FALSE ); - } else if ( p.x() > width()-margin ) { - cursorRight( mark, clear_mark, FALSE ); - } else { - stopAutoScroll(); - break; - } - } -} - -void TQtMultiLineEdit::dndTimeout() -{ -#ifndef TQT_NO_DRAGANDDROP - doDrag(); -#endif -} - -int TQtMultiLineEdit::setNumRowsAndTruncate() -{ - int n = contents->count(); - int r = 0; - while ( d->maxlines >= 0 && n > d->maxlines ) { - // truncate - contents->at(n-2)->newline = TRUE; - contents->removeLast(); - if ( markAnchorY == n-1 ) - markAnchorY--; - if ( markDragY == n-1 ) - markDragY--; - if ( cursorY == n-1 ) { - cursorY--; - cursorX = contents->at(cursorY)->s.length(); - } - n--; - r++; - } - setNumRows( n ); - return r; -} - -/* \reimp -*/ -bool TQtMultiLineEdit::event( TQEvent * e ) -{ - if ( e->type() == TQEvent::AccelOverride && !isReadOnly() ) { - TQKeyEvent* ke = (TQKeyEvent*) e; - if ( ke->state() & ControlButton ) { - switch ( ke->key() ) { - case Key_A: - case Key_E: -#if defined (_WS_WIN_) - case Key_Insert: -#endif - case Key_X: - case Key_V: - case Key_C: - case Key_Left: - case Key_Right: - case Key_Up: - case Key_Down: - case Key_Home: - case Key_End: - ke->accept(); - default: - break; - } - } else { - switch ( ke->key() ) { - case Key_Delete: - case Key_Home: - case Key_End: - case Key_Backspace: - ke->accept(); - default: - break; - } - } - } - return TQWidget::event( e ); -} - -/* \reimp -*/ - -bool TQtMultiLineEdit::focusNextPrevChild( bool ) -{ - return FALSE; -} - -#endif |