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 //----------------------------------------------- 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 //----------------------------------------------- 78 WindowCommandDispatch::~WindowCommandDispatch() 79 { 80 m_xSMGR.clear(); 81 } 82 83 //----------------------------------------------- 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 //----------------------------------------------- 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 //----------------------------------------------- 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 //----------------------------------------------- 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