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 //_______________________________________________
28 // my own includes
29
30 #include <dispatch/windowcommanddispatch.hxx>
31 #include <threadhelp/readguard.hxx>
32 #include <threadhelp/writeguard.hxx>
33 #include <targets.h>
34 #include <services.h>
35
36 //_______________________________________________
37 // interface includes
38
39 #include <com/sun/star/frame/XDispatchProvider.hpp>
40 #include <com/sun/star/frame/XDispatch.hpp>
41 #include <com/sun/star/util/XURLTransformer.hpp>
42
43 //_______________________________________________
44 // includes of other projects
45
46 #include <vcl/window.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/cmdevt.hxx>
49 #include <vos/mutex.hxx>
50 #include <toolkit/helper/vclunohelper.hxx>
51 #include <rtl/logfile.hxx>
52
53 //_______________________________________________
54 // namespace
55
56 namespace framework{
57
58 namespace css = ::com::sun::star;
59
60 //_______________________________________________
61 // declarations
62
63 const ::rtl::OUString WindowCommandDispatch::COMMAND_PREFERENCES = ::rtl::OUString::createFromAscii(".uno:OptionsTreeDialog");
64 const ::rtl::OUString WindowCommandDispatch::COMMAND_ABOUTBOX = ::rtl::OUString::createFromAscii(".uno:About");
65
66 //-----------------------------------------------
WindowCommandDispatch(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,const css::uno::Reference<css::frame::XFrame> & xFrame)67 WindowCommandDispatch::WindowCommandDispatch(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
68 const css::uno::Reference< css::frame::XFrame >& xFrame)
69 : ThreadHelpBase( )
70 , m_xSMGR (xSMGR )
71 , m_xFrame (xFrame )
72 , m_xWindow (xFrame->getContainerWindow())
73 {
74 impl_startListening();
75 }
76
77 //-----------------------------------------------
~WindowCommandDispatch()78 WindowCommandDispatch::~WindowCommandDispatch()
79 {
80 m_xSMGR.clear();
81 }
82
83 //-----------------------------------------------
disposing(const css::lang::EventObject &)84 void SAL_CALL WindowCommandDispatch::disposing(const css::lang::EventObject& /*aSource*/)
85 throw (css::uno::RuntimeException)
86 {
87 // We hold our window weak ... so there is no need to clear it's reference here.
88 // The window and we will die by ref count automatically.
89 }
90
91 //-----------------------------------------------
impl_startListening()92 void WindowCommandDispatch::impl_startListening()
93 {
94 // SYNCHRONIZED ->
95 ReadGuard aReadLock(m_aLock);
96 css::uno::Reference< css::awt::XWindow > xWindow( m_xWindow.get(), css::uno::UNO_QUERY );
97 aReadLock.unlock();
98 // <- SYNCHRONIZED
99
100 if ( ! xWindow.is())
101 return;
102
103 // SYNCHRONIZED ->
104 ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());
105
106 Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
107 if ( ! pWindow)
108 return;
109
110 pWindow->AddEventListener( LINK(this, WindowCommandDispatch, impl_notifyCommand) );
111
112 aSolarLock.clear();
113 // <- SYNCHRONIZED
114 }
115
116 //-----------------------------------------------
IMPL_LINK(WindowCommandDispatch,impl_notifyCommand,void *,pParam)117 IMPL_LINK(WindowCommandDispatch, impl_notifyCommand, void*, pParam)
118 {
119 if ( ! pParam)
120 return 0L;
121
122 const VclWindowEvent* pEvent = (VclWindowEvent*)pParam;
123 if (pEvent->GetId() != VCLEVENT_WINDOW_COMMAND)
124 return 0L;
125
126 const CommandEvent* pCommand = (CommandEvent*)pEvent->GetData();
127 if (pCommand->GetCommand() != COMMAND_SHOWDIALOG)
128 return 0L;
129
130 const CommandDialogData* pData = pCommand->GetDialogData();
131 if ( ! pData)
132 return 0L;
133
134 const int nCommand = pData->GetDialogId();
135 ::rtl::OUString sCommand;
136
137 switch (nCommand)
138 {
139 case SHOWDIALOG_ID_PREFERENCES :
140 sCommand = WindowCommandDispatch::COMMAND_PREFERENCES;
141 break;
142
143 case SHOWDIALOG_ID_ABOUT :
144 sCommand = WindowCommandDispatch::COMMAND_ABOUTBOX;
145 break;
146
147 default :
148 return 0L;
149 }
150
151 impl_dispatchCommand(sCommand);
152
153 return 0L;
154 }
155
156 //-----------------------------------------------
impl_dispatchCommand(const::rtl::OUString & sCommand)157 void WindowCommandDispatch::impl_dispatchCommand(const ::rtl::OUString& sCommand)
158 {
159 // ignore all errors here. It's clicking a menu entry only ...
160 // The user will try it again, in case nothing happens .-)
161 try
162 {
163 // SYNCHRONIZED ->
164 ReadGuard aReadLock(m_aLock);
165 css::uno::Reference< css::frame::XDispatchProvider > xProvider(m_xFrame.get(), css::uno::UNO_QUERY_THROW);
166 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
167 aReadLock.unlock();
168 // <- SYNCHRONIZED
169
170 // check provider ... we know it's weak reference only
171 if ( ! xProvider.is())
172 return;
173
174 css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
175 css::util::URL aCommand;
176 aCommand.Complete = sCommand;
177 xParser->parseStrict(aCommand);
178
179 css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aCommand, SPECIALTARGET_SELF, 0);
180 if (xDispatch.is())
181 xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
182 }
183 catch(const css::uno::Exception&)
184 {}
185 }
186
187 } // namespace framework
188