[Libreoffice-commits] core.git: Branch 'feature/gsoc-basic-ide-completion-and-other-bits' - basctl/source basctl/uiconfig basic/source include/basic

Gergo Mocsi gmocsi91 at gmail.com
Mon Jul 29 13:36:28 PDT 2013


 basctl/source/basicide/baside2b.cxx                   |  120 ++++++++++++++++--
 basctl/source/basicide/codecompleteoptionsdlg.cxx     |    3 
 basctl/source/basicide/codecompleteoptionsdlg.hxx     |    1 
 basctl/uiconfig/basicide/ui/codecompleteoptionsdlg.ui |   19 ++
 basic/source/classes/codecompletecache.cxx            |   37 +++++
 basic/source/classes/sbxmod.cxx                       |   26 ---
 include/basic/codecompletecache.hxx                   |   20 ---
 include/basic/sbmod.hxx                               |    2 
 8 files changed, 170 insertions(+), 58 deletions(-)

New commits:
commit 5b26a68284d6f3e79b1d63a2ebd5b60be6cdfa46
Author: Gergo Mocsi <gmocsi91 at gmail.com>
Date:   Mon Jul 29 22:27:41 2013 +0200

    GSOC work, "autocomplete procedures" fix + new feature
    
    Fixed the procedure autoclose function. Now, autoclose is based on the syntax higlighter: if finds an opening token, starts searching forward to a close token.
    If there is another sub/function keyword, or EOF is reached, the procedure is considered incomplete.
    If the end token is found, the procedure is considered to be closed.
    Added function autocorrect symbol spelling, wich corrects the ascii case of the keywords, and corrects the spelling of the extended types.
    
    Change-Id: Ibd17f319a6d6ff5c3f91f4adb7a10dc701f0468a

diff --git a/basctl/source/basicide/baside2b.cxx b/basctl/source/basicide/baside2b.cxx
index f0f6ae8..3aebafd 100644
--- a/basctl/source/basicide/baside2b.cxx
+++ b/basctl/source/basicide/baside2b.cxx
@@ -502,6 +502,37 @@ void EditorWindow::KeyInput( const KeyEvent& rKEvt )
     // see if there is an accelerator to be processed first
     bool bDone = SfxViewShell::Current()->KeyInput( rKEvt );
 
+    if( (rKEvt.GetKeyCode().GetCode() == KEY_SPACE ||
+        rKEvt.GetKeyCode().GetCode() == KEY_TAB ||
+        rKEvt.GetKeyCode().GetCode() == KEY_RETURN ) && CodeCompleteOptions::IsAutoCorrectSpellingOn() )
+    {
+        TextSelection aSel = GetEditView()->GetSelection();
+        sal_uLong nLine =  aSel.GetStart().GetPara();
+        OUString aLine( pEditEngine->GetText( nLine ) ); // the line being modified
+
+        HighlightPortions aPortions;
+        aHighlighter.getHighlightPortions( nLine, aLine, aPortions );
+        if( aPortions.size() > 0 )
+        {
+            HighlightPortion& r = aPortions[aPortions.size()-1];
+            if( r.tokenType == 9 ) // correct the last entered keyword
+            {
+                OUString sStr = aLine.copy(r.nBegin, r.nEnd - r.nBegin);
+                if( !sStr.isEmpty() )
+                {
+                    //capitalize first letter and replace
+                    sStr = sStr.toAsciiLowerCase();
+                    sStr = sStr.replaceAt( 0, 1, OUString(sStr[0]).toAsciiUpperCase() );
+
+                    TextPaM aStart(nLine, aSel.GetStart().GetIndex() - sStr.getLength() );
+                    TextSelection sTextSelection(aStart, TextPaM(nLine, aSel.GetStart().GetIndex()));
+                    pEditEngine->ReplaceText( sTextSelection, sStr );
+                    pEditView->SetSelection( aSel );
+                }
+            }
+        }
+    }
+
     if( rKEvt.GetCharCode() == '"' && CodeCompleteOptions::IsAutoCloseQuotesOn() )
     {//autoclose double quotes
         TextSelection aSel = GetEditView()->GetSelection();
@@ -541,21 +572,77 @@ void EditorWindow::KeyInput( const KeyEvent& rKEvt )
     {//autoclose implementation
         TextSelection aSel = GetEditView()->GetSelection();
         sal_uLong nLine = aSel.GetStart().GetPara();
+        OUString aLine( pEditEngine->GetText( nLine ) );
         OUString sActSub = GetActualSubName( nLine );
-        IncompleteProcedures aProcData = rModulWindow.GetSbModule()->GetIncompleteProcedures();
-        for( unsigned int i = 0; i < aProcData.size(); ++i )
+
+        HighlightPortions aPortions;
+        aHighlighter.getHighlightPortions( nLine, aLine, aPortions );
+        OUString sProcType;
+        OUString sProcName;
+        bool bFoundType = false;
+        bool bFoundName = false;
+        if( aPortions.size() != 0 )
         {
-            if( aProcData[i].sProcName == sActSub )
-            {//found the procedure to autocomplete
-                TextPaM aEnd( aProcData[i].nLine, 0 );
-                TextPaM aStart( aProcData[i].nLine, 0 );
-                GetEditView()->SetSelection( TextSelection( aStart, aEnd ) );
-                if( aProcData[i].aType == AutocompleteType::ACSUB )
-                    GetEditView()->InsertText( OUString("\nEnd Sub\n") );
-                if( aProcData[i].aType == AutocompleteType::ACFUNC )
-                    GetEditView()->InsertText( OUString("\nEnd Function\n") );
-                GetEditView()->SetSelection( aSel );
-                break;
+            for ( size_t i = 0; i < aPortions.size(); i++ )
+            {
+                HighlightPortion& r = aPortions[i];
+                OUString sTokStr = aLine.copy(r.nBegin, r.nEnd - r.nBegin);
+                if( r.tokenType == 9 && ( sTokStr.equalsIgnoreAsciiCase("sub")
+                    || sTokStr.equalsIgnoreAsciiCase("function")) )
+                {
+                    sProcType = sTokStr;
+                    bFoundType = true;
+                }
+                if( r.tokenType == 1 && bFoundType )
+                {
+                    sProcName = sTokStr;
+                    bFoundName = true;
+                    break;
+                }
+            }
+            if( bFoundType && bFoundName )
+            {// found, search for end
+                if( nLine+1 == pEditEngine->GetParagraphCount() )
+                { //append to the end
+                    OUString sText("\nEnd ");
+                    if( sProcType.equalsIgnoreAsciiCase("function") )
+                        sText += OUString( "Function\n" );
+                    if( sProcType.equalsIgnoreAsciiCase("sub") )
+                        sText += OUString( "Sub\n" );
+                    pEditView->InsertText( sText );
+                }
+                else
+                {
+                    for( sal_uLong i = nLine+1; i < pEditEngine->GetParagraphCount(); ++i )
+                    {
+                        OUString aCurrLine = pEditEngine->GetText( i );
+                        HighlightPortions aCurrPortions;
+                        aHighlighter.getHighlightPortions( i, aCurrLine, aCurrPortions );
+                        if( aCurrPortions.size() >= 3 )
+                        {
+                            HighlightPortion& r1 = aCurrPortions[0];
+                            OUString sStr1 = aCurrLine.copy(r1.nBegin, r1.nEnd - r1.nBegin);
+
+                            if( r1.tokenType == 9 )
+                            {
+                                if( sStr1.equalsIgnoreAsciiCase("sub") )
+                                {
+                                    pEditView->InsertText( OUString ( "\nEnd Sub\n" ) );
+                                    break;
+                                }
+                                if( sStr1.equalsIgnoreAsciiCase("function") )
+                                {
+                                    pEditView->InsertText( OUString ( "\nEnd Function\n" ) );
+                                    break;
+                                }
+                                if( sStr1.equalsIgnoreAsciiCase("end") )
+                                {
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
             }
         }
     }
@@ -582,6 +669,13 @@ void EditorWindow::KeyInput( const KeyEvent& rKEvt )
 
             OUString sBaseName = aVect[0];//variable name
             OUString sVarType = aCodeCompleteCache.GetVarType( sBaseName );
+            if( !sVarType.isEmpty() && CodeCompleteOptions::IsAutoCorrectSpellingOn() )//correct variable name
+            {
+                TextPaM aStart(nLine, aSel.GetStart().GetIndex() - sBaseName.getLength() );
+                TextSelection sTextSelection(aStart, TextPaM(nLine, aSel.GetStart().GetIndex()));
+                pEditEngine->ReplaceText( sTextSelection, aCodeCompleteCache.GetCorrectCaseVarName(sBaseName) );
+                pEditView->SetSelection( aSel );
+            }
 
             Reference< lang::XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory(), UNO_SET_THROW );
             Reference< reflection::XIdlReflection > xRefl( xFactory->createInstance("com.sun.star.reflection.CoreReflection"), UNO_QUERY_THROW );
diff --git a/basctl/source/basicide/codecompleteoptionsdlg.cxx b/basctl/source/basicide/codecompleteoptionsdlg.cxx
index ff4398b..e79190c 100644
--- a/basctl/source/basicide/codecompleteoptionsdlg.cxx
+++ b/basctl/source/basicide/codecompleteoptionsdlg.cxx
@@ -36,6 +36,7 @@ CodeCompleteOptionsDlg::CodeCompleteOptionsDlg( Window* pWindow )
     get(pAutocloseProcChk, "autoclose_proc");
     get(pAutocloseParenChk, "autoclose_paren");
     get(pAutocloseQuotesChk, "autoclose_quotes");
+    get(pAutoCorrectSpellingChk, "autocorrect_spelling");
 
     pOkBtn->SetClickHdl( LINK( this, CodeCompleteOptionsDlg, OkHdl ) );
     pCancelBtn->SetClickHdl( LINK( this, CodeCompleteOptionsDlg, CancelHdl ) );
@@ -44,6 +45,7 @@ CodeCompleteOptionsDlg::CodeCompleteOptionsDlg( Window* pWindow )
     pAutocloseProcChk->Check( CodeCompleteOptions::IsProcedureAutoCompleteOn() );
     pAutocloseQuotesChk->Check( CodeCompleteOptions::IsAutoCloseQuotesOn() );
     pAutocloseParenChk->Check( CodeCompleteOptions::IsAutoCloseParenthesisOn() );
+    pAutoCorrectSpellingChk->Check( CodeCompleteOptions::IsAutoCorrectSpellingOn() );
 }
 
 CodeCompleteOptionsDlg::~CodeCompleteOptionsDlg()
@@ -56,6 +58,7 @@ IMPL_LINK_NOARG(CodeCompleteOptionsDlg, OkHdl)
     CodeCompleteOptions::SetProcedureAutoCompleteOn( pAutocloseProcChk->IsChecked() );
     CodeCompleteOptions::SetAutoCloseQuotesOn( pAutocloseQuotesChk->IsChecked() );
     CodeCompleteOptions::SetAutoCloseParenthesisOn( pAutocloseParenChk->IsChecked() );
+    CodeCompleteOptions::SetAutoCorrectSpellingOn( pAutoCorrectSpellingChk->IsChecked() );
     Close();
     return 0;
 }
diff --git a/basctl/source/basicide/codecompleteoptionsdlg.hxx b/basctl/source/basicide/codecompleteoptionsdlg.hxx
index 2154c8a..4c8b177 100644
--- a/basctl/source/basicide/codecompleteoptionsdlg.hxx
+++ b/basctl/source/basicide/codecompleteoptionsdlg.hxx
@@ -36,6 +36,7 @@ private:
     CheckBox* pAutocloseProcChk;
     CheckBox* pAutocloseParenChk;
     CheckBox* pAutocloseQuotesChk;
+    CheckBox* pAutoCorrectSpellingChk;
 
     DECL_LINK(OkHdl, void*);
     DECL_LINK(CancelHdl, void*);
diff --git a/basctl/uiconfig/basicide/ui/codecompleteoptionsdlg.ui b/basctl/uiconfig/basicide/ui/codecompleteoptionsdlg.ui
index 1c0d86c..50f16f7 100644
--- a/basctl/uiconfig/basicide/ui/codecompleteoptionsdlg.ui
+++ b/basctl/uiconfig/basicide/ui/codecompleteoptionsdlg.ui
@@ -36,11 +36,11 @@
                 <property name="label">gtk-ok</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_stock">True</property>
                 <property name="image_position">right</property>
-                <property name="has_default">True</property>
-                <property name="can_default">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -174,6 +174,21 @@
                             <property name="position">2</property>
                           </packing>
                         </child>
+                        <child>
+                          <object class="GtkCheckButton" id="autocorrect_spelling">
+                            <property name="label" translatable="yes">Autocorrect Symbol Spelling</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="xalign">0</property>
+                            <property name="draw_indicator">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">3</property>
+                          </packing>
+                        </child>
                       </object>
                     </child>
                   </object>
diff --git a/basic/source/classes/codecompletecache.cxx b/basic/source/classes/codecompletecache.cxx
index 0c757df..f48952f 100644
--- a/basic/source/classes/codecompletecache.cxx
+++ b/basic/source/classes/codecompletecache.cxx
@@ -27,10 +27,11 @@ namespace
 }
 
 CodeCompleteOptions::CodeCompleteOptions()
-: bIsCodeCompleteOn( true ),
+: bIsCodeCompleteOn( false ),
 bIsProcedureAutoCompleteOn( false ),
 bIsAutoCloseQuotesOn( false ),
-bIsAutoCloseParenthesisOn( false )
+bIsAutoCloseParenthesisOn( false ),
+bIsAutoCorrectSpellingOn( false )
 {
 }
 
@@ -79,6 +80,16 @@ void CodeCompleteOptions::SetAutoCloseParenthesisOn( const bool& b )
     theCodeCompleteOptions::get().bIsAutoCloseParenthesisOn = b;
 }
 
+bool CodeCompleteOptions::IsAutoCorrectSpellingOn()
+{
+    return theCodeCompleteOptions::get().aMiscOptions.IsExperimentalMode() && theCodeCompleteOptions::get().bIsAutoCorrectSpellingOn;
+}
+
+void CodeCompleteOptions::SetAutoCorrectSpellingOn( const bool& b )
+{
+    theCodeCompleteOptions::get().bIsAutoCorrectSpellingOn = b;
+}
+
 std::ostream& operator<< (std::ostream& aStream, const CodeCompleteDataCache& aCache)
 {
     aStream << "Global variables" << std::endl;
@@ -164,4 +175,26 @@ OUString CodeCompleteDataCache::GetVarType( const OUString& sVarName ) const
     return OUString(""); //not found
 }
 
+OUString CodeCompleteDataCache::GetCorrectCaseVarName( const OUString& sVarName ) const
+{
+    for( CodeCompleteVarScopes::const_iterator aIt = aVarScopes.begin(); aIt != aVarScopes.end(); ++aIt )
+    {
+        CodeCompleteVarTypes aTypes = aIt->second;
+        for( CodeCompleteVarTypes::const_iterator aOtherIt = aTypes.begin(); aOtherIt != aTypes.end(); ++aOtherIt )
+        {
+            if( aOtherIt->first.equalsIgnoreAsciiCase( sVarName ) )
+            {
+                return aOtherIt->first;
+            }
+        }
+    }
+    //not a local, search global scope
+    for( CodeCompleteVarTypes::const_iterator aIt = aGlobalVars.begin(); aIt != aGlobalVars.end(); ++aIt )
+    {
+        if( aIt->first.equalsIgnoreAsciiCase( sVarName ) )
+            return aIt->first;
+    }
+    return OUString(""); //not found
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx
index fa04809..989f5f5 100644
--- a/basic/source/classes/sbxmod.cxx
+++ b/basic/source/classes/sbxmod.cxx
@@ -894,10 +894,7 @@ void SbModule::SetSource32( const OUString& r )
     StartDefinitions();
     SbiTokenizer aTok( r );
     aTok.SetCompatible( IsVBACompat() );
-    if( CodeCompleteOptions::IsProcedureAutoCompleteOn() )
-    {
-        aIncompleteProcs.clear();
-    }
+
     while( !aTok.IsEof() )
     {
         SbiToken eEndTok = NIL;
@@ -941,15 +938,12 @@ void SbModule::SetSource32( const OUString& r )
         }
         // Definition of the method
         SbMethod* pMeth = NULL;
-        OUString sMethName;
         if( eEndTok != NIL )
         {
             sal_uInt16 nLine1 = aTok.GetLine();
             if( aTok.Next() == SYMBOL )
             {
                 OUString aName_( aTok.GetSym() );
-                //std::cerr << "method name: " << aName_ << std::endl;
-                sMethName = aName_;
                 SbxDataType t = aTok.GetType();
                 if( t == SbxVARIANT && eEndTok == ENDSUB )
                 {
@@ -973,36 +967,18 @@ void SbModule::SetSource32( const OUString& r )
                 if( aTok.Next() == eEndTok )
                 {
                     pMeth->nLine2 = aTok.GetLine();
-                    //std::cerr << "there is end for "<< sMethName << std::endl;
                     break;
                 }
             }
             if( aTok.IsEof() )
             {
                 pMeth->nLine2 = aTok.GetLine();
-                if( CodeCompleteOptions::IsProcedureAutoCompleteOn() )
-                {
-                    IncompleteProcData aProcData;
-                    aProcData.sProcName = sMethName;
-                    aProcData.nLine = pMeth->nLine2;
-
-                    if( eEndTok == ENDSUB )
-                        aProcData.aType = ACSUB;
-                    if( eEndTok == ENDFUNC )
-                        aProcData.aType = ACFUNC;
-                    aIncompleteProcs.push_back(aProcData);
-                }
             }
         }
     }
     EndDefinitions( sal_True );
 }
 
-IncompleteProcedures SbModule::GetIncompleteProcedures() const
-{
-    return aIncompleteProcs;
-}
-
 // Broadcast of a hint to all Basics
 
 static void _SendHint( SbxObject* pObj, sal_uIntPtr nId, SbMethod* p )
diff --git a/include/basic/codecompletecache.hxx b/include/basic/codecompletecache.hxx
index c12139b..cb92a64 100644
--- a/include/basic/codecompletecache.hxx
+++ b/include/basic/codecompletecache.hxx
@@ -29,24 +29,10 @@
 #include <svtools/miscopt.hxx>
 #include <vector>
 
-enum BASIC_DLLPUBLIC AutocompleteType
-{
-    ACSUB,
-    ACFUNC
-};
-
-struct IncompleteProcData
-{
-    OUString sProcName;
-    sal_uInt16 nLine;
-    AutocompleteType aType;
-};
-
 typedef boost::unordered_map< OUString, OUString, OUStringHash > CodeCompleteVarTypes;
 /* variable name, type */
 typedef boost::unordered_map< OUString, CodeCompleteVarTypes, OUStringHash > CodeCompleteVarScopes;
 /* procedure, CodeCompleteVarTypes */
-typedef std::vector< IncompleteProcData > IncompleteProcedures;
 
 class BASIC_DLLPUBLIC CodeCompleteOptions
 {
@@ -59,6 +45,7 @@ private:
     bool bIsProcedureAutoCompleteOn;
     bool bIsAutoCloseQuotesOn;
     bool bIsAutoCloseParenthesisOn;
+    bool bIsAutoCorrectSpellingOn;
     SvtMiscOptions aMiscOptions;
 
 public:
@@ -76,6 +63,10 @@ public:
 
     static bool IsAutoCloseParenthesisOn();
     static void SetAutoCloseParenthesisOn( const bool& b );
+
+    static bool IsAutoCorrectSpellingOn();
+    static void SetAutoCorrectSpellingOn( const bool& b );
+
 };
 
 class BASIC_DLLPUBLIC CodeCompleteDataCache
@@ -100,6 +91,7 @@ public:
     void InsertGlobalVar( const OUString& sVarName, const OUString& sVarType );
     void InsertLocalVar( const OUString& sProcName, const OUString& sVarName, const OUString& sVarType );
     OUString GetVarType( const OUString& sVarName ) const;
+    OUString GetCorrectCaseVarName( const OUString& sVarName ) const;
     void print() const; // wrapper for operator<<, prints to std::cerr
     void Clear();
 };
diff --git a/include/basic/sbmod.hxx b/include/basic/sbmod.hxx
index 22b2bdb..543a199 100644
--- a/include/basic/sbmod.hxx
+++ b/include/basic/sbmod.hxx
@@ -56,7 +56,6 @@ class BASIC_DLLPUBLIC SbModule : public SbxObject, private ::boost::noncopyable
     std::vector< OUString > mModuleVariableNames;
 
     BASIC_DLLPRIVATE void implClearIfVarDependsOnDeletedBasic( SbxVariable* pVar, StarBASIC* pDeletedBasic );
-    IncompleteProcedures aIncompleteProcs;
 
 protected:
     com::sun::star::uno::Reference< com::sun::star::script::XInvocation > mxWrapper;
@@ -137,7 +136,6 @@ public:
     bool createCOMWrapperForIface( ::com::sun::star::uno::Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject );
     void GetCodeCompleteDataFromParse(CodeCompleteDataCache& aCache);
     SbxArrayRef GetMethods();
-    IncompleteProcedures GetIncompleteProcedures() const;
 };
 
 SV_DECL_IMPL_REF(SbModule)


More information about the Libreoffice-commits mailing list