bump product version to 4.1.6.2
[LibreOffice.git] / framework / source / helper / persistentwindowstate.cxx
blobd6733eadd3c52a46c24d12fe94cfeda9107ca42d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <pattern/window.hxx>
21 #include <helper/persistentwindowstate.hxx>
22 #include <threadhelp/writeguard.hxx>
23 #include <threadhelp/readguard.hxx>
24 #include <macros/generic.hxx>
25 #include <services.h>
27 #include <com/sun/star/awt/XWindow.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/lang/IllegalArgumentException.hpp>
31 #include <com/sun/star/frame/ModuleManager.hpp>
33 #include <comphelper/processfactory.hxx>
34 #include <comphelper/configurationhelper.hxx>
35 #include <vcl/window.hxx>
36 #include <vcl/syswin.hxx>
38 #include <toolkit/unohlp.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/wrkwin.hxx>
41 #include <rtl/string.hxx>
44 namespace framework{
47 //*****************************************************************************************************************
48 // XInterface, XTypeProvider
50 DEFINE_XINTERFACE_4(PersistentWindowState ,
51 OWeakObject ,
52 DIRECT_INTERFACE (css::lang::XTypeProvider ),
53 DIRECT_INTERFACE (css::lang::XInitialization ),
54 DIRECT_INTERFACE (css::frame::XFrameActionListener ),
55 DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener))
57 DEFINE_XTYPEPROVIDER_4(PersistentWindowState ,
58 css::lang::XTypeProvider ,
59 css::lang::XInitialization ,
60 css::frame::XFrameActionListener,
61 css::lang::XEventListener )
63 //*****************************************************************************************************************
64 PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
65 : ThreadHelpBase (&Application::GetSolarMutex())
66 , m_xSMGR (xSMGR )
67 , m_bWindowStateAlreadySet(sal_False )
71 //*****************************************************************************************************************
72 PersistentWindowState::~PersistentWindowState()
76 //*****************************************************************************************************************
77 void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
78 throw(css::uno::Exception ,
79 css::uno::RuntimeException)
81 // check arguments
82 css::uno::Reference< css::frame::XFrame > xFrame;
83 if (lArguments.getLength() < 1)
84 throw css::lang::IllegalArgumentException(
85 DECLARE_ASCII("Empty argument list!"),
86 static_cast< ::cppu::OWeakObject* >(this),
87 1);
89 lArguments[0] >>= xFrame;
90 if (!xFrame.is())
91 throw css::lang::IllegalArgumentException(
92 DECLARE_ASCII("No valid frame specified!"),
93 static_cast< ::cppu::OWeakObject* >(this),
94 1);
96 // SAFE -> ----------------------------------
97 WriteGuard aWriteLock(m_aLock);
98 // hold the frame as weak reference(!) so it can die everytimes :-)
99 m_xFrame = xFrame;
100 aWriteLock.unlock();
101 // <- SAFE ----------------------------------
103 // start listening
104 xFrame->addFrameActionListener(this);
107 //*****************************************************************************************************************
108 void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
109 throw(css::uno::RuntimeException)
111 // SAFE -> ----------------------------------
112 ReadGuard aReadLock(m_aLock);
113 css::uno::Reference< css::uno::XComponentContext > xContext = comphelper::getComponentContext(m_xSMGR);
114 css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
115 sal_Bool bRestoreWindowState = !m_bWindowStateAlreadySet;
116 aReadLock.unlock();
117 // <- SAFE ----------------------------------
119 // frame already gone ? We hold it weak only ...
120 if (!xFrame.is())
121 return;
123 // no window -> no position and size available
124 css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
125 if (!xWindow.is())
126 return;
128 // unknown module -> no configuration available!
129 OUString sModuleName = PersistentWindowState::implst_identifyModule(xContext, xFrame);
130 if (sModuleName.isEmpty())
131 return;
133 switch(aEvent.Action)
135 case css::frame::FrameAction_COMPONENT_ATTACHED :
137 if (bRestoreWindowState)
139 OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xContext, sModuleName);
140 PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState);
141 // SAFE -> ----------------------------------
142 WriteGuard aWriteLock(m_aLock);
143 m_bWindowStateAlreadySet = sal_True;
144 aWriteLock.unlock();
145 // <- SAFE ----------------------------------
148 break;
150 case css::frame::FrameAction_COMPONENT_REATTACHED :
152 // nothing todo here, because its not allowed to change position and size
153 // of an alredy existing frame!
155 break;
157 case css::frame::FrameAction_COMPONENT_DETACHING :
159 OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
160 PersistentWindowState::implst_setWindowStateOnConfig(xContext, sModuleName, sWindowState);
162 break;
163 default:
164 break;
168 //*****************************************************************************************************************
169 void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&)
170 throw(css::uno::RuntimeException)
172 // nothing todo here - because we hold the frame as weak reference only
175 //*****************************************************************************************************************
176 OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
177 const css::uno::Reference< css::frame::XFrame >& xFrame)
179 OUString sModuleName;
181 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager =
182 css::frame::ModuleManager::create( rxContext );
186 sModuleName = xModuleManager->identify(xFrame);
188 catch(const css::uno::RuntimeException&)
189 { throw; }
190 catch(const css::uno::Exception&)
191 { sModuleName = OUString(); }
193 return sModuleName;
196 //*****************************************************************************************************************
197 OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
198 const OUString& sModuleName)
200 OUString sWindowState;
202 OUStringBuffer sRelPathBuf(256);
203 sRelPathBuf.appendAscii("Office/Factories/*[\"");
204 sRelPathBuf.append (sModuleName );
205 sRelPathBuf.appendAscii("\"]" );
207 OUString sPackage("org.openoffice.Setup/");
208 OUString sRelPath = sRelPathBuf.makeStringAndClear();
209 OUString sKey("ooSetupFactoryWindowAttributes");
213 ::comphelper::ConfigurationHelper::readDirectKey(rxContext,
214 sPackage,
215 sRelPath,
216 sKey,
217 ::comphelper::ConfigurationHelper::E_READONLY) >>= sWindowState;
219 catch(const css::uno::RuntimeException&)
220 { throw; }
221 catch(const css::uno::Exception&)
222 { sWindowState = OUString(); }
224 return sWindowState;
227 //*****************************************************************************************************************
228 void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
229 const OUString& sModuleName ,
230 const OUString& sWindowState)
232 OUStringBuffer sRelPathBuf(256);
233 sRelPathBuf.appendAscii("Office/Factories/*[\"");
234 sRelPathBuf.append (sModuleName );
235 sRelPathBuf.appendAscii("\"]" );
237 OUString sPackage("org.openoffice.Setup/");
238 OUString sRelPath = sRelPathBuf.makeStringAndClear();
239 OUString sKey("ooSetupFactoryWindowAttributes");
243 ::comphelper::ConfigurationHelper::writeDirectKey(rxContext,
244 sPackage,
245 sRelPath,
246 sKey,
247 css::uno::makeAny(sWindowState),
248 ::comphelper::ConfigurationHelper::E_STANDARD);
250 catch(const css::uno::RuntimeException&)
251 { throw; }
252 catch(const css::uno::Exception&)
256 //*****************************************************************************************************************
257 OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
259 OUString sWindowState;
261 if (xWindow.is())
263 // SOLAR SAFE -> ------------------------
264 SolarMutexGuard aSolarGuard;
266 Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
267 // check for system window is necessary to guarantee correct pointer cast!
268 if (
269 (pWindow ) &&
270 (pWindow->IsSystemWindow())
273 sal_uLong nMask = WINDOWSTATE_MASK_ALL;
274 nMask &= ~(WINDOWSTATE_MASK_MINIMIZED);
275 sWindowState = OStringToOUString(
276 ((SystemWindow*)pWindow)->GetWindowState(nMask),
277 RTL_TEXTENCODING_UTF8);
279 // <- SOLAR SAFE ------------------------
282 return sWindowState;
286 //*********************************************************************************************************
287 void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow ,
288 const OUString& sWindowState)
290 if (
291 (!xWindow.is() ) ||
292 ( sWindowState.isEmpty() )
294 return;
296 // SOLAR SAFE -> ------------------------
297 SolarMutexGuard aSolarGuard;
299 Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
300 if (!pWindow)
301 return;
303 // check for system and work window - its necessary to guarantee correct pointer cast!
304 sal_Bool bSystemWindow = pWindow->IsSystemWindow();
305 sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW);
307 if (!bSystemWindow && !bWorkWindow)
308 return;
310 SystemWindow* pSystemWindow = (SystemWindow*)pWindow;
311 WorkWindow* pWorkWindow = (WorkWindow* )pWindow;
313 // dont save this special state!
314 if (pWorkWindow->IsMinimized())
315 return;
317 OUString sOldWindowState = OStringToOUString( pSystemWindow->GetWindowState(), RTL_TEXTENCODING_ASCII_US );
318 if ( sOldWindowState != sWindowState )
319 pSystemWindow->SetWindowState(OUStringToOString(sWindowState,RTL_TEXTENCODING_UTF8));
320 // <- SOLAR SAFE ------------------------
323 } // namespace framework
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */