diff --git a/harbour/ChangeLog b/harbour/ChangeLog index b33d5d9cca..d88fb4d4f9 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,35 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-01-11 01:52 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + * contrib/hbqt/hbqt_destruct.cpp + + Added .prg callable hbqt_QMainWindow_saveSettings() and + hbqt_QMainWindow_restSettings(). These two functions are + essential to save and restore last hbIDE interface exactly + in the same state it was closed last. This I could not achieve + via pure .prg code. + + * contrib/hbide/hbide.prg + * contrib/hbide/ideeditor.prg + * contrib/hbide/idesaveload.prg + + Implemented restoring exact geometry of main window plus + all the docking windows plus toolbars. hbIDE creates + idesettings.ini in the folder returned by hb_dirBase(). + Note that idesettings.ini is not a windows .ini format + and please do not try to change even a single byte of its + contents. + + + Implemented splitting any source into multiple windows. + This implementation allows you to edit different parts of + same source simultaneously. This feature allows you to split + window horizontally or vertically. You can split many times. + This feature can be activated as such: + 1. Right-click somewhere in the editing tab + 2. Context menu will be displayed, point to item + 3. Select from "Split Horiz..." etc. + + Please report any functionality which may be incorporated hereunder. + 2010-01-11 08:12 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + contrib/hbide/resources/findsource.ui %+ TOBE implemented in "Sources List" tabpage of "Project Properties" dialog. diff --git a/harbour/contrib/hbide/hbide.prg b/harbour/contrib/hbide/hbide.prg index 57a7c30484..2e43e0bf97 100644 --- a/harbour/contrib/hbide/hbide.prg +++ b/harbour/contrib/hbide/hbide.prg @@ -326,6 +326,9 @@ METHOD HbIde:create( cProjIni ) ::setSizeByIni( ::oProjTree:oWidget, ProjectTreeGeometry ) ::setSizeByIni( ::oEditTree:oWidget, ProjectTreeGeometry ) + /* Restore Settings */ + hbide_restSettings( Self ) + /* Request Main Window to Appear on the Screen */ ::oDlg:Show() @@ -348,8 +351,8 @@ METHOD HbIde:create( cProjIni ) CASE ::mp1 == xbeK_INS IF !empty( ::qCurEdit ) - ::qCurEdit:setOverwriteMode( ! ::qCurEdit:overwriteMode() ) - ::oCurEditor:dispEditInfo() + ::qCurEdit:setOverwriteMode( !::qCurEdit:overwriteMode() ) + ::oCurEditor:dispEditInfo( ::qCurEdit ) ENDIF CASE ::mp1 == xbeK_ESC @@ -498,6 +501,8 @@ METHOD HbIde:execAction( cKey ) ::oEM:convertSelection( cKey ) CASE cKey == "Invert" ::oEM:convertSelection( cKey ) + CASE cKey == "MatchPairs" + // CASE cKey == "InsertDateTime" ::oEM:insertText( cKey ) CASE cKey == "InsertRandomName" diff --git a/harbour/contrib/hbide/ideeditor.prg b/harbour/contrib/hbide/ideeditor.prg index cf81cea72c..56a2a2253d 100644 --- a/harbour/contrib/hbide/ideeditor.prg +++ b/harbour/contrib/hbide/ideeditor.prg @@ -118,6 +118,7 @@ CLASS IdeEditsManager INHERIT IdeObject METHOD exeBlock() METHOD addSourceInTree() METHOD removeSourceInTree() + METHOD splitEdit() ENDCLASS @@ -132,6 +133,7 @@ METHOD IdeEditsManager:new( oIde ) /*----------------------------------------------------------------------*/ METHOD IdeEditsManager:create( oIde ) + LOCAL oSub DEFAULT oIde TO ::oIde @@ -154,6 +156,12 @@ METHOD IdeEditsManager:create( oIde ) aadd( ::aActions, { "" , ::qContextMenu:addSeparator() } ) aadd( ::aActions, { "Apply Theme" , ::qContextMenu:addAction( "Apply Theme" ) } ) + oSub := QMenu():configure( ::qContextMenu:addMenu_1( "Split" ) ) + // + aadd( ::aActions, { "Split H" , oSub:addAction( "Split Horiz..." ) } ) + aadd( ::aActions, { "Split V" , oSub:addAction( "Split Verti..." ) } ) + aadd( ::aActions, { "Close Split" , oSub:addAction( "Close Split" ) } ) + RETURN Self /*----------------------------------------------------------------------*/ @@ -234,6 +242,17 @@ METHOD IdeEditsManager:exeBlock( nMode, p ) /*----------------------------------------------------------------------*/ +METHOD IdeEditsManager:splitEdit() + LOCAL oEdit + + IF !empty( oEdit := ::getEditorCurrent() ) + oEdit:split() + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD IdeEditsManager:buildEditor( cSourceFile, nPos, nHPos, nVPos, cTheme ) aadd( ::aEdits, IdeEditor():new():create( ::oIde, cSourceFile, nPos, nHPos, nVPos, cTheme ) ) @@ -648,12 +667,14 @@ CLASS IdeEditor INHERIT IdeObject DATA aTab INIT {} DATA qCursor + DATA aSplits INIT {} METHOD new() METHOD create() METHOD destroy() METHOD buildTabPage() + METHOD buildEditor() METHOD removeTabPage() METHOD activateTab() METHOD closeTab() @@ -662,6 +683,7 @@ CLASS IdeEditor INHERIT IdeObject METHOD applyTheme() METHOD setDocumentProperties() METHOD exeBlock() + METHOD split() ENDCLASS @@ -712,42 +734,26 @@ METHOD IdeEditor:create( oIde, cSourceFile, nPos, nHPos, nVPos, cTheme ) ::buildTabPage( ::sourceFile ) - ::qEdit := QPlainTextEdit():new( ::oTab:oWidget ) - ::qEdit:setLineWrapMode( QTextEdit_NoWrap ) - ::qEdit:setFont( ::oFont:oWidget ) - ::qEdit:ensureCursorVisible() - * ::qEdit:setStyleSheet( GetStyleSheet( "QPlainTextEdit" ) ) + ::qEdit := ::buildEditor( 0 ) /* Main Editor */ ::qDocument := QTextDocument():configure( ::qEdit:document() ) + // + ::Connect( ::qDocument, "blockCountChanged(int)" , {|o,p | ::exeBlock( 21, p, o ) } ) + ::Connect( ::qDocument, "contentsChanged()" , {| | ::exeBlock( 22 ) } ) - ::qLayout := QBoxLayout():new() - ::qLayout:setDirection( 0 ) + ::qLayout := QGridLayout():new() ::qLayout:setContentsMargins( 0,0,0,0 ) - ::qLayout:addWidget( ::qEdit ) - + ::qLayout:setHorizontalSpacing( 5 ) + ::qLayout:setVerticalSpacing( 5 ) + // ::oTab:oWidget:setLayout( ::qLayout ) + // Row Col RSpn CSpn + ::qLayout:addWidget_1( ::qEdit, 0, 1, 1, 1 ) IF ::cType != "U" ::qHiliter := ::oThemes:SetSyntaxHilighting( ::qEdit, @::cTheme ) ENDIF - ::qEdit:setContextMenuPolicy( Qt_CustomContextMenu ) - ::connect( ::qEdit , "customContextMenuRequested(QPoint)", {|o,p| ::exeBlock( 1, p, o ) } ) - - /* QPlainTextEdit */ - ::Connect( ::qEdit , "textChanged()" , {| | ::setTabImage() } ) - ::Connect( ::qEdit , "cursorPositionChanged()" , {| | ::dispEditInfo() } ) - ::Connect( ::qEdit , "copyAvailable(bool)" , {|o,p | ::exeBlock( 3, p, o ) } ) - ::Connect( ::qEdit , "modificationChanged(bool)", {|o,p | ::exeBlock( 4, p, o ) } ) - ::Connect( ::qEdit , "redoAvailable(bool)" , {|o,p | ::exeBlock( 5, p, o ) } ) - ::Connect( ::qEdit , "selectionChanged()" , {|o,p | ::exeBlock( 6, p, o ) } ) - ::Connect( ::qEdit , "undoAvailable(bool)" , {|o,p | ::exeBlock( 7, p, o ) } ) - ::Connect( ::qEdit , "updateRequest(QRect,int)" , {|o,p,p1| ::exeBlock( 8, p, p1, o ) } ) - /* QTextDocument */ - ::Connect( ::qDocument, "blockCountChanged(int)" , {|o,p | ::exeBlock( 21, p, o ) } ) - ::Connect( ::qDocument, "contentsChanged()" , {| | ::exeBlock( 22 ) } ) - - ::qEdit:show() ::qCursor := QTextCursor():configure( ::qEdit:textCursor() ) @@ -767,19 +773,81 @@ METHOD IdeEditor:create( oIde, cSourceFile, nPos, nHPos, nVPos, cTheme ) /*----------------------------------------------------------------------*/ -METHOD IdeEditor:exeBlock( nMode, p, p1 ) - LOCAL pAct, qAct +METHOD IdeEditor:split( nMode, qEditP ) + LOCAL qEdit, nRows, nCols + + HB_SYMBOL_UNUSED( qEditP ) + + nRows := ::qLayout:rowCount() + nCols := ::qlayout:columnCount() + + qEdit := ::buildEditor() + IF nMode == 1 /* Horizontal */ + ::qLayout:addWidget( qEdit, nRows - 1, nCols ) + ELSEIF nMode == 2 /* Vertical */ + ::qLayout:addWidget( qEdit, nRows, nCols - 1 ) + ENDIF + + aadd( ::aSplits, qEdit ) + + qEdit:setDocument( ::qEdit:document() ) + + qEdit:show() + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD IdeEditor:buildEditor() + LOCAL qEdit + + qEdit := QPlainTextEdit():new() + qEdit:setLineWrapMode( QTextEdit_NoWrap ) + qEdit:setFont( ::oFont:oWidget ) + qEdit:ensureCursorVisible() + + qEdit:setContextMenuPolicy( Qt_CustomContextMenu ) + ::connect( qEdit, "customContextMenuRequested(QPoint)", {|o,p| ::exeBlock( 1, p, o, qEdit ) } ) + + ::Connect( qEdit, "textChanged()" , {| | ::setTabImage() } ) + ::Connect( qEdit, "cursorPositionChanged()" , {| | ::dispEditInfo( qEdit ) } ) + ::Connect( qEdit, "updateRequest(QRect,int)" , {|o,p,p1| ::exeBlock( 8, p, p1, o ) } ) + ::Connect( qEdit, "copyAvailable(bool)" , {|o,p | ::exeBlock( 3, p, o ) } ) + ::Connect( qEdit, "modificationChanged(bool)", {|o,p | ::exeBlock( 4, p, o ) } ) + ::Connect( qEdit, "redoAvailable(bool)" , {|o,p | ::exeBlock( 5, p, o ) } ) + ::Connect( qEdit, "selectionChanged()" , {|o,p | ::exeBlock( 6, p, o ) } ) + ::Connect( qEdit, "undoAvailable(bool)" , {|o,p | ::exeBlock( 7, p, o ) } ) + ::Connect( qEdit, "updateRequest(QRect,int)" , {|o,p,p1| ::exeBlock( 8, p, p1, o ) } ) + + RETURN qEdit + +/*----------------------------------------------------------------------*/ + +METHOD IdeEditor:exeBlock( nMode, p, p1, qEdit ) + LOCAL pAct, qAct, n //LOCAL qRect HB_SYMBOL_UNUSED( p ) HB_SYMBOL_UNUSED( p1 ) SWITCH nMode + /* QPlainTextEdit */ CASE 1 // "customContextMenuRequested(QPoint)" - IF !empty( pAct := ::oEM:qContextMenu:exec_1( ::qEdit:mapToGlobal( p ) ) ) + IF !empty( pAct := ::oEM:qContextMenu:exec_1( qEdit:mapToGlobal( p ) ) ) qAct := QAction():configure( pAct ) DO CASE + CASE qAct:text() == "Split Horiz..." + ::split( 1, qEdit ) + CASE qAct:text() == "Split Verti..." + ::split( 2, qEdit ) + CASE qAct:text() == "Close Split" + IF ( n := ascan( ::aSplits, {|o| o == qEdit } ) ) > 0 + ::qLayout:removeWidget( qEdit ) + hb_adel( ::aSplits, n, .t. ) + qEdit:close() + qEdit:pPtr := 0 + ENDIF CASE qAct:text() == "Apply Theme" ::applyTheme() ENDCASE @@ -806,6 +874,7 @@ METHOD IdeEditor:exeBlock( nMode, p, p1 ) //qRect := QRect():configure( p ) //hbide_dbg( "updateRequest(QRect,int)", qRect:x(), qRect:y(), qRect:width(), qRect:height(), p1 ) EXIT + /* QTabPage */ CASE 11 // QEvent_ContextMenu hbide_dbg( "QEvent_ContextMenu" ) @@ -813,6 +882,7 @@ METHOD IdeEditor:exeBlock( nMode, p, p1 ) CASE 12 // QEvent_ContextMenu hbide_dbg( "QEvent_ContextMenu" ) EXIT + /* QTextDocument */ CASE 21 // "blockCountChanged(int)" ::nBlock := QTextCursor():configure( ::qEdit:textCursor() ):blockNumber() @@ -851,7 +921,7 @@ METHOD IdeEditor:setDocumentProperties() ::oIde:updateFuncList() ::oIde:updateTitleBar() - ::dispEditInfo() + ::dispEditInfo( ::qEdit ) ::oIde:manageFocusInEditor() @@ -933,7 +1003,15 @@ METHOD IdeEditor:closeTab( mp1, mp2, oXbp ) */ METHOD IdeEditor:removeTabPage() LOCAL cSource := ::sourceFile - LOCAL n + LOCAL n, qEdit + + FOR EACH qEdit IN ::aSplits + ::qLayout:removeWidget( qEdit ) + qEdit:close() + qEdit:pPtr := 0 + qEdit := NIL + NEXT + ::aSplits := {} n := aScan( ::oIde:aTabs, {|e_| e_[ TAB_OEDITOR ]:nID == ::nID } ) IF n > 0 @@ -990,20 +1068,23 @@ METHOD IdeEditor:removeTabPage() /*----------------------------------------------------------------------*/ -METHOD IdeEditor:dispEditInfo() - LOCAL s +METHOD IdeEditor:dispEditInfo( qEdit ) + LOCAL s, qDocument, qCursor - ::qCursor := QTextCursor():configure( ::qEdit:textCursor() ) + DEFAULT qEdit TO ::qEdit - s := "Line "+ hb_ntos( ::qCursor:blockNumber() + 1 ) + " of " + ; - hb_ntos( ::qDocument:blockCount() ) + "" + qDocument := QTextDocument():configure( qEdit:document() ) + qCursor := QTextCursor():configure( qEdit:textCursor() ) + + s := "Line "+ hb_ntos( qCursor:blockNumber() + 1 ) + " of " + ; + hb_ntos( qDocument:blockCount() ) + "" ::oIde:oSBar:getItem( SB_PNL_MAIN ):caption := "Success" ::oIde:oSBar:getItem( SB_PNL_READY ):caption := "Ready" ::oIde:oSBar:getItem( SB_PNL_LINE ):caption := s - ::oIde:oSBar:getItem( SB_PNL_COLUMN ):caption := "Col " + hb_ntos( ::qCursor:columnNumber() + 1 ) - ::oIde:oSBar:getItem( SB_PNL_INS ):caption := iif( ::qEdit:overwriteMode() , " ", "Ins" ) - ::oIde:oSBar:getItem( SB_PNL_MODIFIED ):caption := iif( ::qDocument:isModified(), "Modified", iif( ::qEdit:isReadOnly(), "ReadOnly", " " ) ) + ::oIde:oSBar:getItem( SB_PNL_COLUMN ):caption := "Col " + hb_ntos( qCursor:columnNumber() + 1 ) + ::oIde:oSBar:getItem( SB_PNL_INS ):caption := iif( qEdit:overwriteMode() , " ", "Ins" ) + ::oIde:oSBar:getItem( SB_PNL_MODIFIED ):caption := iif( qDocument:isModified(), "Modified", iif( qEdit:isReadOnly(), "ReadOnly", " " ) ) ::oIde:oSBar:getItem( SB_PNL_STREAM ):caption := "Stream" ::oIde:oSBar:getItem( SB_PNL_EDIT ):caption := "Edit" diff --git a/harbour/contrib/hbide/idesaveload.prg b/harbour/contrib/hbide/idesaveload.prg index c5cc7d2785..b377285ab6 100644 --- a/harbour/contrib/hbide/idesaveload.prg +++ b/harbour/contrib/hbide/idesaveload.prg @@ -286,14 +286,16 @@ FUNCTION hbide_loadINI( oIde, cHbideIni ) /*----------------------------------------------------------------------*/ STATIC FUNCTION hbide_saveSettings( oIde ) - LOCAL qSet, qWidget - qWidget := oIde:oDlg:oWidget - - qSet := QSettings():new( hb_dirBase() + "idesettings.ini", 1 ) - - qSet:setValue( "hbIDE" , qWidget:saveState() ) - qSet:setValue( "hbIDE-g", qWidget:geometry() ) + hbqt_QMainWindow_saveSettings( hb_dirBase() + "idesettings.ini", "hbIDE", oIde:oDlg:oWidget:pPtr ) + + RETURN nil + +/*----------------------------------------------------------------------*/ + +FUNCTION hbide_restSettings( oIde ) + + hbqt_QMainWindow_restSettings( hb_dirBase() + "idesettings.ini", "hbIDE", oIde:oDlg:oWidget:pPtr ) RETURN nil diff --git a/harbour/contrib/hbqt/hbqt_destruct.cpp b/harbour/contrib/hbqt/hbqt_destruct.cpp index a31523b79a..f4df9ce0d8 100644 --- a/harbour/contrib/hbqt/hbqt_destruct.cpp +++ b/harbour/contrib/hbqt/hbqt_destruct.cpp @@ -60,6 +60,8 @@ #if QT_VERSION >= 0x040500 #include +#include +#include static int s_iObjectReleaseMethod = HBQT_RELEASE_WITH_DELETE_LATER; @@ -133,6 +135,20 @@ HB_FUNC( HBQT_SETCODECFORCSTRINGS ) QTextCodec::setCodecForCStrings( codec ); } +HB_FUNC( HBQT_QMAINWINDOW_SAVESETTINGS ) +{ + QSettings qSet( hbqt_par_QString( 1 ), QSettings::IniFormat ); + + qSet.setValue( hbqt_par_QString( 2 ), hbqt_par_QMainWindow( 3 )->saveState() ); +} + +HB_FUNC( HBQT_QMAINWINDOW_RESTSETTINGS ) +{ + QSettings qSet( hbqt_par_QString( 1 ), QSettings::IniFormat ); + + hbqt_par_QMainWindow( 3 )->restoreState( qSet.value( hbqt_par_QString( 2 ) ).toByteArray() ); +} + /*----------------------------------------------------------------------*/ #endif // #if QT_VERSION >= 0x040500