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 #include "precompiled_sfx2.hxx"
23
24 #include "sfx2/sidebar/CommandInfoProvider.hxx"
25
26 #include <comphelper/processfactory.hxx>
27 #include <svtools/acceleratorexecute.hxx>
28 #include <cppuhelper/compbase1.hxx>
29 #include <cppuhelper/basemutex.hxx>
30
31 #include <com/sun/star/frame/XModuleManager.hpp>
32 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
33 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
34
35 using namespace css;
36 using namespace cssu;
37 using ::rtl::OUString;
38
39
40 #define A2S(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
41
42
43 namespace
44 {
45 typedef ::cppu::WeakComponentImplHelper1 <
46 css::lang::XEventListener
47 > FrameListenerInterfaceBase;
48 class FrameListener
49 : public ::cppu::BaseMutex,
50 public FrameListenerInterfaceBase
51 {
52 public:
FrameListener(sfx2::sidebar::CommandInfoProvider & rInfoProvider,const Reference<frame::XFrame> & rxFrame)53 FrameListener (sfx2::sidebar::CommandInfoProvider& rInfoProvider, const Reference<frame::XFrame>& rxFrame)
54 : FrameListenerInterfaceBase(m_aMutex),
55 mrInfoProvider(rInfoProvider),
56 mxFrame(rxFrame)
57 {
58 if (mxFrame.is())
59 mxFrame->addEventListener(this);
60 }
~FrameListener(void)61 virtual ~FrameListener (void)
62 {
63 }
disposing(void)64 virtual void SAL_CALL disposing (void)
65 {
66 if (mxFrame.is())
67 mxFrame->removeEventListener(this);
68 }
disposing(const css::lang::EventObject & rEvent)69 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
70 throw (cssu::RuntimeException)
71 {
72 (void)rEvent;
73 mrInfoProvider.SetFrame(NULL);
74 mxFrame = NULL;
75 }
76
77 private:
78 sfx2::sidebar::CommandInfoProvider& mrInfoProvider;
79 Reference<frame::XFrame> mxFrame;
80 };
81 }
82
83
84
85 namespace sfx2 { namespace sidebar {
86
Instance(void)87 CommandInfoProvider& CommandInfoProvider::Instance (void)
88 {
89 static CommandInfoProvider aProvider;
90 return aProvider;
91 }
92
93
94
95
CommandInfoProvider(void)96 CommandInfoProvider::CommandInfoProvider (void)
97 : mxServiceFactory(comphelper::getProcessServiceFactory()),
98 mxCachedDataFrame(),
99 mxCachedDocumentAcceleratorConfiguration(),
100 mxCachedModuleAcceleratorConfiguration(),
101 mxCachedGlobalAcceleratorConfiguration(),
102 msCachedModuleIdentifier(),
103 mxFrameListener()
104 {
105 }
106
107
108
109
~CommandInfoProvider(void)110 CommandInfoProvider::~CommandInfoProvider (void)
111 {
112 if (mxFrameListener.is())
113 {
114 mxFrameListener->dispose();
115 mxFrameListener = NULL;
116 }
117 }
118
119
120
121
GetLabelForCommand(const OUString & rsCommandName,const Reference<frame::XFrame> & rxFrame)122 OUString CommandInfoProvider::GetLabelForCommand (
123 const OUString& rsCommandName,
124 const Reference<frame::XFrame>& rxFrame)
125 {
126 SetFrame(rxFrame);
127
128 const OUString sLabel (GetCommandLabel(rsCommandName));
129 const OUString sShortCut (GetCommandShortcut(rsCommandName));
130 if (sShortCut.getLength() > 0)
131 return sLabel + A2S(" (") + sShortCut + A2S(")");
132 else
133 return sLabel;
134 }
135
136
137
138
SetFrame(const Reference<frame::XFrame> & rxFrame)139 void CommandInfoProvider::SetFrame (const Reference<frame::XFrame>& rxFrame)
140 {
141 if (rxFrame != mxCachedDataFrame)
142 {
143 // Detach from the old frame.
144 if (mxFrameListener.is())
145 {
146 mxFrameListener->dispose();
147 mxFrameListener = NULL;
148 }
149
150 // Release objects that are tied to the old frame.
151 mxCachedDocumentAcceleratorConfiguration = NULL;
152 mxCachedModuleAcceleratorConfiguration = NULL;
153 msCachedModuleIdentifier = OUString();
154 mxCachedDataFrame = rxFrame;
155
156 // Connect to the new frame.
157 if (rxFrame.is())
158 mxFrameListener = new FrameListener(*this, rxFrame);
159 }
160 }
161
162
163
164
GetDocumentAcceleratorConfiguration(void)165 Reference<ui::XAcceleratorConfiguration> CommandInfoProvider::GetDocumentAcceleratorConfiguration (void)
166 {
167 if ( ! mxCachedDocumentAcceleratorConfiguration.is())
168 {
169 // Get the accelerator configuration for the document.
170 if (mxCachedDataFrame.is())
171 {
172 Reference<frame::XController> xController = mxCachedDataFrame->getController();
173 if (xController.is())
174 {
175 Reference<frame::XModel> xModel (xController->getModel());
176 if (xModel.is())
177 {
178 Reference<ui::XUIConfigurationManagerSupplier> xSupplier (xModel, UNO_QUERY);
179 if (xSupplier.is())
180 {
181 Reference<ui::XUIConfigurationManager> xConfigurationManager(
182 xSupplier->getUIConfigurationManager(),
183 UNO_QUERY);
184 if (xConfigurationManager.is())
185 {
186 mxCachedDocumentAcceleratorConfiguration = Reference<ui::XAcceleratorConfiguration>(
187 xConfigurationManager->getShortCutManager(),
188 UNO_QUERY);
189 }
190 }
191 }
192 }
193 }
194 }
195 return mxCachedDocumentAcceleratorConfiguration;
196 }
197
198
199
200
GetModuleAcceleratorConfiguration(void)201 Reference<ui::XAcceleratorConfiguration> CommandInfoProvider::GetModuleAcceleratorConfiguration (void)
202 {
203 if ( ! mxCachedModuleAcceleratorConfiguration.is())
204 {
205 try
206 {
207 Reference<ui::XModuleUIConfigurationManagerSupplier> xSupplier (
208 mxServiceFactory->createInstance(A2S("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")),
209 UNO_QUERY);
210 Reference<ui::XUIConfigurationManager> xManager (
211 xSupplier->getUIConfigurationManager(GetModuleIdentifier()));
212 if (xManager.is())
213 {
214 mxCachedModuleAcceleratorConfiguration = Reference<ui::XAcceleratorConfiguration>(
215 xManager->getShortCutManager(),
216 UNO_QUERY);
217 }
218 }
219 catch (Exception&)
220 {
221 }
222 }
223 return mxCachedModuleAcceleratorConfiguration;
224 }
225
226
227
228
GetGlobalAcceleratorConfiguration(void)229 Reference<ui::XAcceleratorConfiguration> CommandInfoProvider::GetGlobalAcceleratorConfiguration (void)
230 {
231 // Get the global accelerator configuration.
232 if ( ! mxCachedGlobalAcceleratorConfiguration.is())
233 {
234 mxCachedGlobalAcceleratorConfiguration = Reference<ui::XAcceleratorConfiguration>(
235 mxServiceFactory->createInstance(A2S("com.sun.star.ui.GlobalAcceleratorConfiguration")),
236 UNO_QUERY);
237 }
238
239 return mxCachedGlobalAcceleratorConfiguration;
240 }
241
242
243
244
GetModuleIdentifier(void)245 OUString CommandInfoProvider::GetModuleIdentifier (void)
246 {
247 if (msCachedModuleIdentifier.getLength() == 0)
248 {
249 Reference<frame::XModuleManager> xModuleManager (
250 mxServiceFactory->createInstance(A2S("com.sun.star.frame.ModuleManager")),
251 UNO_QUERY);
252 if (xModuleManager.is())
253 msCachedModuleIdentifier = xModuleManager->identify(mxCachedDataFrame);
254 }
255 return msCachedModuleIdentifier;
256 }
257
258
259
260
GetCommandShortcut(const OUString & rsCommandName)261 OUString CommandInfoProvider::GetCommandShortcut (const OUString& rsCommandName)
262 {
263 OUString sShortcut;
264
265 sShortcut = RetrieveShortcutsFromConfiguration(GetDocumentAcceleratorConfiguration(), rsCommandName);
266 if (sShortcut.getLength() > 0)
267 return sShortcut;
268
269 sShortcut = RetrieveShortcutsFromConfiguration(GetModuleAcceleratorConfiguration(), rsCommandName);
270 if (sShortcut.getLength() > 0)
271 return sShortcut;
272
273 sShortcut = RetrieveShortcutsFromConfiguration(GetGlobalAcceleratorConfiguration(), rsCommandName);
274 if (sShortcut.getLength() > 0)
275 return sShortcut;
276
277 return OUString();
278 }
279
280
281
282
RetrieveShortcutsFromConfiguration(const Reference<ui::XAcceleratorConfiguration> & rxConfiguration,const OUString & rsCommandName)283 OUString CommandInfoProvider::RetrieveShortcutsFromConfiguration(
284 const Reference<ui::XAcceleratorConfiguration>& rxConfiguration,
285 const OUString& rsCommandName)
286 {
287 if (rxConfiguration.is())
288 {
289 try
290 {
291 Sequence<OUString> aCommands(1);
292 aCommands[0] = rsCommandName;
293
294 Sequence<Any> aKeyCodes (rxConfiguration->getPreferredKeyEventsForCommandList(aCommands));
295 if (aCommands.getLength() == 1)
296 {
297 css::awt::KeyEvent aKeyEvent;
298 if (aKeyCodes[0] >>= aKeyEvent)
299 {
300 return svt::AcceleratorExecute::st_AWTKey2VCLKey(aKeyEvent).GetName();
301 }
302 }
303 }
304 catch (lang::IllegalArgumentException&)
305 {
306 }
307 }
308 return OUString();
309 }
310
311
312
313
GetCommandProperties(const OUString & rsCommandName)314 Sequence<beans::PropertyValue> CommandInfoProvider::GetCommandProperties (const OUString& rsCommandName)
315 {
316 Sequence<beans::PropertyValue> aProperties;
317
318 try
319 {
320 const OUString sModuleIdentifier (GetModuleIdentifier());
321 if (sModuleIdentifier.getLength() > 0)
322 {
323 Reference<container::XNameAccess> xNameAccess (
324 mxServiceFactory->createInstance(
325 OUString::createFromAscii("com.sun.star.frame.UICommandDescription")),
326 UNO_QUERY);
327 Reference<container::XNameAccess> xUICommandLabels;
328 if (xNameAccess.is())
329 if (xNameAccess->getByName(sModuleIdentifier) >>= xUICommandLabels)
330 xUICommandLabels->getByName(rsCommandName) >>= aProperties;
331 }
332 }
333 catch (Exception&)
334 {
335 }
336
337 return aProperties;
338 }
339
340
341
342
GetCommandLabel(const OUString & rsCommandName)343 OUString CommandInfoProvider::GetCommandLabel (const OUString& rsCommandName)
344 {
345 const Sequence<beans::PropertyValue> aProperties (GetCommandProperties(rsCommandName));
346 for (sal_Int32 nIndex=0; nIndex<aProperties.getLength(); ++nIndex)
347 {
348 if (aProperties[nIndex].Name.equalsAscii("Name"))
349 {
350 OUString sLabel;
351 aProperties[nIndex].Value >>= sLabel;
352 return sLabel;
353 }
354 }
355 return OUString();
356 }
357
358
359 } } // end of namespace sfx2/framework
360