From 35f52f50b0d110fa34515cccea06e3345f3a78e3 Mon Sep 17 00:00:00 2001 From: Pritpal Bedi Date: Sun, 30 May 2010 02:06:42 +0000 Subject: [PATCH] 2010-05-29 18:50 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbqt/generator/hbqtgen.prg ! A minor fix, no effect on sources. * contrib/hbqt/doc/en/class_hbqplaintextedit.txt * contrib/hbqt/hbqt_hbqplaintextedit.cpp * contrib/hbqt/hbqt_hbqplaintextedit.h * contrib/hbqt/qtgui/HBQPlainTextEdit.cpp * contrib/hbqt/qtgui/THBQPlainTextEdit.prg * contrib/hbqt/qth/HBQPlainTextEdit.qth + Added more PRG callable methods. * contrib/hbide/hbide.prg * contrib/hbide/ideactions.prg * contrib/hbide/idedocks.prg * contrib/hbide/idedocwriter.prg * contrib/hbide/ideedit.prg * contrib/hbide/ideeditor.prg * contrib/hbide/idefunctions.prg * contrib/hbide/ideharbourhelp.prg * contrib/hbide/idemisc.prg * contrib/hbide/ideobject.prg * contrib/hbide/ideprojmanager.prg * contrib/hbide/ideshortcuts.prg + Implemented: selection "persistancy" controllable programatically" Ctrl+F11 is designated for this task. A slot in "Keyboard Mappings" is also provided. By default persistant selection is disabled and hence behaves exectly like it was before persistancy and more natural like other editors. Ctrl+F11 toggles it on/off and if switched on, behaviour will follow the implemenation just before this commit. If selection mode is activated programatically, behavior remains the same as before. Please test, bumps are expected. % Some major artifacts how cursor should behave after paste, etc. + Implemented: document writer is now capable to pulls the existing help body and correctly reinstates the changes. This implies that for your sources help it can be used in real-time. Please test and post if you find difficulties. TODO: the same behavior with disk files. --- harbour/ChangeLog | 43 ++ harbour/contrib/hbide/hbide.prg | 1 + harbour/contrib/hbide/ideactions.prg | 5 +- harbour/contrib/hbide/idedocks.prg | 20 + harbour/contrib/hbide/idedocwriter.prg | 163 ++++++- harbour/contrib/hbide/ideedit.prg | 24 +- harbour/contrib/hbide/ideeditor.prg | 140 ++++++ harbour/contrib/hbide/idefunctions.prg | 2 +- harbour/contrib/hbide/ideharbourhelp.prg | 138 ++++++ harbour/contrib/hbide/idemisc.prg | 9 + harbour/contrib/hbide/ideobject.prg | 1 + harbour/contrib/hbide/ideprojmanager.prg | 2 +- harbour/contrib/hbide/ideshortcuts.prg | 8 + .../hbqt/doc/en/class_hbqplaintextedit.txt | 1 + harbour/contrib/hbqt/generator/hbqtgen.prg | 15 +- .../contrib/hbqt/hbqt_hbqplaintextedit.cpp | 400 ++++++++++-------- harbour/contrib/hbqt/hbqt_hbqplaintextedit.h | 4 +- .../contrib/hbqt/qtgui/HBQPlainTextEdit.cpp | 14 + .../contrib/hbqt/qtgui/THBQPlainTextEdit.prg | 5 + harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth | 1 + 20 files changed, 781 insertions(+), 215 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 71c649f462..001869ce92 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,49 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-05-29 18:50 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + * contrib/hbqt/generator/hbqtgen.prg + ! A minor fix, no effect on sources. + + * contrib/hbqt/doc/en/class_hbqplaintextedit.txt + * contrib/hbqt/hbqt_hbqplaintextedit.cpp + * contrib/hbqt/hbqt_hbqplaintextedit.h + * contrib/hbqt/qtgui/HBQPlainTextEdit.cpp + * contrib/hbqt/qtgui/THBQPlainTextEdit.prg + * contrib/hbqt/qth/HBQPlainTextEdit.qth + + Added more PRG callable methods. + + * contrib/hbide/hbide.prg + * contrib/hbide/ideactions.prg + * contrib/hbide/idedocks.prg + * contrib/hbide/idedocwriter.prg + * contrib/hbide/ideedit.prg + * contrib/hbide/ideeditor.prg + * contrib/hbide/idefunctions.prg + * contrib/hbide/ideharbourhelp.prg + * contrib/hbide/idemisc.prg + * contrib/hbide/ideobject.prg + * contrib/hbide/ideprojmanager.prg + * contrib/hbide/ideshortcuts.prg + + + Implemented: selection "persistancy" controllable programatically" + Ctrl+F11 is designated for this task. A slot in "Keyboard Mappings" + is also provided. By default persistant selection is disabled and + hence behaves exectly like it was before persistancy and more natural + like other editors. Ctrl+F11 toggles it on/off and if switched on, + behaviour will follow the implemenation just before this commit. + If selection mode is activated programatically, behavior remains + the same as before. Please test, bumps are expected. + + % Some major artifacts how cursor should behave after paste, etc. + + + Implemented: document writer is now capable to pulls the existing + help body and correctly reinstates the changes. This implies that + for your sources help it can be used in real-time. Please test + and post if you find difficulties. + + TODO: the same behavior with disk files. + 2010-05-29 23:42 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * INSTALL + HB_QT_STATIC not Windows specific anymore. diff --git a/harbour/contrib/hbide/hbide.prg b/harbour/contrib/hbide/hbide.prg index 7d215fe6c5..4cbf7214bb 100644 --- a/harbour/contrib/hbide/hbide.prg +++ b/harbour/contrib/hbide/hbide.prg @@ -221,6 +221,7 @@ CLASS HbIde DATA oSkeltnDock DATA oFindDock DATA oSourceThumbnailDock + DATA oQScintillaDock DATA lProjTreeVisible INIT .t. DATA lDockRVisible INIT .f. diff --git a/harbour/contrib/hbide/ideactions.prg b/harbour/contrib/hbide/ideactions.prg index 27e851dde3..4889adfdb0 100644 --- a/harbour/contrib/hbide/ideactions.prg +++ b/harbour/contrib/hbide/ideactions.prg @@ -544,7 +544,10 @@ METHOD IdeActions:buildMainMenu() oSubMenu:oWidget:addAction_4( ::oSkeltnDock:oWidget:toggleViewAction() ) oSubMenu:oWidget:addAction_4( ::oThemesDock:oWidget:toggleViewAction() ) oSubMenu:oWidget:addAction_4( ::oFindDock:oWidget:toggleViewAction() ) - oSubMenu:oWidget:addAction_4( ::oSourceThumbnailDock:oWidget:toggleViewAction() ) + oSubMenu:oWidget:addAction_4( ::oSourceThumbnailDock:oWidget:toggleViewAction() ) + #ifdef QT_WITH_SCINTILLA + oSubMenu:oWidget:addAction_4( ::oQScintillaDock:oWidget:toggleViewAction() ) + #endif oSubMenu:oWidget:addSeparator() oSubMenu:oWidget:addAction_4( ::oDockB2:oWidget:toggleViewAction() ) * oSubMenu:oWidget:addAction_4( ::oDockB1:oWidget:toggleViewAction() ) diff --git a/harbour/contrib/hbide/idedocks.prg b/harbour/contrib/hbide/idedocks.prg index 5066ff3ebd..369e2d1520 100644 --- a/harbour/contrib/hbide/idedocks.prg +++ b/harbour/contrib/hbide/idedocks.prg @@ -84,6 +84,7 @@ #define dockHelpDock_visibilityChanged 310 #define oFuncDock_visibilityChanged 311 #define dockSourceThumbnail_visibilityChanged 312 +#define dockQScintilla_visibilityChanged 313 /*----------------------------------------------------------------------*/ @@ -135,6 +136,7 @@ CLASS IdeDocks INHERIT IdeObject METHOD getPanelIcon( cView ) METHOD animateComponents( nMode ) METHOD buildSourceThumbnail() + METHOD buildQScintilla() ENDCLASS @@ -173,6 +175,7 @@ METHOD IdeDocks:destroy() ::disconnect( ::oFuncDock:oWidget , "visibilityChanged(bool)" ) ::disconnect( ::oSourceThumbnailDock:oWidget, "visibilityChanged(bool)" ) + ::disconnect( ::oQScintillaDock:oWidget, "visibilityChanged(bool)" ) #if 0 /* Not Implemented */ ::disconnect( ::oDockPT:oWidget , "visibilityChanged(bool)" ) @@ -280,6 +283,7 @@ METHOD IdeDocks:buildDockWidgets() ::buildDocWriter() ::buildFunctionsDock() ::buildSourceThumbnail() + ::buildQScintilla() /* Bottom Docks */ ::oDlg:oWidget:tabifyDockWidget( ::oDockB:oWidget , ::oDockB1:oWidget ) @@ -296,6 +300,7 @@ METHOD IdeDocks:buildDockWidgets() ::oDlg:oWidget:tabifyDockWidget( ::oThemesDock:oWidget , ::oFindDock:oWidget ) ::oDlg:oWidget:tabifyDockWidget( ::oFindDock:oWidget , ::oDocWriteDock:oWidget ) ::oDlg:oWidget:tabifyDockWidget( ::oDocWriteDock:oWidget , ::oSourceThumbnailDock:oWidget ) + ::oDlg:oWidget:tabifyDockWidget( ::oSourceThumbnailDock:oWidget, ::oQScintillaDock:oWidget ) ::buildToolBarPanels() @@ -333,6 +338,9 @@ METHOD IdeDocks:execEvent( nMode, p ) CASE nMode == 2 /* HelpWidget:contextMenuRequested(qPoint) */ hbide_popupBrwContextMenu( ::qHelpBrw, p ) + CASE nMode == dockQScintilla_visibilityChanged + IF p; ::oEM:qscintilla(); ENDIF + CASE nMode == dockSourceThumbnail_visibilityChanged IF p; ::oEM:showThumbnail(); ENDIF @@ -1014,6 +1022,18 @@ METHOD IdeDocks:buildSourceThumbnail() /*----------------------------------------------------------------------*/ +METHOD IdeDocks:buildQScintilla() + LOCAL nAreas := Qt_LeftDockWidgetArea + Qt_RightDockWidgetArea + Qt_TopDockWidgetArea + Qt_BottomDockWidgetArea + + ::oIde:oQScintillaDock := ::getADockWidget( nAreas, "dockQScintilla", "QScintilla Widget", QDockWidget_DockWidgetFloatable ) + ::oDlg:oWidget:addDockWidget_1( Qt_RightDockWidgetArea, ::oQScintillaDock:oWidget, Qt_Horizontal ) + + ::connect( ::oQScintillaDock:oWidget, "visibilityChanged(bool)", {|p| ::execEvent( dockQScintilla_visibilityChanged, p ) } ) + + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD IdeDocks:setStatusText( nPart, xValue ) LOCAL oPanel := ::oSBar:getItem( nPart ) diff --git a/harbour/contrib/hbide/idedocwriter.prg b/harbour/contrib/hbide/idedocwriter.prg index c02e94ed4f..f5ab4d8cc4 100644 --- a/harbour/contrib/hbide/idedocwriter.prg +++ b/harbour/contrib/hbide/idedocwriter.prg @@ -121,7 +121,7 @@ FUNCTION hbide_populateParam( txt_, cToken, cParam ) IF !empty( cParam ) aadd( txt_, cToken ) a_:= hbide_memoToArray( cParam ) - aeval( a_, {|e| aadd( txt_, " * " + e ) } ) + aeval( a_, {|e| aadd( txt_, " * " + strtran( strtran( e, chr( 13 ), "" ), chr( 10 ), "" ) ) } ) ENDIF RETURN nil @@ -171,9 +171,12 @@ CLASS IdeDocWriter INHERIT IdeObject METHOD parsePrototype( cProto ) METHOD clear() METHOD fillForm( aFacts ) + METHOD fillFormByObject( oFunc ) METHOD buildDocument() METHOD saveInFunction() METHOD saveInFile() + METHOD pullDocFromSource( nLineFrom, oEdit ) + METHOD removeDocHelp( nLineFrom, oEdit ) ENDCLASS @@ -250,21 +253,21 @@ METHOD IdeDocWriter:setImages() METHOD IdeDocWriter:installSignals() - ::oUI:signal( "buttonArgs" , "toggled(bool)", {|p| ::execEvent( buttonArgs_clicked , p ) } ) - ::oUI:signal( "buttonDesc" , "toggled(bool)", {|p| ::execEvent( buttonDesc_clicked , p ) } ) - ::oUI:signal( "buttonExamples" , "toggled(bool)", {|p| ::execEvent( buttonExample_clicked , p ) } ) - ::oUI:signal( "buttonTests" , "toggled(bool)", {|p| ::execEvent( buttonTests_clicked , p ) } ) + ::oUI:signal( "buttonArgs" , "toggled(bool)", {|p| ::execEvent( buttonArgs_clicked , p ) } ) + ::oUI:signal( "buttonDesc" , "toggled(bool)", {|p| ::execEvent( buttonDesc_clicked , p ) } ) + ::oUI:signal( "buttonExamples" , "toggled(bool)", {|p| ::execEvent( buttonExample_clicked , p ) } ) + ::oUI:signal( "buttonTests" , "toggled(bool)", {|p| ::execEvent( buttonTests_clicked , p ) } ) - ::oUI:signal( "buttonCloseArgs" , "clicked()", {| | ::execEvent( buttonCloseArgs_clicked ) } ) - ::oUI:signal( "buttonCloseDesc" , "clicked()", {| | ::execEvent( buttonCloseDesc_clicked ) } ) - ::oUI:signal( "buttonCloseExamples", "clicked()", {| | ::execEvent( buttonCloseExample_clicked ) } ) - ::oUI:signal( "buttonCloseTests" , "clicked()", {| | ::execEvent( buttonCloseTests_clicked ) } ) + ::oUI:signal( "buttonCloseArgs" , "clicked()" , {| | ::execEvent( buttonCloseArgs_clicked ) } ) + ::oUI:signal( "buttonCloseDesc" , "clicked()" , {| | ::execEvent( buttonCloseDesc_clicked ) } ) + ::oUI:signal( "buttonCloseExamples" , "clicked()" , {| | ::execEvent( buttonCloseExample_clicked ) } ) + ::oUI:signal( "buttonCloseTests" , "clicked()" , {| | ::execEvent( buttonCloseTests_clicked ) } ) - ::oUI:signal( "buttonClear" , "clicked()", {| | ::execEvent( buttonClear_clicked ) } ) - ::oUI:signal( "buttonSaveInFunc" , "clicked()", {| | ::execEvent( buttonSaveInFunc_clicked ) } ) - ::oUI:signal( "buttonSave" , "clicked()", {| | ::execEvent( buttonSave_clicked ) } ) + ::oUI:signal( "buttonClear" , "clicked()" , {| | ::execEvent( buttonClear_clicked ) } ) + ::oUI:signal( "buttonSaveInFunc" , "clicked()" , {| | ::execEvent( buttonSaveInFunc_clicked ) } ) + ::oUI:signal( "buttonSave" , "clicked()" , {| | ::execEvent( buttonSave_clicked ) } ) - ::oUI:signal( "buttonLoadFromCurFunc", "clicked()", {|| ::execEvent( buttonLoadFromCurFunc_clicked ) } ) + ::oUI:signal( "buttonLoadFromCurFunc", "clicked()" , {|| ::execEvent( buttonLoadFromCurFunc_clicked ) } ) RETURN Self @@ -404,8 +407,111 @@ METHOD IdeDocWriter:fillForm( aFacts ) /*----------------------------------------------------------------------*/ +METHOD IdeDocWriter:fillFormByObject( oFunc ) + + ::oUI:q_editVersion :setText ( oFunc:cVersion ) + ::oUI:q_editStatus :setText ( oFunc:cStatus ) + ::oUI:q_editCompliance :setText ( oFunc:cPlatForms ) + ::oUI:q_editCategory :setText ( oFunc:cCategory ) + ::oUI:q_editSubCategory :setText ( oFunc:cSubCategory ) + ::oUI:q_editName :setText ( oFunc:cName ) + ::oUI:q_editExtLink :setText ( oFunc:cExternalLink ) + ::oUI:q_editOneLiner :setText ( oFunc:cOneLiner ) + ::oUI:q_editSyntax :setText ( hbide_ar2delString( oFunc:aSyntax , "; " ) ) + ::oUI:q_editReturns :setText ( hbide_ar2delString( oFunc:aReturns, "; " ) ) + ::oUI:q_editSeeAlso :setText ( oFunc:cSeaAlso ) + ::oUI:q_editFiles :setText ( hbide_ar2delString( oFunc:aFiles , "; " ) ) + ::oUI:q_plainArgs :setPlainText ( hbide_arrayTOmemo( oFunc:aArguments ) ) + ::oUI:q_plainDesc :setPlainText ( hbide_arrayTOmemo( oFunc:aDescription ) ) + ::oUI:q_plainExamples :setPlainText ( hbide_arrayTOmemo( oFunc:aExamples ) ) + ::oUI:q_plainTests :setPlainText ( hbide_arrayTOmemo( oFunc:aTests ) ) + + ::oUI:q_comboTemplate:setCurrentIndex( iif( oFunc:cTemplate == "Procedure", 1, ; + iif( oFunc:cTemplate == "Class", 2, 0 ) ) ) + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD IdeDocWriter:removeDocHelp( nLineFrom, oEdit ) + LOCAL i, cLine, n, lExists, lDone, nFrom, nTo + + n := 0 + lExists := .f. + lDone := .f. + + FOR i := ( nLineFrom - 1 ) TO 1 STEP -1 + cLine := oEdit:getLine( i ) + + IF "$END$" $ cLine + nTo := i + 1 + lExists := .t. + ENDIF + IF "$DOC$" $ cLine + lDone := .t. + nFrom := i + ENDIF + IF ++n > 4 .AND. ! lExists + EXIT + ENDIF + IF lDone + EXIT + ENDIF + NEXT + + IF !empty( nFrom ) .AND. !empty( nTo ) + oEdit:goto( nFrom ) + FOR i := 1 TO ( nTo - nFrom + 1 ) + oEdit:deleteLine() + NEXT + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD IdeDocWriter:pullDocFromSource( nLineFrom, oEdit ) + LOCAL aDoc, i, cLine, n, lExists, lDone, a_ + + aDoc := {} + n := 0 + lExists := .f. + lDone := .f. + + FOR i := ( nLineFrom - 1 ) TO 1 STEP -1 + cLine := oEdit:getLine( i ) + + IF "$END$" $ cLine + lExists := .t. + ENDIF + IF "$DOC$" $ cLine + lDone := .t. + ENDIF + + IF lExists + aadd( aDoc, cLine ) + ENDIF + + IF ++n > 4 .AND. ! lExists /* Search must terminate after 4 lines if document is not in sight */ + EXIT + ENDIF + IF lDone + EXIT + ENDIF + NEXT + + a_:={} + IF lDone + FOR i := len( aDoc ) TO 1 STEP -1 + aadd( a_, aDoc[ i ] ) + NEXT + ENDIF + + RETURN a_ + +/*----------------------------------------------------------------------*/ + METHOD IdeDocWriter:loadCurrentFuncDoc() - LOCAL oEdit, nCurLine, n, cProto, nProtoLine, aFacts + LOCAL oEdit, nCurLine, n, cProto, nProtoLine, aFacts, aDoc, oFunc //LOCAL qCursor, qEdit IF !empty( oEdit := ::oEM:getEditObjectCurrent() ) @@ -434,7 +540,15 @@ METHOD IdeDocWriter:loadCurrentFuncDoc() ::nFuncLine := nProtoLine ::nTagsIndex := n ::cSourceFile := oEdit:oEditor:sourceFile - ::fillForm( aFacts ) + IF empty( aDoc := ::pullDocFromSource( nProtoLine, oEdit ) ) + ::fillForm( aFacts ) + ELSE + IF !empty( oFunc := ::oHL:getDocFunction( aDoc ) ) + ::fillFormByObject( oFunc ) + ELSE + ::fillForm( aFacts ) + ENDIF + ENDIF ENDIF ENDIF ENDIF @@ -520,7 +634,7 @@ METHOD IdeDocWriter:saveInFile() /*----------------------------------------------------------------------*/ METHOD IdeDocWriter:saveInFunction() - LOCAL nCurLine, oEdit + LOCAL nCurLine, oEdit, qCursor, a_, b_, s /* Bring it on top and make it current */ ::oSM:editSource( ::cSourceFile, , , , , , .f. ) @@ -540,10 +654,25 @@ METHOD IdeDocWriter:saveInFunction() // This is possible user might have edited the source; just issue warning MsgBox( "Source is modified, anyway proceeding.", "Documentation Save Alert" ) ENDIF + + qCursor := QTextCursor():from( oEdit:qEdit:textCursor() ) + qCursor:beginEditBlock() + + ::removeDocHelp( nCurLine, oEdit ) + b_:={} + a_:= ::buildDocument() + FOR EACH s IN a_ + IF "*" $ s + aadd( b_, s ) + ENDIF + NEXT oEdit:home() - oEdit:insertText( hbide_arrayToMemo( ::buildDocument() ) ) + oEdit:insertText( hbide_arrayToMemo( b_ ) ) oEdit:up() oEdit:deleteLine() + + qCursor:endEditBlock() + oEdit:qEdit:setTextCursor( qCursor ) oEdit:qEdit:centerCursor() ENDIF ENDIF diff --git a/harbour/contrib/hbide/ideedit.prg b/harbour/contrib/hbide/ideedit.prg index 6fb7b1bf2a..1a428c41d5 100644 --- a/harbour/contrib/hbide/ideedit.prg +++ b/harbour/contrib/hbide/ideedit.prg @@ -178,6 +178,7 @@ CLASS IdeEdit INHERIT IdeObject METHOD toggleColumnSelectionMode() METHOD toggleLineSelectionMode() METHOD clearSelection() + METHOD togglePersistentSelection() METHOD getWord( lSelect ) METHOD getLine( nLine, lSelect ) @@ -758,7 +759,7 @@ STATIC FUNCTION hbide_qCursorDownInsert( qCursor ) /*----------------------------------------------------------------------*/ METHOD IdeEdit:copyBlockContents( aCord ) - LOCAL nT, nL, nB, nR, nW, i, cLine, nMode, qClip + LOCAL nT, nL, nB, nR, nW, i, cLine, nMode, qClip, oLine LOCAL cClip := "" hbide_normalizeRect( aCord, @nT, @nL, @nB, @nR ) @@ -769,7 +770,7 @@ METHOD IdeEdit:copyBlockContents( aCord ) nW := nR - nL FOR i := nT TO nB cLine := ::getLine( i + 1 ) - + oLine := cLine IF nMode == selectionMode_stream IF aCord[ 1 ] > aCord[ 3 ] IF i == nT .AND. i == nB @@ -798,7 +799,7 @@ METHOD IdeEdit:copyBlockContents( aCord ) ENDIF aadd( ::aBlockCopyContents, cLine ) - cClip += cLine + iif( i < nB, hb_osNewLine(), "" ) + cClip += cLine + iif( i < nB, hb_osNewLine(), iif( cLine == oLine, hb_osNewLine(), "" ) ) NEXT * HB_TRACE( HB_TR_ALWAYS, "copyBlockContents", cClip ) @@ -820,7 +821,11 @@ METHOD IdeEdit:pasteBlockContents( nMode ) RETURN Self ENDIF - aCopy := hbide_memoToArray( QClipboard():new():text() ) +// aCopy := hbide_memoToArray( QClipboard():new():text() ) + aCopy := hb_ATokens( StrTran( RTrim( QClipboard():new():text() ), Chr( 13 ) + Chr( 10 ), _EOL ), _EOL ) + IF empty( aCopy[ len( aCopy ) ] ) + hb_adel( aCopy, len( aCopy ), .t. ) + ENDIF IF empty( aCopy ) RETURN Self ENDIF @@ -837,9 +842,9 @@ METHOD IdeEdit:pasteBlockContents( nMode ) ENDIF nPasteMode := iif( empty( nPasteMode ), selectionMode_stream, nPasteMode ) + qCursor := QTextCursor():from( ::qEdit:textCursor() ) + nCol := qCursor:columnNumber() - qCursor := QTextCursor():from( ::qEdit:textCursor() ) - nCol := qCursor:columnNumber() qCursor:beginEditBlock() // DO CASE @@ -877,6 +882,7 @@ METHOD IdeEdit:pasteBlockContents( nMode ) ENDCASE // qCursor:endEditBlock() + ::qEdit:ensureCursorVisible() RETURN Self @@ -1307,6 +1313,12 @@ METHOD IdeEdit:clearSelection() /*----------------------------------------------------------------------*/ +METHOD IdeEdit:togglePersistentSelection() + ::qEdit:hbTogglePersistentSelection() + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD IdeEdit:toggleCurrentLineHighlightMode() ::qEdit:hbHighlightCurrentLine( ::lCurrentLineHighlightEnabled ) RETURN Self diff --git a/harbour/contrib/hbide/ideeditor.prg b/harbour/contrib/hbide/ideeditor.prg index bb8de40ae1..0466be5c0e 100644 --- a/harbour/contrib/hbide/ideeditor.prg +++ b/harbour/contrib/hbide/ideeditor.prg @@ -171,6 +171,7 @@ CLASS IdeEditsManager INHERIT IdeObject METHOD showThumbnail() METHOD changeThumbnail() METHOD spaces2tabs() + METHOD qscintilla() ENDCLASS @@ -510,6 +511,15 @@ METHOD IdeEditsManager:setSourceVisibleByIndex( nIndex ) /* nIndex is 0 based */ /*----------------------------------------------------------------------*/ +METHOD IdeEditsManager:qscintilla() + LOCAL oEdit + IF !empty( oEdit := ::getEditorCurrent() ) + oEdit:qscintilla() + ENDIF + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD IdeEditsManager:undo() LOCAL oEdit IF !empty( oEdit := ::getEditObjectCurrent() ) @@ -1118,6 +1128,7 @@ CLASS IdeEditor INHERIT IdeObject METHOD showThumbnail() METHOD changeThumbnail() METHOD scrollThumbnail() + METHOD qscintilla() ENDCLASS @@ -1536,6 +1547,7 @@ METHOD IdeEditor:showThumbnail() ::oSourceThumbnailDock:oWidget:setWidget( ::qThumbnail:qEdit ) ::qThumbnail:qEdit:clear() ::qThumbnail:qEdit:setPlainText( hb_memoRead( ::sourceFile ) ) + RETURN Self /*----------------------------------------------------------------------*/ @@ -1565,3 +1577,131 @@ METHOD IdeEditor:scrollThumbnail() RETURN Self /*----------------------------------------------------------------------*/ +// QScintilla Test +/*----------------------------------------------------------------------*/ + +METHOD IdeEditor:qscintilla() + #ifdef HB_WITH_QSCINTILLA + #include "hbqscintilla.ch" + + #if 0 + SCE_FS_DEFAULT + SCE_FS_COMMENT + SCE_FS_COMMENTLINE + SCE_FS_COMMENTDOC + SCE_FS_COMMENTLINEDOC + SCE_FS_COMMENTDOCKEYWORD + SCE_FS_COMMENTDOCKEYWORDERROR + SCE_FS_KEYWORD + SCE_FS_KEYWORD2 + SCE_FS_KEYWORD3 + SCE_FS_KEYWORD4 + SCE_FS_NUMBER + SCE_FS_STRING + SCE_FS_PREPROCESSOR + SCE_FS_OPERATOR + SCE_FS_IDENTIFIER + SCE_FS_DATE + SCE_FS_STRINGEOL + SCE_FS_CONSTANT + SCE_FS_WORDOPERATOR + SCE_FS_DISABLEDCODE + SCE_FS_DEFAULT_C + SCE_FS_COMMENTDOC_C + SCE_FS_COMMENTLINEDOC_C + SCE_FS_KEYWORD_C + SCE_FS_KEYWORD2_C + SCE_FS_NUMBER_C + SCE_FS_STRING_C + SCE_FS_PREPROCESSOR_C + SCE_FS_OPERATOR_C + SCE_FS_IDENTIFIER_C + SCE_FS_STRINGEOL_C + SCE_FS_BRACE + #endif + + STATIC oSci, qLexer, qAPIs, fontBold, fontNormal, fontItalic, c1, c2, c3 + + IF empty( oSci ) + oSci := HBQsciScintilla():new() + // + oSci:setAutoIndent( .t. ) + oSci:setCaretLineVisible( .t. ) + oSci:setCaretWidth( 2 ) + oSci:setFolding( QsciScintilla_BoxedTreeFoldStyle ) + oSci:setTabWidth( 3 ) + oSci:setMarginLineNumbers( 0,.t. ) + oSci:setMarginWidth( 0,30 ) + oSci:setSelectionBackgroundColor( QColor():new( 255,0,0 ) ) + oSci:setEdgeColumn( 40 ) + oSci:setCallTipsVisible( 3 ) + oSci:setFont( ::oFont:oWidget ) + oSci:setEdgeColor( QColor():new( 0,0,255 ) ) + oSci:setMarginsFont( ::oFont:oWidget ) + oSci:setIndentationGuides( .t. ) + + oSci:setCallTipsHighlightColor( QColor():new( 255,127,0 ) ) + + /* Auto Completion */ + oSci:setAutoCompletionSource( QsciScintilla_AcsAll ) + oSci:setAutoCompletionThreshold( 3 ) + oSci:setAutoCompletionCaseSensitivity( .t. ) + oSci:setAutoCompletionShowSingle( .t. ) + oSci:setAutoCompletionFillupsEnabled( .t. ) + +HB_TRACE( HB_TR_ALWAYS, time() ) + oSci:setText( hb_memoread( "c:\harbour\contrib\hbide\idemisc.prg" ) ) + // oSci:setText( hb_memoread( "c:\harbour\contrib\hbide\ideparseexpr.c" ) ) +HB_TRACE( HB_TR_ALWAYS, time(), "after" ) + c1 := QColor():new( 0,0,255 ) + c2 := QColor():new( 0,12,133 ) + c3 := QColor():new( 20,122,144 ) + oSci:setBraceMatching( QsciScintilla_StrictBraceMatch ) + oSci:setMatchedBraceForegroundColor( c1 ) + oSci:setMatchedBraceBackgroundColor( c2 ) + oSci:setUnmatchedBraceForegroundColor( c3 ) + + qLexer := QsciLexerFlagship():new() + //qLexer := QsciLexerCPP():new() + qLexer:setDefaultFont( ::oFont:oWidget ) + qLexer:setFoldAtElse( .f. ) + + fontBold := QFont():new() + fontBold:setFamily( "Courier New" ) + fontBold:setPointSize(10) + fontBold:setWeight(100) + + fontNormal := QFont():new() + fontNormal:setFamily( "Courier New" ) + fontNormal:setPointSize(10) + + fontItalic := QFont():new() + fontItalic:setFamily( "Courier New" ) + fontItalic:setPointSize( 10 ) + fontItalic:setItalic( .t. ) + + qLexer:setFont( fontBold, SCE_FS_COMMENTLINEDOC ) + qLexer:setFont( fontBold, SCE_FS_COMMENTDOCKEYWORD ) + qLexer:setFont( fontBold, SCE_FS_NUMBER ) + + qLexer:setColor( QColor():new( 255, 127, 67 ), SCE_FS_KEYWORD ) + qLexer:setColor( QColor():new( 255, 0, 127 ), SCE_FS_KEYWORD2 ) + qLexer:setColor( QColor():new( 127, 67 , 255 ), SCE_FS_OPERATOR ) + qLexer:setColor( QColor():new( 255, 0 , 0 ), SCE_FS_BRACE ) + + qApis := QsciAPIs():new( qLexer ) + qApis:load( "c:/temp/cpp.api" ) + qApis:prepare() + qLexer:setAPIs( qApis ) + + oSci:setLexer( qLexer ) + qLexer:setEditor( oSci ) + + ENDIF + ::oQScintillaDock:oWidget:setWidget( oSci ) + #endif + RETURN Self + +/*----------------------------------------------------------------------*/ + + diff --git a/harbour/contrib/hbide/idefunctions.prg b/harbour/contrib/hbide/idefunctions.prg index d8b0391c5a..38efcb20c1 100644 --- a/harbour/contrib/hbide/idefunctions.prg +++ b/harbour/contrib/hbide/idefunctions.prg @@ -525,7 +525,7 @@ METHOD IdeFunctions:tagProject( cProjectTitle ) aSumData := {} cComments := CheckComments( aText ) aSummary := Summarize( aText, cComments, @aSumData , iif( upper( cExt ) == ".PRG", 9, 1 ) ) - aTags := UpdateTags( cSrc, aSummary, aSumData, @aFuncList, @aLines ) + aTags := UpdateTags( cSrc, aSummary, aSumData, @aFuncList, @aLines, aText ) IF !empty( aTags ) aeval( aTags, {|e_| aadd( aCTags, { e_[1],e_[2],e_[3],e_[4],e_[7] } ) } ) diff --git a/harbour/contrib/hbide/ideharbourhelp.prg b/harbour/contrib/hbide/ideharbourhelp.prg index ca3eb3c694..7e37c9bfa0 100644 --- a/harbour/contrib/hbide/ideharbourhelp.prg +++ b/harbour/contrib/hbide/ideharbourhelp.prg @@ -194,6 +194,7 @@ CLASS IdeHarbourHelp INHERIT IdeObject METHOD paintRequested( pPrinter ) METHOD parseTextFile( cTextFile, oParent ) METHOD jumpToFunction( cFunction ) + METHOD getDocFunction( acBuffer ) ENDCLASS @@ -766,6 +767,143 @@ METHOD IdeHarbourHelp:populateIndex() /*----------------------------------------------------------------------*/ +METHOD IdeHarbourHelp:getDocFunction( acBuffer ) + LOCAL a_, s, oFunc, nPart, lIsFunc + + IF hb_isArray( acBuffer ) + a_:= acBuffer + ELSE + a_:= hbide_memoTOarray( acBuffer ) + ENDIF + + oFunc := IdeDocFunction():new() + + lIsFunc := .f. + FOR EACH s IN a_ + + DO CASE + CASE "$DOC$" $ s + lIsFunc := .t. + CASE "$END$" $ s + EXIT + CASE "$TEMPLATE$" $ s + nPart := DOC_FUN_TEMPLATE + CASE "$FUNCNAME$" $ s .OR. "$NAME$" $ s + nPart := DOC_FUN_FUNCNAME + CASE "$CATEGORY$" $ s + nPart := DOC_FUN_CATEGORY + CASE "$SUBCATEGORY$" $ s + nPart := DOC_FUN_SUBCATEGORY + CASE "$ONELINER$" $ s + nPart := DOC_FUN_ONELINER + CASE "$SYNTAX$" $ s + nPart := DOC_FUN_SYNTAX + CASE "$ARGUMENTS$" $ s + nPart := DOC_FUN_ARGUMENTS + CASE "$RETURNS$" $ s + nPart := DOC_FUN_RETURNS + CASE "$DESCRIPTION$" $ s + nPart := DOC_FUN_DESCRIPTION + CASE "$EXAMPLES$" $ s + nPart := DOC_FUN_EXAMPLES + CASE "$TESTS$" $ s + nPart := DOC_FUN_TESTS + CASE "$FILES$" $ s + nPart := DOC_FUN_FILES + CASE "$STATUS$" $ s + nPart := DOC_FUN_STATUS + CASE "$PLATFORMS$" $ s .OR. "$COMPLIANCE$" $ s + nPart := DOC_FUN_PLATFORMS + CASE "$SEEALSO$" $ s + nPart := DOC_FUN_SEEALSO + CASE "$VERSION$" $ s + nPart := DOC_FUN_VERSION + CASE "$INHERITS" $ s + nPart := DOC_FUN_INHERITS + CASE "$METHODS" $ s + nPart := DOC_FUN_METHODS + CASE "$EXTERNALLINK" $ s + nPart := DOC_FUN_EXTERNALLINK + OTHERWISE + IF ! lIsFunc + LOOP // It is a fake line not within $DOC$ => $END$ block + ENDIF + s := substr( s, 9 ) + + SWITCH nPart + CASE DOC_FUN_BEGINS + EXIT + CASE DOC_FUN_TEMPLATE + oFunc:cTemplate := s + EXIT + CASE DOC_FUN_FUNCNAME + oFunc:cName := alltrim( s ) + EXIT + CASE DOC_FUN_CATEGORY + oFunc:cCategory := alltrim( s ) + EXIT + CASE DOC_FUN_SUBCATEGORY + oFunc:cSubCategory := alltrim( s ) + EXIT + CASE DOC_FUN_ONELINER + oFunc:cOneLiner := s + EXIT + CASE DOC_FUN_SYNTAX + aadd( oFunc:aSyntax , s ) + EXIT + CASE DOC_FUN_ARGUMENTS + aadd( oFunc:aArguments , s ) + EXIT + CASE DOC_FUN_RETURNS + aadd( oFunc:aReturns , s ) + EXIT + CASE DOC_FUN_DESCRIPTION + aadd( oFunc:aDescription, s ) + EXIT + CASE DOC_FUN_EXAMPLES + aadd( oFunc:aExamples , s ) + EXIT + CASE DOC_FUN_TESTS + aadd( oFunc:aTests , s ) + EXIT + CASE DOC_FUN_FILES + aadd( oFunc:aFiles , s ) + EXIT + CASE DOC_FUN_STATUS + oFunc:cStatus := alltrim( s ) + EXIT + CASE DOC_FUN_PLATFORMS + oFunc:cPlatForms := alltrim( s ) + EXIT + CASE DOC_FUN_SEEALSO + oFunc:cSeaAlso := alltrim( s ) + EXIT + CASE DOC_FUN_INHERITS + oFunc:cInherits := alltrim( s ) + EXIT + CASE DOC_FUN_METHODS + aadd( oFunc:aMethods , s ) + EXIT + CASE DOC_FUN_VERSION + oFunc:cVersion := alltrim( s ) + EXIT + CASE DOC_FUN_EXTERNALLINK + oFunc:cExternalLink := alltrim( s ) + EXIT + OTHERWISE + nPart := DOC_FUN_NONE + EXIT + ENDSWITCH + ENDCASE + NEXT + + IF ! lIsFunc + oFunc := NIL + ENDIF + RETURN oFunc + +/*----------------------------------------------------------------------*/ + METHOD IdeHarbourHelp:parseTextFile( cTextFile, oParent ) LOCAL a_, s, nPart, oFunc, oTWItem LOCAL lIsFunc := .f. diff --git a/harbour/contrib/hbide/idemisc.prg b/harbour/contrib/hbide/idemisc.prg index 83a441d5db..8dcf13a415 100644 --- a/harbour/contrib/hbide/idemisc.prg +++ b/harbour/contrib/hbide/idemisc.prg @@ -386,6 +386,15 @@ FUNCTION hbide_parseWithMetaData( s, a_ ) /*----------------------------------------------------------------------*/ +FUNCTION hbide_ar2delString( a_, cDlm ) + LOCAL s := "" + + aeval( a_, {|e| s += e + cDlm } ) + + RETURN substr( s, 1, len( s ) - len( cDlm ) ) + +/*----------------------------------------------------------------------*/ + FUNCTION hbide_arrayToMemo( a_ ) LOCAL s := "" diff --git a/harbour/contrib/hbide/ideobject.prg b/harbour/contrib/hbide/ideobject.prg index ddb064fbb4..3496e3ae90 100644 --- a/harbour/contrib/hbide/ideobject.prg +++ b/harbour/contrib/hbide/ideobject.prg @@ -190,6 +190,7 @@ CLASS IdeObject ACCESS oSkltnsTreeDock INLINE ::oIde:oSkltnsTreeDock ACCESS oFindDock INLINE ::oIde:oFindDock ACCESS oSourceThumbnailDock INLINE ::oIde:oSourceThumbnailDock + ACCESS oQScintillaDock INLINE ::oIde:oQScintillaDock ACCESS oMainToolbar INLINE ::oIde:oMainToolbar ACCESS lProjTreeVisible INLINE ::oIde:lProjTreeVisible diff --git a/harbour/contrib/hbide/ideprojmanager.prg b/harbour/contrib/hbide/ideprojmanager.prg index 6580dfc23c..2c3550bd0b 100644 --- a/harbour/contrib/hbide/ideprojmanager.prg +++ b/harbour/contrib/hbide/ideprojmanager.prg @@ -1248,7 +1248,7 @@ METHOD IdeProjManager:buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) IF ::oProject:type == "Lib" aadd( aHbp, "-hblib" ) ELSEIF ::oProject:type == "Dll" - aadd( aHbp, "-hbdyn" ) + // aadd( aHbp, "-hbdynvm" ) /* Better if is provided as a flag -hbdyn or -hbdynvm */ ENDIF ENDIF diff --git a/harbour/contrib/hbide/ideshortcuts.prg b/harbour/contrib/hbide/ideshortcuts.prg index d5a0573877..76e58caa79 100644 --- a/harbour/contrib/hbide/ideshortcuts.prg +++ b/harbour/contrib/hbide/ideshortcuts.prg @@ -210,6 +210,7 @@ CLASS IdeShortcuts INHERIT IdeObject METHOD toggleColumnSelectionMode() METHOD toggleLineSelectionMode() METHOD clearSelection() + METHOD togglePersistentSelection() /* Navigation */ METHOD home() @@ -1045,6 +1046,9 @@ METHOD IdeShortcuts:toggleColumnSelectionMode() METHOD IdeShortcuts:toggleLineSelectionMode() RETURN ::oEdit:toggleLineSelectionMode() /*----------------------------------------------------------------------*/ +METHOD IdeShortcuts:togglePersistentSelection() + RETURN ::oEdit:togglePersistentSelection() +/*----------------------------------------------------------------------*/ METHOD IdeShortcuts:clearSelection() RETURN ::oEdit:clearSelection() /*----------------------------------------------------------------------*/ @@ -1481,6 +1485,9 @@ METHOD IdeShortcuts:loadMethods() aadd( ::aMethods, { 'clearSelection()', ; 'clearSelection()', ; 'Clears the selection block, if any, and resets the selection mode to stream.' } ) + aadd( ::aMethods, { 'togglePersistentSelection()', ; + 'togglePersistentSelection()', ; + 'Toggles persistent selection mode. It switches on/off this mode' } ) aadd( ::aMethods, { ' Retreivals', ; @@ -1566,6 +1573,7 @@ METHOD IdeShortcuts:loadDftSCuts() aadd( b_, { "Insert Separator", "F7" , "NO", "NO" , "NO" , "", '::separator( "" )' , "insert-separator", "", "" } ) aadd( b_, { "Toggle Line Selection Mode", "F11", "NO", "NO" , "NO" , "", '::toggleLineSelectionMode()', "" , "", "" } ) + aadd( b_, { "Toggle Persistent Selection Mode", "F11", "NO", "YES" , "NO" , "", '::togglePersistentSelection()', "" , "", "" } ) aadd( b_, { "Clear Selection" , "F11" , "NO", "NO" , "YES", "", '::clearSelection()' , "" , "", "" } ) aadd( b_, { "Present Snippets", "K" , "NO", "YES", "NO" , "", '::presentSkeletons()' , "" , "", "" } ) aadd( b_, { "Goto Function" , "T" , "NO", "YES", "NO" , "", '::gotoFunction()' , "" , "", "" } ) diff --git a/harbour/contrib/hbqt/doc/en/class_hbqplaintextedit.txt b/harbour/contrib/hbqt/doc/en/class_hbqplaintextedit.txt index 590a527475..54932f607e 100644 --- a/harbour/contrib/hbqt/doc/en/class_hbqplaintextedit.txt +++ b/harbour/contrib/hbqt/doc/en/class_hbqplaintextedit.txt @@ -76,6 +76,7 @@ :hbGetViewportInfo() -> NIL :hbApplyKey( nKey, nModifiers, cTxt ) -> NIL :hbHighlightArea( nTop, nLeft, nBottom, nRight, nMode ) -> NIL + :hbTogglePersistentSelection() -> NIL $DESCRIPTION$ diff --git a/harbour/contrib/hbqt/generator/hbqtgen.prg b/harbour/contrib/hbqt/generator/hbqtgen.prg index ec990c7521..45ffa4d630 100644 --- a/harbour/contrib/hbqt/generator/hbqtgen.prg +++ b/harbour/contrib/hbqt/generator/hbqtgen.prg @@ -115,13 +115,13 @@ FUNCTION Main( ... ) CASE right( cLParam,4 ) == '.qth' aadd( aProFiles, cParam ) - CASE left( cParam,2 ) == '-O' + CASE lower( left( cParam,2 ) ) == '-o' cPathOut := substr( cParam, 3 ) - CASE left( cParam,2 ) == '-I' + CASE lower( left( cParam,2 ) ) == '-i' cPathIn := substr( cParam, 3 ) - CASE left( cParam,2 ) == '-D' + CASE lower( left( cParam,2 ) ) == '-d' cPathDoc := substr( cParam, 3 ) CASE cParam == '-c' @@ -133,18 +133,17 @@ FUNCTION Main( ... ) ENDCASE NEXT - IF empty( aPrjFiles ) .and. hb_fileExists( "qt45.qtp" ) + IF empty( aPrjFiles ) .AND. empty( aProFiles ) .AND. hb_fileExists( "qt45.qtp" ) aadd( aPrjFiles, "qt45.qtp" ) ENDIF - IF empty( aPrjFiles ) - + IF empty( aPrjFiles ) .AND. empty( aProFiles ) FOR EACH a_ IN directory( "*.qtp" ) aadd( aPrjFiles, a_[ 1 ] ) NEXT ENDIF - IF empty( aPrjFiles ) .and. empty( aProFiles ) + IF empty( aPrjFiles ) .AND. empty( aProFiles ) DispHelp() RETURN nil ENDIF @@ -224,7 +223,7 @@ STATIC FUNCTION ManageProject( cProFile, cPathIn, cPathOut, cPathDoc ) OutStd( 'Project file has unbalanced comment section...' + s_NewLine ) RETURN nil ENDIF - cPrj := substr( cPrj,1,n-1 ) + substr( cPrj,nn+2 ) + cPrj := substr( cPrj, 1, n-1 ) + substr( cPrj, nn+2 ) ENDDO /* Prepare to be parsed properly */ diff --git a/harbour/contrib/hbqt/hbqt_hbqplaintextedit.cpp b/harbour/contrib/hbqt/hbqt_hbqplaintextedit.cpp index 3767aa2ee2..07d22bd8f7 100644 --- a/harbour/contrib/hbqt/hbqt_hbqplaintextedit.cpp +++ b/harbour/contrib/hbqt/hbqt_hbqplaintextedit.cpp @@ -118,6 +118,8 @@ HBQPlainTextEdit::HBQPlainTextEdit( QWidget * parent ) : QPlainTextEdit( parent hitTestRow = -1; hitTestColumn = -1; highlight = QRect( -1, -1, -1, -1 ); + isSelectionPersistent = false; + isShiftPressed = false; connect( this, SIGNAL( blockCountChanged( int ) ) , this, SLOT( hbUpdateLineNumberAreaWidth( int ) ) ); connect( this, SIGNAL( updateRequest( const QRect &, int ) ), this, SLOT( hbUpdateLineNumberArea( const QRect &, int ) ) ); @@ -179,6 +181,13 @@ void HBQPlainTextEdit::hbApplyKey( int key, Qt::KeyboardModifiers modifiers, con /*----------------------------------------------------------------------*/ +void HBQPlainTextEdit::hbTogglePersistentSelection() +{ + isSelectionPersistent = ! isSelectionPersistent; +} + +/*----------------------------------------------------------------------*/ + void HBQPlainTextEdit::hbRefresh() { repaint(); @@ -656,6 +665,11 @@ void HBQPlainTextEdit::hbPaste() hb_vmEvalBlockV( block, 1, p1, p2 ); hb_itemRelease( p1 ); hb_itemRelease( p2 ); + + if( ! isSelectionPersistent ) + { + hbClearSelection(); + } } else { @@ -727,8 +741,16 @@ void HBQPlainTextEdit::mousePressEvent( QMouseEvent *event ) } else { - selectionState = 1; setCursorWidth( 1 ); + if( ! isSelectionPersistent ) + { + selectionState = 0; + hbClearSelection(); + } + else + { + selectionState = 1; + } QPlainTextEdit::mousePressEvent( event ); } } @@ -957,6 +979,12 @@ bool HBQPlainTextEdit::hbKeyPressSelection( QKeyEvent * event ) int k = event->key(); + if( ctrl && event->text().isEmpty() ) + { + event->ignore(); + return true; + } + if( ctrl && ( k == Qt::Key_C || k == Qt::Key_V || k == Qt::Key_X || k == Qt::Key_A || k == Qt::Key_Z || k == Qt::Key_Y ) ) { @@ -971,220 +999,220 @@ bool HBQPlainTextEdit::hbKeyPressSelection( QKeyEvent * event ) bool bClear = false; - if( shift && isNavableKey( k ) && selectionMode == selectionMode_line ) + if( shift && isNavableKey( k ) ) { - selectionMode = selectionMode_stream; - selectionState = 0; - hbClearSelection(); - repaint(); - } - - if( selectionMode == selectionMode_column || selectionMode == selectionMode_stream ) - { - QTextCursor c( textCursor() ); - int col = c.columnNumber(); - int row = c.blockNumber(); - - if( shift && isNavableKey( k ) ) + if( selectionMode == selectionMode_line ) { - if( selectionMode == selectionMode_line ) - { - selectionMode = selectionMode_stream; - selectionState = 0; - } + selectionMode = selectionMode_stream; + selectionState = 0; + } - if( selectionState == 0 ) - { - hbClearSelection(); - } + if( selectionState == 0 ) + { + hbClearSelection(); + } + + isShiftPressed = true; + event->accept(); + QTextCursor c( textCursor() ); + c.clearSelection(); + setTextCursor( c ); + + if( columnBegins == -1 ) + { if( selectionMode == selectionMode_column ) setCursorWidth( 0 ); - else - setCursorWidth( 1 ); - if( columnBegins == -1 ) - { - selectionState = 2; - // - rowBegins = row; - columnBegins = col; - rowEnds = row; - columnEnds = col; - emit selectionChanged(); - } + selectionState = 2; + rowBegins = c.blockNumber(); + columnBegins = c.columnNumber(); + rowEnds = rowBegins; + columnEnds = columnBegins; + emit selectionChanged(); + repaint(); + } - if( selectionMode == selectionMode_column ) - { - switch( k ) - { - case Qt::Key_Left: - if( col == 0 ) - { - columnEnds--; - columnEnds = columnEnds < 0 ? 0 : columnEnds; - repaint(); - event->ignore(); - return true; - } - break; + QKeyEvent * ev = new QKeyEvent( event->type(), event->key(), Qt::NoModifier, event->text() ); + keyPressEvent( ev ); + return true; + } - case Qt::Key_Right: - int pos = c.position(); - c.movePosition( QTextCursor::EndOfLine, QTextCursor::MoveAnchor ); - if( c.columnNumber() <= columnEnds ) - { - columnEnds++; - #if 0 /* Tobe Matured */ - int w = fontMetrics().averageCharWidth(); - if( ( columnEnds * w ) > viewport()->width() ) - { - int v = horizontalScrollBar()->value(); - horizontalScrollBar()->setValue( v + w ); - if( horizontalScrollBar()->value() == v ) - { - horizontalScrollBar()->setMaximum( horizontalScrollBar()->maximum() + w ); - horizontalScrollBar()->setValue( v + w ); - } - } - #endif - repaint(); - event->ignore(); - return true; - } - c.setPosition( pos ); - break; - } - } - event->accept(); - c.clearSelection(); - setTextCursor( c ); + if( isShiftPressed && isNavableKey( k ) ) + { + isShiftPressed = false; - QKeyEvent * ev = new QKeyEvent( event->type(), event->key(), Qt::NoModifier, event->text() ); - QPlainTextEdit::keyPressEvent( ev ); + if( selectionMode == selectionMode_stream ) + { + QPlainTextEdit::keyPressEvent( event ); - c = textCursor(); - col = c.columnNumber(); - row = c.blockNumber(); - - if( selectionMode == selectionMode_column ) - { - switch( k ) - { - case Qt::Key_Right: - columnEnds++; - break; - case Qt::Key_Left: - columnEnds--; - columnEnds = columnEnds < 0 ? 0 : columnEnds; - break; - case Qt::Key_Up: - case Qt::Key_PageUp: - case Qt::Key_Down: - case Qt::Key_PageDown: - rowEnds = row; - break; - default: - rowEnds = row; - columnEnds = col; - } - } - else - { - rowEnds = row; - columnEnds = col; - } - update(); - return true; - } // if( shift && isNavableKey( k ) ) + rowEnds = textCursor().blockNumber(); + columnEnds = textCursor().columnNumber(); + } else if( selectionMode == selectionMode_column ) { - if( ! ctrl && k >= ' ' && k < 127 && columnBegins >= 0 ) + switch( k ) { - if( ( columnBegins == columnEnds && selectionState > 0 ) || isCursorInSelection() ) - { - if( block ) - { - PHB_ITEM p1 = hb_itemPutNI( NULL, 21013 ); - PHB_ITEM p2 = hb_itemNew( NULL ); - hb_arrayNew( p2, 7 ); - hb_arraySetNI( p2, 1, rowBegins ); - hb_arraySetNI( p2, 2, columnBegins ); - hb_arraySetNI( p2, 3, rowEnds ); - hb_arraySetNI( p2, 4, columnEnds ); - hb_arraySetNI( p2, 5, selectionMode ); - hb_arraySetNI( p2, 6, selectionState ); - hb_arraySetPtr( p2, 7, event ); - hb_vmEvalBlockV( block, 2, p1, p2 ); - hb_itemRelease( p1 ); - hb_itemRelease( p2 ); - - if( columnBegins == columnEnds ) - { - columnBegins++; - columnEnds++; - } - repaint(); - event->accept(); - return true; - } - } - } - if( ! ctrl && ( k == Qt::Key_Backspace || k == Qt::Key_Delete ) && columnBegins >= 0 && selectionState > 0 ) + case Qt::Key_Right: { - hbCut( k ); - - if( k == Qt::Key_Backspace ) - { - columnBegins--; - columnEnds--; + QTextCursor c( textCursor() ); + c.movePosition( QTextCursor::EndOfLine ); + if( c.columnNumber() <= columnEnds ){ + setTextCursor( c ); + ensureCursorVisible(); } else { - columnEnds = columnBegins; + #if 0 /* Tobe Matured */ + int v = horizontalScrollBar()->value(); + int m = horizontalScrollBar()->maximum(); + int w = fontMetrics().averageCharWidth(); + if( ( ( columnEnds + 1 ) * w ) > m ){ + if( v == m ) + horizontalScrollBar()->setMaximum( m + w ); + } + horizontalScrollBar()->setValue( v + w ); + #endif + } + event->ignore(); + columnEnds++; + break; + } + case Qt::Key_Left: + { + QTextCursor c( textCursor() ); + int col = c.columnNumber(); + if( col < columnEnds - 1 ){ + c.movePosition( QTextCursor::Left ); + columnEnds--; + } + else if( columnEnds - 1 >= 0 ){ + columnEnds--; + } + event->ignore(); + break; + } + case Qt::Key_Home: + { + QPlainTextEdit::keyPressEvent( event ); + columnEnds = textCursor().columnNumber(); + break; + } + case Qt::Key_End: + { + QTextCursor c( textCursor() ); + c.movePosition( QTextCursor::EndOfLine, QTextCursor::MoveAnchor ); + if( c.columnNumber() <= columnEnds ){ + QPlainTextEdit::keyPressEvent( event ); + columnEnds = textCursor().columnNumber();; + } else { + event->ignore(); + } + break; + } + case Qt::Key_Up: + case Qt::Key_PageUp: + case Qt::Key_Down: + case Qt::Key_PageDown: + QPlainTextEdit::keyPressEvent( event ); + rowEnds = textCursor().blockNumber(); + break; + default: + event->ignore(); + break; + } + } + repaint(); + return true; + } + else if( ! ctrl && k >= ' ' && k < 127 && columnBegins >= 0 && selectionMode == selectionMode_column ) + { + if( ( columnBegins == columnEnds && selectionState > 0 ) || isCursorInSelection() ) + { + if( block ) + { + PHB_ITEM p1 = hb_itemPutNI( NULL, 21013 ); + PHB_ITEM p2 = hb_itemNew( NULL ); + hb_arrayNew( p2, 7 ); + hb_arraySetNI( p2, 1, rowBegins ); + hb_arraySetNI( p2, 2, columnBegins ); + hb_arraySetNI( p2, 3, rowEnds ); + hb_arraySetNI( p2, 4, columnEnds ); + hb_arraySetNI( p2, 5, selectionMode ); + hb_arraySetNI( p2, 6, selectionState ); + hb_arraySetPtr( p2, 7, event ); + hb_vmEvalBlockV( block, 2, p1, p2 ); + hb_itemRelease( p1 ); + hb_itemRelease( p2 ); + + if( columnBegins == columnEnds ){ + columnBegins++; + columnEnds++; } repaint(); event->accept(); return true; } - else - { - bClear = true; - } - } - else if( selectionMode == selectionMode_stream || selectionMode == selectionMode_line ) - { - if( selectionState > 0 && ! ctrl && k == Qt::Key_Delete && columnBegins >= 0 ) - { - hbCut( k ); - repaint(); - selectionState = 0; - event->accept(); - return true; - } - else - { - selectionState = 0; - } } else - { bClear = true; + } + else if( ! ctrl && ( k == Qt::Key_Backspace || k == Qt::Key_Delete ) && columnBegins >= 0 && selectionState > 0 && selectionMode == selectionMode_column ) + { + hbCut( k ); + if( k == Qt::Key_Backspace ){ + columnBegins--; + columnEnds--; } + else { + columnEnds = columnBegins; + } + repaint(); + event->accept(); + return true; + } + else if( ! ctrl && k == Qt::Key_Delete && columnBegins >= 0 && selectionState > 0 && ( selectionMode == selectionMode_stream || selectionMode == selectionMode_line ) ) + { + hbCut( k ); + repaint(); + selectionState = 0; + event->accept(); + return true; + } + else if( isNavableKey( k ) || ( k >= ' ' && k < 127 ) ) + { + bClear = true; + } - if( bClear ) + if( bClear ) + { + if( isSelectionPersistent ) { if( selectionState > 0 ) { emit selectionChanged(); setCursorWidth( 1 ); selectionState = 0; - if( columnEnds == columnBegins ) - { + if( columnEnds == columnBegins ){ hbClearSelection(); } } } + else + { + if( selectionState > 0 ) + { + emit selectionChanged(); + setCursorWidth( 1 ); + selectionState = 0; + hbClearSelection(); + repaint(); + } + } } + selectionState = 0; + return false; + + #if 0 else if( selectionMode == selectionMode_line ) { if( isLineSelectionON && isNavableKey( k ) ) @@ -1195,8 +1223,19 @@ bool HBQPlainTextEdit::hbKeyPressSelection( QKeyEvent * event ) repaint(); return true; } + else if( ! isSelectionPersistent ) + { + if( selectionState > 0 ) + { + emit selectionChanged(); + setCursorWidth( 1 ); + selectionState = 0; + hbClearSelection(); + repaint(); + } + } } - return false; + #endif } /*----------------------------------------------------------------------*/ @@ -1222,8 +1261,7 @@ void HBQPlainTextEdit::keyPressEvent( QKeyEvent * event ) event->ignore(); return; // let the completer do default behavior case Qt::Key_Space: - if( block ) - { + if( block ){ PHB_ITEM p1 = hb_itemPutNI( NULL, 21001 ); hb_vmEvalBlockV( block, 1, p1 ); hb_itemRelease( p1 ); @@ -1505,6 +1543,8 @@ void HBQPlainTextEdit::lineNumberAreaPaintEvent( QPaintEvent *event ) void HBQPlainTextEdit::hbPaintHighlight( QPaintEvent * event ) { + HB_SYMBOL_UNUSED( event ); + if( highlight.top() > -1 ) { int fontHeight = fontMetrics().height(); diff --git a/harbour/contrib/hbqt/hbqt_hbqplaintextedit.h b/harbour/contrib/hbqt/hbqt_hbqplaintextedit.h index 81c4b8db3d..a18764291c 100644 --- a/harbour/contrib/hbqt/hbqt_hbqplaintextedit.h +++ b/harbour/contrib/hbqt/hbqt_hbqplaintextedit.h @@ -152,7 +152,8 @@ private: int hitTestRow; int hitTestColumn; QRect highlight; - + bool isSelectionPersistent; + bool isShiftPressed; protected: bool event( QEvent * event ); @@ -204,6 +205,7 @@ public slots: void hbGetViewportInfo(); void hbApplyKey( int key, Qt::KeyboardModifiers modifiers = 0, const QString & txt = "" ); void hbHighlightArea( int, int, int, int, int ); + void hbTogglePersistentSelection(); private slots: void hbSlotCursorPositionChanged(); diff --git a/harbour/contrib/hbqt/qtgui/HBQPlainTextEdit.cpp b/harbour/contrib/hbqt/qtgui/HBQPlainTextEdit.cpp index 1b666a3a57..f670b5e01d 100644 --- a/harbour/contrib/hbqt/qtgui/HBQPlainTextEdit.cpp +++ b/harbour/contrib/hbqt/qtgui/HBQPlainTextEdit.cpp @@ -832,6 +832,20 @@ HB_FUNC( QT_HBQPLAINTEXTEDIT_HBHIGHLIGHTAREA ) } } +/* + * void hbTogglePersistentSelection() + */ +HB_FUNC( QT_HBQPLAINTEXTEDIT_HBTOGGLEPERSISTENTSELECTION ) +{ + HBQPlainTextEdit * p = hbqt_par_HBQPlainTextEdit( 1 ); + if( p ) + ( p )->hbTogglePersistentSelection(); + else + { + HB_TRACE( HB_TR_DEBUG, ( "............................... F=QT_HBQPLAINTEXTEDIT_HBTOGGLEPERSISTENTSELECTION FP=( p )->hbTogglePersistentSelection(); p is NULL" ) ); + } +} + /*----------------------------------------------------------------------*/ #endif /* #if QT_VERSION >= 0x040500 */ diff --git a/harbour/contrib/hbqt/qtgui/THBQPlainTextEdit.prg b/harbour/contrib/hbqt/qtgui/THBQPlainTextEdit.prg index d9e02d34d9..d813c342b8 100644 --- a/harbour/contrib/hbqt/qtgui/THBQPlainTextEdit.prg +++ b/harbour/contrib/hbqt/qtgui/THBQPlainTextEdit.prg @@ -115,6 +115,7 @@ CREATE CLASS HBQPlainTextEdit INHERIT HbQtObjectHandler, QPlainTextEdit METHOD hbGetViewportInfo() METHOD hbApplyKey( nKey, nModifiers, cTxt ) METHOD hbHighlightArea( nTop, nLeft, nBottom, nRight, nMode ) + METHOD hbTogglePersistentSelection() ENDCLASS @@ -319,3 +320,7 @@ METHOD HBQPlainTextEdit:hbApplyKey( nKey, nModifiers, cTxt ) METHOD HBQPlainTextEdit:hbHighlightArea( nTop, nLeft, nBottom, nRight, nMode ) RETURN Qt_HBQPlainTextEdit_hbHighlightArea( ::pPtr, nTop, nLeft, nBottom, nRight, nMode ) + +METHOD HBQPlainTextEdit:hbTogglePersistentSelection() + RETURN Qt_HBQPlainTextEdit_hbTogglePersistentSelection( ::pPtr ) + diff --git a/harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth b/harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth index d3db754c00..1a7459ee8f 100644 --- a/harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth +++ b/harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth @@ -146,6 +146,7 @@ HB_FUNC( QT_HBQPLAINTEXTEDIT ) void hbGetViewportInfo() void hbApplyKey( int key, Qt::KeyboardModifiers modifiers = 0, const QString & txt ) void hbHighlightArea( int top, int left, int bottom, int right, int mode ) + void hbTogglePersistentSelection()