summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/widgets/tqlineedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/widgets/tqlineedit.cpp')
-rw-r--r--tqtinterface/qt4/src/widgets/tqlineedit.cpp108
1 files changed, 100 insertions, 8 deletions
diff --git a/tqtinterface/qt4/src/widgets/tqlineedit.cpp b/tqtinterface/qt4/src/widgets/tqlineedit.cpp
index 2d41152..10c1be8 100644
--- a/tqtinterface/qt4/src/widgets/tqlineedit.cpp
+++ b/tqtinterface/qt4/src/widgets/tqlineedit.cpp
@@ -40,6 +40,12 @@
#include "tqlineedit.h"
#ifndef TQT_NO_LINEEDIT
+
+// Keep this position to avoid patch rejection
+#ifndef TQT_NO_IM
+#include "tqinputcontext.h"
+#endif
+
#include "tqpainter.h"
#include "tqdrawutil.h"
#include "tqfontmetrics.h"
@@ -248,12 +254,17 @@ struct TQLineEditPrivate : public TQt
// input methods
int imstart, imend, imselstart, imselend;
+ bool composeMode() const { return preeditLength(); }
+ bool hasIMSelection() const { return imSelectionLength(); }
+ int preeditLength() const { return ( imend - imstart ); }
+ int imSelectionLength() const { return ( imselend - imselstart ); }
// complex text tqlayout
TQTextLayout textLayout;
void updateTextLayout();
void moveCursor( int pos, bool mark = FALSE );
void setText( const TQString& txt );
+ int xToPosInternal( int x, TQTextItem::CursorPosition ) const;
int xToPos( int x, TQTextItem::CursorPosition = TQTextItem::BetweenCharacters ) const;
inline int visualAlignment() const { return tqalignment ? tqalignment : int( isRightToLeft() ? TQt::AlignRight : TQt::AlignLeft ); }
TQRect cursorRect() const;
@@ -591,6 +602,7 @@ void TQLineEdit::setEchoMode( EchoMode mode )
return;
d->echoMode = mode;
d->updateTextLayout();
+ setInputMethodEnabled( mode == Normal );
update();
}
@@ -1422,6 +1434,8 @@ bool TQLineEdit::event( TQEvent * e )
*/
void TQLineEdit::mousePressEvent( TQMouseEvent* e )
{
+ if ( sendMouseEventToInputContext( e ) )
+ return;
if ( e->button() == Qt::RightButton )
return;
if ( d->tripleClickTimer && ( e->pos() - d->tripleClick ).manhattanLength() <
@@ -1451,7 +1465,8 @@ void TQLineEdit::mousePressEvent( TQMouseEvent* e )
*/
void TQLineEdit::mouseMoveEvent( TQMouseEvent * e )
{
-
+ if ( sendMouseEventToInputContext( e ) )
+ return;
#ifndef TQT_NO_CURSOR
if ( ( e->state() & Qt::MouseButtonMask ) == 0 ) {
if ( !d->readOnly && d->dragEnabled
@@ -1480,6 +1495,8 @@ void TQLineEdit::mouseMoveEvent( TQMouseEvent * e )
*/
void TQLineEdit::mouseReleaseEvent( TQMouseEvent* e )
{
+ if ( sendMouseEventToInputContext( e ) )
+ return;
#ifndef TQT_NO_DRAGANDDROP
if ( e->button() == Qt::LeftButton ) {
if ( d->dndTimer ) {
@@ -1506,6 +1523,8 @@ void TQLineEdit::mouseReleaseEvent( TQMouseEvent* e )
*/
void TQLineEdit::mouseDoubleClickEvent( TQMouseEvent* e )
{
+ if ( sendMouseEventToInputContext( e ) )
+ return;
if ( e->button() == Qt::LeftButton ) {
deselect();
d->cursor = d->xToPos( e->pos().x() );
@@ -1775,6 +1794,33 @@ void TQLineEdit::keyPressEvent( TQKeyEvent * e )
e->ignore();
}
+
+/*!
+ This function is not intended as polymorphic usage. Just a shared code
+ fragment that calls TQWidget::sendMouseEventToInputContext() easily for this
+ class.
+ */
+bool TQLineEdit::sendMouseEventToInputContext( TQMouseEvent *e )
+{
+#ifndef TQT_NO_IM
+ if ( d->composeMode() ) {
+ int cursor = d->xToPosInternal( e->pos().x(), TQTextItem::OnCharacters );
+ int mousePos = cursor - d->imstart;
+ if ( mousePos >= 0 && mousePos < d->preeditLength() ) {
+ TQWidget::sendMouseEventToInputContext( mousePos, e->type(),
+ e->button(), e->state() );
+ } else if ( e->type() != TQEvent::MouseMove ) {
+ // send button events on out of preedit
+ TQWidget::sendMouseEventToInputContext( -1, e->type(),
+ e->button(), e->state() );
+ }
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+
/*! \reimp
*/
void TQLineEdit::imStartEvent( TQIMEvent *e )
@@ -1841,6 +1887,8 @@ void TQLineEdit::focusInEvent( TQFocusEvent* tqfe )
}
if( !hasSelectedText() || tqstyle().tqstyleHint( TQStyle::SH_BlinkCursorWhenTextSelected ) )
d->setCursorVisible( TRUE );
+ if ( d->hasIMSelection() )
+ d->cursor = d->imselstart;
d->updateMicroFocusHint();
}
@@ -1934,6 +1982,14 @@ void TQLineEdit::drawContents( TQPainter *p )
} else if (d->hscroll < 0) {
d->hscroll = 0;
}
+ // This updateMicroFocusHint() is corresponding to update() at
+ // IMCompose event. Although the function is invoked from various
+ // other points, some situations such as "candidate selection on
+ // AlignHCenter'ed text" need this invocation because
+ // updateMicroFocusHint() requires updated contentsRect(), and
+ // there are no other chances in such situation that invoke the
+ // function.
+ d->updateMicroFocusHint();
// 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());
@@ -1974,7 +2030,7 @@ void TQLineEdit::drawContents( TQPainter *p )
}
// input method edit area
- if ( d->imstart < d->imend && (last >= d->imstart && first < d->imend ) ) {
+ if ( d->composeMode() && (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();
@@ -1987,11 +2043,16 @@ void TQLineEdit::drawContents( TQPainter *p )
imCol.setHsv( h1, s1, ( v1 + v2 ) / 2 );
p->fillRect( highlight, imCol );
p->tqdrawTextItem( topLeft, ti, textflags );
+ // draw preedit's underline
+ if (d->imend - d->imstart > 0) {
+ p->setPen( cg.text() );
+ p->drawLine( highlight.bottomLeft(), highlight.bottomRight() );
+ }
p->restore();
}
// input method selection
- if ( d->imselstart < d->imselend && (last >= d->imselstart && first < d->imselend ) ) {
+ if ( d->hasIMSelection() && (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();
@@ -2019,7 +2080,11 @@ void TQLineEdit::drawContents( TQPainter *p )
}
// draw cursor
- if ( d->cursorVisible && !supressCursor ) {
+ //
+ // Asian users regard IM selection text as cursor on candidate
+ // selection phase of input method, so ordinary cursor should be
+ // invisible if IM selection text exists.
+ if ( d->cursorVisible && !supressCursor && !d->hasIMSelection() ) {
TQPoint from( topLeft.x() + cix, lineRect.top() );
TQPoint to = from + TQPoint( 0, lineRect.height() );
p->drawLine( from, to );
@@ -2134,6 +2199,10 @@ enum { IdUndo, IdRedo, IdSep1, IdCut, IdCopy, IdPaste, IdClear, IdSep2, IdSelect
void TQLineEdit::contextMenuEvent( TQContextMenuEvent * e )
{
#ifndef TQT_NO_POPUPMENU
+#ifndef TQT_NO_IM
+ if ( d->composeMode() )
+ return;
+#endif
d->separate();
TQPopupMenu *menu = createPopupMenu();
if (!menu)
@@ -2187,6 +2256,13 @@ TQPopupMenu *TQLineEdit::createPopupMenu()
+ ACCEL_KEY( A )
#endif
);
+
+#ifndef TQT_NO_IM
+ TQInputContext *qic = getInputContext();
+ if ( qic )
+ qic->addMenusTo( popup );
+#endif
+
popup->setItemEnabled( id - IdUndo, d->isUndoAvailable() );
popup->setItemEnabled( id - IdRedo, d->isRedoAvailable() );
#ifndef TQT_NO_CLIPBOARD
@@ -2320,7 +2396,7 @@ void TQLineEditPrivate::updateTextLayout()
textLayout.endLine(0, 0, TQt::AlignLeft|TQt::SingleLine, &ascent);
}
-int TQLineEditPrivate::xToPos( int x, TQTextItem::CursorPosition betweenOrOn ) const
+int TQLineEditPrivate::xToPosInternal( int x, TQTextItem::CursorPosition betweenOrOn ) const
{
x-= q->contentsRect().x() - hscroll + innerMargin;
for ( int i = 0; i < textLayout.numItems(); ++i ) {
@@ -2329,7 +2405,13 @@ int TQLineEditPrivate::xToPos( int x, TQTextItem::CursorPosition betweenOrOn ) c
if ( x >= tir.left() && x <= tir.right() )
return ti.xToCursor( x - tir.x(), betweenOrOn ) + ti.from();
}
- return x < 0 ? 0 : text.length();
+ return x < 0 ? -1 : text.length();
+}
+
+int TQLineEditPrivate::xToPos( int x, TQTextItem::CursorPosition betweenOrOn ) const
+{
+ int pos = xToPosInternal( x, betweenOrOn );
+ return ( pos < 0 ) ? 0 : pos;
}
@@ -2350,9 +2432,19 @@ TQRect TQLineEditPrivate::cursorRect() const
void TQLineEditPrivate::updateMicroFocusHint()
{
+ // To reduce redundant microfocus update notification, we remember
+ // the old rect and update the microfocus if actual update is
+ // required. The rect o is intentionally static because some
+ // notifyee requires the microfocus information as global update
+ // rather than per notifyee update to place shared widget around
+ // microfocus.
+ static TQRect o;
if ( q->hasFocus() ) {
- TQRect r = cursorRect();
- q->setMicroFocusHint( r.x(), r.y(), r.width(), r.height() );
+ TQRect r = cursorRect();
+ if ( o != r ) {
+ o = r;
+ q->setMicroFocusHint( r.x(), r.y(), r.width(), r.height() );
+ }
}
}