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
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26
27 #include <dispatch/startmoduledispatcher.hxx>
28
29 //_______________________________________________
30 // my own includes
31
32 #include <pattern/frame.hxx>
33 #include <threadhelp/readguard.hxx>
34 #include <threadhelp/writeguard.hxx>
35 #include <framework/framelistanalyzer.hxx>
36 #include <dispatchcommands.h>
37 #include <targets.h>
38 #include <services.h>
39 #include <general.h>
40
41 //_______________________________________________
42 // interface includes
43 #include <com/sun/star/frame/XDesktop.hpp>
44 #include <com/sun/star/frame/XController.hpp>
45 #include <com/sun/star/frame/CommandGroup.hpp>
46 #include <com/sun/star/awt/XTopWindow.hpp>
47 #include "com/sun/star/beans/XFastPropertySet.hpp"
48 #include <com/sun/star/frame/XModuleManager.hpp>
49
50 //_______________________________________________
51 // includes of other projects
52 #include <toolkit/helper/vclunohelper.hxx>
53 #include <vcl/window.hxx>
54 #include <vcl/svapp.hxx>
55 #include <vos/mutex.hxx>
56 #include <unotools/moduleoptions.hxx>
57
58 //_______________________________________________
59 // namespace
60
61 namespace framework{
62
63 #ifdef fpf
64 #error "Who uses \"fpf\" as define. It will overwrite my namespace alias ..."
65 #endif
66 namespace fpf = ::framework::pattern::frame;
67
68 //_______________________________________________
69 // declarations
70
DEFINE_XINTERFACE_4(StartModuleDispatcher,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::frame::XNotifyingDispatch),DIRECT_INTERFACE (css::frame::XDispatch),DIRECT_INTERFACE (css::frame::XDispatchInformationProvider))71 DEFINE_XINTERFACE_4(StartModuleDispatcher ,
72 OWeakObject ,
73 DIRECT_INTERFACE(css::lang::XTypeProvider ),
74 DIRECT_INTERFACE(css::frame::XNotifyingDispatch ),
75 DIRECT_INTERFACE(css::frame::XDispatch ),
76 DIRECT_INTERFACE(css::frame::XDispatchInformationProvider))
77
78 // Note: XStatusListener is an implementation detail. Hide it for scripting!
79 DEFINE_XTYPEPROVIDER_4(StartModuleDispatcher ,
80 css::lang::XTypeProvider ,
81 css::frame::XDispatchInformationProvider,
82 css::frame::XNotifyingDispatch ,
83 css::frame::XDispatch )
84
85 //-----------------------------------------------
86 StartModuleDispatcher::StartModuleDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
87 const css::uno::Reference< css::frame::XFrame >& xFrame ,
88 const ::rtl::OUString& sTarget)
89 : ThreadHelpBase (&Application::GetSolarMutex() )
90 , ::cppu::OWeakObject( )
91 , m_xSMGR (xSMGR )
92 , m_xOwner (xFrame )
93 , m_sDispatchTarget (sTarget )
94 , m_lStatusListener (m_aLock.getShareableOslMutex())
95 {
96 }
97
98 //-----------------------------------------------
~StartModuleDispatcher()99 StartModuleDispatcher::~StartModuleDispatcher()
100 {
101 }
102
103 //-----------------------------------------------
dispatch(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> & lArguments)104 void SAL_CALL StartModuleDispatcher::dispatch(const css::util::URL& aURL ,
105 const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
106 throw(css::uno::RuntimeException)
107 {
108 dispatchWithNotification(aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
109 }
110
111 //-----------------------------------------------
dispatchWithNotification(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> &,const css::uno::Reference<css::frame::XDispatchResultListener> & xListener)112 void SAL_CALL StartModuleDispatcher::dispatchWithNotification(const css::util::URL& aURL ,
113 const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/,
114 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
115 throw(css::uno::RuntimeException)
116 {
117 ::sal_Int16 nResult = css::frame::DispatchResultState::DONTKNOW;
118 if (aURL.Complete.equals (CMD_UNO_SHOWSTARTMODULE))
119 {
120 nResult = css::frame::DispatchResultState::FAILURE;
121 if (implts_isBackingModePossible ())
122 {
123 if (implts_establishBackingMode ())
124 nResult = css::frame::DispatchResultState::SUCCESS;
125 }
126 }
127
128 implts_notifyResultListener(xListener, nResult, css::uno::Any());
129 }
130
131 //-----------------------------------------------
getSupportedCommandGroups()132 css::uno::Sequence< ::sal_Int16 > SAL_CALL StartModuleDispatcher::getSupportedCommandGroups()
133 throw(css::uno::RuntimeException)
134 {
135 return css::uno::Sequence< ::sal_Int16 >();
136 }
137
138 //-----------------------------------------------
getConfigurableDispatchInformation(::sal_Int16)139 css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL StartModuleDispatcher::getConfigurableDispatchInformation(::sal_Int16 /*nCommandGroup*/)
140 throw(css::uno::RuntimeException)
141 {
142 return css::uno::Sequence< css::frame::DispatchInformation >();
143 }
144
145 //-----------------------------------------------
addStatusListener(const css::uno::Reference<css::frame::XStatusListener> &,const css::util::URL &)146 void SAL_CALL StartModuleDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
147 const css::util::URL& /*aURL*/ )
148 throw(css::uno::RuntimeException)
149 {
150 }
151
152 //-----------------------------------------------
removeStatusListener(const css::uno::Reference<css::frame::XStatusListener> &,const css::util::URL &)153 void SAL_CALL StartModuleDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
154 const css::util::URL& /*aURL*/ )
155 throw(css::uno::RuntimeException)
156 {
157 }
158
159 //-----------------------------------------------
implts_isBackingModePossible()160 ::sal_Bool StartModuleDispatcher::implts_isBackingModePossible ()
161 {
162 if ( ! SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE))
163 return sal_False;
164
165 // SAFE -> ----------------------------------
166 ReadGuard aReadLock(m_aLock);
167 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
168 aReadLock.unlock();
169 // <- SAFE ----------------------------------
170
171 css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
172 xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
173
174 FrameListAnalyzer aCheck(
175 xDesktop,
176 css::uno::Reference< css::frame::XFrame >(),
177 FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);
178
179 ::sal_Bool bIsPossible = sal_False;
180 ::sal_Int32 nVisibleFrames = aCheck.m_lOtherVisibleFrames.getLength ();
181
182 if (
183 ( ! aCheck.m_xBackingComponent.is ()) &&
184 ( nVisibleFrames < 1 )
185 )
186 {
187 bIsPossible = sal_True;
188 }
189
190 return bIsPossible;
191 }
192
193 //-----------------------------------------------
implts_establishBackingMode()194 ::sal_Bool StartModuleDispatcher::implts_establishBackingMode()
195 {
196 // SAFE -> ----------------------------------
197 ReadGuard aReadLock(m_aLock);
198 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
199 aReadLock.unlock();
200 // <- SAFE ----------------------------------
201
202 css::uno::Reference< css::frame::XFrame > xDesktop (xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
203 css::uno::Reference< css::frame::XFrame > xFrame = xDesktop->findFrame (SPECIALTARGET_BLANK, 0);
204 css::uno::Reference< css::awt::XWindow > xContainerWindow = xFrame->getContainerWindow ();
205
206 css::uno::Sequence< css::uno::Any > lArgs(1);
207 lArgs[0] <<= xContainerWindow;
208
209 css::uno::Reference< css::frame::XController > xStartModule(
210 xSMGR->createInstanceWithArguments(SERVICENAME_STARTMODULE, lArgs),
211 css::uno::UNO_QUERY_THROW);
212
213 css::uno::Reference< css::awt::XWindow > xComponentWindow(xStartModule, css::uno::UNO_QUERY);
214 xFrame->setComponent(xComponentWindow, xStartModule);
215 xStartModule->attachFrame(xFrame);
216 xContainerWindow->setVisible(sal_True);
217
218 return sal_True;
219 }
220
221 //-----------------------------------------------
implts_notifyResultListener(const css::uno::Reference<css::frame::XDispatchResultListener> & xListener,::sal_Int16 nState,const css::uno::Any & aResult)222 void StartModuleDispatcher::implts_notifyResultListener(const css::uno::Reference< css::frame::XDispatchResultListener >& xListener,
223 ::sal_Int16 nState ,
224 const css::uno::Any& aResult )
225 {
226 if ( ! xListener.is())
227 return;
228
229 css::frame::DispatchResultEvent aEvent(
230 css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY),
231 nState,
232 aResult);
233
234 xListener->dispatchFinished(aEvent);
235 }
236
237 } // namespace framework
238