2012-07-23 22:41 UTC-0800 Pritpal Bedi (bedipritpal@hotmail.com)

* contrib/hbide/edit.prg
  * contrib/hbide/editor.prg
  * contrib/hbqt/qtgui/hbqt_hbqplaintextedit.cpp
  * contrib/hbqt/qtgui/hbqt_hbqplaintextedit.h
    % An exhaustive commit focused on selctions management,
       specially column selection. It also fixes the regression 
       injected in last commit where I broke few here-and-theres.
       The changes are so exhaustive that I lost many to document,
       but following are the main points you should know:
        1. + Tripple click selection of a line. 
             Unlike other editors, HbIDE implements tripple-click
             like this: double-click selects a word; do-not move 
             the cusor, click once, line is selected. Standard editors
             measure the time between clicks, HbIDE measure the position
             of click. This way user is not constrained to quickly 
             inject the third click. However, double-click carries 
             standard behavior.
        2. + Shift+TAB now behaves as expected. It removes preceeding
             <nTabSpaces>. <nTabSpaces> can be configured via 
             <Setup><Setup HbIDE>. Defaults to 3.
        3. + TAB and Shift+TAB are also available in column selection.
        4. + Ctrl+Left|Right, TAB/Shift+TAB and Backspace moves the 
             selection cursor without affecting selected rows in 
             column-selection mode when starting and ending columns are the 
             same; which eventually becomes the multiline editing cursor.
             In practice there are lot many times when moving to 
             another column without leaving the multi-line selection 
             is needed.
        5. + Enabled the physical cursor at all times, no matter in 
             which selection mode the cursor is. Earlier it was disabled
             in column selection mode.
        6. + TAB keys management is brought to PRG level instead of C++.
             This has made it possible to have them working under 
             multi-line block editing mode ( extended column-selection mode).

        ;;   A good amount of efforts have gone in this direction, and 
             as I am into it deep, please forward your suggessions as to 
             how the various behaviors should be.
This commit is contained in:
Pritpal Bedi
2012-07-24 06:37:37 +00:00
parent 33d0c02967
commit eafed942b4
4 changed files with 589 additions and 501 deletions

View File

@@ -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
/*----------------------------------------------------------------------*/

View File

@@ -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
/*----------------------------------------------------------------------*/

File diff suppressed because it is too large Load Diff

View File

@@ -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();