1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #include <com/sun/star/lang/XServiceInfo.hpp>
24 #include <com/sun/star/frame/XDesktop.hpp>
25 #include <com/sun/star/container/XNameAccess.hpp>
26 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
27 #include <com/sun/star/ui/XUIConfigurationStorage.hpp>
28 #include <com/sun/star/ui/XModuleUIConfigurationManager.hpp>
29 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
30 #include <ooo/vba/office/MsoBarType.hpp>
31 
32 #include "vbacommandbars.hxx"
33 #include "vbacommandbar.hxx"
34 
35 using namespace com::sun::star;
36 using namespace ooo::vba;
37 
38 
39 typedef ::cppu::WeakImplHelper1< container::XEnumeration > CommandBarEnumeration_BASE;
40 
41 class CommandBarEnumeration : public CommandBarEnumeration_BASE
42 {
43     uno::Reference< XHelperInterface > m_xParent;
44     uno::Reference< uno::XComponentContext > m_xContext;
45     VbaCommandBarHelperRef m_pCBarHelper;
46     uno::Sequence< rtl::OUString > m_sNames;
47     sal_Int32 m_nCurrentPosition;
48 public:
CommandBarEnumeration(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,VbaCommandBarHelperRef pHelper)49     CommandBarEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, VbaCommandBarHelperRef pHelper) throw ( uno::RuntimeException ) : m_xParent( xParent ), m_xContext( xContext ), m_pCBarHelper( pHelper ) , m_nCurrentPosition( 0 )
50     {
51         uno::Reference< container::XNameAccess > xNameAccess = m_pCBarHelper->getPersistentWindowState();
52         m_sNames = xNameAccess->getElementNames();
53     }
hasMoreElements()54     virtual sal_Bool SAL_CALL hasMoreElements() throw ( uno::RuntimeException )
55     {
56         if( m_nCurrentPosition < m_sNames.getLength() )
57             return sal_True;
58         return sal_False;
59     }
nextElement()60     virtual uno::Any SAL_CALL nextElement() throw ( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
61     {
62         // FIXME: should be add menubar
63         if( hasMoreElements() )
64         {
65             rtl::OUString sResourceUrl( m_sNames[ m_nCurrentPosition++ ] );
66             if( sResourceUrl.indexOf( rtl::OUString::createFromAscii("private:resource/toolbar/") ) != -1 )
67             {
68                 uno::Reference< container::XIndexAccess > xCBarSetting = m_pCBarHelper->getSettings( sResourceUrl );
69                 uno::Reference< XCommandBar > xCommandBar( new ScVbaCommandBar( m_xParent, m_xContext, m_pCBarHelper, xCBarSetting, sResourceUrl, sal_False, sal_False ) );
70              }
71              else
72                 return nextElement();
73         }
74         else
75             throw container::NoSuchElementException();
76         return uno::Any();
77     }
78 };
79 
ScVbaCommandBars(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<container::XIndexAccess> & xIndexAccess,const uno::Reference<frame::XModel> & xModel)80 ScVbaCommandBars::ScVbaCommandBars( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : CommandBars_BASE( xParent, xContext, xIndexAccess )
81 {
82     m_pCBarHelper.reset( new VbaCommandBarHelper( mxContext, xModel ) );
83     m_xNameAccess = m_pCBarHelper->getPersistentWindowState();
84 }
85 
~ScVbaCommandBars()86 ScVbaCommandBars::~ScVbaCommandBars()
87 {
88 }
89 
90 // XEnumerationAccess
91 uno::Type SAL_CALL
getElementType()92 ScVbaCommandBars::getElementType() throw ( uno::RuntimeException )
93 {
94     return XCommandBar::static_type( 0 );
95 }
96 
97 uno::Reference< container::XEnumeration >
createEnumeration()98 ScVbaCommandBars::createEnumeration() throw ( uno::RuntimeException )
99 {
100     return uno::Reference< container::XEnumeration >( new CommandBarEnumeration( this, mxContext, m_pCBarHelper ) );
101 }
102 
103 uno::Any
createCollectionObject(const uno::Any & aSource)104 ScVbaCommandBars::createCollectionObject( const uno::Any& aSource )
105 {
106     // aSource should be a name at this time, because of the class is API wrapper.
107     rtl::OUString sResourceUrl;
108     uno::Reference< container::XIndexAccess > xBarSettings;
109     rtl::OUString sBarName;
110     sal_Bool bMenu = sal_False;
111     uno::Any aRet;
112 
113     if( aSource >>= sBarName )
114     {
115         // some built-in command bars
116         if( m_pCBarHelper->getModuleId().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.sheet.SpreadsheetDocument") ) )
117         {
118             if( sBarName.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM("Worksheet Menu Bar") ) )
119             {
120                 // spreadsheet menu bar
121                 sResourceUrl = rtl::OUString::createFromAscii( ITEM_MENUBAR_URL );
122                 bMenu = sal_True;
123             }
124             else if( sBarName.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM("Cell") ) )
125             {
126                 // EVIL HACK (tm): spreadsheet cell context menu as dummy object without functionality
127                 aRet <<= uno::Reference< XCommandBar >( new VbaDummyCommandBar( this, mxContext, sBarName, office::MsoBarType::msoBarTypePopup ) );
128             }
129         }
130         else if( m_pCBarHelper->getModuleId().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.text.TextDocument") ) )
131         {
132             if( sBarName.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM("Menu Bar") ) )
133             {
134                 // text processor menu bar
135                 sResourceUrl = rtl::OUString::createFromAscii( ITEM_MENUBAR_URL );
136                 bMenu = sal_True;
137             }
138         }
139 
140         // nothing found - try to resolve from name
141         if( !aRet.hasValue() && (sResourceUrl.getLength() == 0) )
142         {
143             sResourceUrl = m_pCBarHelper->findToolbarByName( m_xNameAccess, sBarName );
144             bMenu = sal_False;
145         }
146     }
147 
148     if( sResourceUrl.getLength() )
149     {
150         xBarSettings = m_pCBarHelper->getSettings( sResourceUrl );
151         aRet <<= uno::Reference< XCommandBar >( new ScVbaCommandBar( this, mxContext, m_pCBarHelper, xBarSettings, sResourceUrl, bMenu, sal_False ) );
152     }
153 
154     if( !aRet.hasValue() )
155         throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Toolbar do not exist") ), uno::Reference< uno::XInterface >() );
156 
157     return aRet;
158 }
159 
160 // XCommandBars
161 uno::Reference< XCommandBar > SAL_CALL
Add(const css::uno::Any & Name,const css::uno::Any &,const css::uno::Any &,const css::uno::Any & Temporary)162 ScVbaCommandBars::Add( const css::uno::Any& Name, const css::uno::Any& /*Position*/, const css::uno::Any& /*MenuBar*/, const css::uno::Any& Temporary ) throw (css::script::BasicErrorException, css::uno::RuntimeException)
163 {
164     // FIXME: only support to add Toolbar
165     // Position - MsoBar MenuBar - sal_Bool
166     // Currently only the Name is supported.
167     rtl::OUString sName;
168     if( Name.hasValue() )
169         Name >>= sName;
170 
171     rtl::OUString sResourceUrl;
172     if( sName.getLength() )
173     {
174         sResourceUrl = m_pCBarHelper->findToolbarByName( m_xNameAccess, sName );
175         if( sResourceUrl.getLength() )
176             throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Toolbar exists") ), uno::Reference< uno::XInterface >() );
177     }
178     else
179     {
180         sName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Custom1") );
181     }
182 
183     sal_Bool bTemporary = sal_False;
184     if( Temporary.hasValue() )
185         Temporary >>= bTemporary;
186 
187     sResourceUrl = VbaCommandBarHelper::generateCustomURL();
188     uno::Reference< container::XIndexAccess > xBarSettings( m_pCBarHelper->getSettings( sResourceUrl ), uno::UNO_QUERY_THROW );
189     uno::Reference< XCommandBar > xCBar( new ScVbaCommandBar( this, mxContext, m_pCBarHelper, xBarSettings, sResourceUrl, sal_False, bTemporary ) );
190     xCBar->setName( sName );
191     return xCBar;
192 }
193 sal_Int32 SAL_CALL
getCount()194 ScVbaCommandBars::getCount() throw(css::uno::RuntimeException)
195 {
196     // Filter out all toolbars from the window collection
197     sal_Int32 nCount = 1; // there is a Menubar in OOo
198     uno::Sequence< ::rtl::OUString > allNames = m_xNameAccess->getElementNames();
199     for( sal_Int32 i = 0; i < allNames.getLength(); i++ )
200     {
201         if(allNames[i].indexOf( rtl::OUString::createFromAscii("private:resource/toolbar/") ) != -1 )
202         {
203             nCount++;
204         }
205     }
206     return nCount;
207 }
208 
209 // ScVbaCollectionBaseImpl
210 uno::Any SAL_CALL
Item(const uno::Any & aIndex,const uno::Any &)211 ScVbaCommandBars::Item( const uno::Any& aIndex, const uno::Any& /*aIndex2*/ ) throw( uno::RuntimeException )
212 {
213     if( aIndex.getValueTypeClass() == uno::TypeClass_STRING )
214     {
215         return createCollectionObject( aIndex );
216     }
217 
218     // hardcode if "aIndex = 1" that would return "main menu".
219     sal_Int16 nIndex = 0;
220     aIndex >>= nIndex;
221     if( nIndex == 1 )
222     {
223         uno::Any aSource;
224         if( m_pCBarHelper->getModuleId().equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" ) )
225             aSource <<= rtl::OUString::createFromAscii( "Worksheet Menu Bar" );
226         else if( m_pCBarHelper->getModuleId().equalsAscii("com.sun.star.text.TextDocument") )
227             aSource <<= rtl::OUString::createFromAscii( "Menu Bar" );
228         if( aSource.hasValue() )
229             return createCollectionObject( aSource );
230     }
231     return uno::Any();
232 }
233 
234 // XHelperInterface
235 rtl::OUString&
getServiceImplName()236 ScVbaCommandBars::getServiceImplName()
237 {
238     static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaCommandBars") );
239     return sImplName;
240 }
241 uno::Sequence<rtl::OUString>
getServiceNames()242 ScVbaCommandBars::getServiceNames()
243 {
244     static uno::Sequence< rtl::OUString > aServiceNames;
245     if ( aServiceNames.getLength() == 0 )
246     {
247         aServiceNames.realloc( 1 );
248         aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.CommandBars" ) );
249     }
250     return aServiceNames;
251 }
252 
253