summaryrefslogtreecommitdiffstats
path: root/debian/pinentry-tqt/pinentry-tqt-1.2.1/tqt/secqlineedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'debian/pinentry-tqt/pinentry-tqt-1.2.1/tqt/secqlineedit.cpp')
-rw-r--r--debian/pinentry-tqt/pinentry-tqt-1.2.1/tqt/secqlineedit.cpp1957
1 files changed, 1957 insertions, 0 deletions
diff --git a/debian/pinentry-tqt/pinentry-tqt-1.2.1/tqt/secqlineedit.cpp b/debian/pinentry-tqt/pinentry-tqt-1.2.1/tqt/secqlineedit.cpp
new file mode 100644
index 00000000..da0637a5
--- /dev/null
+++ b/debian/pinentry-tqt/pinentry-tqt-1.2.1/tqt/secqlineedit.cpp
@@ -0,0 +1,1957 @@
+/* secqlineedit.cpp - Secure version of TQLineEdit.
+ * Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+ * Copyright (C) 2003 g10 Code GmbH
+ *
+ * The license of the original qlineedit.cpp file from which this file
+ * is derived can be found below. Modified by Marcus Brinkmann
+ * <marcus@g10code.de>. All modifications are licensed as follows, so
+ * that the intersection of the two licenses is then the GNU General
+ * Public License version 2.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+
+/* Undo/Redo is disabled, because it uses unsecure memory for the
+ history buffer. */
+#define SECURE_NO_UNDO 1
+
+
+/**********************************************************************
+** $Id$
+**
+** Implementation of SecTQLineEdit widget class
+**
+** Created : 941011
+**
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
+** licenses may use this file in accordance with the TQt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about TQt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for TQPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "secqlineedit.h"
+#include "ntqpainter.h"
+#include "ntqdrawutil.h"
+#include "ntqfontmetrics.h"
+#include "ntqpixmap.h"
+#include "ntqclipboard.h"
+#include "ntqapplication.h"
+#include "ntqtimer.h"
+#include "ntqpopupmenu.h"
+#include "ntqstringlist.h"
+#include "ntqguardedptr.h"
+#include "ntqstyle.h"
+#include "ntqwhatsthis.h"
+#include "secqinternal_p.h"
+#include "private/qtextlayout_p.h"
+#include "ntqvaluevector.h"
+#if defined(QT_ACCESSIBILITY_SUPPORT)
+#include "ntqaccessible.h"
+#endif
+
+#ifndef QT_NO_ACCEL
+#include "ntqkeysequence.h"
+#define ACCEL_KEY(k) "\t" + TQString(TQKeySequence( TQt::CTRL | TQt::Key_ ## k ))
+#else
+#define ACCEL_KEY(k) "\t" + TQString("Ctrl+" #k)
+#endif
+
+#define innerMargin 1
+
+struct SecTQLineEditPrivate : public TQt
+{
+ SecTQLineEditPrivate( SecTQLineEdit *q )
+ : q(q), cursor(0), cursorTimer(0), tripleClickTimer(0), frame(1),
+ cursorVisible(0), separator(0), readOnly(0), modified(0),
+ direction(TQChar::DirON), alignment(0),
+ echoMode(0), textDirty(0), selDirty(0),
+ ascent(0), maxLength(32767), menuId(0),
+ hscroll(0),
+ undoState(0), selstart(0), selend(0),
+ imstart(0), imend(0), imselstart(0), imselend(0)
+ {}
+ void init( const SecTQString&);
+
+ SecTQLineEdit *q;
+ SecTQString text;
+ int cursor;
+ int cursorTimer;
+ TQPoint tripleClick;
+ int tripleClickTimer;
+ uint frame : 1;
+ uint cursorVisible : 1;
+ uint separator : 1;
+ uint readOnly : 1;
+ uint modified : 1;
+ uint direction : 5;
+ uint alignment : 3;
+ uint echoMode : 2;
+ uint textDirty : 1;
+ uint selDirty : 1;
+ int ascent;
+ int maxLength;
+ int menuId;
+ int hscroll;
+
+ void finishChange( int validateFromState = -1, bool setModified = TRUE );
+
+ void setCursorVisible( bool visible );
+
+
+ // undo/redo handling
+ enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection };
+ struct Command {
+ inline Command(){}
+ inline Command( CommandType type, int pos, TQChar c )
+ :type(type),c(c),pos(pos){}
+ uint type : 4;
+ TQChar c;
+ int pos;
+ };
+ int undoState;
+ TQValueVector<Command> history;
+#ifndef SECURE_NO_UNDO
+ void addCommand( const Command& cmd );
+#endif /* SECURE_NO_UNDO */
+
+ void insert( const SecTQString& s );
+ void del( bool wasBackspace = FALSE );
+ void remove( int pos );
+
+ inline void separate() { separator = TRUE; }
+#ifndef SECURE_NO_UNDO
+ inline void undo( int until = -1 ) {
+ if ( !isUndoAvailable() )
+ return;
+ deselect();
+ while ( undoState && undoState > until ) {
+ Command& cmd = history[--undoState];
+ switch ( cmd.type ) {
+ case Insert:
+ text.remove( cmd.pos, 1);
+ cursor = cmd.pos;
+ break;
+ case Remove:
+ case RemoveSelection:
+ text.insert( cmd.pos, cmd.c );
+ cursor = cmd.pos + 1;
+ break;
+ case Delete:
+ case DeleteSelection:
+ text.insert( cmd.pos, cmd.c );
+ cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if ( until < 0 && undoState ) {
+ Command& next = history[undoState-1];
+ if ( next.type != cmd.type && next.type < RemoveSelection
+ && !( cmd.type >= RemoveSelection && next.type != Separator ) )
+ break;
+ }
+ }
+ modified = ( undoState != 0 );
+ textDirty = TRUE;
+ }
+ inline void redo() {
+ if ( !isRedoAvailable() )
+ return;
+ deselect();
+ while ( undoState < (int)history.size() ) {
+ Command& cmd = history[undoState++];
+ switch ( cmd.type ) {
+ case Insert:
+ text.insert( cmd.pos, cmd.c );
+ cursor = cmd.pos + 1;
+ break;
+ case Remove:
+ case Delete:
+ case RemoveSelection:
+ case DeleteSelection:
+ text.remove( cmd.pos, 1 );
+ cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if ( undoState < (int)history.size() ) {
+ Command& next = history[undoState];
+ if ( next.type != cmd.type && cmd.type < RemoveSelection
+ && !( next.type >= RemoveSelection && cmd.type != Separator ) )
+ break;
+ }
+ }
+ textDirty = TRUE;
+ }
+#endif /* SECURE_NO_UNDO */
+ inline bool isUndoAvailable() const { return !readOnly && undoState; }
+ inline bool isRedoAvailable() const { return !readOnly && undoState < (int)history.size(); }
+
+
+ // bidi
+ inline bool isRightToLeft() const { return direction==TQChar::DirON?text.isRightToLeft():(direction==TQChar::DirR); }
+
+ // selection
+ int selstart, selend;
+ inline bool allSelected() const { return !text.isEmpty() && selstart == 0 && selend == (int)text.length(); }
+ inline bool hasSelectedText() const { return !text.isEmpty() && selend > selstart; }
+ inline void deselect() { selDirty |= (selend > selstart); selstart = selend = 0; }
+ void removeSelectedText();
+#ifndef QT_NO_CLIPBOARD
+ void copy( bool clipboard = TRUE ) const;
+#endif
+ inline bool inSelection( int x ) const
+ { if ( selstart >= selend ) return FALSE;
+ int pos = xToPos( x, TQTextItem::OnCharacters ); return pos >= selstart && pos < selend; }
+
+ // input methods
+ int imstart, imend, imselstart, imselend;
+
+ // complex text layout
+ TQTextLayout textLayout;
+ void updateTextLayout();
+ void moveCursor( int pos, bool mark = FALSE );
+ void setText( const SecTQString& txt );
+ int xToPos( int x, TQTextItem::CursorPosition = TQTextItem::BetweenCharacters ) const;
+ inline int visualAlignment() const { return alignment ? alignment : int( isRightToLeft() ? AlignRight : AlignLeft ); }
+ TQRect cursorRect() const;
+ void updateMicroFocusHint();
+
+};
+
+
+/*!
+ \class SecTQLineEdit
+ \brief The SecTQLineEdit widget is a one-line text editor.
+
+ \ingroup basic
+ \mainclass
+
+ A line edit allows the user to enter and edit a single line of
+ plain text with a useful collection of editing functions,
+ including undo and redo, cut and paste,
+
+ By changing the echoMode() of a line edit, it can also be used as
+ a "write-only" field, for inputs such as passwords.
+
+ The length of the text can be constrained to maxLength().
+
+ A related class is TQTextEdit which allows multi-line, rich-text
+ editing.
+
+ You can change the text with setText() or insert(). The text is
+ retrieved with text(); the displayed text (which may be different,
+ see \l{EchoMode}) is retrieved with displayText(). Text can be
+ selected with setSelection() or selectAll(), and the selection can
+ be cut(), copy()ied and paste()d. The text can be aligned with
+ setAlignment().
+
+ When the text changes the textChanged() signal is emitted; when
+ the Return or Enter key is pressed the returnPressed() signal is
+ emitted.
+
+ When the text changes the textModified() signal is emitted in all
+ cases.
+
+ By default, SecTQLineEdits have a frame as specified by the Windows
+ and Motif style guides; you can turn it off by calling
+ setFrame(FALSE).
+
+ The default key bindings are described below.
+ \target desc
+ \table
+ \header \i Keypress \i Action
+ \row \i Left Arrow \i Moves the cursor one character to the left.
+ \row \i Shift+Left Arrow \i Moves and selects text one character to the left.
+ \row \i Right Arrow \i Moves the cursor one character to the right.
+ \row \i Shift+Right Arrow \i Moves and selects text one character to the right.
+ \row \i Home \i Moves the cursor to the beginning of the line.
+ \row \i End \i Moves the cursor to the end of the line.
+ \row \i Backspace \i Deletes the character to the left of the cursor.
+ \row \i Ctrl+Backspace \i Deletes the word to the left of the cursor.
+ \row \i Delete \i Deletes the character to the right of the cursor.
+ \row \i Ctrl+Delete \i Deletes the word to the right of the cursor.
+ \row \i Ctrl+A \i Moves the cursor to the beginning of the line.
+ \row \i Ctrl+B \i Moves the cursor one character to the left.
+ \row \i Ctrl+C \i Copies the selected text to the clipboard.
+ (Windows also supports Ctrl+Insert for this operation.)
+ \row \i Ctrl+D \i Deletes the character to the right of the cursor.
+ \row \i Ctrl+E \i Moves the cursor to the end of the line.
+ \row \i Ctrl+F \i Moves the cursor one character to the right.
+ \row \i Ctrl+H \i Deletes the character to the left of the cursor.
+ \row \i Ctrl+K \i Deletes to the end of the line.
+ \row \i Ctrl+V \i Pastes the clipboard text into line edit.
+ (Windows also supports Shift+Insert for this operation.)
+ \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
+ (Windows also supports Shift+Delete for this operation.)
+ \row \i Ctrl+Z \i Undoes the last operation.
+ \row \i Ctrl+Y \i Redoes the last undone operation.
+ \endtable
+
+ Any other key sequence that represents a valid character, will
+ cause the character to be inserted into the line edit.
+
+ <img src=qlined-m.png> <img src=qlined-w.png>
+
+ \sa TQTextEdit TQLabel TQComboBox
+ \link guibooks.html#fowler GUI Design Handbook: Field, Entry\endlink
+*/
+
+
+/*!
+ \fn void SecTQLineEdit::textChanged( const SecTQString& )
+
+ This signal is emitted whenever the text changes. The argument is
+ the new text.
+*/
+
+/*!
+ \fn void SecTQLineEdit::selectionChanged()
+
+ This signal is emitted whenever the selection changes.
+
+ \sa hasSelectedText(), selectedText()
+*/
+
+/*!
+ \fn void SecTQLineEdit::lostFocus()
+
+ This signal is emitted when the line edit has lost focus.
+
+ \sa hasFocus(), TQWidget::focusInEvent(), TQWidget::focusOutEvent()
+*/
+
+
+
+/*!
+ Constructs a line edit with no text.
+
+ The maximum text length is set to 32767 characters.
+
+ The \a parent and \a name arguments are sent to the TQWidget constructor.
+
+ \sa setText(), setMaxLength()
+*/
+
+SecTQLineEdit::SecTQLineEdit( TQWidget* parent, const char* name )
+ : TQFrame( parent, name, WNoAutoErase ), d(new SecTQLineEditPrivate( this ))
+{
+ d->init( SecTQString::null );
+}
+
+/*!
+ Constructs a line edit containing the text \a contents.
+
+ The cursor position is set to the end of the line and the maximum
+ text length to 32767 characters.
+
+ The \a parent and \a name arguments are sent to the TQWidget
+ constructor.
+
+ \sa text(), setMaxLength()
+*/
+
+SecTQLineEdit::SecTQLineEdit( const SecTQString& contents, TQWidget* parent, const char* name )
+ : TQFrame( parent, name, WNoAutoErase ), d(new SecTQLineEditPrivate( this ))
+{
+ d->init( contents );
+}
+
+/*!
+ Destroys the line edit.
+*/
+
+SecTQLineEdit::~SecTQLineEdit()
+{
+ delete d;
+}
+
+
+/*!
+ \property SecTQLineEdit::text
+ \brief the line edit's text
+
+ Setting this property clears the selection, clears the undo/redo
+ history, moves the cursor to the end of the line and resets the
+ \c modified property to FALSE.
+
+ The text is truncated to maxLength() length.
+
+ \sa insert()
+*/
+SecTQString SecTQLineEdit::text() const
+{
+ return ( d->text.isNull() ? SecTQString ("") : d->text );
+}
+
+void SecTQLineEdit::setText( const SecTQString& text)
+{
+ resetInputContext();
+ d->setText( text );
+ d->modified = FALSE;
+ d->finishChange( -1, FALSE );
+}
+
+
+/*!
+ \property SecTQLineEdit::displayText
+ \brief the displayed text
+
+ If \c EchoMode is \c Normal this returns the same as text(); if
+ \c EchoMode is \c Password it returns a string of asterisks
+ text().length() characters long, e.g. "******"; if \c EchoMode is
+ \c NoEcho returns an empty string, "".
+
+ \sa setEchoMode() text() EchoMode
+*/
+
+TQString SecTQLineEdit::displayText() const
+{
+ if ( d->echoMode == NoEcho )
+ return TQString::fromLatin1("");
+
+ TQChar pwd_char = TQChar (style().styleHint( TQStyle::SH_LineEdit_PasswordCharacter, this));
+ TQString res;
+ res.fill (pwd_char, d->text.length ());
+ return res;
+}
+
+
+/*!
+ \property SecTQLineEdit::maxLength
+ \brief the maximum permitted length of the text
+
+ If the text is too long, it is truncated at the limit.
+
+ If truncation occurs any selected text will be unselected, the
+ cursor position is set to 0 and the first part of the string is
+ shown.
+*/
+
+int SecTQLineEdit::maxLength() const
+{
+ return d->maxLength;
+}
+
+void SecTQLineEdit::setMaxLength( int maxLength )
+{
+ d->maxLength = maxLength;
+ setText( d->text );
+}
+
+
+
+/*!
+ \property SecTQLineEdit::frame
+ \brief whether the line edit draws itself with a frame
+
+ If enabled (the default) the line edit draws itself inside a
+ two-pixel frame, otherwise the line edit draws itself without any
+ frame.
+*/
+bool SecTQLineEdit::frame() const
+{
+ return frameShape() != NoFrame;
+}
+
+
+void SecTQLineEdit::setFrame( bool enable )
+{
+ setFrameStyle( enable ? ( LineEditPanel | Sunken ) : NoFrame );
+}
+
+
+/*!
+ \enum SecTQLineEdit::EchoMode
+
+ This enum type describes how a line edit should display its
+ contents.
+
+ \value Normal Display characters as they are entered. This is the
+ default.
+ \value NoEcho Do not display anything. This may be appropriate
+ for passwords where even the length of the
+ password should be kept secret.
+ \value Password Display asterisks instead of the characters
+ actually entered.
+
+ \sa setEchoMode() echoMode()
+*/
+
+
+/*!
+ \property SecTQLineEdit::echoMode
+ \brief the line edit's echo mode
+
+ The initial setting is \c Normal, but SecTQLineEdit also supports \c
+ NoEcho and \c Password modes.
+
+ The widget's display and the ability to copy the text is affected
+ by this setting.
+
+ \sa EchoMode displayText()
+*/
+
+SecTQLineEdit::EchoMode SecTQLineEdit::echoMode() const
+{
+ return (EchoMode) d->echoMode;
+}
+
+void SecTQLineEdit::setEchoMode( EchoMode mode )
+{
+ d->echoMode = mode;
+ d->updateTextLayout();
+ update();
+}
+
+
+
+/*!
+ Returns a recommended size for the widget.
+
+ The width returned, in pixels, is usually enough for about 15 to
+ 20 characters.
+*/
+
+TQSize SecTQLineEdit::sizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm( font() );
+ int h = TQMAX(fm.lineSpacing(), 14) + 2*innerMargin;
+ int w = fm.width( 'x' ) * 17; // "some"
+ int m = frameWidth() * 2;
+ return (style().sizeFromContents(TQStyle::CT_LineEdit, this,
+ TQSize( w + m, h + m ).
+ expandedTo(TQApplication::globalStrut())));
+}
+
+
+/*!
+ Returns a minimum size for the line edit.
+
+ The width returned is enough for at least one character.
+*/
+
+TQSize SecTQLineEdit::minimumSizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm = fontMetrics();
+ int h = fm.height() + TQMAX( 2*innerMargin, fm.leading() );
+ int w = fm.maxWidth();
+ int m = frameWidth() * 2;
+ return TQSize( w + m, h + m );
+}
+
+
+/*!
+ \property SecTQLineEdit::cursorPosition
+ \brief the current cursor position for this line edit
+
+ Setting the cursor position causes a repaint when appropriate.
+*/
+
+int SecTQLineEdit::cursorPosition() const
+{
+ return d->cursor;
+}
+
+
+void SecTQLineEdit::setCursorPosition( int pos )
+{
+ if ( pos <= (int) d->text.length() )
+ d->moveCursor( pos );
+}
+
+
+/*!
+ \property SecTQLineEdit::alignment
+ \brief the alignment of the line edit
+
+ Possible Values are \c TQt::AlignAuto, \c TQt::AlignLeft, \c
+ TQt::AlignRight and \c TQt::AlignHCenter.
+
+ Attempting to set the alignment to an illegal flag combination
+ does nothing.
+
+ \sa TQt::AlignmentFlags
+*/
+
+int SecTQLineEdit::alignment() const
+{
+ return d->alignment;
+}
+
+void SecTQLineEdit::setAlignment( int flag )
+{
+ d->alignment = flag & 0x7;
+ update();
+}
+
+
+/*!
+ \obsolete
+ \fn void SecTQLineEdit::cursorRight( bool, int )
+
+ Use cursorForward() instead.
+
+ \sa cursorForward()
+*/
+
+/*!
+ \obsolete
+ \fn void SecTQLineEdit::cursorLeft( bool, int )
+ For compatibilty with older applications only. Use cursorBackward()
+ instead.
+ \sa cursorBackward()
+*/
+
+/*!
+ Moves the cursor forward \a steps characters. If \a mark is TRUE
+ each character moved over is added to the selection; if \a mark is
+ FALSE the selection is cleared.
+
+ \sa cursorBackward()
+*/
+
+void SecTQLineEdit::cursorForward( bool mark, int steps )
+{
+ int cursor = d->cursor;
+ if ( steps > 0 ) {
+ while( steps-- )
+ cursor = d->textLayout.nextCursorPosition( cursor );
+ } else if ( steps < 0 ) {
+ while ( steps++ )
+ cursor = d->textLayout.previousCursorPosition( cursor );
+ }
+ d->moveCursor( cursor, mark );
+}
+
+
+/*!
+ Moves the cursor back \a steps characters. If \a mark is TRUE each
+ character moved over is added to the selection; if \a mark is
+ FALSE the selection is cleared.
+
+ \sa cursorForward()
+*/
+void SecTQLineEdit::cursorBackward( bool mark, int steps )
+{
+ cursorForward( mark, -steps );
+}
+
+/*!
+ Moves the cursor one word forward. If \a mark is TRUE, the word is
+ also selected.
+
+ \sa cursorWordBackward()
+*/
+void SecTQLineEdit::cursorWordForward( bool mark )
+{
+ d->moveCursor( d->textLayout.nextCursorPosition(d->cursor, TQTextLayout::SkipWords), mark );
+}
+
+/*!
+ Moves the cursor one word backward. If \a mark is TRUE, the word
+ is also selected.
+
+ \sa cursorWordForward()
+*/
+
+void SecTQLineEdit::cursorWordBackward( bool mark )
+{
+ d->moveCursor( d->textLayout.previousCursorPosition(d->cursor, TQTextLayout::SkipWords), mark );
+}
+
+
+/*!
+ If no text is selected, deletes the character to the left of the
+ text cursor and moves the cursor one position to the left. If any
+ text is selected, the cursor is moved to the beginning of the
+ selected text and the selected text is deleted.
+
+ \sa del()
+*/
+void SecTQLineEdit::backspace()
+{
+ int priorState = d->undoState;
+ if ( d->hasSelectedText() ) {
+ d->removeSelectedText();
+ } else if ( d->cursor ) {
+ --d->cursor;
+ d->del( TRUE );
+ }
+ d->finishChange( priorState );
+
+ emit backspacePressed();
+}
+
+/*!
+ If no text is selected, deletes the character to the right of the
+ text cursor. If any text is selected, the cursor is moved to the
+ beginning of the selected text and the selected text is deleted.
+
+ \sa backspace()
+*/
+
+void SecTQLineEdit::del()
+{
+ int priorState = d->undoState;
+ if ( d->hasSelectedText() ) {
+ d->removeSelectedText();
+ } else {
+ int n = d->textLayout.nextCursorPosition( d->cursor ) - d->cursor;
+ while ( n-- )
+ d->del();
+ }
+ d->finishChange( priorState );
+}
+
+/*!
+ Moves the text cursor to the beginning of the line unless it is
+ already there. If \a mark is TRUE, text is selected towards the
+ first position; otherwise, any selected text is unselected if the
+ cursor is moved.
+
+ \sa end()
+*/
+
+void SecTQLineEdit::home( bool mark )
+{
+ d->moveCursor( 0, mark );
+}
+
+/*!
+ Moves the text cursor to the end of the line unless it is already
+ there. If \a mark is TRUE, text is selected towards the last
+ position; otherwise, any selected text is unselected if the cursor
+ is moved.
+
+ \sa home()
+*/
+
+void SecTQLineEdit::end( bool mark )
+{
+ d->moveCursor( d->text.length(), mark );
+}
+
+
+/*!
+ \property SecTQLineEdit::modified
+ \brief whether the line edit's contents has been modified by the user
+
+ The modified flag is never read by SecTQLineEdit; it has a default value
+ of FALSE and is changed to TRUE whenever the user changes the line
+ edit's contents.
+
+ This is useful for things that need to provide a default value but
+ do not start out knowing what the default should be (perhaps it
+ depends on other fields on the form). Start the line edit without
+ the best default, and when the default is known, if modified()
+ returns FALSE (the user hasn't entered any text), insert the
+ default value.
+
+ Calling clearModified() or setText() resets the modified flag to
+ FALSE.
+*/
+
+bool SecTQLineEdit::isModified() const
+{
+ return d->modified;
+}
+
+/*!
+ Resets the modified flag to FALSE.
+
+ \sa isModified()
+*/
+void SecTQLineEdit::clearModified()
+{
+ d->modified = FALSE;
+ d->history.clear();
+ d->undoState = 0;
+}
+
+/*!
+ \obsolete
+ \property SecTQLineEdit::edited
+ \brief whether the line edit has been edited. Use modified instead.
+*/
+bool SecTQLineEdit::edited() const { return d->modified; }
+void SecTQLineEdit::setEdited( bool on ) { d->modified = on; }
+
+/*!
+ \obsolete
+ \property SecTQLineEdit::hasMarkedText
+ \brief whether part of the text has been selected by the user. Use hasSelectedText instead.
+*/
+
+/*!
+ \property SecTQLineEdit::hasSelectedText
+ \brief whether there is any text selected
+
+ hasSelectedText() returns TRUE if some or all of the text has been
+ selected by the user; otherwise returns FALSE.
+
+ \sa selectedText()
+*/
+
+
+bool SecTQLineEdit::hasSelectedText() const
+{
+ return d->hasSelectedText();
+}
+
+/*!
+ \obsolete
+ \property SecTQLineEdit::markedText
+ \brief the text selected by the user. Use selectedText instead.
+*/
+
+/*!
+ \property SecTQLineEdit::selectedText
+ \brief the selected text
+
+ If there is no selected text this property's value is
+ TQString::null.
+
+ \sa hasSelectedText()
+*/
+
+SecTQString SecTQLineEdit::selectedText() const
+{
+ if ( d->hasSelectedText() )
+ return d->text.mid( d->selstart, d->selend - d->selstart );
+ return SecTQString::null;
+}
+
+/*!
+ selectionStart() returns the index of the first selected character in the
+ line edit or -1 if no text is selected.
+
+ \sa selectedText()
+*/
+
+int SecTQLineEdit::selectionStart() const
+{
+ return d->hasSelectedText() ? d->selstart : -1;
+}
+
+
+/*!
+ Selects text from position \a start and for \a length characters.
+
+ \sa deselect() selectAll()
+*/
+
+void SecTQLineEdit::setSelection( int start, int length )
+{
+ if ( start < 0 || start > (int)d->text.length() || length < 0 ) {
+ d->selstart = d->selend = 0;
+ } else {
+ d->selstart = start;
+ d->selend = TQMIN( start + length, (int)d->text.length() );
+ d->cursor = d->selend;
+ }
+ update();
+}
+
+
+/*!
+ \property SecTQLineEdit::undoAvailable
+ \brief whether undo is available
+*/
+
+bool SecTQLineEdit::isUndoAvailable() const
+{
+ return d->isUndoAvailable();
+}
+
+/*!
+ \property SecTQLineEdit::redoAvailable
+ \brief whether redo is available
+*/
+
+bool SecTQLineEdit::isRedoAvailable() const
+{
+ return d->isRedoAvailable();
+}
+
+/*!
+ Selects all the text (i.e. highlights it) and moves the cursor to
+ the end. This is useful when a default value has been inserted
+ because if the user types before clicking on the widget, the
+ selected text will be deleted.
+
+ \sa setSelection() deselect()
+*/
+
+void SecTQLineEdit::selectAll()
+{
+ d->selstart = d->selend = d->cursor = 0;
+ d->moveCursor( d->text.length(), TRUE );
+}
+
+/*!
+ Deselects any selected text.
+
+ \sa setSelection() selectAll()
+*/
+
+void SecTQLineEdit::deselect()
+{
+ d->deselect();
+ d->finishChange();
+}
+
+
+/*!
+ Deletes any selected text, inserts \a newText and sets it as the
+ new contents of the line edit.
+*/
+void SecTQLineEdit::insert( const SecTQString &newText )
+{
+// q->resetInputContext(); //#### FIX ME IN QT
+ int priorState = d->undoState;
+ d->removeSelectedText();
+ d->insert( newText );
+ d->finishChange( priorState );
+}
+
+/*!
+ Clears the contents of the line edit.
+*/
+void SecTQLineEdit::clear()
+{
+ int priorState = d->undoState;
+ resetInputContext();
+ d->selstart = 0;
+ d->selend = d->text.length();
+ d->removeSelectedText();
+ d->separate();
+ d->finishChange( priorState );
+}
+
+/*!
+ Undoes the last operation if undo is \link
+ SecTQLineEdit::undoAvailable available\endlink. Deselects any current
+ selection, and updates the selection start to the current cursor
+ position.
+*/
+void SecTQLineEdit::undo()
+{
+#ifndef SECURE_NO_UNDO
+ resetInputContext();
+ d->undo();
+ d->finishChange( -1, FALSE );
+#endif
+}
+
+/*!
+ Redoes the last operation if redo is \link
+ SecTQLineEdit::redoAvailable available\endlink.
+*/
+void SecTQLineEdit::redo()
+{
+#ifndef SECURE_NO_UNDO
+ resetInputContext();
+ d->redo();
+ d->finishChange();
+#endif
+}
+
+
+/*!
+ \property SecTQLineEdit::readOnly
+ \brief whether the line edit is read only.
+
+ In read-only mode, the user can still copy the text to the
+ clipboard (if echoMode() is \c Normal), but cannot edit it.
+
+ SecTQLineEdit does not show a cursor in read-only mode.
+
+ \sa setEnabled()
+*/
+
+bool SecTQLineEdit::isReadOnly() const
+{
+ return d->readOnly;
+}
+
+void SecTQLineEdit::setReadOnly( bool enable )
+{
+ d->readOnly = enable;
+#ifndef QT_NO_CURSOR
+ setCursor( enable ? arrowCursor : ibeamCursor );
+#endif
+ update();
+}
+
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+ Copies the selected text to the clipboard and deletes it, if there
+ is any, and if echoMode() is \c Normal.
+
+ \sa copy() paste() setValidator()
+*/
+
+void SecTQLineEdit::cut()
+{
+ if ( hasSelectedText() ) {
+ copy();
+ del();
+ }
+}
+
+
+/*!
+ Copies the selected text to the clipboard, if there is any, and if
+ echoMode() is \c Normal.
+
+ \sa cut() paste()
+*/
+
+void SecTQLineEdit::copy() const
+{
+ d->copy();
+}
+
+/*!
+ Inserts the clipboard's text at the cursor position, deleting any
+ selected text, providing the line edit is not \link
+ SecTQLineEdit::readOnly read-only\endlink.
+
+ \sa copy() cut()
+*/
+
+void SecTQLineEdit::paste()
+{
+ d->removeSelectedText();
+ insert( TQApplication::clipboard()->text( TQClipboard::Clipboard ) );
+}
+
+void SecTQLineEditPrivate::copy( bool clipboard ) const
+{
+#ifndef SECURE
+ TQString t = q->selectedText();
+ if ( !t.isEmpty() && echoMode == SecTQLineEdit::Normal ) {
+ q->disconnect( TQApplication::clipboard(), SIGNAL(selectionChanged()), q, 0);
+ TQApplication::clipboard()->setText( t, clipboard ? TQClipboard::Clipboard : TQClipboard::Selection );
+ q->connect( TQApplication::clipboard(), SIGNAL(selectionChanged()),
+ q, SLOT(clipboardChanged()) );
+ }
+#endif
+}
+
+#endif // !QT_NO_CLIPBOARD
+
+/*!\reimp
+*/
+
+void SecTQLineEdit::resizeEvent( TQResizeEvent *e )
+{
+ TQFrame::resizeEvent( e );
+}
+
+/*! \reimp
+*/
+bool SecTQLineEdit::event( TQEvent * e )
+{
+ if ( e->type() == TQEvent::AccelOverride && !d->readOnly ) {
+ TQKeyEvent* ke = (TQKeyEvent*) e;
+ if ( ke->state() == NoButton || ke->state() == ShiftButton
+ || ke->state() == Keypad ) {
+ if ( ke->key() < Key_Escape ) {
+ ke->accept();
+ } else if ( ke->state() == NoButton
+ || ke->state() == ShiftButton ) {
+ switch ( ke->key() ) {
+ case Key_Delete:
+ case Key_Home:
+ case Key_End:
+ case Key_Backspace:
+ case Key_Left:
+ case Key_Right:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ } else if ( ke->state() & ControlButton ) {
+ switch ( ke->key() ) {
+// Those are too frequently used for application functionality
+/* case Key_A:
+ case Key_B:
+ case Key_D:
+ case Key_E:
+ case Key_F:
+ case Key_H:
+ case Key_K:
+*/
+ case Key_C:
+ case Key_V:
+ case Key_X:
+ case Key_Y:
+ case Key_Z:
+ case Key_Left:
+ case Key_Right:
+#if defined (Q_WS_WIN)
+ case Key_Insert:
+ case Key_Delete:
+#endif
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ } else if ( e->type() == TQEvent::Timer ) {
+ // should be timerEvent, is here for binary compatibility
+ int timerId = ((TQTimerEvent*)e)->timerId();
+ if ( timerId == d->cursorTimer ) {
+ if(!hasSelectedText() || style().styleHint( TQStyle::SH_BlinkCursorWhenTextSelected ))
+ d->setCursorVisible( !d->cursorVisible );
+ } else if ( timerId == d->tripleClickTimer ) {
+ killTimer( d->tripleClickTimer );
+ d->tripleClickTimer = 0;
+ }
+ }
+ return TQWidget::event( e );
+}
+
+/*! \reimp
+*/
+void SecTQLineEdit::mousePressEvent( TQMouseEvent* e )
+{
+ if ( e->button() == RightButton )
+ return;
+ if ( d->tripleClickTimer && ( e->pos() - d->tripleClick ).manhattanLength() <
+ TQApplication::startDragDistance() ) {
+ selectAll();
+ return;
+ }
+ bool mark = e->state() & ShiftButton;
+ int cursor = d->xToPos( e->pos().x() );
+ d->moveCursor( cursor, mark );
+}
+
+/*! \reimp
+*/
+void SecTQLineEdit::mouseMoveEvent( TQMouseEvent * e )
+{
+
+#ifndef QT_NO_CURSOR
+ if ( ( e->state() & MouseButtonMask ) == 0 ) {
+ if ( !d->readOnly )
+ setCursor( ( d->inSelection( e->pos().x() ) ? arrowCursor : ibeamCursor ) );
+ }
+#endif
+
+ if ( e->state() & LeftButton ) {
+ d->moveCursor( d->xToPos( e->pos().x() ), TRUE );
+ }
+}
+
+/*! \reimp
+*/
+void SecTQLineEdit::mouseReleaseEvent( TQMouseEvent* e )
+{
+#ifndef QT_NO_CLIPBOARD
+ if (TQApplication::clipboard()->supportsSelection() ) {
+ if ( e->button() == LeftButton ) {
+ d->copy( FALSE );
+ } else if ( !d->readOnly && e->button() == MidButton ) {
+ d->deselect();
+ insert( TQApplication::clipboard()->text( TQClipboard::Selection ) );
+ }
+ }
+#endif
+}
+
+/*! \reimp
+*/
+void SecTQLineEdit::mouseDoubleClickEvent( TQMouseEvent* e )
+{
+ if ( e->button() == TQt::LeftButton ) {
+ deselect();
+ d->cursor = d->xToPos( e->pos().x() );
+ d->cursor = d->textLayout.previousCursorPosition( d->cursor, TQTextLayout::SkipWords );
+ // ## text layout should support end of words.
+ int end = d->textLayout.nextCursorPosition( d->cursor, TQTextLayout::SkipWords );
+ while ( end > d->cursor && d->text[end-1].isSpace() )
+ --end;
+ d->moveCursor( end, TRUE );
+ d->tripleClickTimer = startTimer( TQApplication::doubleClickInterval() );
+ d->tripleClick = e->pos();
+ }
+}
+
+/*!
+ \fn void SecTQLineEdit::returnPressed()
+
+ This signal is emitted when the Return or Enter key is pressed.
+*/
+
+/*!
+ Converts key press event \a e into a line edit action.
+
+ If Return or Enter is pressed the signal returnPressed() is
+ emitted.
+
+ The default key bindings are listed in the \link #desc detailed
+ description.\endlink
+*/
+
+void SecTQLineEdit::keyPressEvent( TQKeyEvent * e )
+{
+ d->setCursorVisible( TRUE );
+ if ( e->key() == Key_Enter || e->key() == Key_Return ) {
+ emit returnPressed();
+ e->ignore();
+ return;
+ }
+ if ( !d->readOnly ) {
+ TQString t = e->text();
+ if ( !t.isEmpty() && (!e->ascii() || e->ascii()>=32) &&
+ e->key() != Key_Delete &&
+ e->key() != Key_Backspace ) {
+#ifdef Q_WS_X11
+ extern bool tqt_hebrew_keyboard_hack;
+ if ( tqt_hebrew_keyboard_hack ) {
+ // the X11 keyboard layout is broken and does not reverse
+ // braces correctly. This is a hack to get halfway correct
+ // behaviour
+ if ( d->isRightToLeft() ) {
+ TQChar *c = (TQChar *)t.unicode();
+ int l = t.length();
+ while( l-- ) {
+ if ( c->mirrored() )
+ *c = c->mirroredChar();
+ c++;
+ }
+ }
+ }
+#endif
+ insert( t );
+ return;
+ }
+ }
+ bool unknown = FALSE;
+ if ( e->state() & ControlButton ) {
+ switch ( e->key() ) {
+ case Key_A:
+#if defined(Q_WS_X11)
+ home( e->state() & ShiftButton );
+#else
+ selectAll();
+#endif
+ break;
+ case Key_B:
+ cursorForward( e->state() & ShiftButton, -1 );
+ break;
+#ifndef QT_NO_CLIPBOARD
+ case Key_C:
+ copy();
+ break;
+#endif
+ case Key_D:
+ if ( !d->readOnly ) {
+ del();
+ }
+ break;
+ case Key_E:
+ end( e->state() & ShiftButton );
+ break;
+ case Key_F:
+ cursorForward( e->state() & ShiftButton, 1 );
+ break;
+ case Key_H:
+ if ( !d->readOnly ) {
+ backspace();
+ }
+ break;
+ case Key_K:
+ if ( !d->readOnly ) {
+ int priorState = d->undoState;
+ d->deselect();
+ while ( d->cursor < (int) d->text.length() )
+ d->del();
+ d->finishChange( priorState );
+ }
+ break;
+#if defined(Q_WS_X11)
+ case Key_U:
+ if ( !d->readOnly )
+ clear();
+ break;
+#endif
+#ifndef QT_NO_CLIPBOARD
+ case Key_V:
+ if ( !d->readOnly )
+ paste();
+ break;
+ case Key_X:
+ if ( !d->readOnly && d->hasSelectedText() && echoMode() == Normal ) {
+ copy();
+ del();
+ }
+ break;
+#if defined (Q_WS_WIN)
+ case Key_Insert:
+ copy();
+ break;
+#endif
+#endif
+ case Key_Delete:
+ if ( !d->readOnly ) {
+ cursorWordForward( TRUE );
+ del();
+ }
+ break;
+ case Key_Backspace:
+ if ( !d->readOnly ) {
+ cursorWordBackward( TRUE );
+ del();
+ }
+ break;
+ case Key_Right:
+ case Key_Left:
+ if ( d->isRightToLeft() == (e->key() == Key_Right) ) {
+ if ( echoMode() == Normal )
+ cursorWordBackward( e->state() & ShiftButton );
+ else
+ home( e->state() & ShiftButton );
+ } else {
+ if ( echoMode() == Normal )
+ cursorWordForward( e->state() & ShiftButton );
+ else
+ end( e->state() & ShiftButton );
+ }
+ break;
+ case Key_Z:
+ if ( !d->readOnly ) {
+ if(e->state() & ShiftButton)
+ redo();
+ else
+ undo();
+ }
+ break;
+ case Key_Y:
+ if ( !d->readOnly )
+ redo();
+ break;
+ default:
+ unknown = TRUE;
+ }
+ } else { // ### check for *no* modifier
+ switch ( e->key() ) {
+ case Key_Shift:
+ // ### TODO
+ break;
+ case Key_Left:
+ case Key_Right: {
+ int step = (d->isRightToLeft() == (e->key() == Key_Right)) ? -1 : 1;
+ cursorForward( e->state() & ShiftButton, step );
+ }
+ break;
+ case Key_Backspace:
+ if ( !d->readOnly ) {
+ backspace();
+ }
+ break;
+ case Key_Home:
+#ifdef Q_WS_MACX
+ case Key_Up:
+#endif
+ home( e->state() & ShiftButton );
+ break;
+ case Key_End:
+#ifdef Q_WS_MACX
+ case Key_Down:
+#endif
+ end( e->state() & ShiftButton );
+ break;
+ case Key_Delete:
+ if ( !d->readOnly ) {
+#if defined (Q_WS_WIN)
+ if ( e->state() & ShiftButton ) {
+ cut();
+ break;
+ }
+#endif
+ del();
+ }
+ break;
+#if defined (Q_WS_WIN)
+ case Key_Insert:
+ if ( !d->readOnly && e->state() & ShiftButton )
+ paste();
+ else
+ unknown = TRUE;
+ break;
+#endif
+ case Key_F14: // Undo key on Sun keyboards
+ if ( !d->readOnly )
+ undo();
+ break;
+#ifndef QT_NO_CLIPBOARD
+ case Key_F16: // Copy key on Sun keyboards
+ copy();
+ break;
+ case Key_F18: // Paste key on Sun keyboards
+ if ( !d->readOnly )
+ paste();
+ break;
+ case Key_F20: // Cut key on Sun keyboards
+ if ( !d->readOnly && hasSelectedText() && echoMode() == Normal ) {
+ copy();
+ del();
+ }
+ break;
+#endif
+ default:
+ unknown = TRUE;
+ }
+ }
+ if ( e->key() == Key_Direction_L )
+ d->direction = TQChar::DirL;
+ else if ( e->key() == Key_Direction_R )
+ d->direction = TQChar::DirR;
+
+ if ( unknown )
+ e->ignore();
+}
+
+/*! \reimp
+ */
+void SecTQLineEdit::imStartEvent( TQIMEvent *e )
+{
+ if ( d->readOnly ) {
+ e->ignore();
+ return;
+ }
+ d->removeSelectedText();
+ d->updateMicroFocusHint();
+ d->imstart = d->imend = d->imselstart = d->imselend = d->cursor;
+}
+
+/*! \reimp
+ */
+void SecTQLineEdit::imComposeEvent( TQIMEvent *e )
+{
+ if ( d->readOnly ) {
+ e->ignore();
+ } else {
+ d->text.replace( d->imstart, d->imend - d->imstart, e->text() );
+ d->imend = d->imstart + e->text().length();
+ d->imselstart = d->imstart + e->cursorPos();
+ d->imselend = d->imselstart + e->selectionLength();
+ d->cursor = e->selectionLength() ? d->imend : d->imselend;
+ d->updateTextLayout();
+ update();
+ }
+}
+
+/*! \reimp
+ */
+void SecTQLineEdit::imEndEvent( TQIMEvent *e )
+{
+ if ( d->readOnly ) {
+ e->ignore();
+ } else {
+ d->text.remove( d->imstart, d->imend - d->imstart );
+ d->cursor = d->imselstart = d->imselend = d->imend = d->imstart;
+ d->textDirty = TRUE;
+ insert( e->text() );
+ }
+}
+
+/*!\reimp
+*/
+
+void SecTQLineEdit::focusInEvent( TQFocusEvent* e )
+{
+ if ( e->reason() == TQFocusEvent::Tab ||
+ e->reason() == TQFocusEvent::Backtab ||
+ e->reason() == TQFocusEvent::Shortcut )
+ selectAll();
+ if ( !d->cursorTimer ) {
+ int cft = TQApplication::cursorFlashTime();
+ d->cursorTimer = cft ? startTimer( cft/2 ) : -1;
+ }
+ d->updateMicroFocusHint();
+}
+
+/*!\reimp
+*/
+
+void SecTQLineEdit::focusOutEvent( TQFocusEvent* e )
+{
+ if ( e->reason() != TQFocusEvent::ActiveWindow &&
+ e->reason() != TQFocusEvent::Popup )
+ deselect();
+ d->setCursorVisible( FALSE );
+ if ( d->cursorTimer > 0 )
+ killTimer( d->cursorTimer );
+ d->cursorTimer = 0;
+ emit lostFocus();
+}
+
+/*!\reimp
+*/
+void SecTQLineEdit::drawContents( TQPainter *p )
+{
+ const TQColorGroup& cg = colorGroup();
+ TQRect cr = contentsRect();
+ TQFontMetrics fm = fontMetrics();
+ TQRect lineRect( cr.x() + innerMargin, cr.y() + (cr.height() - fm.height() + 1) / 2,
+ cr.width() - 2*innerMargin, fm.height() );
+ TQBrush bg = TQBrush( paletteBackgroundColor() );
+ if ( paletteBackgroundPixmap() )
+ bg = TQBrush( cg.background(), *paletteBackgroundPixmap() );
+ else if ( !isEnabled() )
+ bg = cg.brush( TQColorGroup::Background );
+ p->save();
+ p->setClipRegion( TQRegion(cr) - lineRect );
+ p->fillRect( cr, bg );
+ p->restore();
+ SecTQSharedDoubleBuffer buffer( p, lineRect.x(), lineRect.y(),
+ lineRect.width(), lineRect.height(),
+ hasFocus() ? SecTQSharedDoubleBuffer::Force : 0 );
+ p = buffer.painter();
+ p->fillRect( lineRect, bg );
+
+ // locate cursor position
+ int cix = 0;
+ TQTextItem ci = d->textLayout.findItem( d->cursor );
+ if ( ci.isValid() ) {
+ if ( d->cursor != (int)d->text.length() && d->cursor == ci.from() + ci.length()
+ && ci.isRightToLeft() != d->isRightToLeft() )
+ ci = d->textLayout.findItem( d->cursor + 1 );
+ cix = ci.x() + ci.cursorToX( d->cursor - ci.from() );
+ }
+
+ // horizontal scrolling
+ int minLB = TQMAX( 0, -fm.minLeftBearing() );
+ int minRB = TQMAX( 0, -fm.minRightBearing() );
+ int widthUsed = d->textLayout.widthUsed() + 1 + minRB;
+ if ( (minLB + widthUsed) <= lineRect.width() ) {
+ switch ( d->visualAlignment() ) {
+ case AlignRight:
+ d->hscroll = widthUsed - lineRect.width();
+ break;
+ case AlignHCenter:
+ d->hscroll = ( widthUsed - lineRect.width() ) / 2;
+ break;
+ default:
+ d->hscroll = 0;
+ break;
+ }
+ d->hscroll -= minLB;
+ } else if ( cix - d->hscroll >= lineRect.width() ) {
+ d->hscroll = cix - lineRect.width() + 1;
+ } else if ( cix - d->hscroll < 0 ) {
+ d->hscroll = cix;
+ } else if ( widthUsed - d->hscroll < lineRect.width() ) {
+ d->hscroll = widthUsed - lineRect.width() + 1;
+ }
+ // the y offset is there to keep the baseline constant in case we have script changes in the text.
+ TQPoint topLeft = lineRect.topLeft() - TQPoint(d->hscroll, d->ascent-fm.ascent());
+
+ // draw text, selections and cursors
+ p->setPen( cg.text() );
+ bool supressCursor = d->readOnly, hasRightToLeft = d->isRightToLeft();
+ int textflags = 0;
+ if ( font().underline() )
+ textflags |= TQt::Underline;
+ if ( font().strikeOut() )
+ textflags |= TQt::StrikeOut;
+ if ( font().overline() )
+ textflags |= TQt::Overline;
+
+ for ( int i = 0; i < d->textLayout.numItems(); i++ ) {
+ TQTextItem ti = d->textLayout.itemAt( i );
+ hasRightToLeft |= ti.isRightToLeft();
+ int tix = topLeft.x() + ti.x();
+ int first = ti.from();
+ int last = ti.from() + ti.length() - 1;
+
+ // text and selection
+ if ( d->selstart < d->selend && (last >= d->selstart && first < d->selend ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->selstart - first, 0 ) ),
+ lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->selend - first, last - first + 1 ) ) - 1,
+ lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRegion( TQRegion( lineRect ) - highlight, TQPainter::CoordPainter );
+ p->drawTextItem( topLeft, ti, textflags );
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+ p->fillRect( highlight, cg.highlight() );
+ p->setPen( cg.highlightedText() );
+ p->drawTextItem( topLeft, ti, textflags );
+ p->restore();
+ } else {
+ p->drawTextItem( topLeft, ti, textflags );
+ }
+
+ // input method edit area
+ if ( d->imstart < d->imend && (last >= d->imstart && first < d->imend ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->imstart - first, 0 ) ), lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->imend - first, last - first + 1 ) )-1, lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+
+ int h1, s1, v1, h2, s2, v2;
+ cg.color( TQColorGroup::Base ).hsv( &h1, &s1, &v1 );
+ cg.color( TQColorGroup::Background ).hsv( &h2, &s2, &v2 );
+ TQColor imCol;
+ imCol.setHsv( h1, s1, ( v1 + v2 ) / 2 );
+ p->fillRect( highlight, imCol );
+ p->drawTextItem( topLeft, ti, textflags );
+ p->restore();
+ }
+
+ // input method selection
+ if ( d->imselstart < d->imselend && (last >= d->imselstart && first < d->imselend ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->imselstart - first, 0 ) ), lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->imselend - first, last - first + 1 ) )-1, lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+ p->fillRect( highlight, cg.text() );
+ p->setPen( paletteBackgroundColor() );
+ p->drawTextItem( topLeft, ti, textflags );
+ p->restore();
+ }
+ }
+
+ // draw cursor
+ if ( d->cursorVisible && !supressCursor ) {
+ TQPoint from( topLeft.x() + cix, lineRect.top() );
+ TQPoint to = from + TQPoint( 0, lineRect.height() );
+ p->drawLine( from, to );
+ if ( hasRightToLeft ) {
+ to = from + TQPoint( (ci.isRightToLeft()?-2:2), 2 );
+ p->drawLine( from, to );
+ from.ry() += 4;
+ p->drawLine( from, to );
+ }
+ }
+ buffer.end();
+}
+
+
+enum { IdUndo, IdRedo, IdSep1, IdCut, IdCopy, IdPaste, IdClear, IdSep2, IdSelectAll };
+
+
+/*! \reimp */
+void SecTQLineEdit::windowActivationChange( bool b )
+{
+ //### remove me with WHighlightSelection attribute
+ if ( palette().active() != palette().inactive() )
+ update();
+ TQWidget::windowActivationChange( b );
+}
+
+/*! \reimp */
+
+void SecTQLineEdit::setPalette( const TQPalette & p )
+{
+ //### remove me with WHighlightSelection attribute
+ TQWidget::setPalette( p );
+ update();
+}
+
+/*!
+ \obsolete
+ \fn void SecTQLineEdit::repaintArea( int from, int to )
+ Repaints all characters from \a from to \a to. If cursorPos is
+ between from and to, ensures that cursorPos is visible.
+*/
+
+/*! \reimp
+ */
+void SecTQLineEdit::setFont( const TQFont & f )
+{
+ TQWidget::setFont( f );
+ d->updateTextLayout();
+}
+
+
+void SecTQLineEdit::clipboardChanged()
+{
+}
+
+void SecTQLineEditPrivate::init( const SecTQString& txt )
+{
+#ifndef QT_NO_CURSOR
+ q->setCursor( readOnly ? arrowCursor : ibeamCursor );
+#endif
+ q->setFocusPolicy( TQWidget::StrongFocus );
+ q->setInputMethodEnabled( TRUE );
+ // Specifies that this widget can use more, but is able to survive on
+ // less, horizontal space; and is fixed vertically.
+ q->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
+ q->setBackgroundMode( PaletteBase );
+ q->setKeyCompression( TRUE );
+ q->setMouseTracking( TRUE );
+ q->setAcceptDrops( TRUE );
+ q->setFrame( TRUE );
+ text = txt;
+ updateTextLayout();
+ cursor = text.length();
+}
+
+void SecTQLineEditPrivate::updateTextLayout()
+{
+ // replace all non-printable characters with spaces (to avoid
+ // drawing boxes when using fonts that don't have glyphs for such
+ // characters)
+ const TQString &displayText = q->displayText();
+ TQString str(displayText.unicode(), displayText.length());
+ TQChar* uc = (TQChar*)str.unicode();
+ for (int i = 0; i < (int)str.length(); ++i) {
+ if (! uc[i].isPrint())
+ uc[i] = TQChar(0x0020);
+ }
+ textLayout.setText( str, q->font() );
+ // ### want to do textLayout.setRightToLeft( text.isRightToLeft() );
+ textLayout.beginLayout( TQTextLayout::SingleLine );
+ textLayout.beginLine( INT_MAX );
+ while ( !textLayout.atEnd() )
+ textLayout.addCurrentItem();
+ ascent = 0;
+ textLayout.endLine(0, 0, TQt::AlignLeft, &ascent);
+}
+
+int SecTQLineEditPrivate::xToPos( int x, TQTextItem::CursorPosition betweenOrOn ) const
+{
+ x-= q->contentsRect().x() - hscroll + innerMargin;
+ for ( int i = 0; i < textLayout.numItems(); ++i ) {
+ TQTextItem ti = textLayout.itemAt( i );
+ TQRect tir = ti.rect();
+ if ( x >= tir.left() && x <= tir.right() )
+ return ti.xToCursor( x - tir.x(), betweenOrOn ) + ti.from();
+ }
+ return x < 0 ? 0 : text.length();
+}
+
+
+TQRect SecTQLineEditPrivate::cursorRect() const
+{
+ TQRect cr = q->contentsRect();
+ int cix = cr.x() - hscroll + innerMargin;
+ TQTextItem ci = textLayout.findItem( cursor );
+ if ( ci.isValid() ) {
+ if ( cursor != (int)text.length() && cursor == ci.from() + ci.length()
+ && ci.isRightToLeft() != isRightToLeft() )
+ ci = textLayout.findItem( cursor + 1 );
+ cix += ci.x() + ci.cursorToX( cursor - ci.from() );
+ }
+ int ch = q->fontMetrics().height();
+ return TQRect( cix-4, cr.y() + ( cr.height() - ch + 1) / 2, 8, ch + 1 );
+}
+
+void SecTQLineEditPrivate::updateMicroFocusHint()
+{
+ if ( q->hasFocus() ) {
+ TQRect r = cursorRect();
+ q->setMicroFocusHint( r.x(), r.y(), r.width(), r.height() );
+ }
+}
+
+void SecTQLineEditPrivate::moveCursor( int pos, bool mark )
+{
+ if ( pos != cursor )
+ separate();
+ bool fullUpdate = mark || hasSelectedText();
+ if ( mark ) {
+ int anchor;
+ if ( selend > selstart && cursor == selstart )
+ anchor = selend;
+ else if ( selend > selstart && cursor == selend )
+ anchor = selstart;
+ else
+ anchor = cursor;
+ selstart = TQMIN( anchor, pos );
+ selend = TQMAX( anchor, pos );
+ } else {
+ selstart = selend = 0;
+ }
+ if ( fullUpdate ) {
+ cursor = pos;
+ q->update();
+ } else {
+ setCursorVisible( FALSE );
+ cursor = pos;
+ setCursorVisible( TRUE );
+ }
+ updateMicroFocusHint();
+ if ( mark ) {
+ if( !q->style().styleHint( TQStyle::SH_BlinkCursorWhenTextSelected ))
+ setCursorVisible( FALSE );
+ emit q->selectionChanged();
+ }
+}
+
+void SecTQLineEditPrivate::finishChange( int validateFromState, bool setModified )
+{
+ bool lineDirty = selDirty;
+ if ( textDirty ) {
+ if ( validateFromState >= 0 ) {
+#ifndef SECURE_NO_UNDO
+ undo( validateFromState );
+#endif /* SECURE_NO_UNDO */
+ history.resize( undoState );
+ textDirty = setModified = FALSE;
+ }
+ updateTextLayout();
+ updateMicroFocusHint();
+ lineDirty |= textDirty;
+ if ( setModified )
+ modified = TRUE;
+ if ( textDirty ) {
+ textDirty = FALSE;
+ emit q->textChanged( text );
+ }
+ emit q->textModified( text );
+#if defined(QT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( q, 0, TQAccessible::ValueChanged );
+#endif
+ }
+ if ( selDirty ) {
+ selDirty = FALSE;
+ emit q->selectionChanged();
+ }
+ if ( lineDirty || !setModified )
+ q->update();
+}
+
+void SecTQLineEditPrivate::setText( const SecTQString& txt )
+{
+ deselect();
+ SecTQString oldText = text;
+ text = txt.isEmpty() ? SecTQString ("") : txt.left( maxLength );
+ history.clear();
+ undoState = 0;
+ cursor = text.length();
+ textDirty = 1; // Err on safe side.
+}
+
+
+void SecTQLineEditPrivate::setCursorVisible( bool visible )
+{
+ if ( (bool)cursorVisible == visible )
+ return;
+ if ( cursorTimer )
+ cursorVisible = visible;
+ TQRect r = cursorRect();
+ if ( !q->contentsRect().contains( r ) )
+ q->update();
+ else
+ q->update( r );
+}
+
+#ifndef SECURE_NO_UNDO
+
+void SecTQLineEditPrivate::addCommand( const Command& cmd )
+{
+ if ( separator && undoState && history[undoState-1].type != Separator ) {
+ history.resize( undoState + 2 );
+ history[undoState++] = Command( Separator, 0, 0 );
+ } else {
+ history.resize( undoState + 1);
+ }
+ separator = FALSE;
+ history[ undoState++ ] = cmd;
+}
+#endif /* SECURE_NO_UNDO */
+
+void SecTQLineEditPrivate::insert( const SecTQString& s )
+{
+ int remaining = maxLength - text.length();
+ text.insert( cursor, s.left(remaining) );
+ for ( int i = 0; i < (int) s.left(remaining).length(); ++i )
+ {
+#ifndef SECURE_NO_UNDO
+ addCommand( Command( Insert, cursor, s.at(i) ) );
+#endif /* SECURE_NO_UNDO */
+ cursor++;
+ }
+ textDirty = TRUE;
+}
+
+void SecTQLineEditPrivate::del( bool wasBackspace )
+{
+ if ( cursor < (int) text.length() ) {
+#ifndef SECURE_NO_UNDO
+ addCommand ( Command( (CommandType)(wasBackspace?Remove:Delete), cursor, text.at(cursor) ) );
+#endif /* SECURE_NO_UNDO */
+ text.remove( cursor, 1 );
+ textDirty = TRUE;
+ }
+}
+
+void SecTQLineEditPrivate::removeSelectedText()
+{
+ if ( selstart < selend && selend <= (int) text.length() ) {
+ separate();
+#ifndef SECURE_NO_UNDO
+ int i ;
+ if ( selstart <= cursor && cursor < selend ) {
+ // cursor is within the selection. Split up the commands
+ // to be able to restore the correct cursor position
+ for ( i = cursor; i >= selstart; --i )
+ addCommand ( Command( DeleteSelection, i, text.at(i) ) );
+ for ( i = selend - 1; i > cursor; --i )
+ addCommand ( Command( DeleteSelection, i - cursor + selstart - 1, text.at(i) ) );
+ } else {
+ for ( i = selend-1; i >= selstart; --i )
+ addCommand ( Command( RemoveSelection, i, text.at(i) ) );
+ }
+#endif /* SECURE_NO_UNDO */
+ text.remove( selstart, selend - selstart );
+ if ( cursor > selstart )
+ cursor -= TQMIN( cursor, selend ) - selstart;
+ deselect();
+ textDirty = TRUE;
+ }
+}
+
+#include "secqlineedit.moc"