1*6d739b60SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*6d739b60SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*6d739b60SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*6d739b60SAndrew Rist * distributed with this work for additional information 6*6d739b60SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*6d739b60SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*6d739b60SAndrew Rist * "License"); you may not use this file except in compliance 9*6d739b60SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*6d739b60SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*6d739b60SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*6d739b60SAndrew Rist * software distributed under the License is distributed on an 15*6d739b60SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*6d739b60SAndrew Rist * KIND, either express or implied. See the License for the 17*6d739b60SAndrew Rist * specific language governing permissions and limitations 18*6d739b60SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*6d739b60SAndrew Rist *************************************************************/ 21*6d739b60SAndrew Rist 22*6d739b60SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_framework.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 28cdf0e10cSrcweir // my own includes 29cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 30cdf0e10cSrcweir #include <pattern/window.hxx> 31cdf0e10cSrcweir #include <helper/persistentwindowstate.hxx> 32cdf0e10cSrcweir #include <threadhelp/writeguard.hxx> 33cdf0e10cSrcweir #include <threadhelp/readguard.hxx> 34cdf0e10cSrcweir #include <macros/generic.hxx> 35cdf0e10cSrcweir #include <services.h> 36cdf0e10cSrcweir 37cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 38cdf0e10cSrcweir // interface includes 39cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 40cdf0e10cSrcweir #include <com/sun/star/awt/XWindow.hpp> 41cdf0e10cSrcweir 42cdf0e10cSrcweir #ifndef _COM_SUN_STAR_LANG_XSERVICXEINFO_HPP_ 43cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp> 44cdf0e10cSrcweir #endif 45cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp> 46cdf0e10cSrcweir #include <com/sun/star/frame/XModuleManager.hpp> 47cdf0e10cSrcweir 48cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 49cdf0e10cSrcweir // other includes 50cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 51cdf0e10cSrcweir #include <comphelper/configurationhelper.hxx> 52cdf0e10cSrcweir #include <vcl/window.hxx> 53cdf0e10cSrcweir #include <vcl/syswin.hxx> 54cdf0e10cSrcweir 55cdf0e10cSrcweir #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ 56cdf0e10cSrcweir #include <toolkit/unohlp.hxx> 57cdf0e10cSrcweir #endif 58cdf0e10cSrcweir #include <vcl/svapp.hxx> 59cdf0e10cSrcweir #include <vcl/wrkwin.hxx> 60cdf0e10cSrcweir #include <rtl/string.hxx> 61cdf0e10cSrcweir 62cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 63cdf0e10cSrcweir // namespace 64cdf0e10cSrcweir 65cdf0e10cSrcweir namespace framework{ 66cdf0e10cSrcweir 67cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 68cdf0e10cSrcweir // definitions 69cdf0e10cSrcweir 70cdf0e10cSrcweir //***************************************************************************************************************** 71cdf0e10cSrcweir // XInterface, XTypeProvider 72cdf0e10cSrcweir 73cdf0e10cSrcweir DEFINE_XINTERFACE_4(PersistentWindowState , 74cdf0e10cSrcweir OWeakObject , 75cdf0e10cSrcweir DIRECT_INTERFACE (css::lang::XTypeProvider ), 76cdf0e10cSrcweir DIRECT_INTERFACE (css::lang::XInitialization ), 77cdf0e10cSrcweir DIRECT_INTERFACE (css::frame::XFrameActionListener ), 78cdf0e10cSrcweir DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener)) 79cdf0e10cSrcweir 80cdf0e10cSrcweir DEFINE_XTYPEPROVIDER_4(PersistentWindowState , 81cdf0e10cSrcweir css::lang::XTypeProvider , 82cdf0e10cSrcweir css::lang::XInitialization , 83cdf0e10cSrcweir css::frame::XFrameActionListener, 84cdf0e10cSrcweir css::lang::XEventListener ) 85cdf0e10cSrcweir 86cdf0e10cSrcweir //***************************************************************************************************************** 87cdf0e10cSrcweir PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 88cdf0e10cSrcweir : ThreadHelpBase (&Application::GetSolarMutex()) 89cdf0e10cSrcweir , m_xSMGR (xSMGR ) 90cdf0e10cSrcweir , m_bWindowStateAlreadySet(sal_False ) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94cdf0e10cSrcweir //***************************************************************************************************************** 95cdf0e10cSrcweir PersistentWindowState::~PersistentWindowState() 96cdf0e10cSrcweir { 97cdf0e10cSrcweir } 98cdf0e10cSrcweir 99cdf0e10cSrcweir //***************************************************************************************************************** 100cdf0e10cSrcweir void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) 101cdf0e10cSrcweir throw(css::uno::Exception , 102cdf0e10cSrcweir css::uno::RuntimeException) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir // check arguments 105cdf0e10cSrcweir css::uno::Reference< css::frame::XFrame > xFrame; 106cdf0e10cSrcweir if (lArguments.getLength() < 1) 107cdf0e10cSrcweir throw css::lang::IllegalArgumentException( 108cdf0e10cSrcweir DECLARE_ASCII("Empty argument list!"), 109cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >(this), 110cdf0e10cSrcweir 1); 111cdf0e10cSrcweir 112cdf0e10cSrcweir lArguments[0] >>= xFrame; 113cdf0e10cSrcweir if (!xFrame.is()) 114cdf0e10cSrcweir throw css::lang::IllegalArgumentException( 115cdf0e10cSrcweir DECLARE_ASCII("No valid frame specified!"), 116cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >(this), 117cdf0e10cSrcweir 1); 118cdf0e10cSrcweir 119cdf0e10cSrcweir // SAFE -> ---------------------------------- 120cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 121cdf0e10cSrcweir // hold the frame as weak reference(!) so it can die everytimes :-) 122cdf0e10cSrcweir m_xFrame = xFrame; 123cdf0e10cSrcweir aWriteLock.unlock(); 124cdf0e10cSrcweir // <- SAFE ---------------------------------- 125cdf0e10cSrcweir 126cdf0e10cSrcweir // start listening 127cdf0e10cSrcweir xFrame->addFrameActionListener(this); 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 130cdf0e10cSrcweir //***************************************************************************************************************** 131cdf0e10cSrcweir void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent) 132cdf0e10cSrcweir throw(css::uno::RuntimeException) 133cdf0e10cSrcweir { 134cdf0e10cSrcweir // SAFE -> ---------------------------------- 135cdf0e10cSrcweir ReadGuard aReadLock(m_aLock); 136cdf0e10cSrcweir css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ; 137cdf0e10cSrcweir css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY); 138cdf0e10cSrcweir sal_Bool bRestoreWindowState = !m_bWindowStateAlreadySet; 139cdf0e10cSrcweir aReadLock.unlock(); 140cdf0e10cSrcweir // <- SAFE ---------------------------------- 141cdf0e10cSrcweir 142cdf0e10cSrcweir // frame already gone ? We hold it weak only ... 143cdf0e10cSrcweir if (!xFrame.is()) 144cdf0e10cSrcweir return; 145cdf0e10cSrcweir 146cdf0e10cSrcweir // no window -> no position and size available 147cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow(); 148cdf0e10cSrcweir if (!xWindow.is()) 149cdf0e10cSrcweir return; 150cdf0e10cSrcweir 151cdf0e10cSrcweir // unknown module -> no configuration available! 152cdf0e10cSrcweir ::rtl::OUString sModuleName = PersistentWindowState::implst_identifyModule(xSMGR, xFrame); 153cdf0e10cSrcweir if (!sModuleName.getLength()) 154cdf0e10cSrcweir return; 155cdf0e10cSrcweir 156cdf0e10cSrcweir switch(aEvent.Action) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir case css::frame::FrameAction_COMPONENT_ATTACHED : 159cdf0e10cSrcweir { 160cdf0e10cSrcweir if (bRestoreWindowState) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xSMGR, sModuleName); 163cdf0e10cSrcweir PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState); 164cdf0e10cSrcweir // SAFE -> ---------------------------------- 165cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 166cdf0e10cSrcweir m_bWindowStateAlreadySet = sal_True; 167cdf0e10cSrcweir aWriteLock.unlock(); 168cdf0e10cSrcweir // <- SAFE ---------------------------------- 169cdf0e10cSrcweir } 170cdf0e10cSrcweir } 171cdf0e10cSrcweir break; 172cdf0e10cSrcweir 173cdf0e10cSrcweir case css::frame::FrameAction_COMPONENT_REATTACHED : 174cdf0e10cSrcweir { 175cdf0e10cSrcweir // nothing todo here, because its not allowed to change position and size 176cdf0e10cSrcweir // of an alredy existing frame! 177cdf0e10cSrcweir } 178cdf0e10cSrcweir break; 179cdf0e10cSrcweir 180cdf0e10cSrcweir case css::frame::FrameAction_COMPONENT_DETACHING : 181cdf0e10cSrcweir { 182cdf0e10cSrcweir ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow); 183cdf0e10cSrcweir PersistentWindowState::implst_setWindowStateOnConfig(xSMGR, sModuleName, sWindowState); 184cdf0e10cSrcweir } 185cdf0e10cSrcweir break; 186cdf0e10cSrcweir default: 187cdf0e10cSrcweir break; 188cdf0e10cSrcweir } 189cdf0e10cSrcweir } 190cdf0e10cSrcweir 191cdf0e10cSrcweir //***************************************************************************************************************** 192cdf0e10cSrcweir void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&) 193cdf0e10cSrcweir throw(css::uno::RuntimeException) 194cdf0e10cSrcweir { 195cdf0e10cSrcweir // nothing todo here - because we hold the frame as weak reference only 196cdf0e10cSrcweir } 197cdf0e10cSrcweir 198cdf0e10cSrcweir //***************************************************************************************************************** 199cdf0e10cSrcweir ::rtl::OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , 200cdf0e10cSrcweir const css::uno::Reference< css::frame::XFrame >& xFrame) 201cdf0e10cSrcweir { 202cdf0e10cSrcweir ::rtl::OUString sModuleName; 203cdf0e10cSrcweir 204cdf0e10cSrcweir css::uno::Reference< css::frame::XModuleManager > xModuleManager( 205cdf0e10cSrcweir xSMGR->createInstance(SERVICENAME_MODULEMANAGER), 206cdf0e10cSrcweir css::uno::UNO_QUERY_THROW); 207cdf0e10cSrcweir 208cdf0e10cSrcweir try 209cdf0e10cSrcweir { 210cdf0e10cSrcweir sModuleName = xModuleManager->identify(xFrame); 211cdf0e10cSrcweir } 212cdf0e10cSrcweir catch(const css::uno::RuntimeException& exRun) 213cdf0e10cSrcweir { throw exRun; } 214cdf0e10cSrcweir catch(const css::uno::Exception&) 215cdf0e10cSrcweir { sModuleName = ::rtl::OUString(); } 216cdf0e10cSrcweir 217cdf0e10cSrcweir return sModuleName; 218cdf0e10cSrcweir } 219cdf0e10cSrcweir 220cdf0e10cSrcweir //***************************************************************************************************************** 221cdf0e10cSrcweir ::rtl::OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , 222cdf0e10cSrcweir const ::rtl::OUString& sModuleName) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir ::rtl::OUString sWindowState; 225cdf0e10cSrcweir 226cdf0e10cSrcweir ::rtl::OUStringBuffer sRelPathBuf(256); 227cdf0e10cSrcweir sRelPathBuf.appendAscii("Office/Factories/*[\""); 228cdf0e10cSrcweir sRelPathBuf.append (sModuleName ); 229cdf0e10cSrcweir sRelPathBuf.appendAscii("\"]" ); 230cdf0e10cSrcweir 231cdf0e10cSrcweir ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/"); 232cdf0e10cSrcweir ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear(); 233cdf0e10cSrcweir ::rtl::OUString sKey = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes"); 234cdf0e10cSrcweir 235cdf0e10cSrcweir try 236cdf0e10cSrcweir { 237cdf0e10cSrcweir ::comphelper::ConfigurationHelper::readDirectKey(xSMGR, 238cdf0e10cSrcweir sPackage, 239cdf0e10cSrcweir sRelPath, 240cdf0e10cSrcweir sKey, 241cdf0e10cSrcweir ::comphelper::ConfigurationHelper::E_READONLY) >>= sWindowState; 242cdf0e10cSrcweir } 243cdf0e10cSrcweir catch(const css::uno::RuntimeException& exRun) 244cdf0e10cSrcweir { throw exRun; } 245cdf0e10cSrcweir catch(const css::uno::Exception&) 246cdf0e10cSrcweir { sWindowState = ::rtl::OUString(); } 247cdf0e10cSrcweir 248cdf0e10cSrcweir return sWindowState; 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir //***************************************************************************************************************** 252cdf0e10cSrcweir void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , 253cdf0e10cSrcweir const ::rtl::OUString& sModuleName , 254cdf0e10cSrcweir const ::rtl::OUString& sWindowState) 255cdf0e10cSrcweir { 256cdf0e10cSrcweir ::rtl::OUStringBuffer sRelPathBuf(256); 257cdf0e10cSrcweir sRelPathBuf.appendAscii("Office/Factories/*[\""); 258cdf0e10cSrcweir sRelPathBuf.append (sModuleName ); 259cdf0e10cSrcweir sRelPathBuf.appendAscii("\"]" ); 260cdf0e10cSrcweir 261cdf0e10cSrcweir ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/"); 262cdf0e10cSrcweir ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear(); 263cdf0e10cSrcweir ::rtl::OUString sKey = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes"); 264cdf0e10cSrcweir 265cdf0e10cSrcweir try 266cdf0e10cSrcweir { 267cdf0e10cSrcweir ::comphelper::ConfigurationHelper::writeDirectKey(xSMGR, 268cdf0e10cSrcweir sPackage, 269cdf0e10cSrcweir sRelPath, 270cdf0e10cSrcweir sKey, 271cdf0e10cSrcweir css::uno::makeAny(sWindowState), 272cdf0e10cSrcweir ::comphelper::ConfigurationHelper::E_STANDARD); 273cdf0e10cSrcweir } 274cdf0e10cSrcweir catch(const css::uno::RuntimeException& exRun) 275cdf0e10cSrcweir { throw exRun; } 276cdf0e10cSrcweir catch(const css::uno::Exception&) 277cdf0e10cSrcweir {} 278cdf0e10cSrcweir } 279cdf0e10cSrcweir 280cdf0e10cSrcweir //***************************************************************************************************************** 281cdf0e10cSrcweir ::rtl::OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow) 282cdf0e10cSrcweir { 283cdf0e10cSrcweir ::rtl::OUString sWindowState; 284cdf0e10cSrcweir 285cdf0e10cSrcweir if (xWindow.is()) 286cdf0e10cSrcweir { 287cdf0e10cSrcweir // SOLAR SAFE -> ------------------------ 288cdf0e10cSrcweir ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex()); 289cdf0e10cSrcweir 290cdf0e10cSrcweir Window* pWindow = VCLUnoHelper::GetWindow(xWindow); 291cdf0e10cSrcweir // check for system window is neccessary to guarantee correct pointer cast! 292cdf0e10cSrcweir if ( 293cdf0e10cSrcweir (pWindow ) && 294cdf0e10cSrcweir (pWindow->IsSystemWindow()) 295cdf0e10cSrcweir ) 296cdf0e10cSrcweir { 297cdf0e10cSrcweir sal_uLong nMask = WINDOWSTATE_MASK_ALL; 298cdf0e10cSrcweir nMask &= ~(WINDOWSTATE_MASK_MINIMIZED); 299cdf0e10cSrcweir sWindowState = B2U_ENC( 300cdf0e10cSrcweir ((SystemWindow*)pWindow)->GetWindowState(nMask), 301cdf0e10cSrcweir RTL_TEXTENCODING_UTF8); 302cdf0e10cSrcweir } 303cdf0e10cSrcweir 304cdf0e10cSrcweir aSolarLock.clear(); 305cdf0e10cSrcweir // <- SOLAR SAFE ------------------------ 306cdf0e10cSrcweir } 307cdf0e10cSrcweir 308cdf0e10cSrcweir return sWindowState; 309cdf0e10cSrcweir } 310cdf0e10cSrcweir 311cdf0e10cSrcweir 312cdf0e10cSrcweir //********************************************************************************************************* 313cdf0e10cSrcweir void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow , 314cdf0e10cSrcweir const ::rtl::OUString& sWindowState) 315cdf0e10cSrcweir { 316cdf0e10cSrcweir if ( 317cdf0e10cSrcweir (!xWindow.is() ) || 318cdf0e10cSrcweir ( sWindowState.getLength() < 1) 319cdf0e10cSrcweir ) 320cdf0e10cSrcweir return; 321cdf0e10cSrcweir 322cdf0e10cSrcweir // SOLAR SAFE -> ------------------------ 323cdf0e10cSrcweir ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex()); 324cdf0e10cSrcweir 325cdf0e10cSrcweir Window* pWindow = VCLUnoHelper::GetWindow(xWindow); 326cdf0e10cSrcweir if (!pWindow) 327cdf0e10cSrcweir return; 328cdf0e10cSrcweir 329cdf0e10cSrcweir // check for system and work window - its neccessary to guarantee correct pointer cast! 330cdf0e10cSrcweir sal_Bool bSystemWindow = pWindow->IsSystemWindow(); 331cdf0e10cSrcweir sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW); 332cdf0e10cSrcweir 333cdf0e10cSrcweir if (!bSystemWindow && !bWorkWindow) 334cdf0e10cSrcweir return; 335cdf0e10cSrcweir 336cdf0e10cSrcweir SystemWindow* pSystemWindow = (SystemWindow*)pWindow; 337cdf0e10cSrcweir WorkWindow* pWorkWindow = (WorkWindow* )pWindow; 338cdf0e10cSrcweir 339cdf0e10cSrcweir // dont save this special state! 340cdf0e10cSrcweir if (pWorkWindow->IsMinimized()) 341cdf0e10cSrcweir return; 342cdf0e10cSrcweir 343cdf0e10cSrcweir ::rtl::OUString sOldWindowState = ::rtl::OStringToOUString( pSystemWindow->GetWindowState(), RTL_TEXTENCODING_ASCII_US ); 344cdf0e10cSrcweir if ( sOldWindowState != sWindowState ) 345cdf0e10cSrcweir pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8)); 346cdf0e10cSrcweir 347cdf0e10cSrcweir aSolarLock.clear(); 348cdf0e10cSrcweir // <- SOLAR SAFE ------------------------ 349cdf0e10cSrcweir } 350cdf0e10cSrcweir 351cdf0e10cSrcweir } // namespace framework 352