diff --git a/harbour/contrib/hbide/edit.prg b/harbour/contrib/hbide/edit.prg index 5962b4d61e..ff2216d1b0 100644 --- a/harbour/contrib/hbide/edit.prg +++ b/harbour/contrib/hbide/edit.prg @@ -250,6 +250,7 @@ CLASS IdeEdit INHERIT IdeObject METHOD highlightPage() METHOD reformatLine( nPos, nAdded, nDeleted ) + METHOD handleTab( key ) ENDCLASS @@ -560,7 +561,15 @@ METHOD IdeEdit:execKeyEvent( nMode, nEvent, p, p1 ) lCtrl := hb_bitAnd( kbm, Qt_ControlModifier ) == Qt_ControlModifier lShift := hb_bitAnd( kbm, Qt_ShiftModifier ) == Qt_ShiftModifier - IF ::oSC:execKey( Self, key, lAlt, lCtrl, lShift ) + SWITCH key /* On top of any user defined action be executed - QPlainTextEdit's default keys */ + CASE Qt_Key_Tab + CASE Qt_Key_Backtab + p:accept() + ::handleTab( key ) + RETURN .t. + ENDSWITCH + + IF ::oSC:execKey( Self, key, lAlt, lCtrl, lShift ) /* User Defined Actions */ RETURN .f. ENDIF @@ -631,13 +640,10 @@ METHOD IdeEdit:execKeyEvent( nMode, nEvent, p, p1 ) EXIT CASE QEvent_MouseButtonDblClick ::lCopyWhenDblClicked := .t. + ::clickFuncHelp() EXIT CASE 1001 /* Fired from hbqt_hbqplaintextedit.cpp */ SWITCH p - CASE QEvent_MouseButtonDblClick - ::lCopyWhenDblClicked := .f. /* not intuitive */ - ::clickFuncHelp() - EXIT CASE 21000 /* Sends Block Info { t,l,b,r,mode,state } hbGetBlockInfo() */ ::aSelectionInfo := p1 ::oDK:setButtonState( "SelectionMode", ::aSelectionInfo[ 5 ] > 1 ) @@ -977,7 +983,7 @@ METHOD IdeEdit:pasteBlockContents() NEXT EXIT ENDSWITCH - // + qCursor:endEditBlock() ::qEdit:ensureCursorVisible() @@ -985,8 +991,8 @@ METHOD IdeEdit:pasteBlockContents() /*----------------------------------------------------------------------*/ -METHOD IdeEdit:insertBlockContents( oKey ) - LOCAL nT, nL, nB, nR, nW, i, cLine, cKey, qCursor, aCord +METHOD IdeEdit:insertBlockContents( oKey ) /* Only called if block selection is on */ + LOCAL nT, nL, nB, nR, nW, i, cLine, cKey, qCursor, aCord, qCur IF ::lReadOnly RETURN Self @@ -999,6 +1005,7 @@ METHOD IdeEdit:insertBlockContents( oKey ) nW := nR - nL qCursor := ::qEdit:textCursor() + qCur := ::qEdit:textCursor() qCursor:beginEditBlock() IF nW == 0 @@ -1008,19 +1015,17 @@ METHOD IdeEdit:insertBlockContents( oKey ) hbide_qReplaceLine( qCursor, i, cLine ) NEXT - hbide_qPositionCursor( qCursor, nB, nR + 1 ) + hbide_qPositionCursor( qCursor, qCur:blockNumber(), nR + 1 ) ELSE FOR i := nT TO nB cLine := ::getLine( i + 1 ) cLine := pad( substr( cLine, 1, nL ), nL ) + replicate( cKey, nW ) + substr( cLine, nR + 1 ) - hbide_qReplaceLine( qCursor, i, cLine ) NEXT - hbide_qPositionCursor( qCursor, nB, nR ) + hbide_qPositionCursor( qCursor, qCur:blockNumber(), nR ) ENDIF - // - ::qEdit:setCursorWidth( 1 ) + ::qEdit:setTextCursor( qCursor ) qCursor:endEditBlock() @@ -1029,7 +1034,7 @@ METHOD IdeEdit:insertBlockContents( oKey ) /*----------------------------------------------------------------------*/ METHOD IdeEdit:cutBlockContents( k ) - LOCAL nT, nL, nB, nR, i, cLine, qCursor, nSelMode, aCord + LOCAL nT, nL, nB, nR, i, cLine, qCursor, nSelMode, aCord, qCur IF ::lReadOnly RETURN Self @@ -1045,6 +1050,7 @@ METHOD IdeEdit:cutBlockContents( k ) nSelMode := aCord[ 5 ] qCursor := ::qEdit:textCursor() + qCur := ::qEdit:textCursor() qCursor:beginEditBlock() IF k == Qt_Key_Backspace @@ -1054,7 +1060,7 @@ METHOD IdeEdit:cutBlockContents( k ) cLine := pad( substr( cLine, 1, nL - 1 ), nL - 1 ) + substr( cLine, nL + 1 ) hbide_qReplaceLine( qCursor, i, cLine ) NEXT - hbide_qPositionCursor( qCursor, nB, nR - 1 ) + hbide_qPositionCursor( qCursor, qCur:blockNumber(), nR - 1 ) ENDIF ELSE IF k == Qt_Key_Delete .OR. k == Qt_Key_X @@ -1064,8 +1070,8 @@ METHOD IdeEdit:cutBlockContents( k ) cLine := pad( substr( cLine, 1, nL ), nL ) + substr( cLine, nR + 1 ) hbide_qReplaceLine( qCursor, i, cLine ) NEXT - //hbide_qPositionCursor( qCursor, nT, nL ) - ::qEdit:hbSetSelectionInfo( { -1, -1, -1, -1, __selectionMode_column__ } ) + hbide_qPositionCursor( qCursor, qCur:blockNumber(), nL ) + ::qEdit:hbSetSelectionInfo( { nT, nL, nB, nL, __selectionMode_column__ } ) ELSEIF nSelMode == __selectionMode_stream__ hbide_qPositionCursor( qCursor, nT, nL ) @@ -1094,7 +1100,7 @@ METHOD IdeEdit:cutBlockContents( k ) /*----------------------------------------------------------------------*/ -METHOD IdeEdit:blockComment() +METHOD IdeEdit:blockComment() /* Toggles the block comments - always inserted at the begining of the line */ LOCAL nT, nL, nB, nR, nW, i, cLine, qCursor, aCord, nMode, a_ LOCAL cComment := "// " LOCAL nLen := Len( cComment ) @@ -1108,33 +1114,39 @@ METHOD IdeEdit:blockComment() nW := nR - nL IF nW >= 0 - nMode := aCord[ 5 ] - a_:= hbide_setQCursor( ::qEdit ) ; qCursor := a_[ 1 ] + nMode := aCord[ 5 ] + a_:= hbide_setQCursor( ::qEdit ) + qCursor := a_[ 1 ] FOR i := nT TO nB cLine := ::getLine( i + 1 ) - DO CASE - CASE nMode == __selectionMode_stream__ .OR. nMode == __selectionMode_line__ + SWITCH nMode + CASE __selectionMode_stream__ + CASE __selectionMode_line__ IF substr( cLine, 1, nLen ) == cComment cLine := substr( cLine, nLen + 1 ) ELSE cLine := cComment + cLine ENDIF - - CASE nMode == __selectionMode_column__ + EXIT + CASE __selectionMode_column__ IF substr( cLine, nL + 1, nLen ) == cComment cLine := pad( substr( cLine, 1, nL ), nL ) + substr( cLine, nL + nLen + 1 ) ELSE cLine := pad( substr( cLine, 1, nL ), nL ) + cComment + substr( cLine, nL + 1 ) ENDIF - - ENDCASE + EXIT + ENDSWITCH hbide_qReplaceLine( qCursor, i, cLine ) NEXT - +#if 1 hbide_setQCursor( ::qEdit, a_ ) +#else + hbide_qPositionCursor( qCursor, qCur:blockNumber(), nL ) + ::qEdit:hbSetSelectionInfo( { nT, nL, nB, nL, __selectionMode_column__ } ) +#endif ENDIF RETURN Self @@ -1186,6 +1198,62 @@ METHOD IdeEdit:streamComment() /*----------------------------------------------------------------------*/ +METHOD IdeEdit:handleTab( key ) + LOCAL nT, nL, nB, nR, i, cLine, qCursor, aCord, nMode, nCol, nRow + LOCAL cComment := space( ::nTabSpaces ) + LOCAL nLen := ::nTabSpaces + LOCAL nOff := iif( key == Qt_Key_Tab, nLen, -nLen ) + + HB_SYMBOL_UNUSED( key ) + IF ::lReadOnly + RETURN Self + ENDIF + + aCord := ::aSelectionInfo + hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR ) + nMode := aCord[ 5 ] + + qCursor := ::qEdit:textCursor() + qCursor:beginEditBlock() + nCol := qCursor:columnNumber() + nRow := qCursor:blockNumber() + + SWITCH nMode + CASE __selectionMode_column__ + FOR i := nT TO nB + cLine := ::getLine( i + 1 ) + IF key == Qt_Key_Tab + cLine := substr( cLine, 1, nCol ) + cComment + substr( cLine, nCol + 1 ) + ELSE + cLine := substr( cLine, 1, nCol - 3 ) + substr( cLine, nCol + 1 ) + ENDIF + hbide_qReplaceLine( qCursor, i, cLine ) + NEXT + hbide_qPositionCursor( qCursor, nRow, max( 0, nCol + nOff ) ) + ::qEdit:hbSetSelectionInfo( { nT, max( 0, nL + nOff ), nB, max( 0, nR + nOff ), __selectionMode_column__ } ) + EXIT + CASE __selectionMode_stream__ + CASE __selectionMode_line__ + IF nL >= 0 /* Selection is marked */ + ::cutBlockContents( Qt_Key_Delete ) + ENDIF + cLine := ::getLine( nRow + 1 ) + IF key == Qt_Key_Tab + cLine := substr( cLine, 1, nCol ) + cComment + substr( cLine, nCol + 1 ) + ELSE + cLine := substr( cLine, 1, nCol - nLen ) + substr( cLine, nCol + 1 ) + ENDIF + hbide_qReplaceLine( qCursor, nRow, cLine ) + hbide_qPositionCursor( qCursor, nRow, max( 0, nCol + nOff ) ) + EXIT + ENDSWITCH + ::qEdit:setTextCursor( qCursor ) + qCursor:endEditBlock() + + RETURN .t. + +/*----------------------------------------------------------------------*/ + METHOD IdeEdit:blockIndent( nDirctn ) LOCAL nT, nL, nB, nR, nW, i, cLine, qCursor, aCord, a_, nMode, cLineSel @@ -1199,22 +1267,14 @@ METHOD IdeEdit:blockIndent( nDirctn ) IF nW >= 0 nMode := aCord[ 5 ] - a_:= hbide_setQCursor( ::qEdit ) ; qCursor := a_[ 1 ] + a_:= hbide_setQCursor( ::qEdit ) + qCursor := a_[ 1 ] FOR i := nT TO nB cLine := ::getLine( i + 1 ) - DO CASE - CASE nMode == __selectionMode_stream__ .OR. nMode == __selectionMode_line__ - IF nDirctn == -1 - IF left( cLine, 1 ) == " " - cLine := substr( cLine, 2 ) - ENDIF - ELSE - cLine := " " + cLine - ENDIF - - CASE nMode == __selectionMode_column__ + SWITCH nMode + CASE __selectionMode_column__ cLineSel := pad( substr( cLine, nL + 1, nW ), nW ) IF nDirctn == -1 IF left( cLineSel, 1 ) == " " @@ -1224,8 +1284,18 @@ METHOD IdeEdit:blockIndent( nDirctn ) cLineSel := " " + cLineSel ENDIF cLine := pad( substr( cLine, 1, nL ), nL ) + cLineSel + substr( cLine, nR + 1 ) - - ENDCASE + EXIT + CASE __selectionMode_stream__ + CASE __selectionMode_line__ + IF nDirctn == -1 + IF left( cLine, 1 ) == " " + cLine := substr( cLine, 2 ) + ENDIF + ELSE + cLine := " " + cLine + ENDIF + EXIT + ENDSWITCH hbide_qReplaceLine( qCursor, i, cLine ) NEXT @@ -2759,3 +2829,4 @@ STATIC FUNCTION hbide_normalizeRect( aCord, nT, nL, nB, nR ) RETURN NIL /*----------------------------------------------------------------------*/ + diff --git a/harbour/contrib/hbide/editor.prg b/harbour/contrib/hbide/editor.prg index 8e11314f2b..6b1367668c 100644 --- a/harbour/contrib/hbide/editor.prg +++ b/harbour/contrib/hbide/editor.prg @@ -300,6 +300,7 @@ METHOD IdeEditsManager:updateFieldsList( cAlias ) LOCAL aFlds IF ! empty( cAlias ) .AND. ! empty( aFlds := ::oBM:fetchFldsList( cAlias ) ) + asort( aFlds, , , {|e,f| lower( e ) < lower( f ) } ) ::qFldsStrList:clear() @@ -307,8 +308,8 @@ METHOD IdeEditsManager:updateFieldsList( cAlias ) ::qFldsModel:setStringList( ::qFldsStrList ) ::qCompleter:setModel( ::qFldsModel ) - RETURN .t. + RETURN .t. ELSE ::qCompleter:setModel( ::qCompModel ) @@ -2040,3 +2041,4 @@ STATIC FUNCTION hbide_qtDesigner() RETURN NIL /*----------------------------------------------------------------------*/ + diff --git a/harbour/contrib/hbqt/qtgui/hbqt_hbqplaintextedit.cpp b/harbour/contrib/hbqt/qtgui/hbqt_hbqplaintextedit.cpp index cbfc22e033..71c2e0ba14 100644 --- a/harbour/contrib/hbqt/qtgui/hbqt_hbqplaintextedit.cpp +++ b/harbour/contrib/hbqt/qtgui/hbqt_hbqplaintextedit.cpp @@ -80,9 +80,6 @@ HB_EXTERN_END #include -#define selectionState_off 0 -#define selectionState_on 1 - #define selectionMode_none 0 #define selectionMode_stream 1 #define selectionMode_column 2 @@ -92,6 +89,10 @@ HB_EXTERN_END #define selectionDisplay_qt 1 #define selectionDisplay_ide 2 +#define mouseMode_none 0 +#define mouseMode_select 1 +#define mouseMode_drag 2 + /*----------------------------------------------------------------------*/ HBQPlainTextEdit::HBQPlainTextEdit( QWidget * parent ) : QPlainTextEdit( parent ) @@ -111,7 +112,6 @@ HBQPlainTextEdit::HBQPlainTextEdit( QWidget * parent ) : QPlainTextEdit( parent columnEnds = -1; rowBegins = -1; rowEnds = -1; - selectionState = selectionState_off; selectionMode = selectionMode_stream; selectionDisplay = selectionDisplay_none; isColumnSelectionON = false; @@ -130,6 +130,9 @@ HBQPlainTextEdit::HBQPlainTextEdit( QWidget * parent ) : QPlainTextEdit( parent isCompletionTipsActive = true; isInDrag = false; dragStartPosition = QPoint(); + clickPos = QPoint(); + iClicks = 0; + mouseMode = mouseMode_none; #if 0 QTextFrameFormat format( this->document()->rootFrame()->frameFormat() ); @@ -307,7 +310,6 @@ void HBQPlainTextEdit::hbSetEventBlock( PHB_ITEM pBlock ) if( pBlock ) { block = hb_itemNew( pBlock ); - // hb_gcUnlock( block ); } } @@ -340,28 +342,7 @@ void HBQPlainTextEdit::hbSetProtoStyle( const QString & css ) bool HBQPlainTextEdit::event( QEvent *event ) { - if( event->type() == QEvent::KeyPress ) - { - QKeyEvent *keyEvent = ( QKeyEvent * ) event; - if( ( keyEvent->key() == Qt::Key_Tab ) && ( keyEvent->modifiers() & Qt::ControlModifier ) ) - { - return false; - } - else - { - if( ( keyEvent->key() == Qt::Key_Tab ) && !( keyEvent->modifiers() & Qt::ControlModifier & Qt::AltModifier & Qt::ShiftModifier ) ) - { - this->hbInsertTab( 0 ); - return true; - } - else if( ( keyEvent->key() == Qt::Key_Backtab ) && ( keyEvent->modifiers() & Qt::ShiftModifier ) ) - { - this->hbInsertTab( 1 ); - return true; - } - } - } - else if( event->type() == QEvent::ToolTip ) + if( event->type() == QEvent::ToolTip ) { event->ignore(); #if 0 @@ -374,7 +355,6 @@ bool HBQPlainTextEdit::event( QEvent *event ) #endif return false;//true; } - return QPlainTextEdit::event( event ); } @@ -434,7 +414,27 @@ bool HBQPlainTextEdit::isCursorInSelection() int col = c.columnNumber(); int row = c.blockNumber(); - return( col >= cb && col <= ce && row >= rb && row <= re ); + if( selectionMode == selectionMode_column ) + { + HB_TRACE( HB_TR_DEBUG, ( "isCursorInSelection( Modif %i %i %i %i RC %i %i Cur %i %i", rb, cb, re, ce, rowBegins, columnBegins, row, col ) ); + return( col >= cb && col <= ce && row >= rb && row <= re ); + } + else + { + if( row == rb ) + { + return( col >= cb ); + } + else if( row == re ) + { + return( col <= ce ); + } + else if( row >= rb && row <= re ) + { + return( true ); + } + } + return( false ); } /*----------------------------------------------------------------------*/ @@ -453,7 +453,7 @@ void HBQPlainTextEdit::hbPostSelectionInfo() hb_arraySetNI( p2, 3, rowEnds ); hb_arraySetNI( p2, 4, columnEnds ); hb_arraySetNI( p2, 5, selectionMode ); - hb_arraySetNI( p2, 6, selectionState ); + hb_arraySetNI( p2, 6, 0 ); hb_arraySetNI( p2, 7, 0 ); hb_vmEvalBlockV( block, 2, p1, p2 ); @@ -467,7 +467,6 @@ void HBQPlainTextEdit::hbPostSelectionInfo() void HBQPlainTextEdit::hbClearSelection() { - setCursorWidth( 1 ); rowBegins = -1; rowEnds = -1; columnBegins = -1; @@ -479,7 +478,6 @@ void HBQPlainTextEdit::hbClearSelection() void HBQPlainTextEdit::hbSelectAll() { - setCursorWidth( 1 ); rowBegins = 0; rowEnds = document()->blockCount(); columnBegins = 0; @@ -536,7 +534,6 @@ void HBQPlainTextEdit::hbSetSelectionMode( int mode, bool byApplication ) } setTextCursor( c ); } - setCursorWidth( 1 ); } else { @@ -544,7 +541,6 @@ void HBQPlainTextEdit::hbSetSelectionMode( int mode, bool byApplication ) { case selectionMode_stream: { - setCursorWidth( 1 ); selectionMode = selectionMode_stream; isStreamSelectionON = true; isColumnSelectionON = false; @@ -560,8 +556,6 @@ void HBQPlainTextEdit::hbSetSelectionMode( int mode, bool byApplication ) } case selectionMode_column: { - setCursorWidth( 0 ); - selectionMode = selectionMode_column; isStreamSelectionON = false; isColumnSelectionON = true; @@ -578,7 +572,6 @@ void HBQPlainTextEdit::hbSetSelectionMode( int mode, bool byApplication ) } case selectionMode_line: { - setCursorWidth( 1 ); selectionMode = selectionMode_line; isStreamSelectionON = false; isColumnSelectionON = false; @@ -603,7 +596,6 @@ void HBQPlainTextEdit::hbSetSelectionMode( int mode, bool byApplication ) { case selectionMode_stream: { - setCursorWidth( 1 ); if( columnBegins >= 0 ) { hbToStream(); @@ -615,7 +607,6 @@ void HBQPlainTextEdit::hbSetSelectionMode( int mode, bool byApplication ) } case selectionMode_column: { - setCursorWidth( 0 ); selectionMode = selectionMode_column; isColumnSelectionON = true; isLineSelectionON = false; @@ -768,13 +759,16 @@ void HBQPlainTextEdit::dropEvent( QDropEvent *event ) if( ( selectionMode == selectionMode_stream || selectionMode == selectionMode_line ) && row >= rowBegins && row <= rowEnds ) { setTextCursor( c ); + mouseMode = mouseMode_select; } else if( selectionMode == selectionMode_column && row >= rowBegins && row <= rowEnds && col >= columnBegins && col <= columnEnds ) { setTextCursor( c ); + mouseMode = mouseMode_select; } else { + mouseMode = mouseMode_none; hbCopy(); if( event->dropAction() != Qt::CopyAction ) { @@ -818,7 +812,6 @@ void HBQPlainTextEdit::dropEvent( QDropEvent *event ) { setTextCursor( c ); } - selectionState = 0; hbClearSelection(); hbPaste(); hbPostSelectionInfo(); @@ -887,79 +880,27 @@ void HBQPlainTextEdit::mouseDoubleClickEvent( QMouseEvent *event ) QTextCursor c( textCursor() ); if( c.hasSelection() ) { - rowBegins = c.blockNumber(); - rowEnds = rowBegins; - columnEnds = c.columnNumber(); - columnBegins = columnEnds - ( c.selectionEnd() - c.selectionStart() ); - selectionMode = selectionMode_stream; + rowBegins = c.blockNumber(); + rowEnds = rowBegins; + columnEnds = c.columnNumber(); + columnBegins = columnEnds - ( c.selectionEnd() - c.selectionStart() ); + selectionMode = selectionMode_stream; + mouseMode = mouseMode_select; c.clearSelection(); setTextCursor( c ); hbPostSelectionInfo(); + clickPos = event->pos(); + iClicks = 2; + repaint(); } - +#if 0 if( block ) { PHB_ITEM p1 = hb_itemPutNI( NULL, QEvent::MouseButtonDblClick ); hb_vmEvalBlockV( block, 1, p1 ); hb_itemRelease( p1 ); } -} - -/*----------------------------------------------------------------------*/ - -void HBQPlainTextEdit::mousePressEvent( QMouseEvent *event ) -{ - if( isSelectionByApplication ) - { - if( isColumnSelectionON ) - { - event->accept(); - } - else - { - QPlainTextEdit::mousePressEvent( event ); - } - return; - } - - if( event->modifiers() & Qt::ShiftModifier ) - { - QTextCursor c( textCursor() ); - rowBegins = c.blockNumber(); - columnBegins = c.columnNumber(); - - QPlainTextEdit::mousePressEvent( event ); - - c = textCursor(); - rowEnds = c.blockNumber(); - columnEnds = c.columnNumber(); - - selectionState = 1; - setCursorWidth( 1 ); - selectionMode = selectionMode_stream; - hbPostSelectionInfo(); - repaint(); - } - else - { - if( event->buttons() & Qt::LeftButton ) - { - setCursorWidth( 1 ); - - QTextCursor c( cursorForPosition( event->pos() ) ); - int row = c.blockNumber(); - int col = c.columnNumber(); - if( ( selectionMode == selectionMode_stream || selectionMode == selectionMode_line ) && row >= rowBegins && row <= rowEnds ) - { - dragStartPosition = event->pos(); - } - else if( selectionMode == selectionMode_column && row >= rowBegins && row <= rowEnds && col >= columnBegins && col <= columnEnds ) - { - dragStartPosition = event->pos(); - } - } - QPlainTextEdit::mousePressEvent( event ); - } +#endif } /*----------------------------------------------------------------------*/ @@ -990,21 +931,85 @@ void HBQPlainTextEdit::mouseReleaseEvent( QMouseEvent *event ) } else { - if( selectionState == 1 ) + QPlainTextEdit::mouseReleaseEvent( event ); + } +} + +/*----------------------------------------------------------------------*/ + +void HBQPlainTextEdit::mousePressEvent( QMouseEvent *event ) +{ + if( isSelectionByApplication ) + { + if( isColumnSelectionON ) { - selectionState = 0; - if( ! isSelectionPersistent ) - { - hbClearSelection(); - repaint(); - } + event->accept(); } else { - selectionState = 1; + QPlainTextEdit::mousePressEvent( event ); } - setCursorWidth( 1 ); + return; + } + else if( event->modifiers() & Qt::ShiftModifier ) + { + QTextCursor c( textCursor() ); + rowBegins = c.blockNumber(); + columnBegins = c.columnNumber(); + + QPlainTextEdit::mousePressEvent( event ); + + c = textCursor(); + rowEnds = c.blockNumber(); + columnEnds = c.columnNumber(); + c.clearSelection(); + setTextCursor( c ); + selectionMode = selectionMode_stream; hbPostSelectionInfo(); + repaint(); + } + else + { + if( event->buttons() & Qt::LeftButton ) + { + QTextCursor c( cursorForPosition( event->pos() ) ); + + if( iClicks == 2 ) /* Handle Tripple-click */ + { + iClicks = 0; + if( ( event->pos() - clickPos ).manhattanLength() < QApplication::startDragDistance() ) + { + selectionMode = selectionMode_stream; + c.movePosition( QTextCursor::EndOfLine ); + columnBegins = 0; + columnEnds = c.columnNumber(); + hbPostSelectionInfo(); + setTextCursor( c ); + event->accept(); + repaint(); + } + else + { + QPlainTextEdit::mousePressEvent( event ); + hbClearSelection(); + } + } + else + { + QPlainTextEdit::mousePressEvent( event ); + dragStartPosition = event->pos(); + if( mouseMode == mouseMode_select && isCursorInSelection() ) + { + mouseMode = mouseMode_drag; + } + else + { + mouseMode = mouseMode_none; + hbClearSelection(); + repaint(); + } + } + } } } @@ -1025,7 +1030,7 @@ void HBQPlainTextEdit::mouseMoveEvent( QMouseEvent *event ) } if( event->buttons() & Qt::LeftButton ) { - if( ( event->pos() - dragStartPosition ).manhattanLength() < QApplication::startDragDistance() ) + if( mouseMode == mouseMode_drag && ( event->pos() - dragStartPosition ).manhattanLength() < QApplication::startDragDistance() ) { QTextCursor c( cursorForPosition( event->pos() ) ); int row = c.blockNumber(); @@ -1052,26 +1057,17 @@ void HBQPlainTextEdit::mouseMoveEvent( QMouseEvent *event ) } } - if( selectionState == 1 ) - { - selectionState = 2; - hbClearSelection(); - } - if( columnBegins == -1 ) { - if( selectionMode == selectionMode_column ) - setCursorWidth( 0 ); - QTextCursor c( textCursor() ); - rowBegins = c.blockNumber(); columnBegins = c.columnNumber(); rowEnds = rowBegins; columnEnds = columnBegins; + mouseMode = mouseMode_select; QPlainTextEdit::mouseMoveEvent( event ); } - else + else if( mouseMode == mouseMode_select ) { if( selectionMode == selectionMode_column ) { @@ -1081,7 +1077,6 @@ void HBQPlainTextEdit::mouseMoveEvent( QMouseEvent *event ) } QPlainTextEdit::mouseMoveEvent( event ); QTextCursor c = textCursor(); - if( selectionMode != selectionMode_column ) { rowEnds = c.blockNumber(); @@ -1089,7 +1084,6 @@ void HBQPlainTextEdit::mouseMoveEvent( QMouseEvent *event ) } c.clearSelection(); setTextCursor( c ); -// repaint(); /* NOT REQUIRED : QPlainTextEdit::mouseMoveEvent( event ); */ } hbPostSelectionInfo(); } @@ -1103,16 +1097,334 @@ void HBQPlainTextEdit::keyReleaseEvent( QKeyEvent * event ) if( ( event->modifiers() & Qt::ControlModifier ) && event->text() == "" ) { - if( selectionState == 2 ) + hbPostSelectionInfo(); + } +} + +/*----------------------------------------------------------------------*/ + +void HBQPlainTextEdit::hbHandleKey( QKeyEvent * event, int k, int selMode, bool shift ) +{ + Q_UNUSED( selMode ); + Q_UNUSED( shift ); + + switch( k ) + { + case Qt::Key_Right: { - selectionState = 1; - emit selectionChanged(); + event->ignore(); + QTextCursor c( textCursor() ); + QTextCursor cc( textCursor() ); + cc.movePosition( QTextCursor::EndOfLine ); + if( columnEnds < cc.columnNumber() ) + { + c.movePosition( QTextCursor::Right ); + setTextCursor( c ); + } + columnEnds++; + break; + } + case Qt::Key_Left: + { + event->ignore(); + QTextCursor c( textCursor() ); + if( columnEnds >= 0 ) + { + if( columnEnds <= c.columnNumber() ) + { + c.movePosition( QTextCursor::Left ); + setTextCursor( c ); + } + columnEnds--; + } + break; + } + case Qt::Key_Home: + case Qt::Key_End: + { + QPlainTextEdit::keyPressEvent( event ); + columnEnds = textCursor().columnNumber(); + break; + } + case Qt::Key_Up: + case Qt::Key_PageUp: + case Qt::Key_Down: + case Qt::Key_PageDown: + { + QPlainTextEdit::keyPressEvent( event ); + rowEnds = textCursor().blockNumber(); + break; } } } /*----------------------------------------------------------------------*/ +bool HBQPlainTextEdit::hbKeyPressSelection( QKeyEvent * event ) +{ + int k; + bool ctrl, shift, isNavable; + + if( isSelectionByApplication ) + { + return hbKeyPressSelectionByApplication( event ); + } + k = event->key(); + ctrl = event->modifiers() & Qt::ControlModifier; + shift = event->modifiers() & Qt::ShiftModifier; + isNavable = isNavableKey( k ); + + if( ctrl && shift && ! isNavable ) + { + return false; + } + if( ctrl && event->text().isEmpty() && ! isNavable ) + { + return false; + } + if( ctrl && ( k == Qt::Key_C || k == Qt::Key_V || k == Qt::Key_X || + k == Qt::Key_A || k == Qt::Key_Z || k == Qt::Key_Y ) ) + { + event->ignore(); + return true; + } + + bool bClear = false; + + if( shift && isNavable ) + { + if( selectionMode == selectionMode_line ) + { + selectionMode = selectionMode_stream; + hbPostSelectionInfo(); + } + + isShiftPressed = true; + + event->accept(); + QTextCursor c( textCursor() ); + c.clearSelection(); + setTextCursor( c ); + + if( columnBegins == -1 || columnEnds == -1 || rowBegins == -1 || rowEnds == -1 ) + { + rowBegins = c.blockNumber(); + columnBegins = c.columnNumber(); + rowEnds = rowBegins; + columnEnds = columnBegins; + hbPostSelectionInfo(); + } + + /* Push key back to system without the shift modifier - it will position position the cursor as intended */ + QKeyEvent * ev = new QKeyEvent( event->type(), event->key(), ctrl ? Qt::ControlModifier : Qt::NoModifier, event->text() ); + keyPressEvent( ev ); + return true; + } + + if( isShiftPressed && isNavable ) + { + isShiftPressed = false; + + if( selectionMode == selectionMode_stream ) + { + QPlainTextEdit::keyPressEvent( event ); + rowEnds = textCursor().blockNumber(); + columnEnds = textCursor().columnNumber(); + } + else if( selectionMode == selectionMode_column ) + { + hbHandleKey( event, k, selectionMode_column, true ); + } + hbPostSelectionInfo(); + repaint(); /* A Must Here , otherwise selection will not be reflected */ + return true; + } + else if( ctrl && isNavable && selectionMode == selectionMode_column && columnBegins >= 0 && columnBegins == columnEnds ) + { + hbHandleKey( event, k, selectionMode_column, false ); + columnBegins = columnEnds; + hbPostSelectionInfo(); + repaint(); + return true; + } + else if( ! ctrl && k >= ' ' && k < 127 && columnBegins >= 0 && selectionMode == selectionMode_column ) + { + if( isCursorInSelection() ) + { + if( block ) + { + PHB_ITEM p1 = hb_itemPutNI( NULL, 21013 ); + PHB_ITEM p2 = hbqt_bindGetHbObject( NULL, ( void * ) event, "HB_QKEYEVENT", NULL, 0 ) ; + hb_vmEvalBlockV( block, 2, p1, p2 ); + hb_itemRelease( p1 ); + hb_itemRelease( p2 ); + + if( columnBegins == columnEnds ) + { + columnBegins++; + columnEnds++; + hbPostSelectionInfo(); + } + event->accept(); + repaint(); + return true; + } + } + else + { + bClear = true; + } + } + else if( ! ctrl && ( k == Qt::Key_Backspace || k == Qt::Key_Delete ) && columnBegins >= 0 ) + { + if( selectionMode == selectionMode_column ) + { + hbCut( k ); + if( k == Qt::Key_Backspace ) + { + columnBegins--; + columnEnds--; + } + else + { + columnEnds = columnBegins; + } + event->accept(); + hbPostSelectionInfo(); + repaint(); + return true; + } + else /* selectionMode == selectionMode_stream || selectionMode == selectionMode_line */ + { + hbCut( Qt::Key_Delete ); + repaint(); + hbPostSelectionInfo(); + if( k == Qt::Key_Delete ) + { + event->accept(); + return true; + } + } + } + else if( ! ctrl && k >= ' ' && k < 127 && columnBegins >= 0 && selectionMode == selectionMode_stream ) + { + hbCut( Qt::Key_Delete ); + hbClearSelection(); + } + else if( ! ctrl && k >= ' ' && k < 127 ) + { + bClear = true; + } + else if( isNavable ) + { + bClear = true; + } + + if( bClear ) + { + if( isSelectionPersistent ) + { + if( columnBegins >= 0 ) + { + if( columnEnds == columnBegins ) + { + hbClearSelection(); + } + hbPostSelectionInfo(); + } + } + else + { + if( columnBegins >= 0 ) + { + hbClearSelection(); + hbPostSelectionInfo(); + repaint(); + } + } + } + return false; +} + +/*----------------------------------------------------------------------*/ + +void HBQPlainTextEdit::keyPressEvent( QKeyEvent * event ) +{ + if( hbHandlePopup( event ) ) + { + return; + } + if( hbKeyPressSelection( event ) ) + { + return; + } + + QPlainTextEdit::keyPressEvent( event ); + + if( ! isCodeCompletionActive ) + { + if( c ){ + c->popup()->hide(); + } + return; + } + + if( ! c ) + { + return; + } + if( isTipActive ) + { + c->popup()->hide(); + return; + } + + if( ! isAliasCompleter ) + { + hbRefreshCompleter( hbTextAlias() ); + } + + if( ( event->modifiers() & ( Qt::ControlModifier | Qt::AltModifier ) ) ) + { + c->popup()->hide(); + return; + } + const bool ctrlOrShift = event->modifiers() & ( Qt::ControlModifier | Qt::ShiftModifier ); + if( ctrlOrShift && event->text().isEmpty() ) + { + return; + } + static QString eow( " ~!@#$%^&*()+{}|:\"<>?,./;'[]\\-=" ); /* end of word */ + bool hasModifier = ( event->modifiers() != Qt::NoModifier ) && !ctrlOrShift; + QString completionPrefix = hbTextUnderCursor( true ); + /*QString completionPrefix = hbTextUnderCursor( false );*/ + + if( hasModifier || + event->text().isEmpty() || + completionPrefix.length() < ( isAliasCompleter ? 0 : 1 ) || + eow.contains( event->text().right( 1 ) ) ) + { + c->popup()->hide(); + return; + } + + if( completionPrefix != c->completionPrefix() ) + { + c->setCompletionPrefix( completionPrefix ); + c->popup()->setCurrentIndex( c->completionModel()->index( 0, 0 ) ); + } + QRect cr = cursorRect(); + + c->popup()->setMaximumWidth( viewport()->width() ); + cr.setWidth( c->popup()->sizeHintForColumn( 0 ) + c->popup()->verticalScrollBar()->sizeHint().width() ); + cr.setTop( cr.top() + horzRulerHeight + 5 ); + cr.setBottom( cr.bottom() + horzRulerHeight + 5 ); + + c->complete( cr ); /* pop it up! */ +} + +/*----------------------------------------------------------------------*/ + bool HBQPlainTextEdit::hbKeyPressSelectionByApplication( QKeyEvent * event ) { bool shift = event->modifiers() & Qt::ShiftModifier; @@ -1208,343 +1520,42 @@ bool HBQPlainTextEdit::hbKeyPressSelectionByApplication( QKeyEvent * event ) /*----------------------------------------------------------------------*/ -bool HBQPlainTextEdit::hbKeyPressSelection( QKeyEvent * event ) -{ - int k; - bool ctrl, shift, isNavable; - - if( isSelectionByApplication ) { - return hbKeyPressSelectionByApplication( event ); - } - - k = event->key(); - ctrl = event->modifiers() & Qt::ControlModifier; - shift = event->modifiers() & Qt::ShiftModifier; - isNavable = isNavableKey( k ); - - if( ctrl && shift && ! isNavable ) { - return false; - } - if( ctrl && event->text().isEmpty() && ! isNavable ) { - return false; - } - if( ctrl && ( k == Qt::Key_C || k == Qt::Key_V || k == Qt::Key_X || - k == Qt::Key_A || k == Qt::Key_Z || k == Qt::Key_Y ) ) { - event->ignore(); - return true; - } - - bool bClear = false; - - if( shift && isNavable ) - { - if( selectionMode == selectionMode_line ) - { - selectionMode = selectionMode_stream; - selectionState = 0; - hbPostSelectionInfo(); - } - if( selectionState == 0 ) - { - hbClearSelection(); - } - - isShiftPressed = true; - - event->accept(); - QTextCursor c( textCursor() ); - c.clearSelection(); - setTextCursor( c ); - - if( columnBegins == -1 ) - { - if( selectionMode == selectionMode_column ) - { - setCursorWidth( 0 ); - } - selectionState = 2; - rowBegins = c.blockNumber(); - columnBegins = c.columnNumber(); - rowEnds = rowBegins; - columnEnds = columnBegins; - hbPostSelectionInfo(); - } - - QKeyEvent * ev = new QKeyEvent( event->type(), event->key(), ctrl ? Qt::ControlModifier : Qt::NoModifier, event->text() ); - keyPressEvent( ev ); - return true; - } - - if( isShiftPressed && isNavable ) - { - isShiftPressed = false; - - if( selectionMode == selectionMode_stream ) - { - QPlainTextEdit::keyPressEvent( event ); - rowEnds = textCursor().blockNumber(); - columnEnds = textCursor().columnNumber(); - } - else if( selectionMode == selectionMode_column ) - { - switch( k ) - { - case Qt::Key_Right: - { - QTextCursor c( textCursor() ); - c.movePosition( QTextCursor::EndOfLine ); - if( columnEnds < c.columnNumber() ) - { - QPlainTextEdit::keyPressEvent( event ); - ensureCursorVisible(); - } - else - { - event->ignore(); - } - columnEnds++; - break; - } - case Qt::Key_Left: - { - QTextCursor c( textCursor() ); - int col = c.columnNumber(); - if( col > 0 ) - { - QPlainTextEdit::keyPressEvent( event ); - columnEnds--; - } - else - { - event->ignore(); - } - break; - } - case Qt::Key_Home: - case Qt::Key_End: - { - QPlainTextEdit::keyPressEvent( event ); - columnEnds = textCursor().columnNumber(); - break; - } - case Qt::Key_Up: - case Qt::Key_PageUp: - case Qt::Key_Down: - case Qt::Key_PageDown: - { - QPlainTextEdit::keyPressEvent( event ); - rowEnds = textCursor().blockNumber(); - break; - } - } - } - hbPostSelectionInfo(); - repaint(); /* A Must Here , otherwise selection will not be reflected */ - return true; - } - else if( ! ctrl && k >= ' ' && k < 127 && columnBegins >= 0 && selectionMode == selectionMode_column ) - { - if( ( columnBegins == columnEnds && selectionState > 0 ) || isCursorInSelection() ) - { - if( block ) - { - PHB_ITEM p1 = hb_itemPutNI( NULL, 21013 ); - PHB_ITEM p2 = hbqt_bindGetHbObject( NULL, ( void * ) event, "HB_QKEYEVENT", NULL, 0 ) ; - hb_vmEvalBlockV( block, 2, p1, p2 ); - hb_itemRelease( p1 ); - hb_itemRelease( p2 ); - - if( columnBegins == columnEnds ) - { - columnBegins++; - columnEnds++; - hbPostSelectionInfo(); - } - event->accept(); - repaint(); - return true; - } - } - else - { - bClear = true; - } - } - else if( ! ctrl && ( k == Qt::Key_Backspace || k == Qt::Key_Delete ) && columnBegins >= 0 && selectionState > 0 ) - { - if( selectionMode == selectionMode_column ) - { - hbCut( k ); - if( k == Qt::Key_Backspace ) - { - columnBegins--; - columnEnds--; - } - else - { - columnEnds = columnBegins; - } - hbPostSelectionInfo(); - event->accept(); - repaint(); - return true; - } - else /* selectionMode == selectionMode_stream || selectionMode == selectionMode_line */ - { - hbCut( Qt::Key_Delete ); - repaint(); - selectionState = 0; - hbPostSelectionInfo(); - if( k == Qt::Key_Delete ) - { - event->accept(); - return true; - } - } - } - else if( ! ctrl && k >= ' ' && k < 127 && columnBegins >= 0 && selectionMode == selectionMode_stream ) - { - hbCut( Qt::Key_Delete ); - hbClearSelection(); - selectionState = 0; - } - else if( ! ctrl && k >= ' ' && k < 127 ) - { - bClear = true; - } - else if( isNavable ) - { - bClear = true; - } - - if( bClear ) - { - if( isSelectionPersistent ) - { - if( selectionState > 0 ) - { - setCursorWidth( 1 ); - selectionState = 0; - if( columnEnds == columnBegins ) - { - hbClearSelection(); - } - hbPostSelectionInfo(); - } - } - else - { - if( selectionState > 0 ) - { - setCursorWidth( 1 ); - selectionState = 0; - hbClearSelection(); - hbPostSelectionInfo(); - repaint(); - } - } - } - return false; -} - -/*----------------------------------------------------------------------*/ - -void HBQPlainTextEdit::keyPressEvent( QKeyEvent * event ) +bool HBQPlainTextEdit::hbHandlePopup( QKeyEvent * event ) { if( c && c->popup()->isVisible() ) { /* The following keys are forwarded by the completer to the widget */ switch( event->key() ) { - case Qt::Key_Enter : - case Qt::Key_Return : - case Qt::Key_Escape : - case Qt::Key_Tab : - case Qt::Key_Backtab : - event->ignore(); - return; /* let the completer do default behavior */ - case Qt::Key_Space: - if( block ) - { - PHB_ITEM p1 = hb_itemPutNI( NULL, 21001 ); - hb_vmEvalBlockV( block, 1, p1 ); - hb_itemRelease( p1 ); - hbRefreshCompleter(); /* Watch closely */ - } - break; - case Qt::Key_ParenLeft: - if( block ) - { - PHB_ITEM p1 = hb_itemPutNI( NULL, 21002 ); - hb_vmEvalBlockV( block, 1, p1 ); - hb_itemRelease( p1 ); - } - break; - default: - break; + case Qt::Key_Enter : + case Qt::Key_Return : + case Qt::Key_Escape : + case Qt::Key_Tab : + case Qt::Key_Backtab : + event->ignore(); + return true; /* let the completer do default behavior */ + case Qt::Key_Space: + if( block ) + { + PHB_ITEM p1 = hb_itemPutNI( NULL, 21001 ); + hb_vmEvalBlockV( block, 1, p1 ); + hb_itemRelease( p1 ); + hbRefreshCompleter(); /* Watch closely */ + } + break; + case Qt::Key_ParenLeft: + if( block ) + { + PHB_ITEM p1 = hb_itemPutNI( NULL, 21002 ); + hb_vmEvalBlockV( block, 1, p1 ); + hb_itemRelease( p1 ); + } + break; + default: + break; } } - - if( hbKeyPressSelection( event ) ) - { - return; - } - - QPlainTextEdit::keyPressEvent( event ); - - if( ! isCodeCompletionActive ){ - if( c ){ - c->popup()->hide(); - } - return; - } - - if( ! c ){ - return; - } - if( isTipActive ){ - c->popup()->hide(); - return; - } - - if( ! isAliasCompleter ){ - hbRefreshCompleter( hbTextAlias() ); - } - - if( ( event->modifiers() & ( Qt::ControlModifier | Qt::AltModifier ) ) ){ - c->popup()->hide(); - return; - } - const bool ctrlOrShift = event->modifiers() & ( Qt::ControlModifier | Qt::ShiftModifier ); - if( ctrlOrShift && event->text().isEmpty() ){ - return; - } - static QString eow( " ~!@#$%^&*()+{}|:\"<>?,./;'[]\\-=" ); /* end of word */ - bool hasModifier = ( event->modifiers() != Qt::NoModifier ) && !ctrlOrShift; - QString completionPrefix = hbTextUnderCursor( true ); - /*QString completionPrefix = hbTextUnderCursor( false );*/ - - if( hasModifier || - event->text().isEmpty() || - completionPrefix.length() < ( isAliasCompleter ? 0 : 1 ) || - eow.contains( event->text().right( 1 ) ) ) - { - c->popup()->hide(); - return; - } - - if( completionPrefix != c->completionPrefix() ) { - c->setCompletionPrefix( completionPrefix ); - c->popup()->setCurrentIndex( c->completionModel()->index( 0, 0 ) ); - } - QRect cr = cursorRect(); - - c->popup()->setMaximumWidth( viewport()->width() ); - cr.setWidth( c->popup()->sizeHintForColumn( 0 ) + c->popup()->verticalScrollBar()->sizeHint().width() ); - cr.setTop( cr.top() + horzRulerHeight + 5 ); - cr.setBottom( cr.bottom() + horzRulerHeight + 5 ); - - c->complete( cr ); /* pop it up! */ + return false; } /*----------------------------------------------------------------------*/ diff --git a/harbour/contrib/hbqt/qtgui/hbqt_hbqplaintextedit.h b/harbour/contrib/hbqt/qtgui/hbqt_hbqplaintextedit.h index 536dae22f5..a328697975 100644 --- a/harbour/contrib/hbqt/qtgui/hbqt_hbqplaintextedit.h +++ b/harbour/contrib/hbqt/qtgui/hbqt_hbqplaintextedit.h @@ -153,7 +153,6 @@ private: int rowEnds; int columnBegins; int columnEnds; - int selectionState; int selectionMode; int selectionDisplay; bool isStreamSelectionON; @@ -177,6 +176,9 @@ private: bool isCompletionTipsActive; bool isInDrag; QPoint dragStartPosition; + QPoint clickPos; + int iClicks; + int mouseMode; protected: bool event( QEvent * event ); @@ -191,6 +193,8 @@ protected: void dragEnterEvent( QDragEnterEvent * event ); void dragMoveEvent( QDragMoveEvent * event ); void dropEvent( QDropEvent * event ); + void hbHandleKey( QKeyEvent * event, int k, int selMode, bool shift ); + bool hbHandlePopup( QKeyEvent * event ); public slots: QString hbTextAlias();