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