[Libreoffice-commits] core.git: Branch 'libreoffice-6-0' - cui/inc cui/source

Muhammet Kara muhammet.kara at pardus.org.tr
Mon Dec 4 11:56:40 UTC 2017


 cui/inc/strings.hrc                             |    2 
 cui/source/customize/CommandCategoryListBox.cxx |  215 ++++++++++++++++++++++--
 cui/source/inc/CommandCategoryListBox.hxx       |    5 
 3 files changed, 211 insertions(+), 11 deletions(-)

New commits:
commit 3b12778af71951bfce321c73509e8b0c59b02853
Author: Muhammet Kara <muhammet.kara at pardus.org.tr>
Date:   Mon Nov 27 21:10:21 2017 +0300

    tdf#112207: Allow assigning macros to ui elements
    
    * Adds "Macros" category to the categories list
    
    * Search/filter feature now works also on the macros category
    
    * Since macros category has multiple trees and subtrees, and many leaf
      elements (macros). I chose to implement the behavior like this:
    
      If there is no filter/search term, the trees will be presented as in the old
      macro selector dialog (collapsed), but if user types a search term, then
      filtering happens: non-matching elements and empty containers/(sub)trees
      are removed and everything is expanded so that user easily sees what
      (s)he is looking for.
    
    Change-Id: I1a93f156a7293c7e61baac882a10ff631961e2af
    Reviewed-on: https://gerrit.libreoffice.org/44938
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Heiko Tietze <tietze.heiko at googlemail.com>
    Reviewed-by: Katarina Behrens <Katarina.Behrens at cib.de>
    (cherry picked from commit 3f2915c40fcc42ac91f2019fd506bfbdd1e5933f)
    Reviewed-on: https://gerrit.libreoffice.org/45779

diff --git a/cui/inc/strings.hrc b/cui/inc/strings.hrc
index dca50c2cd57a..27dd89ba48d1 100644
--- a/cui/inc/strings.hrc
+++ b/cui/inc/strings.hrc
@@ -89,8 +89,10 @@
 #define RID_SVXSTR_ERR_TEXTNOTFOUND                 NC_("RID_SVXSTR_ERR_TEXTNOTFOUND", "No alternatives found.")
 #define RID_SVXSTR_SELECT_FILE_IFRAME               NC_("RID_SVXSTR_SELECT_FILE_IFRAME", "Select File for Floating Frame")
 #define RID_SVXSTR_ALLFUNCTIONS                     NC_("RID_SVXSTR_ALLFUNCTIONS", "All categories")
+#define RID_SVXSTR_MACROS                           NC_("RID_SVXSTR_MACROS", "Macros")
 #define RID_SVXSTR_MYMACROS                         NC_("RID_SVXSTR_MYMACROS", "My Macros")
 #define RID_SVXSTR_PRODMACROS                       NC_("RID_SVXSTR_PRODMACROS", "%PRODUCTNAME Macros")
+#define RID_SVXSTR_NOMACRODESC                      NC_("RID_SVXSTR_NOMACRODESC", "There is no description available for this macro.")
 #define RID_SVXSTR_SELECTOR_ADD_COMMANDS            NC_("RID_SVXSTR_SELECTOR_ADD_COMMANDS", "Add Commands")
 #define RID_SVXSTR_SELECTOR_RUN                     NC_("RID_SVXSTR_SELECTOR_RUN", "Run")
 #define RID_SVXSTR_ROW                              NC_("RID_SVXSTR_ROW", "Insert Rows")
diff --git a/cui/source/customize/CommandCategoryListBox.cxx b/cui/source/customize/CommandCategoryListBox.cxx
index 1763196db5ab..ae100bf0bc03 100644
--- a/cui/source/customize/CommandCategoryListBox.cxx
+++ b/cui/source/customize/CommandCategoryListBox.cxx
@@ -20,9 +20,15 @@
 #include <CommandCategoryListBox.hxx>
 #include <svtools/treelistentry.hxx>
 
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/frame/XDispatchInformationProvider.hpp>
 #include <com/sun/star/frame/theUICommandDescription.hpp>
 #include <com/sun/star/ui/theUICategoryDescription.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
+#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
 #include <vcl/builderfactory.hxx>
 
 // include search util
@@ -65,8 +71,7 @@ void CommandCategoryListBox::dispose()
 
 void CommandCategoryListBox::ClearAll()
 {
-    //TODO: Handle SfxCfgKind::GROUP_SCRIPTCONTAINER when it gets added to Init
-    // Clear style info objects from m_aGroupInfo vector to avoid memory leak
+    // Clear objects from m_aGroupInfo vector to avoid memory leak
     for (const auto & It : m_aGroupInfo)
     {
         if ( It->nKind == SfxCfgKind::GROUP_STYLES && It->pObject )
@@ -74,6 +79,19 @@ void CommandCategoryListBox::ClearAll()
             SfxStyleInfo_Impl* pStyle = static_cast<SfxStyleInfo_Impl*>(It->pObject);
             delete pStyle;
         }
+        else if ( It->nKind == SfxCfgKind::FUNCTION_SCRIPT && It->pObject )
+        {
+            OUString* pScriptURI = static_cast<OUString*>(It->pObject);
+            delete pScriptURI;
+        }
+        else if ( It->nKind == SfxCfgKind::GROUP_SCRIPTCONTAINER && It->pObject)
+        {
+            css::uno::XInterface* xi = static_cast<css::uno::XInterface *>(It->pObject);
+            if (xi != nullptr)
+            {
+                xi->release();
+            }
+        }
     }
 
     m_aGroupInfo.clear();
@@ -85,6 +103,7 @@ void CommandCategoryListBox::Init(
         const css::uno::Reference< css::frame::XFrame >& xFrame,
         const OUString& sModuleLongName)
 {
+    // User will not see incomplete UI
     SetUpdateMode(false);
     ClearAll();
 
@@ -107,7 +126,6 @@ void CommandCategoryListBox::Init(
     m_aStylesInfo.init(sModuleLongName, xModel);
     SetStylesInfo(&m_aStylesInfo);
 
-/**** InitModule Start ****/
     try
     {
         css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider(m_xFrame, css::uno::UNO_QUERY_THROW);
@@ -143,23 +161,32 @@ void CommandCategoryListBox::Init(
             }
 
             nEntryPos = InsertEntry( sGroupName );
-            m_aGroupInfo.push_back( o3tl::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_FUNCTION, rGroupID ) );
+            m_aGroupInfo.push_back(
+              o3tl::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_FUNCTION, rGroupID ) );
             SetEntryData( nEntryPos, m_aGroupInfo.back().get() );
         }
 
-        // Add styles
+        // Add macros category
+        OUString sMacros( CuiResId(RID_SVXSTR_MACROS) );
+        nEntryPos = InsertEntry( sMacros );
+        m_aGroupInfo.push_back(
+            o3tl::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_SCRIPTCONTAINER, 0, nullptr) );
+        SetEntryData( nEntryPos, m_aGroupInfo.back().get() );
+
+        // Add styles category
         OUString sStyle( CuiResId(RID_SVXSTR_GROUP_STYLES) );
         nEntryPos = InsertEntry( sStyle );
         //TODO: last param should contain user data?
-        m_aGroupInfo.push_back( o3tl::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, nullptr ) );
+        m_aGroupInfo.push_back(
+            o3tl::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, nullptr ) );
         SetEntryData( nEntryPos, m_aGroupInfo.back().get() );
     }
     catch(const css::uno::RuntimeException&)
         { throw; }
     catch(const css::uno::Exception&)
     {}
-/**** InitModule End ****/
 
+    // Reveal the updated UI to user
     SetUpdateMode(true);
     SelectEntryPos(0);
 }
@@ -258,7 +285,6 @@ void CommandCategoryListBox::categorySelected(  const VclPtr<SfxConfigFunctionLi
                 }
             }
 
-
             break;
         }
         case SfxCfgKind::GROUP_FUNCTION:
@@ -271,9 +297,85 @@ void CommandCategoryListBox::categorySelected(  const VclPtr<SfxConfigFunctionLi
             FillFunctionsList( lCommands, pFunctionListBox, filterTerm );
             break;
         }
-        case SfxCfgKind::GROUP_SCRIPTCONTAINER:
+        case SfxCfgKind::GROUP_SCRIPTCONTAINER: //Macros
         {
-            //TODO:Implement
+            SAL_INFO("cui.customize", "** ** About to initialise SF Scripts");
+            // Add Scripting Framework entries
+            css::uno::Reference< css::script::browse::XBrowseNode > rootNode;
+            try
+            {
+                css::uno::Reference< css::script::browse::XBrowseNodeFactory > xFac
+                    = css::script::browse::theBrowseNodeFactory::get( m_xContext );
+                rootNode.set( xFac->createView( css::script::browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
+            }
+            catch( css::uno::Exception& e )
+            {
+                SAL_WARN("cui.customize", "Caught some exception whilst retrieving browse nodes from factory... Exception: " << e);
+                // TODO exception handling
+            }
+
+            if ( rootNode.is() && rootNode.get()->hasChildNodes() )
+            {
+                //We call acquire on the XBrowseNode so that it does not
+                //get autodestructed and become invalid when accessed later.
+                rootNode->acquire();
+
+                m_aGroupInfo.push_back(
+                    o3tl::make_unique<SfxGroupInfo_Impl>(
+                        SfxCfgKind::GROUP_SCRIPTCONTAINER, 0, static_cast<void *>(rootNode.get()) ) );
+
+                // Add main macro groups
+                for ( auto const & childGroup : rootNode.get()->getChildNodes() )
+                {
+                    OUString sUIName;
+                    childGroup.get()->acquire();
+
+                    if ( childGroup.get()->hasChildNodes() )
+                    {
+                        if ( childGroup.get()->getName() == "user" )
+                        {
+                            sUIName = CuiResId( RID_SVXSTR_MYMACROS );
+                        }
+                        else if ( childGroup.get()->getName() == "share" )
+                        {
+                            sUIName = CuiResId( RID_SVXSTR_PRODMACROS );
+                        }
+                        else
+                        {
+                            sUIName = childGroup.get()->getName();
+                        }
+
+                        if (sUIName.isEmpty())
+                        {
+                            continue;
+                        }
+
+                        SvTreeListEntry* pMacroGroup = pFunctionListBox->InsertEntry(
+                                          sUIName,
+                                            Image( BitmapEx(RID_CUIBMP_EXPANDED) ), Image( BitmapEx(RID_CUIBMP_COLLAPSED) ) );
+                        m_aGroupInfo.push_back(
+                            o3tl::make_unique<SfxGroupInfo_Impl>(
+                                SfxCfgKind::GROUP_SCRIPTCONTAINER, 0 ) );
+                        SfxGroupInfo_Impl* pGrpInfo = m_aGroupInfo.back().get();
+                        pMacroGroup->SetUserData(pGrpInfo);
+                        pMacroGroup->EnableChildrenOnDemand();
+
+                        //Add the children and the grand children
+                        addChildren( pMacroGroup, childGroup, pFunctionListBox, filterTerm );
+
+                        // Remove the main group if empty
+                        if (!pMacroGroup->HasChildren())
+                        {
+                            pFunctionListBox->RemoveEntry( pMacroGroup );
+                        }
+                        else if (!filterTerm.isEmpty())
+                        {
+                            pFunctionListBox->Expand( pMacroGroup );
+                        }
+                    }
+                }
+            }
+
             break;
         }
         case SfxCfgKind::GROUP_STYLES:
@@ -335,7 +437,7 @@ void CommandCategoryListBox::categorySelected(  const VclPtr<SfxConfigFunctionLi
                 {
                     pFunctionListBox->RemoveEntry(pFuncEntry);
                 }
-                else
+                else if (!filterTerm.isEmpty())
                 {
                     pFunctionListBox->Expand(pFuncEntry);
                 }
@@ -360,4 +462,95 @@ void CommandCategoryListBox::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
     pStylesInfo = pStyles;
 }
 
+void CommandCategoryListBox::addChildren(
+    SvTreeListEntry* parentEntry, const css::uno::Reference< css::script::browse::XBrowseNode > &parentNode,
+    const VclPtr<SfxConfigFunctionListBox>&  pFunctionListBox, const OUString& filterTerm )
+{
+    // Setup search filter parameters
+    m_searchOptions.searchString = filterTerm;
+    utl::TextSearch textSearch( m_searchOptions );
+
+    for (auto const & child : parentNode.get()->getChildNodes())
+    {
+        // Acquire to prevent auto-destruction
+        child.get()->acquire();
+
+        if (child.get()->hasChildNodes())
+        {
+            OUString sUIName = child.get()->getName();
+
+            SvTreeListEntry* pNewEntry = pFunctionListBox->InsertEntry( sUIName, parentEntry );
+
+            m_aGroupInfo.push_back( o3tl::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SCRIPTCONTAINER,
+                                                                         0, static_cast<void *>( child.get())));
+            pNewEntry->SetUserData( m_aGroupInfo.back().get() );
+
+
+
+            pFunctionListBox->SetExpandedEntryBmp(pNewEntry, Image( BitmapEx(RID_CUIBMP_EXPANDED) ) );
+            pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, Image( BitmapEx(RID_CUIBMP_COLLAPSED) ) );
+            pNewEntry->EnableChildrenOnDemand();
+
+            addChildren(pNewEntry, child, pFunctionListBox, filterTerm);
+
+            // Remove the group if empty
+            if (!pNewEntry->HasChildren())
+                pFunctionListBox->RemoveEntry( pNewEntry );
+            else
+                pFunctionListBox->Expand( pNewEntry );
+
+        }
+        else if ( child.get()->getType() == css::script::browse::BrowseNodeTypes::SCRIPT )
+        {
+            // Prepare for filtering
+            OUString sUIName = child.get()->getName();
+            sal_Int32 aStartPos = 0;
+            sal_Int32 aEndPos = sUIName.getLength();
+
+            // Apply the search filter
+            if (!filterTerm.isEmpty()
+                    && !textSearch.SearchForward( sUIName, &aStartPos, &aEndPos ) )
+            {
+                continue;
+            }
+
+            OUString uri, description;
+
+            css::uno::Reference < css::beans::XPropertySet >xPropSet( child.get(), css::uno::UNO_QUERY );
+
+            if (!xPropSet.is())
+            {
+                continue;
+            }
+
+            css::uno::Any value = xPropSet->getPropertyValue("URI");
+            value >>= uri;
+
+            try
+            {
+                value = xPropSet->getPropertyValue("Description");
+                value >>= description;
+            }
+            catch (css::uno::Exception &) {
+                // do nothing, the description will be empty
+            }
+
+            if (description.isEmpty())
+            {
+                description = CuiResId( RID_SVXSTR_NOMACRODESC );
+            }
+
+            OUString* pScriptURI = new OUString( uri );
+
+            SvTreeListEntry* pNewEntry = pFunctionListBox->InsertEntry( sUIName, parentEntry );
+
+            m_aGroupInfo.push_back( o3tl::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SCRIPT, 0, pScriptURI ));
+            m_aGroupInfo.back()->sCommand = uri;
+            m_aGroupInfo.back()->sLabel = sUIName;
+            m_aGroupInfo.back()->sHelpText = description;
+            pNewEntry->SetUserData( m_aGroupInfo.back().get() );
+        }
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/CommandCategoryListBox.hxx b/cui/source/inc/CommandCategoryListBox.hxx
index a80f80a6f5be..8149cc6f261c 100644
--- a/cui/source/inc/CommandCategoryListBox.hxx
+++ b/cui/source/inc/CommandCategoryListBox.hxx
@@ -64,6 +64,11 @@ public:
                             const OUString& filterTerm = OUString() );
 
     void                SetStylesInfo(SfxStylesInfo_Impl* pStyles);
+
+    // Adds children of the given macro group to the functions list
+    void addChildren(
+        SvTreeListEntry* parentEntry, const css::uno::Reference<com::sun::star::script::browse::XBrowseNode> &parentNode,
+        const VclPtr<SfxConfigFunctionListBox> &pFunctionListBox, const OUString &filterTerm);
 };
 
 #endif // INCLUDED_CUI_SOURCE_INC_COMMANDCATEGORYLISTBOX_HXX


More information about the Libreoffice-commits mailing list