1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include <memory>
22 
23 #include <sal/log.hxx>
24 #include <com/sun/star/uno/Any.hxx>
25 #include <comphelper/processfactory.hxx>
26 #include <sfx2/evntconf.hxx>
27 #include <svl/macitem.hxx>
28 #include <tools/diagnose_ex.h>
29 
30 #include <sfx2/objsh.hxx>
31 #include <eventsupplier.hxx>
32 
33 #include <com/sun/star/beans/PropertyValue.hpp>
34 #include <com/sun/star/container/XNameReplace.hpp>
35 #include <com/sun/star/document/XEventsSupplier.hpp>
36 #include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
37 #include <com/sun/star/uno/Sequence.hxx>
38 #include <com/sun/star/uno/Reference.hxx>
39 
40 
41 using namespace com::sun::star;
42 
43 SfxEventNamesList& SfxEventNamesList::operator=( const SfxEventNamesList& ) = default;
44 
~SfxEventNamesList()45 SfxEventNamesList::~SfxEventNamesList()
46 {
47 }
48 
operator ==(const SfxPoolItem & rAttr) const49 bool SfxEventNamesItem::operator==( const SfxPoolItem& rAttr ) const
50 {
51     assert(SfxPoolItem::operator==(rAttr));
52 
53     const SfxEventNamesList& rOwn = aEventsList;
54     const SfxEventNamesList& rOther = static_cast<const SfxEventNamesItem&>( rAttr ).aEventsList;
55 
56     if ( rOwn.size() != rOther.size() )
57         return false;
58 
59     for ( size_t nNo = 0, nCnt = rOwn.size(); nNo < nCnt; ++nNo )
60     {
61         const SfxEventName &rOwnEvent = rOwn.at( nNo );
62         const SfxEventName &rOtherEvent = rOther.at( nNo );
63         if (    rOwnEvent.mnId != rOtherEvent.mnId ||
64                 rOwnEvent.maEventName != rOtherEvent.maEventName ||
65                 rOwnEvent.maUIName != rOtherEvent.maUIName )
66             return false;
67     }
68 
69     return true;
70 
71 }
72 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const73 bool SfxEventNamesItem::GetPresentation( SfxItemPresentation,
74                                          MapUnit,
75                                          MapUnit,
76                                          OUString &rText,
77                                          const IntlWrapper& ) const
78 {
79     rText.clear();
80     return false;
81 }
82 
Clone(SfxItemPool *) const83 SfxEventNamesItem* SfxEventNamesItem::Clone( SfxItemPool *) const
84 {
85     return new SfxEventNamesItem(*this);
86 }
87 
AddEvent(const OUString & rName,const OUString & rUIName,SvMacroItemId nID)88 void SfxEventNamesItem::AddEvent( const OUString& rName, const OUString& rUIName, SvMacroItemId nID )
89 {
90     aEventsList.push_back( SfxEventName( nID, rName, !rUIName.isEmpty() ? rUIName : rName ) );
91 }
92 
93 
CreateEventData_Impl(const SvxMacro * pMacro)94 static uno::Any CreateEventData_Impl( const SvxMacro *pMacro )
95 {
96 /*
97     This function converts a SvxMacro into an Any containing three
98     properties. These properties are EventType and Script. Possible
99     values for EventType are StarBasic, JavaScript, ...
100     The Script property should contain the URL to the macro and looks
101     like "macro://./standard.module1.main()"
102 
103     If pMacro is NULL, we return an empty property sequence, so PropagateEvent_Impl
104     can delete an event binding.
105 */
106     uno::Any aEventData;
107 
108     if ( pMacro )
109     {
110         if ( pMacro->GetScriptType() == STARBASIC )
111         {
112             uno::Sequence < beans::PropertyValue > aProperties(3);
113             beans::PropertyValue *pValues = aProperties.getArray();
114 
115             pValues[ 0 ].Name = PROP_EVENT_TYPE;
116             pValues[ 0 ].Value <<= OUString("STAR_BASIC");
117 
118             pValues[ 1 ].Name = PROP_LIBRARY;
119             pValues[ 1 ].Value <<= pMacro->GetLibName();
120 
121             pValues[ 2 ].Name = PROP_MACRO_NAME;
122             pValues[ 2 ].Value <<= pMacro->GetMacName();
123 
124             aEventData <<= aProperties;
125         }
126         else if ( pMacro->GetScriptType() == EXTENDED_STYPE )
127         {
128             uno::Sequence < beans::PropertyValue > aProperties(2);
129             beans::PropertyValue *pValues = aProperties.getArray();
130 
131             pValues[ 0 ].Name = PROP_EVENT_TYPE;
132             pValues[ 0 ].Value <<= pMacro->GetLibName();
133 
134             pValues[ 1 ].Name = PROP_SCRIPT;
135             pValues[ 1 ].Value <<= pMacro->GetMacName();
136 
137             aEventData <<= aProperties;
138         }
139         else if ( pMacro->GetScriptType() == JAVASCRIPT )
140         {
141             uno::Sequence < beans::PropertyValue > aProperties(2);
142             beans::PropertyValue *pValues = aProperties.getArray();
143 
144             pValues[ 0 ].Name = PROP_EVENT_TYPE;
145             pValues[ 0 ].Value <<= OUString(SVX_MACRO_LANGUAGE_JAVASCRIPT);
146 
147             pValues[ 1 ].Name = PROP_MACRO_NAME;
148             pValues[ 1 ].Value <<= pMacro->GetMacName();
149 
150             aEventData <<= aProperties;
151         }
152         else
153         {
154             SAL_WARN( "sfx.config", "CreateEventData_Impl(): ScriptType not supported!");
155         }
156     }
157     else
158     {
159         uno::Sequence < beans::PropertyValue > aProperties;
160         aEventData <<= aProperties;
161     }
162 
163     return aEventData;
164 }
165 
166 
PropagateEvent_Impl(SfxObjectShell const * pDoc,const OUString & aEventName,const SvxMacro * pMacro)167 static void PropagateEvent_Impl( SfxObjectShell const *pDoc, const OUString& aEventName, const SvxMacro* pMacro )
168 {
169     uno::Reference < document::XEventsSupplier > xSupplier;
170     if ( pDoc )
171     {
172         xSupplier.set( pDoc->GetModel(), uno::UNO_QUERY );
173     }
174     else
175     {
176         xSupplier = frame::theGlobalEventBroadcaster::get(::comphelper::getProcessComponentContext());
177     }
178 
179     if ( !xSupplier.is() )
180         return;
181 
182     uno::Reference < container::XNameReplace > xEvents = xSupplier->getEvents();
183     if ( !aEventName.isEmpty() )
184     {
185         uno::Any aEventData = CreateEventData_Impl( pMacro );
186 
187         try
188         {
189             xEvents->replaceByName( aEventName, aEventData );
190         }
191         catch( const css::lang::IllegalArgumentException& )
192         {
193             TOOLS_WARN_EXCEPTION( "sfx.config", "PropagateEvents_Impl: caught IllegalArgumentException" );
194         }
195         catch( const css::container::NoSuchElementException& )
196         {
197             TOOLS_WARN_EXCEPTION( "sfx.config", "PropagateEvents_Impl: caught NoSuchElementException" );
198         }
199     }
200     else {
201         SAL_INFO( "sfx.config", "PropagateEvents_Impl: Got unknown event" );
202     }
203 }
204 
205 
ConfigureEvent(const OUString & aName,const SvxMacro & rMacro,SfxObjectShell const * pDoc)206 void SfxEventConfiguration::ConfigureEvent( const OUString& aName, const SvxMacro& rMacro, SfxObjectShell const *pDoc )
207 {
208     std::unique_ptr<SvxMacro> pMacro;
209     if ( rMacro.HasMacro() )
210         pMacro.reset( new SvxMacro( rMacro.GetMacName(), rMacro.GetLibName(), rMacro.GetScriptType() ) );
211     PropagateEvent_Impl( pDoc ? pDoc : nullptr, aName, pMacro.get() );
212 }
213 
214 
ConvertToMacro(const css::uno::Any & rElement,SfxObjectShell * pDoc)215 std::unique_ptr<SvxMacro> SfxEventConfiguration::ConvertToMacro( const css::uno::Any& rElement, SfxObjectShell* pDoc )
216 {
217     return SfxEvents_Impl::ConvertToMacro( rElement, pDoc );
218 }
219 
220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
221