diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 18193efbfe..8c70b3fecf 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,31 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-03-10 17:05 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + * 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 + + * contrib/hbide/hbide.prg + * contrib/hbide/ideeditor.prg + * contrib/hbide/idefunctions.prg + * contrib/hbide/ideobject.prg + + + Implemented "Code Completion" feature. + How it works: + 1. Load prototype tags in "Projects Functions Lookup". + 2. Activate some editor tab. + 3. Start typing a function proto. + 4. After 3 characters a popup will appear beneth the cursor. + 5. Select from the list, by mouse or use navigation keys. + 6. Prototype will be there in the editor exactly with + same cases your prototype is defined. + + Input is welcome. + 2010-03-10 21:42 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * utils/hbmk2/hbmk2.prg * config/dos/djgpp.mk diff --git a/harbour/contrib/hbide/hbide.prg b/harbour/contrib/hbide/hbide.prg index 53f012a6ba..cd8d497935 100644 --- a/harbour/contrib/hbide/hbide.prg +++ b/harbour/contrib/hbide/hbide.prg @@ -177,6 +177,8 @@ CLASS HbIde DATA qTBarPanels DATA qTBarDocks DATA qCompleter + DATA qCompModel + DATA qProtoList ACCESS oCurEditor INLINE ::oEM:getEditorCurrent() ACCESS qCurEdit INLINE ::oEM:getEditCurrent() diff --git a/harbour/contrib/hbide/ideeditor.prg b/harbour/contrib/hbide/ideeditor.prg index 70210b3f93..5c3a84e80d 100644 --- a/harbour/contrib/hbide/ideeditor.prg +++ b/harbour/contrib/hbide/ideeditor.prg @@ -198,10 +198,16 @@ METHOD IdeEditsManager:create( oIde ) aadd( ::aActions, { "" , oSub:addSeparator() } ) aadd( ::aActions, { "Close Split" , oSub:addAction( "Close Split Window" ) } ) + ::oIde:qProtoList := QStringList():new() + ::oIde:qCompModel := QStringListModel():new() ::oIde:qCompleter := QCompleter():new() + ::qCompModel:setStringList( ::qProtoList ) + ::qCompleter:setModel( ::qCompModel ) + ::qCompleter:setModelSorting( QCompleter_CaseInsensitivelySortedModel ) ::qCompleter:setCaseSensitivity( Qt_CaseInsensitive ) ::qCompleter:setCompletionMode( QCompleter_PopupCompletion ) + ::qCompleter:setWrapAround( .f. ) ::connect( ::qCompleter, "activated(QString)", {|p| ::execEvent( qcompleter_activated, p ) } ) @@ -265,11 +271,13 @@ METHOD IdeEditsManager:addSourceInTree( cSourceFile ) /*----------------------------------------------------------------------*/ METHOD IdeEditsManager:execEvent( nMode, p ) - - HB_SYMBOL_UNUSED( p ) + LOCAL oEdit DO CASE CASE nMode == qcompleter_activated + IF !empty( oEdit := ::getEditObjectCurrent() ) + oEdit:completeCode( p ) + ENDIF ENDCASE @@ -1398,6 +1406,7 @@ CLASS IdeEdit INHERIT IdeObject METHOD resumePrototype() METHOD showPrototype( cProto ) METHOD hidePrototype() + METHOD completeCode( p ) ENDCLASS @@ -1432,6 +1441,8 @@ METHOD IdeEdit:create( oEditor, nMode ) ::qEdit:hbHighlightCurrentLine( .t. ) /* Via user-setup */ ::qEdit:hbSetSpaces( ::nTabSpaces ) + ::qEdit:hbSetCompleter( ::qCompleter ) + ::toggleLineNumbers() ::qHLayout := QHBoxLayout():new() @@ -2222,6 +2233,23 @@ METHOD IdeEdit:hidePrototype() /*----------------------------------------------------------------------*/ +METHOD IdeEdit:completeCode( p ) + LOCAL qCursor := QTextCursor():from( ::qEdit:textCursor() ) + + qCursor:movePosition( QTextCursor_Left ) + + qCursor:movePosition( QTextCursor_StartOfWord ) + qCursor:movePosition( QTextCursor_EndOfWord, QTextCursor_KeepAnchor ) + qCursor:insertText( p ) + qCursor:movePosition( QTextCursor_Left ) + qCursor:movePosition( QTextCursor_Right ) + + ::qEdit:setTextCursor( qCursor ) + + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD IdeEdit:loadFuncHelp() LOCAL qEdit, qCursor, qTextBlock, cText, cWord, nCol, cPro diff --git a/harbour/contrib/hbide/idefunctions.prg b/harbour/contrib/hbide/idefunctions.prg index 500fd9150b..00ff5f4037 100644 --- a/harbour/contrib/hbide/idefunctions.prg +++ b/harbour/contrib/hbide/idefunctions.prg @@ -425,7 +425,7 @@ METHOD IdeFunctions:enableControls( lEnable ) ::oUI:q_editFunction:setEnabled( lEnable ) - ::showApplicationCursor( iif( lEnable, NIL, Qt_BusyCursor ) ) + ::showApplicationCursor( iif( lEnable, NIL, Qt_WaitCursor ) ) RETURN Self @@ -586,29 +586,56 @@ METHOD IdeFunctions:consolidateList() /*----------------------------------------------------------------------*/ METHOD IdeFunctions:populateTable() - LOCAL oTbl, qItm, a_, n + LOCAL oTbl, qItm, a_, n, s, k_:={} - ::clear( .t. ) - ::buildHeader() + ::clear( .t. ) + ::buildHeader() - oTbl := ::oUI:q_tableFuncList - oTbl:setRowCount( len( ::aList ) ) + oTbl := ::oUI:q_tableFuncList + oTbl:setRowCount( len( ::aList ) ) - n := 0 - FOR EACH a_ IN ::aList - qItm := QTableWidgetItem():new() + n := 0 + FOR EACH a_ IN ::aList + qItm := QTableWidgetItem():new() - qItm:setText( a_[ 3 ] ) - qItm:setTooltip( a_[ 2 ] ) - oTbl:setItem( n, 0, qItm ) - oTbl:setRowHeight( n, 16 ) + qItm:setText( a_[ 3 ] ) + qItm:setTooltip( a_[ 2 ] ) + oTbl:setItem( n, 0, qItm ) + oTbl:setRowHeight( n, 16 ) - QApplication():processEvents() + QApplication():processEvents() - aadd( ::aItems, qItm ) - n++ - ::oUI:q_labelEntries:setText( "Entries: " + hb_ntos( n ) ) - NEXT + aadd( ::aItems, qItm ) + n++ + ::oUI:q_labelEntries:setText( "Entries: " + hb_ntos( n ) ) + NEXT + + ::qProtoList:clear() + + FOR EACH a_ IN ::aList + s := a_[ 2 ] + IF ( n := at( "(", s ) ) == 0 + IF ( n := at( " ", s ) ) > 0 + aadd( k_, substr( s, 1, n - 1 ) ) + ELSE + aadd( k_, trim( s ) ) + ENDIF + ELSE + aadd( k_, substr( s, 1, n - 1 ) ) + ENDIF + NEXT + + asort( k_, , , {|e,f| lower( e ) < lower( f ) } ) + aeval( k_, {|e| ::qProtoList:append( e ) } ) + + ::qCompModel:setStringList( ::qProtoList ) + ::qCompleter:setModel( ::qCompModel ) + ::qCompleter:setModelSorting( QCompleter_CaseInsensitivelySortedModel ) + ::qCompleter:setCaseSensitivity( Qt_CaseInsensitive ) + ::qCompleter:setCompletionMode( QCompleter_PopupCompletion ) + ::qCompleter:setWrapAround( .f. ) + + QListView():from( ::qCompleter:popup() ):setAlternatingRowColors( .t. ) RETURN Self diff --git a/harbour/contrib/hbide/ideobject.prg b/harbour/contrib/hbide/ideobject.prg index 0ea8539580..9e047e1a3a 100644 --- a/harbour/contrib/hbide/ideobject.prg +++ b/harbour/contrib/hbide/ideobject.prg @@ -120,6 +120,8 @@ CLASS IdeObject ACCESS qTBarPanels INLINE ::oIde:qTBarPanels ACCESS qTBarDocks INLINE ::oIde:qTBarDocks ACCESS qCompleter INLINE ::oIde:qCompleter + ACCESS qCompModel INLINE ::oIde:qCompModel + ACCESS qProtoList INLINE ::oIde:qProtoList ACCESS cWrkProject INLINE ::oIde:cWrkProject ACCESS cWrkTheme INLINE ::oIde:cWrkTheme diff --git a/harbour/contrib/hbqt/doc/en/class_hbqplaintextedit.txt b/harbour/contrib/hbqt/doc/en/class_hbqplaintextedit.txt index 89207c03ff..d5d9a7dd19 100644 --- a/harbour/contrib/hbqt/doc/en/class_hbqplaintextedit.txt +++ b/harbour/contrib/hbqt/doc/en/class_hbqplaintextedit.txt @@ -1,20 +1,25 @@ /* - * hbQTgen v1.0 - Harbour Callable Wrappers Generator for Qt v4.5.3+ + * hbQTgen v1.0 - Harbour Callable Wrappers Generator for QT v4.5+ + * * Please do not modify this document as it is subject to change in future. + * * Pritpal Bedi + * + * 03/10/10 - 14:17:24 + * */ + + /* $DOC$ $TEMPLATE$ Class $NAME$ HBQPlainTextEdit() $CATEGORY$ - Harbour Bindings for Qt + Harbour Bindings for Qt 4.5.3+ $SUBCATEGORY$ GUI - $EXTERNALLINK$ - http://doc.trolltech.com/4.5/hbqplaintextedit.html $ONELINER$ Creates a new HBQPlainTextEdit object. $INHERITS$ @@ -60,7 +65,9 @@ :hbMoveLine( nIDirection ) -> NIL :hbHighlightSelectedColumns( lYes ) -> NIL :hbGetSelectedText() -> cQString + :hbTextUnderCursor() -> cQString :hbShowPrototype( cTip ) -> NIL + :hbSetCompleter( pCompleter ) -> NIL $DESCRIPTION$ @@ -81,6 +88,6 @@ C++ Wrappers : contrib/hbqt/qtgui/HBQPlainTextEdit.cpp Library : hbqtgui $SEEALSO$ - QPlainTextEdit + QPlainTextEdit, http://doc.trolltech.com/4.5/hbqplaintextedit.html $END$ */ diff --git a/harbour/contrib/hbqt/hbqt_hbqplaintextedit.cpp b/harbour/contrib/hbqt/hbqt_hbqplaintextedit.cpp index ae1a757133..7a9f208c11 100644 --- a/harbour/contrib/hbqt/hbqt_hbqplaintextedit.cpp +++ b/harbour/contrib/hbqt/hbqt_hbqplaintextedit.cpp @@ -170,6 +170,75 @@ bool HBQPlainTextEdit::event( QEvent *event ) return QPlainTextEdit::event( event ); } +void HBQPlainTextEdit::keyPressEvent( QKeyEvent * event ) +{ + if( c && c->popup()->isVisible() ) + { + // The following keys are forwarded by the completer to the widget + switch( event->key() ) + { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + case Qt::Key_Tab: + case Qt::Key_Backtab: + event->ignore(); + return; // let the completer do default behavior + default: + break; + } + } + + QPlainTextEdit::keyPressEvent( event ); + + const bool ctrlOrShift = event->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); + if( !c || ( ctrlOrShift && event->text().isEmpty() ) ) + return; + + static QString eow( "~!@#$%^&*()+{}|:\"<>?,./;'[]\\-=" ); /* end of word */ + bool hasModifier = ( event->modifiers() != Qt::NoModifier ) && !ctrlOrShift; + QString completionPrefix = hbTextUnderCursor(); + + if( ( hasModifier || event->text().isEmpty() || completionPrefix.length() < 3 + || eow.contains( event->text().right( 1 ) ) ) ) + { + c->popup()->hide(); + return; + } + + if( completionPrefix != c->completionPrefix() ) + { + c->setCompletionPrefix( completionPrefix ); + c->popup()->setCurrentIndex( c->completionModel()->index( 0, 0 ) ); + } + QRect cr = cursorRect(); + cr.setWidth( c->popup()->sizeHintForColumn( 0 ) + c->popup()->verticalScrollBar()->sizeHint().width() ); + c->complete( cr ); // popup it up! +} + +QString HBQPlainTextEdit::hbTextUnderCursor() +{ + QTextCursor tc = textCursor(); + tc.select( QTextCursor::WordUnderCursor ); + return tc.selectedText(); +} + +void HBQPlainTextEdit::resizeEvent( QResizeEvent *e ) +{ + QPlainTextEdit::resizeEvent( e ); + + QRect cr = contentsRect(); + lineNumberArea->setGeometry( QRect( cr.left(), cr.top(), hbLineNumberAreaWidth(), cr.height() ) ); +} + +void HBQPlainTextEdit::focusInEvent( QFocusEvent * event ) +{ + if( c ) + c->setWidget( this ); + + QPlainTextEdit::focusInEvent( event ); +} + void HBQPlainTextEdit::mouseDoubleClickEvent( QMouseEvent *event ) { HB_TRACE( HB_TR_ALWAYS, ( "void HBQPlainTextEdit::mouseDblClickEvent( QMouseEvent * %p )", event ) ); @@ -256,24 +325,6 @@ void HBQPlainTextEdit::lineNumberAreaPaintEvent( QPaintEvent *event ) } } -#if 0 -void HBQPlainTextEdit::contextMenuEvent( QContextMenuEvent *event ) -{ - QWidget::contextMenuEvent( event ); -} - -void HBQPlainTextEdit::keyPressEvent( QKeyEvent *event ) -{ - QPlainTextEdit::keyPressEvent( event ); -} -#endif -void HBQPlainTextEdit::resizeEvent( QResizeEvent *e ) -{ - QPlainTextEdit::resizeEvent( e ); - - QRect cr = contentsRect(); - lineNumberArea->setGeometry( QRect( cr.left(), cr.top(), hbLineNumberAreaWidth(), cr.height() ) ); -} void HBQPlainTextEdit::hbBookmarks( int block ) diff --git a/harbour/contrib/hbqt/hbqt_hbqplaintextedit.h b/harbour/contrib/hbqt/hbqt_hbqplaintextedit.h index 76b288e3cc..efeb54e746 100644 --- a/harbour/contrib/hbqt/hbqt_hbqplaintextedit.h +++ b/harbour/contrib/hbqt/hbqt_hbqplaintextedit.h @@ -63,6 +63,9 @@ #include #include #include +#include +#include +#include #include #include "hbqt_hbqsyntaxhighlighter.h" @@ -123,15 +126,14 @@ private: int columnEnds; bool isColumnSelectionEnabled; bool isTipActive; + QCompleter * c; protected: bool event( QEvent * event ); void resizeEvent( QResizeEvent * event ); void mouseDoubleClickEvent( QMouseEvent * event ); - #if 0 - void contextMenuEvent( QContextMenuEvent * event ); + void focusInEvent( QFocusEvent * event ); void keyPressEvent( QKeyEvent * event ); - #endif public slots: void hbUpdateLineNumberAreaWidth( int newBlockCount ); @@ -153,9 +155,11 @@ public slots: void hbInsertTab( int mode ); void hbHighlightSelectedColumns( bool yes ); QString hbGetSelectedText(); + QString hbTextUnderCursor(); void hbNumberBlockVisible( bool b ); bool hbNumberBlockVisible(); void hbShowPrototype( const QString & tip ); + void hbSetCompleter( QCompleter * completer ) { c = completer; }; private slots: void hbSlotCursorPositionChanged(); diff --git a/harbour/contrib/hbqt/qtgui/HBQPlainTextEdit.cpp b/harbour/contrib/hbqt/qtgui/HBQPlainTextEdit.cpp index 6945f37ff8..7906d801c6 100644 --- a/harbour/contrib/hbqt/qtgui/HBQPlainTextEdit.cpp +++ b/harbour/contrib/hbqt/qtgui/HBQPlainTextEdit.cpp @@ -410,6 +410,14 @@ HB_FUNC( QT_HBQPLAINTEXTEDIT_HBGETSELECTEDTEXT ) hb_retc( hbqt_par_HBQPlainTextEdit( 1 )->hbGetSelectedText().toAscii().data() ); } +/* + * QString hbTextUnderCursor() + */ +HB_FUNC( QT_HBQPLAINTEXTEDIT_HBTEXTUNDERCURSOR ) +{ + hb_retc( hbqt_par_HBQPlainTextEdit( 1 )->hbTextUnderCursor().toAscii().data() ); +} + /* * void hbShowPrototype( const QString & tip ) */ @@ -418,6 +426,14 @@ HB_FUNC( QT_HBQPLAINTEXTEDIT_HBSHOWPROTOTYPE ) hbqt_par_HBQPlainTextEdit( 1 )->hbShowPrototype( HBQPlainTextEdit::tr( hb_parc( 2 ) ) ); } +/* + * void hbSetCompleter( QCompleter * completer ) + */ +HB_FUNC( QT_HBQPLAINTEXTEDIT_HBSETCOMPLETER ) +{ + hbqt_par_HBQPlainTextEdit( 1 )->hbSetCompleter( hbqt_par_QCompleter( 2 ) ); +} + /*----------------------------------------------------------------------*/ #endif /* #if QT_VERSION >= 0x040500 */ diff --git a/harbour/contrib/hbqt/qtgui/THBQPlainTextEdit.prg b/harbour/contrib/hbqt/qtgui/THBQPlainTextEdit.prg index 9f05f44e36..1795a11761 100644 --- a/harbour/contrib/hbqt/qtgui/THBQPlainTextEdit.prg +++ b/harbour/contrib/hbqt/qtgui/THBQPlainTextEdit.prg @@ -99,7 +99,9 @@ CREATE CLASS HBQPlainTextEdit INHERIT HbQtObjectHandler, QPlainTextEdit METHOD hbMoveLine( nIDirection ) METHOD hbHighlightSelectedColumns( lYes ) METHOD hbGetSelectedText() + METHOD hbTextUnderCursor() METHOD hbShowPrototype( cTip ) + METHOD hbSetCompleter( pCompleter ) ENDCLASS @@ -241,6 +243,14 @@ METHOD HBQPlainTextEdit:hbGetSelectedText() RETURN Qt_HBQPlainTextEdit_hbGetSelectedText( ::pPtr ) +METHOD HBQPlainTextEdit:hbTextUnderCursor() + RETURN Qt_HBQPlainTextEdit_hbTextUnderCursor( ::pPtr ) + + METHOD HBQPlainTextEdit:hbShowPrototype( cTip ) RETURN Qt_HBQPlainTextEdit_hbShowPrototype( ::pPtr, cTip ) + +METHOD HBQPlainTextEdit:hbSetCompleter( pCompleter ) + RETURN Qt_HBQPlainTextEdit_hbSetCompleter( ::pPtr, hbqt_ptr( pCompleter ) ) + diff --git a/harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth b/harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth index f22fc84145..26eafa09ee 100644 --- a/harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth +++ b/harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth @@ -55,9 +55,9 @@ ; -QObject = +QObject = Inherits = QPlainTextEdit -Type = +Type = New = @@ -106,7 +106,7 @@ HB_FUNC( QT_HBQPLAINTEXTEDIT ) void hbGotoBookmark(int block) void hbNumberBlockVisible(bool b) bool hbNumberBlockVisible() - void hbHighlightCurrentLine(bool b) + void hbHighlightCurrentLine(bool b) bool hbHighlightCurrentLine() void hbSetEventBlock( PHB_ITEM block ) @@ -130,7 +130,9 @@ HB_FUNC( QT_HBQPLAINTEXTEDIT ) void hbMoveLine( int iDirection ) void hbHighlightSelectedColumns( bool yes ) QString hbGetSelectedText() + QString hbTextUnderCursor() void hbShowPrototype( const QString & tip ) + void hbSetCompleter( QCompleter * completer )