From 4788dd88da5eea2c566c5ba8efee778fdab93760 Mon Sep 17 00:00:00 2001 From: Pritpal Bedi Date: Thu, 11 Mar 2010 01:10:36 +0000 Subject: [PATCH] 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. --- harbour/ChangeLog | 25 ++++++ harbour/contrib/hbide/hbide.prg | 2 + harbour/contrib/hbide/ideeditor.prg | 32 ++++++- harbour/contrib/hbide/idefunctions.prg | 63 ++++++++++---- harbour/contrib/hbide/ideobject.prg | 2 + .../hbqt/doc/en/class_hbqplaintextedit.txt | 17 ++-- .../contrib/hbqt/hbqt_hbqplaintextedit.cpp | 87 +++++++++++++++---- harbour/contrib/hbqt/hbqt_hbqplaintextedit.h | 10 ++- .../contrib/hbqt/qtgui/HBQPlainTextEdit.cpp | 16 ++++ .../contrib/hbqt/qtgui/THBQPlainTextEdit.prg | 10 +++ harbour/contrib/hbqt/qth/HBQPlainTextEdit.qth | 8 +- 11 files changed, 223 insertions(+), 49 deletions(-) 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 )