* 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.
2833 lines
82 KiB
Plaintext
2833 lines
82 KiB
Plaintext
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
*
|
|
* Copyright 2009-2010 Pritpal Bedi <bedipritpal@hotmail.com>
|
|
* www - http://harbour-project.org
|
|
*
|
|
* 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, 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 software; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
|
*
|
|
* As a special exception, the Harbour Project gives permission for
|
|
* additional uses of the text contained in its release of Harbour.
|
|
*
|
|
* The exception is that, if you link the Harbour libraries with other
|
|
* files to produce an executable, this does not by itself cause the
|
|
* resulting executable to be covered by the GNU General Public License.
|
|
* Your use of that executable is in no way restricted on account of
|
|
* linking the Harbour library code into it.
|
|
*
|
|
* This exception does not however invalidate any other reasons why
|
|
* the executable file might be covered by the GNU General Public License.
|
|
*
|
|
* This exception applies only to the code released by the Harbour
|
|
* Project under the name Harbour. If you copy code from other
|
|
* Harbour Project or Free Software Foundation releases into a copy of
|
|
* Harbour, as the General Public License permits, the exception does
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
* anyone as to the status of such modified files, you must delete
|
|
* this exception notice from them.
|
|
*
|
|
* If you write modifications of your own for Harbour, it is your choice
|
|
* whether to permit this exception to apply to your modifications.
|
|
* If you do not wish that, delete this exception notice.
|
|
*
|
|
*/
|
|
/*----------------------------------------------------------------------*/
|
|
/*----------------------------------------------------------------------*/
|
|
/*----------------------------------------------------------------------*/
|
|
/*
|
|
* EkOnkar
|
|
* ( The LORD is ONE )
|
|
*
|
|
* Harbour-Qt IDE
|
|
*
|
|
* Pritpal Bedi <pritpal@vouchcac.com>
|
|
* 27Dec2009
|
|
*/
|
|
/*----------------------------------------------------------------------*/
|
|
/*----------------------------------------------------------------------*/
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
#include "common.ch"
|
|
#include "hbclass.ch"
|
|
#include "hbqtgui.ch"
|
|
#include "hbide.ch"
|
|
#include "xbp.ch"
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
#define __customContextMenuRequested__ 1
|
|
#define __textChanged__ 2
|
|
#define __copyAvailable__ 3
|
|
#define __modificationChanged__ 4
|
|
#define __redoAvailable__ 5
|
|
#define __selectionChanged__ 6
|
|
#define __undoAvailable__ 7
|
|
#define __updateRequest__ 8
|
|
#define __cursorPositionChanged__ 9
|
|
|
|
#define __timerTimeout__ 23
|
|
|
|
#define __selectionMode_stream__ 1
|
|
#define __selectionMode_column__ 2
|
|
#define __selectionMode_line__ 3
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
CLASS IdeEdit INHERIT IdeObject
|
|
|
|
DATA oEditor
|
|
|
|
DATA qEdit
|
|
DATA nOrient INIT 0
|
|
|
|
DATA nMode INIT 0
|
|
DATA nLineNo INIT -99
|
|
DATA nMaxDigits INIT 5 // Tobe
|
|
DATA nMaxRows INIT 100
|
|
DATA nLastLine INIT -99
|
|
DATA nCurLineNo INIT 0
|
|
DATA nPrevLineNo INIT -1
|
|
DATA nPrevLineNo1 INIT -1
|
|
|
|
DATA aBookMarks INIT {}
|
|
|
|
DATA lModified INIT .F.
|
|
DATA lIndentIt INIT .F.
|
|
DATA lUpdatePrevWord INIT .F.
|
|
DATA lCopyWhenDblClicked INIT .F.
|
|
DATA cCurLineText INIT ""
|
|
|
|
DATA cProto INIT ""
|
|
DATA cProtoOrg INIT ""
|
|
DATA qTimer
|
|
DATA nProtoLine INIT -1
|
|
DATA nProtoCol INIT -1
|
|
DATA isSuspended INIT .F.
|
|
|
|
DATA nProtoRows INIT 1
|
|
DATA nProtoCols INIT 10
|
|
|
|
DATA fontFamily
|
|
DATA pointSize
|
|
DATA currentPointSize
|
|
DATA qFont
|
|
DATA aBlockCopyContents INIT {}
|
|
DATA isLineSelectionON INIT .F.
|
|
DATA aSelectionInfo INIT { -1,-1,-1,-1,1,0 }
|
|
DATA aViewportInfo INIT { -1,-1,-1,-1,-1,-1 }
|
|
|
|
DATA isColumnSelectionON INIT .F.
|
|
DATA lReadOnly INIT .F.
|
|
DATA isHighLighted INIT .f.
|
|
DATA cLastWord, cCurWord
|
|
|
|
METHOD new( oIde, oEditor, nMode )
|
|
METHOD create( oIde, oEditor, nMode )
|
|
METHOD destroy()
|
|
METHOD execEvent( nMode, p, p1 )
|
|
METHOD execKeyEvent( nMode, nEvent, p, p1 )
|
|
METHOD connectEditSignals()
|
|
METHOD disconnectEditSignals()
|
|
|
|
METHOD reload()
|
|
METHOD redo()
|
|
METHOD undo()
|
|
METHOD cut()
|
|
METHOD copy()
|
|
METHOD paste()
|
|
METHOD selectAll()
|
|
|
|
METHOD setReadOnly( lReadOnly )
|
|
METHOD setNewMark()
|
|
METHOD gotoMark( nIndex )
|
|
METHOD duplicateLine()
|
|
METHOD deleteLine()
|
|
METHOD blockComment()
|
|
METHOD streamComment()
|
|
METHOD blockIndent( nDirctn )
|
|
METHOD moveLine( nDirection )
|
|
METHOD caseUpper()
|
|
METHOD caseLower()
|
|
METHOD caseInvert()
|
|
METHOD convertQuotes()
|
|
METHOD convertDQuotes()
|
|
METHOD findLastIndent()
|
|
METHOD reLayMarkButtons()
|
|
METHOD presentSkeletons()
|
|
METHOD handleCurrentIndent()
|
|
METHOD handlePreviousWord( lUpdatePrevWord )
|
|
METHOD loadFuncHelp()
|
|
METHOD clickFuncHelp()
|
|
METHOD goto( nLine )
|
|
METHOD gotoFunction()
|
|
METHOD toggleLineNumbers()
|
|
METHOD toggleHorzRuler()
|
|
|
|
METHOD toggleSelectionMode()
|
|
METHOD toggleStreamSelectionMode()
|
|
METHOD toggleColumnSelectionMode()
|
|
METHOD toggleLineSelectionMode()
|
|
METHOD clearSelection()
|
|
METHOD togglePersistentSelection()
|
|
METHOD toggleCodeCompetion()
|
|
METHOD toggleCompetionTips()
|
|
|
|
METHOD getWord( lSelect )
|
|
METHOD getLine( nLine, lSelect )
|
|
METHOD getText()
|
|
METHOD getSelectedText()
|
|
METHOD getColumnNo()
|
|
METHOD getLineNo()
|
|
METHOD insertSeparator( cSep )
|
|
METHOD insertText( cText )
|
|
|
|
METHOD suspendPrototype()
|
|
METHOD resumePrototype()
|
|
METHOD showPrototype( cProto )
|
|
METHOD hidePrototype()
|
|
METHOD completeCode( p )
|
|
|
|
METHOD setLineNumbersBkColor( nR, nG, nB )
|
|
METHOD setCurrentLineColor( nR, nG, nB )
|
|
METHOD getCursor() INLINE ::qEdit:textCursor()
|
|
METHOD find( cText, nPosFrom )
|
|
METHOD refresh()
|
|
METHOD isModified() INLINE ::oEditor:qDocument:isModified()
|
|
METHOD setFont()
|
|
METHOD markCurrentFunction()
|
|
METHOD copyBlockContents()
|
|
METHOD pasteBlockContents()
|
|
METHOD insertBlockContents( oKey )
|
|
METHOD cutBlockContents( k )
|
|
METHOD zoom( nKey )
|
|
METHOD blockConvert( cMode )
|
|
METHOD dispStatusInfo()
|
|
METHOD toggleCurrentLineHighlightMode()
|
|
METHOD currentFunctionIndex()
|
|
METHOD toPreviousFunction()
|
|
METHOD toNextFunction()
|
|
|
|
METHOD home()
|
|
METHOD end()
|
|
METHOD down()
|
|
METHOD up()
|
|
METHOD goBottom()
|
|
METHOD goTop()
|
|
METHOD left()
|
|
METHOD right()
|
|
METHOD panEnd()
|
|
METHOD panHome()
|
|
METHOD pageUp()
|
|
METHOD pageDown()
|
|
METHOD printPreview()
|
|
METHOD paintRequested( qPrinter )
|
|
METHOD tabs2spaces()
|
|
METHOD spaces2tabs()
|
|
METHOD removeTrailingSpaces()
|
|
METHOD formatBraces()
|
|
METHOD upperCaseKeywords()
|
|
METHOD findEx( cText, nFlags, nStart )
|
|
METHOD highlightAll( cText )
|
|
METHOD unHighlight()
|
|
METHOD parseCodeCompletion( cSyntax )
|
|
|
|
METHOD highlightPage()
|
|
METHOD reformatLine( nPos, nAdded, nDeleted )
|
|
METHOD handleTab( key )
|
|
|
|
ENDCLASS
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:new( oIde, oEditor, nMode )
|
|
|
|
DEFAULT oIde TO ::oIde
|
|
DEFAULT oEditor TO ::oEditor
|
|
DEFAULT nMode TO ::nMode
|
|
|
|
::oIde := oIde
|
|
::oEditor := oEditor
|
|
::nMode := nMode
|
|
|
|
::fontFamily := ::oINI:cFontName
|
|
::pointSize := ::oINI:nPointSize
|
|
::currentPointSize := ::oINI:nPointSize
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:create( oIde, oEditor, nMode )
|
|
LOCAL nBlock, oPalette
|
|
|
|
DEFAULT oIde TO ::oIde
|
|
DEFAULT oEditor TO ::oEditor
|
|
DEFAULT nMode TO ::nMode
|
|
|
|
::oIde := oIde
|
|
::oEditor := oEditor
|
|
::nMode := nMode
|
|
|
|
::qEdit := HBQPlainTextEdit()
|
|
//
|
|
::qEdit:setLineWrapMode( QTextEdit_NoWrap )
|
|
::qEdit:ensureCursorVisible()
|
|
::qEdit:setContextMenuPolicy( Qt_CustomContextMenu )
|
|
::qEdit:setTabChangesFocus( .f. )
|
|
::qEdit:setFocusPolicy( Qt_StrongFocus )
|
|
::qEdit:setObjectName( hbide_getNextIDasString( "HBQPlainTextEdit" ) )
|
|
|
|
oPalette := ::qEdit:palette()
|
|
oPalette:setColor( QPalette_Inactive, QPalette_Highlight, QColor( Qt_yellow ) )
|
|
::qEdit:setPalette( oPalette )
|
|
|
|
::setFont()
|
|
|
|
::qEdit:hbSetSpaces( ::nTabSpaces )
|
|
|
|
::qEdit:hbSetCompleter( ::qCompleter )
|
|
|
|
::toggleCurrentLineHighlightMode()
|
|
::toggleLineNumbers()
|
|
::toggleHorzRuler()
|
|
|
|
FOR EACH nBlock IN ::aBookMarks
|
|
::qEdit:hbBookMarks( nBlock )
|
|
NEXT
|
|
|
|
::connectEditSignals()
|
|
|
|
::qEdit:connect( QEvent_KeyPress , {|p| ::execKeyEvent( 101, QEvent_KeyPress , p ) } )
|
|
::qEdit:connect( QEvent_Wheel , {|p| ::execKeyEvent( 102, QEvent_Wheel , p ) } )
|
|
::qEdit:connect( QEvent_FocusIn , {| | ::execKeyEvent( 104, QEvent_FocusIn ) } )
|
|
::qEdit:connect( QEvent_Resize , {| | ::execKeyEvent( 106, QEvent_Resize ) } )
|
|
::qEdit:connect( QEvent_FocusOut , {| | ::execKeyEvent( 105, QEvent_FocusOut ) } )
|
|
::qEdit:connect( QEvent_MouseButtonDblClick, {|p| ::execKeyEvent( 103, QEvent_MouseButtonDblClick, p ) } )
|
|
|
|
::qEdit:hbSetEventBlock( {|p,p1| ::execKeyEvent( 115, 1001, p, p1 ) } )
|
|
|
|
::qTimer := QTimer()
|
|
::qTimer:setInterval( 2000 )
|
|
::qTimer:connect( "timeout()", {|| ::execEvent( __timerTimeout__ ) } )
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:destroy()
|
|
|
|
IF Self == ::oEditor:oEdit
|
|
::oSourceThumbnailDock:oWidget:hide()
|
|
ENDIF
|
|
|
|
::oEditor := NIL
|
|
|
|
::qTimer:disconnect( "timeout()" )
|
|
IF ::qTimer:isActive()
|
|
::qTimer:stop()
|
|
ENDIF
|
|
::qTimer := NIL
|
|
|
|
::qEdit:disconnect( QEvent_KeyPress )
|
|
::qEdit:disconnect( QEvent_Wheel )
|
|
::qEdit:disconnect( QEvent_FocusIn )
|
|
::qEdit:disconnect( QEvent_FocusOut )
|
|
::qEdit:disconnect( QEvent_Resize )
|
|
::qEdit:disconnect( QEvent_MouseButtonDblClick )
|
|
|
|
::disconnectEditSignals()
|
|
|
|
//::qEdit := NIL
|
|
::qEdit:setParent( QWidget() ) /* Works, but GPF on exit */
|
|
::qFont := NIL
|
|
|
|
RETURN NIL
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:disconnectEditSignals()
|
|
|
|
::qEdit:disConnect( "customContextMenuRequested(QPoint)" )
|
|
::qEdit:disConnect( "textChanged()" )
|
|
::qEdit:disConnect( "selectionChanged()" )
|
|
::qEdit:disConnect( "cursorPositionChanged()" )
|
|
::qEdit:disConnect( "copyAvailable(bool)" )
|
|
|
|
#if 0
|
|
::qEdit:disConnect( "updateRequest(QRect,int)" )
|
|
::qEdit:disConnect( "modificationChanged(bool)" )
|
|
::qEdit:disConnect( "redoAvailable(bool)" )
|
|
::qEdit:disConnect( "undoAvailable(bool)" )
|
|
#endif
|
|
|
|
RETURN NIL
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:connectEditSignals()
|
|
|
|
::qEdit:connect( "customContextMenuRequested(QPoint)", {|p | ::execEvent( __customContextMenuRequested__, p ) } )
|
|
::qEdit:connect( "selectionChanged()" , {|p | ::execEvent( __selectionChanged__, p ) } )
|
|
::qEdit:connect( "cursorPositionChanged()" , {| | ::execEvent( __cursorPositionChanged__ ) } )
|
|
::qEdit:connect( "copyAvailable(bool)" , {|p | ::execEvent( __copyAvailable__, p ) } )
|
|
|
|
#if 0
|
|
::qEdit:connect( "modificationChanged(bool)" , {|p | ::execEvent( __modificationChanged__, p ) } )
|
|
::qEdit:connect( "textChanged()" , {| | ::execEvent( __textChanged__ ) } )
|
|
::qEdit:connect( "updateRequest(QRect,int)" , {|p,p1| ::execEvent( __updateRequest__, p, p1 ) } )
|
|
::qEdit:connect( "redoAvailable(bool)" , {|p | ::execEvent( __redoAvailable__, p ) } )
|
|
::qEdit:connect( "undoAvailable(bool)" , {|p | ::execEvent( __undoAvailable__, p ) } )
|
|
#endif
|
|
|
|
RETURN NIL
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:execEvent( nMode, p, p1 )
|
|
LOCAL qAct, n, qCursor, cAct, lOtherEdit
|
|
|
|
HB_SYMBOL_UNUSED( p1 )
|
|
|
|
IF ::lQuitting
|
|
RETURN NIL
|
|
ENDIF
|
|
|
|
qCursor := ::qEdit:textCursor()
|
|
::nCurLineNo := qCursor:blockNumber()
|
|
|
|
SWITCH nMode
|
|
|
|
CASE __timerTimeout__
|
|
IF empty( ::cProto )
|
|
::hidePrototype()
|
|
ELSE
|
|
::showPrototype()
|
|
ENDIF
|
|
EXIT
|
|
|
|
CASE __cursorPositionChanged__
|
|
::oEditor:dispEditInfo( ::qEdit ) /* Is a MUST */
|
|
::markCurrentFunction() /* Optimized */
|
|
EXIT
|
|
|
|
CASE __selectionChanged__
|
|
lOtherEdit := ! ( ::oEditor:qCqEdit == ::qEdit )
|
|
IF lOtherEdit
|
|
::oEditor:qCqEdit := ::qEdit
|
|
::oEditor:qCoEdit := Self
|
|
IF HB_ISOBJECT( ::oEditor:qHiliter )
|
|
::oEditor:qHiliter:hbSetEditor( ::qEdit )
|
|
::qEdit:hbSetHighlighter( ::oEditor:qHiliter )
|
|
ENDIF
|
|
ENDIF
|
|
IF ::aSelectionInfo[ 1 ] > -1 .AND. ::aSelectionInfo[ 1 ] == ::aSelectionInfo[ 3 ]
|
|
::oDK:setStatusText( SB_PNL_SELECTEDCHARS, Len( ::getSelectedText() ) )
|
|
ELSE
|
|
::oDK:setStatusText( SB_PNL_SELECTEDCHARS, 0 )
|
|
ENDIF
|
|
|
|
::unHighlight()
|
|
::oUpDn:show( Self )
|
|
EXIT
|
|
|
|
CASE __copyAvailable__
|
|
IF p .AND. ::lCopyWhenDblClicked
|
|
::qEdit:copy()
|
|
ENDIF
|
|
::lCopyWhenDblClicked := .f.
|
|
EXIT
|
|
|
|
CASE __customContextMenuRequested__
|
|
::oEM:aActions[ 17, 2 ]:setEnabled( !empty( qCursor:selectedText() ) )
|
|
|
|
n := ascan( ::oEditor:aEdits, {|o| o == Self } )
|
|
|
|
::oEM:aActions[ 18, 2 ]:setEnabled( Len( ::oEditor:aEdits ) == 0 .OR. ::oEditor:nSplOrient == -1 .OR. ::oEditor:nSplOrient == 1 )
|
|
::oEM:aActions[ 19, 2 ]:setEnabled( Len( ::oEditor:aEdits ) == 0 .OR. ::oEditor:nSplOrient == -1 .OR. ::oEditor:nSplOrient == 2 )
|
|
::oEM:aActions[ 21, 2 ]:setEnabled( n > 0 )
|
|
|
|
IF empty( qAct := ::oEM:qContextMenu:exec( ::qEdit:mapToGlobal( p ) ) )
|
|
RETURN Self
|
|
ENDIF
|
|
cAct := strtran( qAct:text(), "&", "" )
|
|
SWITCH cAct
|
|
CASE "Split Horizontally"
|
|
::oEditor:split( 1, Self )
|
|
EXIT
|
|
CASE "Split Vertically"
|
|
::oEditor:split( 2, Self )
|
|
EXIT
|
|
CASE "Close Split Window"
|
|
IF n > 0 /* 1 == Main Edit */
|
|
hb_adel( ::oEditor:aEdits, n, .t. )
|
|
::oEditor:qCqEdit := ::oEditor:qEdit
|
|
::oEditor:qCoEdit := ::oEditor:oEdit
|
|
::destroy()
|
|
::oIde:manageFocusInEditor()
|
|
ENDIF
|
|
EXIT
|
|
CASE "Save as Skeleton..."
|
|
::oSK:saveAs( ::getSelectedText() )
|
|
EXIT
|
|
CASE "Apply Theme"
|
|
::oEditor:applyTheme()
|
|
EXIT
|
|
CASE "Goto Function"
|
|
::gotoFunction()
|
|
EXIT
|
|
CASE "Cut"
|
|
::cut()
|
|
EXIT
|
|
CASE "Copy"
|
|
::copy()
|
|
EXIT
|
|
CASE "Paste"
|
|
::paste()
|
|
EXIT
|
|
CASE "Undo"
|
|
::undo()
|
|
EXIT
|
|
CASE "Redo"
|
|
::redo()
|
|
EXIT
|
|
CASE "Diff"
|
|
::oEditor:vssExecute( "Diff" )
|
|
EXIT
|
|
CASE "Get Latest Version"
|
|
::oEditor:vssExecute( "Get" )
|
|
EXIT
|
|
CASE "Checkin"
|
|
::oEditor:vssExecute( "Checkin" )
|
|
EXIT
|
|
CASE "Undo Checkout"
|
|
::oEditor:vssExecute( "Undocheckout" )
|
|
EXIT
|
|
CASE "Checkout"
|
|
::oEditor:vssExecute( "Checkout" )
|
|
EXIT
|
|
ENDSWITCH
|
|
EXIT
|
|
|
|
#if 0
|
|
CASE __textChanged__
|
|
::oEditor:setTabImage( ::qEdit )
|
|
::handlePreviousWord( ::lUpdatePrevWord )
|
|
EXIT
|
|
CASE __modificationChanged__
|
|
::oEditor:setTabImage( ::qEdit )
|
|
EXIT
|
|
CASE __redoAvailable__
|
|
EXIT
|
|
CASE __undoAvailable__
|
|
EXIT
|
|
CASE __updateRequest__
|
|
EXIT
|
|
#endif
|
|
ENDSWITCH
|
|
|
|
RETURN NIL
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:execKeyEvent( nMode, nEvent, p, p1 )
|
|
LOCAL key, kbm, lAlt, lCtrl, lShift
|
|
|
|
HB_SYMBOL_UNUSED( nMode )
|
|
HB_SYMBOL_UNUSED( p1 )
|
|
|
|
SWITCH nEvent
|
|
CASE QEvent_KeyPress
|
|
key := p:key()
|
|
kbm := p:modifiers()
|
|
|
|
lAlt := hb_bitAnd( kbm, Qt_AltModifier ) == Qt_AltModifier
|
|
lCtrl := hb_bitAnd( kbm, Qt_ControlModifier ) == Qt_ControlModifier
|
|
lShift := hb_bitAnd( kbm, Qt_ShiftModifier ) == Qt_ShiftModifier
|
|
|
|
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
|
|
|
|
SWITCH ( key )
|
|
|
|
CASE Qt_Key_F3
|
|
IF ! lCtrl .AND. ! lAlt
|
|
::oFR:find( .f. )
|
|
ENDIF
|
|
EXIT
|
|
CASE Qt_Key_Insert
|
|
IF lCtrl
|
|
::copy()
|
|
ENDIF
|
|
EXIT
|
|
CASE Qt_Key_Backspace
|
|
IF ! lCtrl .AND. ! lAlt
|
|
IF ::getLineNo() == ::nProtoLine .AND. ::getColumnNo() <= ::nProtoCol + 1
|
|
::hidePrototype()
|
|
ENDIF
|
|
ENDIF
|
|
EXIT
|
|
CASE Qt_Key_Space
|
|
IF !lAlt .AND. !lShift .AND. !lCtrl
|
|
::lUpdatePrevWord := .t.
|
|
ENDIF
|
|
EXIT
|
|
CASE Qt_Key_Return
|
|
CASE Qt_Key_Enter
|
|
::handlePreviousWord( .t. )
|
|
::lIndentIt := .t.
|
|
EXIT
|
|
CASE Qt_Key_ParenLeft
|
|
IF ! lCtrl .AND. ! lAlt
|
|
::loadFuncHelp() // Also invokes prototype display
|
|
ENDIF
|
|
EXIT
|
|
CASE Qt_Key_ParenRight
|
|
IF ! lCtrl .AND. ! lAlt
|
|
::hidePrototype()
|
|
ENDIF
|
|
EXIT
|
|
CASE Qt_Key_PageUp
|
|
IF lAlt
|
|
::toPreviousFunction()
|
|
ENDIF
|
|
EXIT
|
|
CASE Qt_Key_PageDown
|
|
IF lAlt
|
|
::toNextFunction()
|
|
ENDIF
|
|
EXIT
|
|
ENDSWITCH
|
|
EXIT
|
|
CASE QEvent_Enter
|
|
CASE QEvent_FocusIn
|
|
IF key == QEvent_FocusIn
|
|
::oUpDn:show()
|
|
ENDIF
|
|
EXIT
|
|
CASE QEvent_Resize
|
|
::oUpDn:show()
|
|
EXIT
|
|
CASE QEvent_Leave
|
|
CASE QEvent_FocusOut
|
|
EXIT
|
|
CASE QEvent_Wheel
|
|
EXIT
|
|
CASE QEvent_MouseButtonDblClick
|
|
::lCopyWhenDblClicked := .t.
|
|
::clickFuncHelp()
|
|
EXIT
|
|
CASE 1001 /* Fired from hbqt_hbqplaintextedit.cpp */
|
|
SWITCH p
|
|
CASE 21000 /* Sends Block Info { t,l,b,r,mode,state } hbGetBlockInfo() */
|
|
::aSelectionInfo := p1
|
|
::oDK:setButtonState( "SelectionMode", ::aSelectionInfo[ 5 ] > 1 )
|
|
EXIT
|
|
CASE 21001
|
|
::handlePreviousWord( .t. )
|
|
EXIT
|
|
CASE 21002
|
|
::loadFuncHelp()
|
|
EXIT
|
|
CASE 21011
|
|
::copyBlockContents()
|
|
EXIT
|
|
CASE 21012
|
|
::pasteBlockContents()
|
|
EXIT
|
|
CASE 21013
|
|
::insertBlockContents( p1 )
|
|
EXIT
|
|
CASE 21014 /* ->hbCut() */
|
|
::cutBlockContents( p1 )
|
|
EXIT
|
|
CASE 21017 /* Sends Block Info { t,l,b,r,mode,state } hbGetBlockInfo() */
|
|
::aViewportInfo := p1
|
|
EXIT
|
|
CASE 21041
|
|
::qEdit:hbSetFieldsListActive( ::oEM:updateFieldsList( p1 ) )
|
|
EXIT
|
|
CASE 21042
|
|
::qEdit:hbSetFieldsListActive( ::oEM:updateFieldsList() )
|
|
EXIT
|
|
ENDSWITCH
|
|
EXIT
|
|
ENDSWITCH
|
|
|
|
RETURN .F. /* Important - NEVER CHANGE IT TO .T. */
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:zoom( nKey )
|
|
|
|
DEFAULT nKey TO 0
|
|
|
|
IF nKey == 1
|
|
IF ::currentPointSize + 1 < 30
|
|
::currentPointSize++
|
|
ENDIF
|
|
|
|
ELSEIF nKey == -1
|
|
IF ::currentPointSize - 1 > 3
|
|
::currentPointSize--
|
|
ENDIF
|
|
|
|
ELSEIF nKey == 0
|
|
::currentPointSize := ::pointSize
|
|
|
|
ELSEIF nKey >= 3 .AND. nKey <= 30
|
|
::currentPointSize := nKey
|
|
|
|
ELSE
|
|
RETURN Self
|
|
|
|
ENDIF
|
|
|
|
::setFont()
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:setFont()
|
|
|
|
::qFont := QFont()
|
|
::qFont:setFamily( ::fontFamily )
|
|
::qFont:setFixedPitch( .t. )
|
|
::qFont:setPointSize( ::currentPointSize )
|
|
|
|
::qEdit:setFont( ::qFont )
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:highlightPage()
|
|
|
|
IF HB_ISOBJECT( ::oEditor:qHiliter )
|
|
::qEdit:hbHighlightPage()
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:dispStatusInfo()
|
|
LOCAL nMode
|
|
|
|
nMode := ::aSelectionInfo[ 5 ]
|
|
::oDK:setButtonState( "SelectionMode", nMode > 1 )
|
|
::oDK:setStatusText( SB_PNL_STREAM, iif( nMode == 2, "Column", iif( nMode == 3, "Line", "Stream" ) ) )
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
STATIC FUNCTION hbide_blockContents( aContents )
|
|
LOCAL oldContents
|
|
STATIC contents := {}
|
|
|
|
oldContents := contents
|
|
IF HB_ISARRAY( aContents )
|
|
contents := aclone( aContents )
|
|
ENDIF
|
|
|
|
RETURN oldContents
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
STATIC FUNCTION hbide_setQCursor( qEdit, a_ )
|
|
LOCAL qCursor
|
|
|
|
IF HB_ISARRAY( a_ )
|
|
qCursor := a_[ 1 ]
|
|
qCursor:movePosition( QTextCursor_Start, QTextCursor_MoveAnchor )
|
|
qCursor:movePosition( QTextCursor_Down , QTextCursor_MoveAnchor, a_[ 2 ] )
|
|
qCursor:movePosition( QTextCursor_Right, QTextCursor_MoveAnchor, a_[ 3 ] )
|
|
qEdit:setTextCursor( qCursor )
|
|
qCursor:endEditBlock()
|
|
ELSE
|
|
qCursor := qEdit:textCursor()
|
|
qCursor:beginEditBlock()
|
|
RETURN { qCursor, qCursor:blockNumber(), qCursor:columnNumber() }
|
|
ENDIF
|
|
|
|
RETURN NIL
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
STATIC FUNCTION hbide_qReplaceLine( qCursor, nLine, cLine )
|
|
|
|
qCursor:movePosition( QTextCursor_Start , QTextCursor_MoveAnchor )
|
|
qCursor:movePosition( QTextCursor_Down , QTextCursor_MoveAnchor, nLine )
|
|
qCursor:movePosition( QTextCursor_StartOfLine, QTextCursor_MoveAnchor )
|
|
qCursor:movePosition( QTextCursor_EndOfLine , QTextCursor_KeepAnchor )
|
|
qCursor:insertText( cLine )
|
|
|
|
RETURN NIL
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
STATIC FUNCTION hbide_qPositionCursor( qCursor, nRow, nCol )
|
|
|
|
qCursor:movePosition( QTextCursor_Start, QTextCursor_MoveAnchor )
|
|
qCursor:movePosition( QTextCursor_Down , QTextCursor_MoveAnchor, nRow )
|
|
qCursor:movePosition( QTextCursor_Right, QTextCursor_MoveAnchor, nCol )
|
|
|
|
RETURN NIL
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
STATIC FUNCTION hbide_invert( cBuffer )
|
|
LOCAL s, i, c, nLen
|
|
|
|
s := ""
|
|
nLen := Len( cBuffer )
|
|
FOR i := 1 TO nLen
|
|
c := substr( cBuffer, i, 1 )
|
|
IF isAlpha( c )
|
|
s += iif( isUpper( c ), lower( c ), upper( c ) )
|
|
ELSE
|
|
s += c
|
|
ENDIF
|
|
NEXT
|
|
|
|
RETURN s
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
STATIC FUNCTION hbide_convertALine( cLine, cMode )
|
|
|
|
SWITCH cMode
|
|
CASE "toupper"
|
|
cLine := upper( cLine )
|
|
EXIT
|
|
CASE "tolower"
|
|
cLine := lower( cLine )
|
|
EXIT
|
|
CASE "invert"
|
|
cLine := hbide_invert( cLine )
|
|
EXIT
|
|
CASE "sgl2dbl"
|
|
cLine := strtran( cLine, "'", '"' )
|
|
EXIT
|
|
CASE "dbl2sgl"
|
|
cLine := strtran( cLine, '"', "'" )
|
|
EXIT
|
|
ENDSWITCH
|
|
|
|
RETURN cLine
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
STATIC FUNCTION hbide_qCursorDownInsert( qCursor )
|
|
LOCAL nRow := qCursor:blockNumber()
|
|
|
|
qCursor:movePosition( QTextCursor_Down, QTextCursor_MoveAnchor )
|
|
IF qCursor:blockNumber() == nRow
|
|
qCursor:movePosition( QTextCursor_EndOfBlock, QTextCursor_MoveAnchor )
|
|
qCursor:insertBlock()
|
|
qCursor:movePosition( QTextCursor_NextBlock, QTextCursor_MoveAnchor )
|
|
ENDIF
|
|
|
|
RETURN NIL
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:copyBlockContents()
|
|
LOCAL nT, nL, nB, nR, nW, i, cLine, nMode, qClip, aCord
|
|
LOCAL cClip := ""
|
|
|
|
HB_TRACE( HB_TR_DEBUG, "IdeEdit:copyBlockContents( aCord )" )
|
|
|
|
aCord := ::aSelectionInfo
|
|
|
|
hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR )
|
|
nMode := aCord[ 5 ]
|
|
|
|
::aBlockCopyContents := {}
|
|
|
|
nW := nR - nL
|
|
FOR i := nT TO nB
|
|
cLine := ::getLine( i + 1 )
|
|
cLine := strtran( cLine, chr( 13 ) )
|
|
cLine := strtran( cLine, chr( 10 ) )
|
|
|
|
IF nMode == __selectionMode_stream__
|
|
IF aCord[ 1 ] > aCord[ 3 ] // Selection - bottom to top
|
|
IF i == nT .AND. i == nB
|
|
cLine := substr( cLine, min( aCord[ 2 ], aCord[ 4 ] ) + 1, nW )
|
|
ELSEIF i == aCord[ 1 ]
|
|
cLine := substr( cLine, 1, aCord[ 2 ] )
|
|
ELSEIF i == aCord[ 3 ]
|
|
cLine := substr( cLine, aCord[ 4 ] + 1 )
|
|
ENDIF
|
|
ELSE // Selection - top to bottom or same row
|
|
IF i == nT .AND. i == nB
|
|
cLine := substr( cLine, min( aCord[ 2 ], aCord[ 4 ] ) + 1, nW )
|
|
ELSEIF i == aCord[ 1 ]
|
|
cLine := substr( cLine, aCord[ 2 ] + 1 )
|
|
ELSEIF i == aCord[ 3 ]
|
|
cLine := substr( cLine, 1, aCord[ 4 ] )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSEIF nMode == __selectionMode_column__
|
|
cLine := pad( substr( cLine, nL + 1, nW ), nW )
|
|
|
|
ELSEIF nMode == __selectionMode_line__
|
|
// Nothing to do, complete line is already pulled
|
|
|
|
ENDIF
|
|
|
|
aadd( ::aBlockCopyContents, cLine )
|
|
cClip += cLine + iif( nT == nB, "", iif( i < nB, hb_eol(), "" ) )
|
|
NEXT
|
|
|
|
hbide_blockContents( { nMode, ::aBlockCopyContents } )
|
|
|
|
qClip := QClipboard()
|
|
qClip:clear()
|
|
qClip:setText( cClip )
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:pasteBlockContents()
|
|
LOCAL i, nCol, qCursor, nMaxCol, aCopy, a_, nPasteMode, nMode
|
|
|
|
IF ::lReadOnly
|
|
RETURN Self
|
|
ENDIF
|
|
|
|
nMode := ::aSelectionInfo[ 5 ]
|
|
|
|
aCopy := hb_ATokens( StrTran( QClipboard():text(), Chr( 13 ) + Chr( 10 ), _EOL ), _EOL )
|
|
IF empty( aCopy )
|
|
RETURN Self
|
|
ENDIF
|
|
|
|
nPasteMode := nMode /* OR Stream - needs to be thought carefully */
|
|
|
|
a_:= hbide_blockContents()
|
|
IF !empty( a_ )
|
|
IF ( Len( a_[ 2 ] ) == len( aCopy ) ) .OR. ( len( a_[ 2 ] ) == len( aCopy ) + 1 )
|
|
IF a_[ 2,1 ] == aCopy[ 1 ]
|
|
nPasteMode := a_[ 1 ]
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
nPasteMode := iif( empty( nPasteMode ), __selectionMode_stream__, nPasteMode )
|
|
qCursor := ::qEdit:textCursor()
|
|
nCol := qCursor:columnNumber()
|
|
|
|
qCursor:beginEditBlock()
|
|
//
|
|
SWITCH nPasteMode
|
|
CASE __selectionMode_column__
|
|
FOR i := 1 TO Len( aCopy )
|
|
qCursor:insertText( aCopy[ i ] )
|
|
IF i < Len( aCopy )
|
|
hbide_qCursorDownInsert( qCursor )
|
|
|
|
qCursor:movePosition( QTextCursor_EndOfLine, QTextCursor_MoveAnchor )
|
|
nMaxCol := qCursor:columnNumber()
|
|
IF nMaxCol < nCol
|
|
qCursor:insertText( replicate( " ", nCol - nMaxCol ) )
|
|
ENDIF
|
|
qCursor:movePosition( QTextCursor_StartOfLine, QTextCursor_MoveAnchor )
|
|
qCursor:movePosition( QTextCursor_Right , QTextCursor_MoveAnchor, nCol )
|
|
ENDIF
|
|
NEXT
|
|
EXIT
|
|
CASE __selectionMode_stream__
|
|
FOR i := 1 TO Len( aCopy )
|
|
qCursor:insertText( aCopy[ i ] )
|
|
IF i < Len( aCopy )
|
|
qCursor:insertText( hb_eol() )
|
|
ENDIF
|
|
NEXT
|
|
EXIT
|
|
CASE __selectionMode_line__
|
|
qCursor:movePosition( QTextCursor_StartOfLine, QTextCursor_MoveAnchor )
|
|
FOR i := 1 TO Len( aCopy )
|
|
qCursor:insertText( aCopy[ i ] )
|
|
qCursor:insertBlock()
|
|
NEXT
|
|
EXIT
|
|
ENDSWITCH
|
|
|
|
qCursor:endEditBlock()
|
|
::qEdit:ensureCursorVisible()
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
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
|
|
ENDIF
|
|
|
|
cKey := chr( hbxbp_QKeyEventToAppEvent( oKey ) )
|
|
|
|
aCord := ::aSelectionInfo
|
|
hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR )
|
|
nW := nR - nL
|
|
|
|
qCursor := ::qEdit:textCursor()
|
|
qCur := ::qEdit:textCursor()
|
|
qCursor:beginEditBlock()
|
|
|
|
IF nW == 0
|
|
FOR i := nT TO nB
|
|
cLine := ::getLine( i + 1 )
|
|
cLine := pad( substr( cLine, 1, nL ), nL ) + cKey + substr( cLine, nL + 1 )
|
|
hbide_qReplaceLine( qCursor, i, cLine )
|
|
NEXT
|
|
|
|
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, qCur:blockNumber(), nR )
|
|
ENDIF
|
|
|
|
::qEdit:setTextCursor( qCursor )
|
|
qCursor:endEditBlock()
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:cutBlockContents( k )
|
|
LOCAL nT, nL, nB, nR, i, cLine, qCursor, nSelMode, aCord, qCur
|
|
|
|
IF ::lReadOnly
|
|
RETURN Self
|
|
ENDIF
|
|
|
|
k := iif( empty( k ), Qt_Key_X, k )
|
|
IF k == Qt_Key_X
|
|
::copyBlockContents()
|
|
ENDIF
|
|
aCord := ::aSelectionInfo
|
|
hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR )
|
|
|
|
nSelMode := aCord[ 5 ]
|
|
|
|
qCursor := ::qEdit:textCursor()
|
|
qCur := ::qEdit:textCursor()
|
|
qCursor:beginEditBlock()
|
|
|
|
IF k == Qt_Key_Backspace
|
|
IF nSelMode == __selectionMode_column__
|
|
FOR i := nT TO nB
|
|
cLine := ::getLine( i + 1 )
|
|
cLine := pad( substr( cLine, 1, nL - 1 ), nL - 1 ) + substr( cLine, nL + 1 )
|
|
hbide_qReplaceLine( qCursor, i, cLine )
|
|
NEXT
|
|
hbide_qPositionCursor( qCursor, qCur:blockNumber(), nR - 1 )
|
|
ENDIF
|
|
ELSE
|
|
IF k == Qt_Key_Delete .OR. k == Qt_Key_X
|
|
IF nSelMode == __selectionMode_column__
|
|
FOR i := nT TO nB
|
|
cLine := ::getLine( i + 1 )
|
|
cLine := pad( substr( cLine, 1, nL ), nL ) + substr( cLine, nR + 1 )
|
|
hbide_qReplaceLine( qCursor, i, cLine )
|
|
NEXT
|
|
hbide_qPositionCursor( qCursor, qCur:blockNumber(), nL )
|
|
::qEdit:hbSetSelectionInfo( { nT, nL, nB, nL, __selectionMode_column__ } )
|
|
|
|
ELSEIF nSelMode == __selectionMode_stream__
|
|
hbide_qPositionCursor( qCursor, nT, nL )
|
|
qCursor:movePosition( QTextCursor_Down , QTextCursor_KeepAnchor, nB - nT )
|
|
qCursor:movePosition( QTextCursor_StartOfLine, QTextCursor_KeepAnchor )
|
|
qCursor:movePosition( QTextCursor_Right , QTextCursor_KeepAnchor, nR )
|
|
qCursor:removeSelectedText()
|
|
::qEdit:hbSetSelectionInfo( { -1, -1, -1, -1, __selectionMode_stream__ } )
|
|
|
|
ELSEIF nSelMode == __selectionMode_line__
|
|
hbide_qPositionCursor( qCursor, nT, nL )
|
|
qCursor:movePosition( QTextCursor_Down , QTextCursor_KeepAnchor, nB - nT + 1 )
|
|
qCursor:movePosition( QTextCursor_StartOfLine, QTextCursor_KeepAnchor )
|
|
qCursor:removeSelectedText()
|
|
::qEdit:hbSetSelectionInfo( { -1, -1, -1, -1, __selectionMode_stream__ } )
|
|
::isLineSelectionON := .f.
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
::qEdit:setTextCursor( qCursor )
|
|
qCursor:endEditBlock()
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
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 )
|
|
|
|
IF ::lReadOnly
|
|
RETURN Self
|
|
ENDIF
|
|
|
|
aCord := ::aSelectionInfo
|
|
hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR )
|
|
nW := nR - nL
|
|
|
|
IF nW >= 0
|
|
nMode := aCord[ 5 ]
|
|
a_:= hbide_setQCursor( ::qEdit )
|
|
qCursor := a_[ 1 ]
|
|
|
|
FOR i := nT TO nB
|
|
cLine := ::getLine( i + 1 )
|
|
|
|
SWITCH nMode
|
|
CASE __selectionMode_stream__
|
|
CASE __selectionMode_line__
|
|
IF substr( cLine, 1, nLen ) == cComment
|
|
cLine := substr( cLine, nLen + 1 )
|
|
ELSE
|
|
cLine := cComment + cLine
|
|
ENDIF
|
|
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
|
|
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
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:streamComment()
|
|
LOCAL nT, nL, nB, nR, nW, i, cLine, qCursor, aCord, nMode, a_
|
|
|
|
IF ::lReadOnly
|
|
RETURN Self
|
|
ENDIF
|
|
|
|
aCord := ::aSelectionInfo
|
|
hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR )
|
|
nW := nR - nL
|
|
|
|
IF nW >= 0
|
|
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__
|
|
IF i == nT
|
|
cLine := substr( cLine, 1, nL ) + "/* " + substr( cLine, nL + 1 )
|
|
ELSEIF i == nB
|
|
cLine := substr( cLine, 1, nR ) + " */" + substr( cLine, nR + 1 )
|
|
ENDIF
|
|
|
|
CASE nMode == __selectionMode_line__
|
|
IF i == nT
|
|
cLine := "/* " + cLine
|
|
ELSEIF i == nB
|
|
cLine += " */"
|
|
ENDIF
|
|
|
|
ENDCASE
|
|
|
|
hbide_qReplaceLine( qCursor, i, cLine )
|
|
NEXT
|
|
|
|
hbide_setQCursor( ::qEdit, a_ )
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
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
|
|
|
|
IF ::lReadOnly
|
|
RETURN Self
|
|
ENDIF
|
|
|
|
aCord := ::aSelectionInfo
|
|
hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR )
|
|
nW := nR - nL
|
|
|
|
IF nW >= 0
|
|
nMode := aCord[ 5 ]
|
|
a_:= hbide_setQCursor( ::qEdit )
|
|
qCursor := a_[ 1 ]
|
|
|
|
FOR i := nT TO nB
|
|
cLine := ::getLine( i + 1 )
|
|
|
|
SWITCH nMode
|
|
CASE __selectionMode_column__
|
|
cLineSel := pad( substr( cLine, nL + 1, nW ), nW )
|
|
IF nDirctn == -1
|
|
IF left( cLineSel, 1 ) == " "
|
|
cLineSel := substr( cLineSel, 2 )
|
|
ENDIF
|
|
ELSE
|
|
cLineSel := " " + cLineSel
|
|
ENDIF
|
|
cLine := pad( substr( cLine, 1, nL ), nL ) + cLineSel + substr( cLine, nR + 1 )
|
|
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
|
|
|
|
hbide_setQCursor( ::qEdit, a_ )
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:blockConvert( cMode )
|
|
LOCAL nT, nL, nB, nR, nW, i, cLine, qCursor, aCord, a_, nMode
|
|
|
|
IF ::lReadOnly
|
|
RETURN Self
|
|
ENDIF
|
|
|
|
aCord := ::aSelectionInfo
|
|
hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR )
|
|
nW := nR - nL
|
|
|
|
IF nW >= 0
|
|
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__
|
|
IF nT == nB
|
|
cLine := substr( cLine, 1, nL ) + hbide_convertALine( substr( cLine, nL + 1, nW ), cMode ) + substr( cLine, nL + 1 + nW )
|
|
ELSE
|
|
IF i == nT
|
|
cLine := substr( cLine, 1, nL ) + hbide_convertALine( substr( cLine, nL + 1 ), cMode )
|
|
ELSEIF i == nB
|
|
cLine := hbide_convertALine( substr( cLine, 1, nR ), cMode ) + substr( cLine, nR + 1 )
|
|
ELSE
|
|
cLine := hbide_convertALine( cLine, cMode )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CASE nMode == __selectionMode_column__
|
|
cLine := pad( substr( cLine, 1, nL ), nL ) + hbide_convertALine( pad( substr( cLine, nL + 1, nW ), nW ), cMode ) + substr( cLine, nR + 1 )
|
|
|
|
CASE nMode == __selectionMode_line__
|
|
cLine := hbide_convertALine( cLine, cMode )
|
|
|
|
ENDCASE
|
|
|
|
hbide_qReplaceLine( qCursor, i, cLine )
|
|
NEXT
|
|
|
|
hbide_setQCursor( ::qEdit, a_ )
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:getSelectedText()
|
|
LOCAL nT, nL, nB, nR, nW, i, cLine, nMode, cClip := "", aCord
|
|
|
|
HB_TRACE( HB_TR_DEBUG, "IdeEdit:getSelectedText()", ProcName( 1 ), procName( 2 ) )
|
|
|
|
aCord := ::aSelectionInfo
|
|
hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR )
|
|
nMode := aCord[ 5 ]
|
|
|
|
nW := nR - nL
|
|
FOR i := nT TO nB
|
|
cLine := ::getLine( i + 1 )
|
|
|
|
IF nMode == __selectionMode_stream__
|
|
IF i == nT .AND. i == nB
|
|
cLine := substr( cLine, nL + 1, nR - nL )
|
|
ELSEIF i == nT
|
|
cLine := substr( cLine, nL + 1 )
|
|
ELSEIF i == nB
|
|
cLine := substr( cLine, 1, nR + 1 )
|
|
ENDIF
|
|
|
|
ELSEIF nMode == __selectionMode_column__
|
|
cLine := pad( substr( cLine, nL + 1, nW ), nW )
|
|
|
|
ELSEIF nMode == __selectionMode_line__
|
|
// Nothing to do, complete line is already pulled
|
|
|
|
ENDIF
|
|
|
|
cClip += cLine + iif( i < nB, hb_eol(), "" )
|
|
NEXT
|
|
|
|
RETURN cClip
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:caseUpper()
|
|
RETURN ::blockConvert( "toupper" )
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:caseLower()
|
|
RETURN ::blockConvert( "tolower" )
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:caseInvert()
|
|
RETURN ::blockConvert( "invert" )
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:convertQuotes()
|
|
RETURN ::blockConvert( "dbl2sgl" )
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:convertDQuotes()
|
|
RETURN ::blockConvert( "sgl2dbl" )
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:currentFunctionIndex()
|
|
LOCAL n := -1, nCurLine
|
|
|
|
IF !empty( ::aTags )
|
|
nCurLine := ::getLineNo()
|
|
IF Len( ::aTags ) == 1
|
|
n := 1
|
|
ELSEIF ( n := ascan( ::aTags, {|e_| e_[ 3 ] >= nCurLine } ) ) == 0
|
|
n := Len( ::aTags )
|
|
ELSEIF n > 0
|
|
n--
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN n
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toNextFunction()
|
|
LOCAL n
|
|
|
|
IF ( n := ::currentFunctionIndex() ) >= 0
|
|
IF n < Len( ::aTags )
|
|
IF ::find( ::aTags[ n+1, 8 ], QTextDocument_FindCaseSensitively )
|
|
::qEdit:centerCursor()
|
|
::down()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toPreviousFunction()
|
|
LOCAL n
|
|
|
|
IF ( n := ::currentFunctionIndex() ) > 1
|
|
IF ::find( ::aTags[ n-1, 8 ], QTextDocument_FindCaseSensitively )
|
|
::qEdit:centerCursor()
|
|
::down()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:markCurrentFunction()
|
|
LOCAL n
|
|
|
|
IF ::oFuncDock:oWidget:isVisible()
|
|
IF ::nPrevLineNo1 != ::getLineNo()
|
|
::nPrevLineNo1 := ::getLineNo()
|
|
IF ( n := ::currentFunctionIndex() ) > 0
|
|
::oIde:oFuncList:setItemColorFG( ::aTags[ n,7 ], { 255,0,0 } )
|
|
::oIde:oFuncList:setVisible( ::aTags[ n,7 ] )
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:presentSkeletons()
|
|
::oSK:selectByMenuAndPostText( ::qEdit )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toggleCurrentLineHighlightMode()
|
|
::qEdit:hbHighlightCurrentLine( ::lCurrentLineHighlightEnabled )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toggleLineNumbers()
|
|
::qEdit:hbNumberBlockVisible( ::lLineNumbersVisible )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toggleHorzRuler()
|
|
::qEdit:hbHorzRulerVisible( ::lHorzRulerVisible )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* Fired by icon */
|
|
|
|
METHOD IdeEdit:toggleSelectionMode()
|
|
LOCAL qFocus
|
|
|
|
qFocus := QApplication():focusWidget()
|
|
::qEdit:hbSetSelectionMode( iif( ::oDK:setButtonState( "SelectionMode" ), 2, 1 ), .f. )
|
|
qFocus:setFocus( 0 )
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toggleStreamSelectionMode()
|
|
::qEdit:hbSetSelectionMode( 1, .t. )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toggleColumnSelectionMode()
|
|
::qEdit:hbSetSelectionMode( 2, .t. )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toggleLineSelectionMode()
|
|
::qEdit:hbSetSelectionMode( 3, .t. )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:clearSelection()
|
|
::qEdit:hbSetSelectionMode( 0, .t. )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:togglePersistentSelection()
|
|
::qEdit:hbTogglePersistentSelection()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toggleCodeCompetion()
|
|
::qEdit:hbToggleCodeCompetion()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:toggleCompetionTips()
|
|
::qEdit:hbToggleCompetionTips()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:reload()
|
|
LOCAL lLoad := .t.
|
|
|
|
IF ::oEditor:qDocument:isModified()
|
|
lLoad := hbide_getYesNo( "Source is in modified state", "Reload it anyway?", "Reload" )
|
|
ENDIF
|
|
IF lLoad
|
|
::oEditor:reload()
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:redo()
|
|
::qEdit:redo()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:undo()
|
|
::qEdit:undo()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:cut()
|
|
IF ::lReadOnly
|
|
RETURN Self
|
|
ENDIF
|
|
::cutBlockContents( Qt_Key_X )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:copy()
|
|
::copyBlockContents()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:paste()
|
|
|
|
IF ::lReadOnly
|
|
RETURN Self
|
|
ENDIF
|
|
IF ::aSelectionInfo[ 1 ] > -1
|
|
::cutBlockContents( Qt_Key_Delete )
|
|
ENDIF
|
|
::pasteBlockContents()
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:selectAll()
|
|
::qEdit:hbSelectAll()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:setReadOnly( lReadOnly )
|
|
IF ::oEditor:lReadOnly
|
|
lReadOnly := .t.
|
|
ELSE
|
|
IF ! HB_ISLOGICAL( lReadOnly )
|
|
lReadOnly := ! ::qEdit:isReadOnly()
|
|
ENDIF
|
|
ENDIF
|
|
::lReadOnly := lReadOnly
|
|
::qEdit:setReadOnly( lReadOnly )
|
|
::oEditor:setTabImage()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:relayMarkButtons()
|
|
LOCAL oBtn
|
|
FOR EACH oBtn IN ::aMarkTBtns
|
|
oBtn:hide()
|
|
NEXT
|
|
FOR EACH oBtn IN ::aBookMarks
|
|
::aMarkTBtns[ oBtn:__enumIndex() ]:show()
|
|
NEXT
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:gotoMark( nIndex )
|
|
|
|
IF Len( ::aBookMarks ) >= nIndex
|
|
::qEdit:hbGotoBookmark( ::aBookMarks[ nIndex ] )
|
|
::qEdit:centerCursor()
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:setNewMark()
|
|
LOCAL qCursor, nBlock, n
|
|
|
|
IF !( qCursor := ::qEdit:textCursor() ):isNull()
|
|
nBlock := qCursor:blockNumber() + 1
|
|
|
|
IF ( n := ascan( ::aBookMarks, nBlock ) ) > 0
|
|
hb_adel( ::aBookMarks, n, .t. )
|
|
::aMarkTBtns[ Len( ::aBookMarks ) + 1 ]:hide()
|
|
ELSE
|
|
IF Len( ::aBookMarks ) == 6
|
|
RETURN Self
|
|
ENDIF
|
|
aadd( ::aBookMarks, nBlock )
|
|
n := Len( ::aBookMarks )
|
|
::aMarkTBtns[ n ]:show()
|
|
ENDIF
|
|
|
|
::qEdit:hbBookMarks( nBlock )
|
|
::qEdit:repaint()
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:setLineNumbersBkColor( nR, nG, nB )
|
|
::qEdit:hbSetLineAreaBkColor( QColor( nR, nG, nB ) )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:setCurrentLineColor( nR, nG, nB )
|
|
::qEdit:hbSetCurrentLineColor( QColor( nR, nG, nB ) )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* TO BE EXTENDED */
|
|
METHOD IdeEdit:find( cText, nPosFrom )
|
|
LOCAL lFound, nPos
|
|
LOCAL qCursor := ::getCursor()
|
|
|
|
nPos := qCursor:position()
|
|
IF HB_ISNUMERIC( nPosFrom )
|
|
qCursor:setPosition( nPosFrom )
|
|
ENDIF
|
|
::qEdit:setTextCursor( qCursor )
|
|
IF ! ( lFound := ::qEdit:find( cText, QTextDocument_FindCaseSensitively ) )
|
|
IF ! HB_ISNUMERIC( nPosFrom )
|
|
lFound := ::qEdit:find( cText, QTextDocument_FindBackward + QTextDocument_FindCaseSensitively )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF ! lFound
|
|
qCursor:setPosition( nPos )
|
|
::qEdit:setTextCursor( qCursor )
|
|
ELSE
|
|
::qEdit:centerCursor()
|
|
ENDIF
|
|
|
|
RETURN lFound
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* nFlags will decide the position, case sensitivity and direction
|
|
*/
|
|
METHOD IdeEdit:findEx( cText, nFlags, nStart )
|
|
LOCAL qCursor, lFound, nPos
|
|
|
|
DEFAULT cText TO ::getSelectedText()
|
|
DEFAULT nFlags TO 0
|
|
DEFAULT nStart TO 0
|
|
|
|
qCursor := ::getCursor()
|
|
nPos := qCursor:position()
|
|
|
|
IF nStart == 0
|
|
// No need to move cursor
|
|
ELSEIF nStart == 1
|
|
::qEdit:moveCursor( QTextCursor_Start )
|
|
ELSEIF nStart == 2
|
|
::qEdit:moveCursor( QTextCursor_End )
|
|
ENDIF
|
|
|
|
IF ( lFound := ::qEdit:find( cText, nFlags ) )
|
|
::qEdit:centerCursor()
|
|
qCursor := ::qEdit:textCursor()
|
|
|
|
::qEdit:hbSetSelectionInfo( { qCursor:blockNumber(), qCursor:columnNumber() - Len( cText ), ;
|
|
qCursor:blockNumber(), qCursor:columnNumber(), 1, .t., .f. } )
|
|
qCursor:clearSelection()
|
|
ELSE
|
|
qCursor:setPosition( nPos )
|
|
::qEdit:setTextCursor( qCursor )
|
|
ENDIF
|
|
|
|
RETURN lFound
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:unHighlight()
|
|
LOCAL qCursor, nPos, lModified
|
|
|
|
IF ::isHighLighted
|
|
::isHighLighted := .f.
|
|
qCursor := ::getCursor()
|
|
nPos := qCursor:position()
|
|
lModified := ::qEdit:document():isModified()
|
|
::qEdit:undo()
|
|
IF ! lModified
|
|
::qEdit:document():setModified( .f. )
|
|
::oEditor:setTabImage( ::qEdit )
|
|
ENDIF
|
|
qCursor:setPosition( nPos )
|
|
::qEdit:setTextCursor( qCursor )
|
|
RETURN .t.
|
|
ENDIF
|
|
|
|
RETURN .f.
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:highlightAll( cText )
|
|
LOCAL qDoc, qFormat, qCursor, qFormatHL, qCur, lModified
|
|
|
|
IF ::unHighLight()
|
|
RETURN Self
|
|
ENDIF
|
|
|
|
::isHighLighted := .t.
|
|
|
|
qDoc := ::oEditor:qDocument
|
|
lModified := ::qEdit:document():isModified()
|
|
|
|
qCur := ::getCursor()
|
|
qCur:beginEditBlock()
|
|
|
|
qCursor := QTextCursor( "QTextDocument", qDoc )
|
|
qFormat := qCursor:charFormat()
|
|
qFormatHL := qFormat
|
|
qFormatHL:setBackground( QBrush( QColor( Qt_yellow ) ) )
|
|
|
|
DO WHILE .t.
|
|
qCursor := qDoc:find( cText, qCursor, 0 )
|
|
IF qCursor:isNull()
|
|
EXIT
|
|
ENDIF
|
|
qCursor:mergeCharFormat( qFormatHL )
|
|
ENDDO
|
|
qCur:endEditBlock()
|
|
|
|
IF ! lModified
|
|
::qEdit:document():setModified( .f. )
|
|
::oEditor:setTabImage( ::qEdit )
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:refresh()
|
|
::qEdit:hbRefresh()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
// TBrowse Like Navigation
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:home()
|
|
::qEdit:hbApplyKey( Qt_Key_Home )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:end()
|
|
::qEdit:hbApplyKey( Qt_Key_End )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:down()
|
|
::qEdit:hbApplyKey( Qt_Key_Down )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:up()
|
|
::qEdit:hbApplyKey( Qt_Key_Up )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:goBottom()
|
|
::qEdit:hbApplyKey( Qt_Key_End, Qt_ControlModifier )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:goTop()
|
|
::qEdit:hbApplyKey( Qt_Key_Home, Qt_ControlModifier )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:left()
|
|
::qEdit:hbApplyKey( Qt_Key_Left )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:right()
|
|
::qEdit:hbApplyKey( Qt_Key_Right )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:panEnd()
|
|
LOCAL qCursor := ::getCursor()
|
|
LOCAL cLine := ::getLine()
|
|
::qEdit:hbGetViewportInfo()
|
|
IF Len( cLine ) - ::aViewportInfo[ 2 ] > ::aViewportInfo[ 4 ]
|
|
qCursor:movePosition( QTextCursor_Right, QTextCursor_MoveAnchor, Len( cLine ) - ::aViewportInfo[ 2 ] )
|
|
ELSE
|
|
qCursor:movePosition( QTextCursor_EndOfLine )
|
|
ENDIF
|
|
::qEdit:setTextCursor( qCursor )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:panHome()
|
|
LOCAL qCursor := ::getCursor()
|
|
::qEdit:hbGetViewportInfo()
|
|
IF ::aViewportInfo[ 2 ] == 0
|
|
qCursor:movePosition( QTextCursor_StartOfLine )
|
|
ELSE
|
|
qCursor:movePosition( QTextCursor_Left, QTextCursor_MoveAnchor, qCursor:columnNumber() - ::aViewportInfo[ 2 ] )
|
|
ENDIF
|
|
::qEdit:setTextCursor( qCursor )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:pageUp()
|
|
::qEdit:hbApplyKey( Qt_Key_PageUp )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:pageDown()
|
|
::qEdit:hbApplyKey( Qt_Key_PageDown )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
//
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:printPreview()
|
|
LOCAL qDlg := QPrintPreviewDialog( ::oDlg:oWidget )
|
|
|
|
qDlg:setWindowTitle( "hbIDE Preview Dialog" )
|
|
qDlg:connect( "paintRequested(QPrinter*)", {|p| ::paintRequested( p ) } )
|
|
* qDlg:setWindowState( Qt_WindowMaximized )
|
|
qDlg:exec()
|
|
qDlg:disconnect( "paintRequested(QPrinter*)" )
|
|
|
|
RETURN self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:paintRequested( qPrinter )
|
|
::qEdit:print( qPrinter )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:upperCaseKeywords()
|
|
LOCAL qDoc, cText, cRegEx, aMatches, aMatch, b_
|
|
|
|
qDoc := ::qEdit:document()
|
|
|
|
IF !( qDoc:isEmpty() )
|
|
qDoc:setUndoRedoEnabled( .f. )
|
|
|
|
cText := qDoc:toPlainText()
|
|
|
|
b_:= { 'function','procedure','thread','return','static','local','default', ;
|
|
'if','else','elseif','endif','end', ;
|
|
'docase','case','endcase','otherwise', ;
|
|
'switch','endswitch', ;
|
|
'do','while','exit','enddo','loop',;
|
|
'for','each','next','step','to','in',;
|
|
'with','replace','object','endwith','request',;
|
|
'nil','and','or','in','not','self',;
|
|
'class','endclass','method','data','var','destructor','inline','assign','access',;
|
|
'inherit','init','create','virtual','message', 'from', 'setget',;
|
|
'begin','sequence','try','catch','always','recover','hb_symbol_unused', ;
|
|
'error','handler','private','public' }
|
|
cRegEx := ""
|
|
aeval( b_, {|e| cRegEx += iif( empty( cRegEx ), "", "|" ) + "\b" + e + "\b" } )
|
|
|
|
aMatches := hb_regExAll( cRegEx, cText, .f., .f., 0, 1, .f. )
|
|
|
|
IF ! empty( aMatches )
|
|
FOR EACH aMatch IN aMatches
|
|
cText := stuff( cText, aMatch[ 2 ], aMatch[ 3 ] - aMatch[ 2 ] + 1, upper( aMatch[ 1 ] ) )
|
|
NEXT
|
|
ENDIF
|
|
|
|
qDoc:clear()
|
|
qDoc:setPlainText( cText )
|
|
|
|
qDoc:setUndoRedoEnabled( .t. )
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:formatBraces()
|
|
LOCAL qDoc, cText
|
|
|
|
qDoc := ::qEdit:document()
|
|
|
|
IF !( qDoc:isEmpty() )
|
|
qDoc:setUndoRedoEnabled( .f. )
|
|
|
|
cText := qDoc:toPlainText()
|
|
|
|
cText := strtran( cText, "( ", "(" )
|
|
cText := strtran( cText, "( ", "(" )
|
|
cText := strtran( cText, "( ", "(" )
|
|
cText := strtran( cText, "( ", "(" )
|
|
cText := strtran( cText, "( ", "(" )
|
|
cText := strtran( cText, "( ", "(" )
|
|
cText := strtran( cText, " (", "(" )
|
|
cText := strtran( cText, " (", "(" )
|
|
cText := strtran( cText, " (", "(" )
|
|
cText := strtran( cText, " (", "(" )
|
|
cText := strtran( cText, " (", "(" )
|
|
|
|
cText := strtran( cText, " )", ")" )
|
|
cText := strtran( cText, " )", ")" )
|
|
cText := strtran( cText, " )", ")" )
|
|
cText := strtran( cText, " )", ")" )
|
|
cText := strtran( cText, " )", ")" )
|
|
cText := strtran( cText, " )", ")" )
|
|
|
|
cText := strtran( cText, "(", "( " )
|
|
cText := strtran( cText, ")", " )" )
|
|
|
|
cText := strtran( cText, "( )", "()" )
|
|
cText := strtran( cText, "( )", "()" )
|
|
cText := strtran( cText, "( )", "()" )
|
|
cText := strtran( cText, "( )", "()" )
|
|
cText := strtran( cText, "( )", "()" )
|
|
|
|
qDoc:clear()
|
|
qDoc:setPlainText( cText )
|
|
|
|
qDoc:setUndoRedoEnabled( .t. )
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:removeTrailingSpaces()
|
|
LOCAL qDoc, cText, a_, s
|
|
|
|
qDoc := ::qEdit:document()
|
|
IF !( qDoc:isEmpty() )
|
|
qDoc:setUndoRedoEnabled( .f. )
|
|
cText := qDoc:toPlainText()
|
|
a_:= hbide_memoToArray( cText )
|
|
FOR EACH s IN a_
|
|
s := trim( s )
|
|
NEXT
|
|
cText := hbide_arrayToMemo( a_ )
|
|
qDoc:clear()
|
|
qDoc:setPlainText( cText )
|
|
qDoc:setUndoRedoEnabled( .t. )
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:tabs2spaces()
|
|
LOCAL qDoc, cText, cSpaces
|
|
|
|
qDoc := ::qEdit:document()
|
|
IF !( qDoc:isEmpty() )
|
|
cSpaces := space( ::nTabSpaces )
|
|
|
|
qDoc:setUndoRedoEnabled( .f. )
|
|
|
|
cText := qDoc:toPlainText()
|
|
qDoc:clear()
|
|
qDoc:setPlainText( strtran( cText, chr( 9 ), cSpaces ) )
|
|
|
|
qDoc:setUndoRedoEnabled( .t. )
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:spaces2tabs()
|
|
LOCAL qDoc, cText, cSpaces
|
|
|
|
qDoc := ::qEdit:document()
|
|
IF !( qDoc:isEmpty() )
|
|
cSpaces := space( ::nTabSpaces )
|
|
|
|
qDoc:setUndoRedoEnabled( .f. )
|
|
|
|
cText := qDoc:toPlainText()
|
|
qDoc:clear()
|
|
qDoc:setPlainText( strtran( cText, cSpaces, chr( 9 ) ) )
|
|
|
|
qDoc:setUndoRedoEnabled( .t. )
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:duplicateLine()
|
|
::qEdit:hbDuplicateLine()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:deleteLine()
|
|
::qEdit:hbDeleteLine()
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:moveLine( nDirection )
|
|
::qEdit:hbMoveLine( nDirection )
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:getText()
|
|
RETURN ::qEdit:textCursor():selectedText()
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:getWord( lSelect )
|
|
LOCAL cText, qCursor := ::qEdit:textCursor()
|
|
|
|
DEFAULT lSelect TO .F.
|
|
|
|
qCursor:select( QTextCursor_WordUnderCursor )
|
|
cText := qCursor:selectedText()
|
|
|
|
IF lSelect
|
|
::qEdit:setTextCursor( qCursor )
|
|
ENDIF
|
|
RETURN cText
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:goto( nLine )
|
|
LOCAL nRows, qGo
|
|
LOCAL qCursor := ::qEdit:textCursor()
|
|
|
|
IF empty( nLine )
|
|
nRows := ::qEdit:blockCount()
|
|
nLine := qCursor:blockNumber()
|
|
|
|
qGo := QInputDialog( ::oDlg:oWidget )
|
|
qGo:setInputMode( 1 )
|
|
qGo:setIntMinimum( 1 )
|
|
qGo:setIntMaximum( nRows )
|
|
qGo:setIntValue( nLine + 1 )
|
|
qGo:setLabelText( "Goto Line Number [1-" + hb_ntos( nRows ) + "]" )
|
|
qGo:setWindowTitle( "Harbour" )
|
|
|
|
::oIde:setPosByIniEx( qGo, ::oINI:cGotoDialogGeometry )
|
|
qGo:exec()
|
|
::oIde:oINI:cGotoDialogGeometry := hbide_posAndSize( qGo )
|
|
nLine := qGo:intValue()
|
|
::qEdit:setFocus()
|
|
ENDIF
|
|
|
|
qCursor:movePosition( QTextCursor_Start )
|
|
qCursor:movePosition( QTextCursor_Down, QTextCursor_MoveAnchor, nLine - 1 )
|
|
::qEdit:setTextCursor( qCursor )
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:getLine( nLine, lSelect )
|
|
LOCAL cText, qCursor := ::qEdit:textCursor()
|
|
|
|
DEFAULT nLine TO qCursor:blockNumber() + 1
|
|
DEFAULT lSelect TO .F.
|
|
|
|
IF nLine != qCursor:blockNumber() + 1
|
|
qCursor:movePosition( QTextCursor_Start )
|
|
qCursor:movePosition( QTextCursor_Down, QTextCursor_MoveAnchor, nLine - 1 )
|
|
ENDIF
|
|
|
|
qCursor:select( QTextCursor_LineUnderCursor )
|
|
cText := qCursor:selectedText()
|
|
IF lSelect
|
|
::qEdit:setTextCursor( qCursor )
|
|
ENDIF
|
|
|
|
RETURN cText
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:getColumnNo()
|
|
RETURN ::qEdit:textCursor():columnNumber() + 1
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:getLineNo()
|
|
RETURN ::qEdit:textCursor():blockNumber() + 1
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:insertSeparator( cSep )
|
|
LOCAL qCursor := ::qEdit:textCursor()
|
|
|
|
IF empty( cSep )
|
|
cSep := ::cSeparator
|
|
ENDIF
|
|
qCursor:beginEditBlock()
|
|
qCursor:movePosition( QTextCursor_StartOfBlock )
|
|
qCursor:insertBlock()
|
|
qCursor:movePosition( QTextCursor_PreviousBlock )
|
|
qCursor:insertText( cSep )
|
|
qCursor:movePosition( QTextCursor_NextBlock )
|
|
qCursor:movePosition( QTextCursor_StartOfBlock )
|
|
qCursor:endEditBlock()
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:insertText( cText )
|
|
LOCAL qCursor, nL, nB
|
|
|
|
IF HB_ISSTRING( cText ) .AND. !Empty( cText )
|
|
qCursor := ::qEdit:textCursor()
|
|
|
|
nL := Len( cText )
|
|
nB := qCursor:position() + nL
|
|
|
|
qCursor:beginEditBlock()
|
|
qCursor:removeSelectedText()
|
|
qCursor:insertText( cText )
|
|
qCursor:setPosition( nB )
|
|
qCursor:endEditBlock()
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* called via qDocument:contentsChange(*/
|
|
|
|
METHOD IdeEdit:reformatLine( nPos, nAdded, nDeleted )
|
|
LOCAL cProto, nRows, nCols
|
|
//LOCAL cWord, nColumn
|
|
//LOCAL qCursor := ::qEdit:textCursor()
|
|
//LOCAL cLine := ::getLine()
|
|
|
|
HB_SYMBOL_UNUSED( nPos )
|
|
HB_SYMBOL_UNUSED( nAdded )
|
|
HB_SYMBOL_UNUSED( nDeleted )
|
|
|
|
//nColumn := qCursor:columnNumber() + 1
|
|
//cWord := ::getWord()
|
|
|
|
//HB_TRACE( HB_TR_ALWAYS, nPos, nAdded, nDeleted, nColumn, len( cWord ), cWord )
|
|
|
|
::handlePreviousWord( ::lUpdatePrevWord )
|
|
::handleCurrentIndent()
|
|
|
|
IF ::nProtoLine != -1
|
|
IF ::getLineNo() == ::nProtoLine .AND. ::getColumnNo() >= ::nProtoCol + 1
|
|
IF !empty( cProto := hbide_formatProto_1( ::cProtoOrg, ::getLine(), ::nProtoCol, ::getColumnNo(), @nRows, @nCols ) )
|
|
::cProto := cProto
|
|
::nProtoRows := nRows
|
|
::nProtoCols := nCols
|
|
::showProtoType()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:handlePreviousWord( lUpdatePrevWord )
|
|
LOCAL qCursor, qTextBlock, cText, cWord, nB, nL, qEdit, lPrevOnly, nCol, nSpace, nSpaces, nOff
|
|
|
|
IF ! lUpdatePrevWord
|
|
RETURN Self
|
|
ENDIF
|
|
::lUpdatePrevWord := .f.
|
|
|
|
qEdit := ::qEdit
|
|
|
|
qCursor := qEdit:textCursor()
|
|
qTextBlock := qCursor:block()
|
|
cText := qTextBlock:text()
|
|
nCol := qCursor:columnNumber()
|
|
IF ( substr( cText, nCol - 1, 1 ) == " " )
|
|
RETURN nil
|
|
ENDIF
|
|
nSpace := iif( substr( cText, nCol, 1 ) == " ", 1, 0 )
|
|
cWord := hbide_getPreviousWord( cText, nCol + 1 )
|
|
|
|
IF !empty( cWord ) .AND. hbide_isHarbourKeyword( cWord, ::oIde )
|
|
lPrevOnly := left( lower( ltrim( cText ) ), Len( cWord ) ) == lower( cWord )
|
|
|
|
nL := Len( cWord ) + nSpace
|
|
nB := qCursor:position() - nL
|
|
|
|
IF lower( ::oEditor:cExt ) $ ".prg,.hb" .AND. ! ::oINI:lSupressHbKWordsToUpper
|
|
qCursor:beginEditBlock()
|
|
qCursor:setPosition( nB )
|
|
qCursor:movePosition( QTextCursor_NextCharacter, QTextCursor_KeepAnchor, nL )
|
|
qCursor:removeSelectedText()
|
|
qCursor:insertText( upper( cWord ) + space( nSpace ) )
|
|
qCursor:endEditBlock()
|
|
qEdit:setTextCursor( qCursor )
|
|
ENDIF
|
|
|
|
IF hbide_isStartingKeyword( cWord, ::oIde )
|
|
IF lPrevOnly
|
|
qCursor:setPosition( nB )
|
|
IF ( nCol := qCursor:columnNumber() ) > 0
|
|
qCursor:beginEditBlock()
|
|
qCursor:movePosition( QTextCursor_StartOfBlock )
|
|
qCursor:movePosition( QTextCursor_NextCharacter, QTextCursor_KeepAnchor, nCol )
|
|
qCursor:removeSelectedText()
|
|
qCursor:movePosition( QTextCursor_NextCharacter, QTextCursor_MoveAnchor, nL )
|
|
qCursor:endEditBlock()
|
|
qEdit:setTextCursor( qCursor )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSEIF hbide_isMinimumIndentableKeyword( cWord, ::oIde ) .AND. ::oINI:lAutoIndent
|
|
IF lPrevOnly
|
|
qCursor:setPosition( nB )
|
|
IF ( nCol := qCursor:columnNumber() ) >= 0
|
|
qCursor:beginEditBlock()
|
|
qCursor:movePosition( QTextCursor_StartOfBlock )
|
|
qCursor:movePosition( QTextCursor_NextCharacter, QTextCursor_KeepAnchor, nCol )
|
|
qCursor:removeSelectedText()
|
|
qCursor:insertText( space( ::nTabSpaces ) )
|
|
qCursor:movePosition( QTextCursor_NextCharacter, QTextCursor_MoveAnchor, nL )
|
|
qEdit:setTextCursor( qCursor )
|
|
qCursor:endEditBlock()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSEIF hbide_isIndentableKeyword( cWord, ::oIde ) .AND. ::oINI:lAutoIndent
|
|
IF lPrevOnly
|
|
nSpaces := hbide_getFrontSpacesAndWord( cText )
|
|
IF nSpaces > 0 .AND. ( nOff := nSpaces % ::nTabSpaces ) > 0
|
|
qCursor:setPosition( nB )
|
|
qCursor:beginEditBlock()
|
|
qCursor:movePosition( QTextCursor_PreviousCharacter, QTextCursor_KeepAnchor, nOff )
|
|
qCursor:removeSelectedText()
|
|
qCursor:movePosition( QTextCursor_NextCharacter, QTextCursor_MoveAnchor, nL )
|
|
qEdit:setTextCursor( qCursor )
|
|
qCursor:endEditBlock()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN .t.
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:findLastIndent()
|
|
LOCAL qCursor, qTextBlock, cText, cWord
|
|
LOCAL nSpaces := 0
|
|
|
|
qCursor := ::qEdit:textCursor()
|
|
qTextBlock := qCursor:block()
|
|
|
|
qTextBlock := qTextBlock:previous()
|
|
DO WHILE .t.
|
|
IF !( qTextBlock:isValid() )
|
|
EXIT
|
|
ENDIF
|
|
IF !empty( cText := qTextBlock:text() )
|
|
nSpaces := hbide_getFrontSpacesAndWord( cText, @cWord )
|
|
IF !empty( cWord )
|
|
IF ::oINI:lSmartIndent .AND. hbide_isIndentableKeyword( cWord, ::oIde )
|
|
nSpaces += ::nTabSpaces
|
|
ENDIF
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
qTextBlock := qTextBlock:previous()
|
|
ENDDO
|
|
|
|
RETURN nSpaces
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:handleCurrentIndent()
|
|
LOCAL qCursor, nSpaces
|
|
|
|
IF ::lIndentIt
|
|
::lIndentIt := .f.
|
|
IF ( nSpaces := ::findLastIndent() ) > 0
|
|
qCursor := ::qEdit:textCursor()
|
|
qCursor:insertText( space( nSpaces ) )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:gotoFunction()
|
|
LOCAL cWord, n
|
|
LOCAL lFindCur := .f.
|
|
IF !empty( cWord := ::getWord( .f. ) )
|
|
IF ( n := ascan( ::aTags, {|e_| lower( cWord ) $ lower( e_[ 7 ] ) } ) ) > 0
|
|
IF ::find( alltrim( ::aTags[ n,8 ] ) )
|
|
lFindCur := .t.
|
|
ENDIF
|
|
ENDIF
|
|
IF ! lFindCur
|
|
::oFN:jumpToFunction( cWord, .t. )
|
|
ENDIF
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:clickFuncHelp()
|
|
LOCAL cWord
|
|
IF !empty( cWord := ::getWord( .f. ) )
|
|
IF ! empty( ::oHL )
|
|
::oHL:jumpToFunction( cWord )
|
|
ENDIF
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:loadFuncHelp()
|
|
LOCAL qEdit, qCursor, qTextBlock, cText, cWord, nCol, cPro
|
|
|
|
qEdit := ::qEdit
|
|
qCursor := qEdit:textCursor()
|
|
qTextBlock := qCursor:block()
|
|
cText := qTextBlock:text()
|
|
nCol := qCursor:columnNumber()
|
|
cWord := hbide_getPreviousWord( cText, nCol )
|
|
|
|
IF !empty( cWord )
|
|
IF empty( cPro := ::oEM:getProto( cWord ) )
|
|
IF ! empty( ::oHL )
|
|
::oHL:jumpToFunction( cWord )
|
|
ENDIF
|
|
IF !empty( cPro := ::oFN:positionToFunction( cWord, .t. ) )
|
|
IF empty( ::cProto )
|
|
::showPrototype( cPro )
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
::showPrototype( cPro )
|
|
ENDIF
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:resumePrototype()
|
|
|
|
::isSuspended := .f.
|
|
IF !empty( ::qEdit )
|
|
IF ::getLineNo() == ::nProtoLine .AND. ::getColumnNo() >= ::nProtoCol
|
|
::qEdit:hbShowPrototype( ::cProto, ::nProtoRows, ::nProtoCols )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:suspendPrototype()
|
|
|
|
::isSuspended := .t.
|
|
IF !empty( ::qEdit )
|
|
::qEdit:hbShowPrototype( "", 0, 0 )
|
|
ENDIF
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:showPrototype( cProto )
|
|
|
|
IF ! ::isSuspended .AND. !empty( ::qEdit )
|
|
IF !empty( cProto )
|
|
::cProtoOrg := cProto
|
|
::cProto := hbide_formatProto( cProto )
|
|
::nProtoLine := ::getLineNo()
|
|
::nProtoCol := ::getColumnNo()
|
|
ENDIF
|
|
::qEdit:hbShowPrototype( ::cProto, ::nProtoRows, ::nProtoCols )
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:hidePrototype()
|
|
|
|
IF !empty( ::qedit )
|
|
::nProtoLine := -1
|
|
::nProtoCol := -1
|
|
::cProto := ""
|
|
::nProtoCols := 10
|
|
::nProtoRows := 1
|
|
::qEdit:hbShowPrototype( "", 0, 0 )
|
|
ENDIF
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:parseCodeCompletion( cSyntax )
|
|
LOCAL cText, n, nFun, nAbr, nSpc
|
|
|
|
nAbr := at( "-", cSyntax )
|
|
nSpc := at( " ", cSyntax )
|
|
nFun := at( "(", cSyntax )
|
|
|
|
IF "[f]" $ cSyntax
|
|
cText := alltrim( substr( cSyntax, 1, nSpc ) )
|
|
|
|
ELSEIF nAbr > 0 .AND. iif( nSpc == 0, .t., nAbr < nSpc ).AND. iif( nFun == 0, .t., nAbr < nFun )
|
|
cText := alltrim( substr( cSyntax, nAbr + 1 ) )
|
|
|
|
ELSE
|
|
IF ::oINI:lCompleteArgumented
|
|
IF ( n := rat( ")", cSyntax ) ) > 0
|
|
cText := trim( substr( cSyntax, 1, n ) )
|
|
ELSE
|
|
cText := trim( cSyntax )
|
|
ENDIF
|
|
ELSE
|
|
IF nFun > 0 .AND. iif( nSpc == 0, .t., nFun < nSpc )
|
|
cText := trim( substr( cSyntax, 1, nFun - 1 ) )
|
|
ELSE
|
|
cText := trim( cSyntax )
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN cText
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
METHOD IdeEdit:completeCode( p )
|
|
LOCAL qCursor := ::qEdit:textCursor()
|
|
LOCAL cWord
|
|
|
|
qCursor:movePosition( QTextCursor_Left )
|
|
|
|
qCursor:movePosition( QTextCursor_StartOfWord )
|
|
qCursor:movePosition( QTextCursor_EndOfWord, QTextCursor_KeepAnchor )
|
|
|
|
cWord := qCursor:selectedText()
|
|
IF cWord == "->"
|
|
qCursor:clearSelection()
|
|
ENDIF
|
|
|
|
qCursor:insertText( ::parseCodeCompletion( p ) )
|
|
qCursor:movePosition( QTextCursor_Left )
|
|
qCursor:movePosition( QTextCursor_Right )
|
|
|
|
::qEdit:setTextCursor( qCursor )
|
|
|
|
::qEdit:hbSetFieldsListActive( ::oEM:updateFieldsList() )
|
|
|
|
RETURN Self
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_getPreviousWord( cText, nPos )
|
|
LOCAL cWord, n
|
|
|
|
cText := alltrim( substr( cText, 1, nPos ) )
|
|
IF ( n := rat( " ", cText ) ) > 0
|
|
cWord := substr( cText, n + 1 )
|
|
ELSE
|
|
cWord := cText
|
|
ENDIF
|
|
|
|
RETURN cWord
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_getFirstWord( cText )
|
|
LOCAL cWord, n
|
|
|
|
cText := alltrim( cText )
|
|
IF ( n := at( " ", cText ) ) > 0
|
|
cWord := left( cText, n-1 )
|
|
ELSE
|
|
cWord := cText
|
|
ENDIF
|
|
|
|
RETURN cWord
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_getFrontSpacesAndWord( cText, cWord )
|
|
LOCAL n := 0
|
|
|
|
DO WHILE .t.
|
|
IF !( substr( cText, ++n, 1 ) == " " )
|
|
EXIT
|
|
ENDIF
|
|
ENDDO
|
|
n--
|
|
|
|
cWord := hbide_getFirstWord( cText )
|
|
|
|
RETURN n
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_isStartingKeyword( cWord, oIde )
|
|
LOCAL s_b_
|
|
|
|
IF empty( s_b_ )
|
|
IF ! oIde:oINI:lReturnAsBeginKeyword
|
|
s_b_ := { ;
|
|
'function' => NIL,;
|
|
'class' => NIL,;
|
|
'method' => NIL }
|
|
ELSE
|
|
s_b_ := { ;
|
|
'function' => NIL,;
|
|
'class' => NIL,;
|
|
'return' => NIL,;
|
|
'method' => NIL }
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN Lower( cWord ) $ s_b_
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_isMinimumIndentableKeyword( cWord, oIde )
|
|
LOCAL s_b_
|
|
|
|
IF empty( s_b_ )
|
|
IF ! oIde:oINI:lReturnAsBeginKeyword
|
|
s_b_ := { ;
|
|
'local' => NIL,;
|
|
'static' => NIL,;
|
|
'return' => NIL,;
|
|
'default' => NIL }
|
|
ELSE
|
|
s_b_ := { ;
|
|
'local' => NIL,;
|
|
'static' => NIL,;
|
|
'default' => NIL }
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN Lower( cWord ) $ s_b_
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_isIndentableKeyword( cWord, oIde )
|
|
STATIC s_b_ := { ;
|
|
'if' => NIL,;
|
|
'else' => NIL,;
|
|
'elseif' => NIL,;
|
|
'docase' => NIL,;
|
|
'case' => NIL,;
|
|
'otherwise' => NIL,;
|
|
'do' => NIL,;
|
|
'while' => NIL,;
|
|
'switch' => NIL,;
|
|
'for' => NIL,;
|
|
'next' => NIL,;
|
|
'begin' => NIL,;
|
|
'sequence' => NIL,;
|
|
'try' => NIL,;
|
|
'catch' => NIL,;
|
|
'always' => NIL,;
|
|
'recover' => NIL,;
|
|
'finally' => NIL }
|
|
|
|
HB_SYMBOL_UNUSED( oIde )
|
|
|
|
RETURN Lower( cWord ) $ s_b_
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_harbourKeywords()
|
|
STATIC s_b_ := { ;
|
|
'function' => NIL,;
|
|
'procedure' => NIL,;
|
|
'thread' => NIL,;
|
|
'return' => NIL,;
|
|
'request' => NIL,;
|
|
'static' => NIL,;
|
|
'local' => NIL,;
|
|
'default' => NIL,;
|
|
'if' => NIL,;
|
|
'else' => NIL,;
|
|
'elseif' => NIL,;
|
|
'endif' => NIL,;
|
|
'end' => NIL,;
|
|
'endswitch' => NIL,;
|
|
'docase' => NIL,;
|
|
'case' => NIL,;
|
|
'endcase' => NIL,;
|
|
'otherwise' => NIL,;
|
|
'switch' => NIL,;
|
|
'do' => NIL,;
|
|
'while' => NIL,;
|
|
'enddo' => NIL,;
|
|
'exit' => NIL,;
|
|
'for' => NIL,;
|
|
'each' => NIL,;
|
|
'next' => NIL,;
|
|
'step' => NIL,;
|
|
'to' => NIL,;
|
|
'class' => NIL,;
|
|
'endclass' => NIL,;
|
|
'method' => NIL,;
|
|
'data' => NIL,;
|
|
'var' => NIL,;
|
|
'destructor' => NIL,;
|
|
'inline' => NIL,;
|
|
'setget' => NIL,;
|
|
'assign' => NIL,;
|
|
'access' => NIL,;
|
|
'inherit' => NIL,;
|
|
'init' => NIL,;
|
|
'create' => NIL,;
|
|
'virtual' => NIL,;
|
|
'message' => NIL,;
|
|
'begin' => NIL,;
|
|
'sequence' => NIL,;
|
|
'try' => NIL,;
|
|
'catch' => NIL,;
|
|
'always' => NIL,;
|
|
'recover' => NIL,;
|
|
'with' => NIL,;
|
|
'replace' => NIL,;
|
|
'hb_symbol_unused' => NIL,;
|
|
'error' => NIL,;
|
|
'handler' => NIL,;
|
|
'loop' => NIL,;
|
|
'in' => NIL,;
|
|
'nil' => NIL,;
|
|
'or' => NIL,;
|
|
'not' => NIL,;
|
|
'and' => NIL }
|
|
|
|
RETURN s_b_
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_isHarbourKeyword( cWord, oIde )
|
|
|
|
HB_SYMBOL_UNUSED( oIde )
|
|
|
|
RETURN Lower( cWord ) $ hbide_harbourKeywords()
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_formatProto_1( cProto, cText, nProtoCol, nCurCol, nRows, nCols )
|
|
LOCAL s, nArgs, cArgs, aArgs, cArg, n, n1, i, nnn, cPro, cFunc
|
|
|
|
IF nCurCol > nProtoCol
|
|
n := at( "(", cProto ) ; n1 := at( ")", cProto )
|
|
IF n > 0 .AND. n1 > 0 .AND. "," $ cProto
|
|
cProto := substr( cProto, 1, n1 )
|
|
|
|
s := substr( cText, nProtoCol, nCurCol - nProtoCol )
|
|
nArgs := 1
|
|
FOR i := 1 TO Len( s )
|
|
IF substr( s, i, 1 ) == ","
|
|
nArgs++
|
|
ENDIF
|
|
NEXT
|
|
|
|
nRows := 1; nCols := 0
|
|
|
|
IF nArgs > 0
|
|
n := at( "(", cProto ) ; n1 := at( ")", cProto )
|
|
|
|
cFunc := substr( cProto, 1, n - 1 )
|
|
cArgs := substr( cProto, n + 1, n1 - n - 1 )
|
|
aArgs := hb_aTokens( cArgs, "," )
|
|
cArgs := ""
|
|
nCols := Len( cFunc ) + 1
|
|
FOR EACH cArg IN aArgs
|
|
cArg := alltrim( cArg )
|
|
|
|
nRows++
|
|
nCols := max( nCols, Len( cArg ) + 3 )
|
|
|
|
cArg := StrTran( cArg, "<", "<" )
|
|
cArg := StrTran( cArg, ">", ">" )
|
|
|
|
nnn := cArg:__enumIndex()
|
|
IF nnn == nArgs
|
|
cArg := "<font color=red><b>" + cArg + "</b></font>"
|
|
ENDIF
|
|
IF nnn == Len( aArgs )
|
|
cArgs += "<br>" + " " + cArg
|
|
ELSE
|
|
cArgs += "<br>" + " " + cArg + "<font color=red><b>" + "," + "</b></font>"
|
|
ENDIF
|
|
NEXT
|
|
nCols += iif( nCols <= Len( cFunc ), 0, 1 )
|
|
|
|
//cPro := "<p style='white-space:pre'>" + "<font color=darkgreen><b>" + cFunc + "</b></font>" + ;
|
|
cPro := "<p style='white-space:pre'>" + "<b>" + cFunc + "</b>" + ;
|
|
"<font color=red><b>" + "(" + "</b></font>" + ;
|
|
cArgs + ;
|
|
"<font color=red><b>" + ")" + "</font>" + "</b></p>"
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN cPro
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
FUNCTION hbide_formatProto( cProto )
|
|
LOCAL n, n1, cArgs
|
|
|
|
cProto := StrTran( cProto, "<", "<" )
|
|
cProto := StrTran( cProto, ">", ">" )
|
|
|
|
n := at( "(", cProto )
|
|
n1 := at( ")", cProto )
|
|
|
|
IF n > 0 .AND. n1 > 0
|
|
cArgs := substr( cProto, n + 1, n1 - n - 1 )
|
|
cArgs := strtran( cArgs, ",", "<font color=red><b>" + "," + "</b></font>" )
|
|
cProto := "<p style='white-space:pre'>" + "<b>" + substr( cProto, 1, n - 1 ) + "</b>" + ;
|
|
"<font color=red><b>" + "(" + "</b></font>" + ;
|
|
cArgs + ;
|
|
"<font color=red><b>" + ")" + "</font>" + "</b></p>"
|
|
ENDIF
|
|
RETURN cProto
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
STATIC FUNCTION hbide_normalizeRect( aCord, nT, nL, nB, nR )
|
|
nT := iif( aCord[ 1 ] > aCord[ 3 ], aCord[ 3 ], aCord[ 1 ] )
|
|
nB := iif( aCord[ 1 ] > aCord[ 3 ], aCord[ 1 ], aCord[ 3 ] )
|
|
nL := iif( aCord[ 2 ] > aCord[ 4 ], aCord[ 4 ], aCord[ 2 ] )
|
|
nR := iif( aCord[ 2 ] > aCord[ 4 ], aCord[ 2 ], aCord[ 4 ] )
|
|
RETURN NIL
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|