1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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>
47 //*****************************************************************************************************************
48 // XInterface, XTypeProvider
50 DEFINE_XINTERFACE_4(PersistentWindowState
,
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())
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
)
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),
89 lArguments
[0] >>= xFrame
;
91 throw css::lang::IllegalArgumentException(
92 DECLARE_ASCII("No valid frame specified!"),
93 static_cast< ::cppu::OWeakObject
* >(this),
96 // SAFE -> ----------------------------------
97 WriteGuard
aWriteLock(m_aLock
);
98 // hold the frame as weak reference(!) so it can die everytimes :-)
101 // <- SAFE ----------------------------------
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
;
117 // <- SAFE ----------------------------------
119 // frame already gone ? We hold it weak only ...
123 // no window -> no position and size available
124 css::uno::Reference
< css::awt::XWindow
> xWindow
= xFrame
->getContainerWindow();
128 // unknown module -> no configuration available!
129 OUString sModuleName
= PersistentWindowState::implst_identifyModule(xContext
, xFrame
);
130 if (sModuleName
.isEmpty())
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
;
145 // <- SAFE ----------------------------------
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!
157 case css::frame::FrameAction_COMPONENT_DETACHING
:
159 OUString sWindowState
= PersistentWindowState::implst_getWindowStateFromWindow(xWindow
);
160 PersistentWindowState::implst_setWindowStateOnConfig(xContext
, sModuleName
, sWindowState
);
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
&)
190 catch(const css::uno::Exception
&)
191 { sModuleName
= OUString(); }
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
,
217 ::comphelper::ConfigurationHelper::E_READONLY
) >>= sWindowState
;
219 catch(const css::uno::RuntimeException
&)
221 catch(const css::uno::Exception
&)
222 { sWindowState
= OUString(); }
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
,
247 css::uno::makeAny(sWindowState
),
248 ::comphelper::ConfigurationHelper::E_STANDARD
);
250 catch(const css::uno::RuntimeException
&)
252 catch(const css::uno::Exception
&)
256 //*****************************************************************************************************************
257 OUString
PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference
< css::awt::XWindow
>& xWindow
)
259 OUString sWindowState
;
263 // SOLAR SAFE -> ------------------------
264 SolarMutexGuard aSolarGuard
;
266 Window
* pWindow
= VCLUnoHelper::GetWindow(xWindow
);
267 // check for system window is necessary to guarantee correct pointer cast!
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 ------------------------
286 //*********************************************************************************************************
287 void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference
< css::awt::XWindow
>& xWindow
,
288 const OUString
& sWindowState
)
292 ( sWindowState
.isEmpty() )
296 // SOLAR SAFE -> ------------------------
297 SolarMutexGuard aSolarGuard
;
299 Window
* pWindow
= VCLUnoHelper::GetWindow(xWindow
);
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
)
310 SystemWindow
* pSystemWindow
= (SystemWindow
*)pWindow
;
311 WorkWindow
* pWorkWindow
= (WorkWindow
* )pWindow
;
313 // dont save this special state!
314 if (pWorkWindow
->IsMinimized())
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: */