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 <helper/persistentwindowstate.hxx>
22 #include <com/sun/star/awt/XWindow.hpp>
23 #include <com/sun/star/lang/IllegalArgumentException.hpp>
24 #include <com/sun/star/frame/ModuleManager.hpp>
26 #include <comphelper/lok.hxx>
27 #include <comphelper/configurationhelper.hxx>
28 #include <vcl/window.hxx>
29 #include <vcl/syswin.hxx>
31 #include <toolkit/helper/vclunohelper.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/wrkwin.hxx>
37 PersistentWindowState::PersistentWindowState(const css::uno::Reference
< css::uno::XComponentContext
>& xContext
)
38 : m_xContext (xContext
)
39 , m_bWindowStateAlreadySet(false )
43 PersistentWindowState::~PersistentWindowState()
47 void SAL_CALL
PersistentWindowState::initialize(const css::uno::Sequence
< css::uno::Any
>& lArguments
)
50 css::uno::Reference
< css::frame::XFrame
> xFrame
;
51 if (!lArguments
.hasElements())
52 throw css::lang::IllegalArgumentException(
53 "Empty argument list!",
54 static_cast< ::cppu::OWeakObject
* >(this),
57 lArguments
[0] >>= xFrame
;
59 throw css::lang::IllegalArgumentException(
60 "No valid frame specified!",
61 static_cast< ::cppu::OWeakObject
* >(this),
70 xFrame
->addFrameActionListener(this);
73 void SAL_CALL
PersistentWindowState::frameAction(const css::frame::FrameActionEvent
& aEvent
)
75 // We don't want to do this stuff when being used through LibreOfficeKit
76 if( comphelper::LibreOfficeKit::isActive() )
79 css::uno::Reference
< css::uno::XComponentContext
> xContext
;
80 css::uno::Reference
< css::frame::XFrame
> xFrame
;
81 bool bRestoreWindowState
;
84 xContext
= m_xContext
;
85 xFrame
.set(m_xFrame
.get(), css::uno::UNO_QUERY
);
86 bRestoreWindowState
= !m_bWindowStateAlreadySet
;
89 // frame already gone ? We hold it weak only ...
93 // no window -> no position and size available
94 css::uno::Reference
< css::awt::XWindow
> xWindow
= xFrame
->getContainerWindow();
98 // unknown module -> no configuration available!
99 OUString sModuleName
= PersistentWindowState::implst_identifyModule(xContext
, xFrame
);
100 if (sModuleName
.isEmpty())
103 switch(aEvent
.Action
)
105 case css::frame::FrameAction_COMPONENT_ATTACHED
:
107 if (bRestoreWindowState
)
109 OUString sWindowState
= PersistentWindowState::implst_getWindowStateFromConfig(xContext
, sModuleName
);
110 PersistentWindowState::implst_setWindowStateOnWindow(xWindow
,sWindowState
);
112 m_bWindowStateAlreadySet
= true;
117 case css::frame::FrameAction_COMPONENT_REATTACHED
:
119 // nothing todo here, because it's not allowed to change position and size
120 // of an already existing frame!
124 case css::frame::FrameAction_COMPONENT_DETACHING
:
126 OUString sWindowState
= PersistentWindowState::implst_getWindowStateFromWindow(xWindow
);
127 PersistentWindowState::implst_setWindowStateOnConfig(xContext
, sModuleName
, sWindowState
);
135 void SAL_CALL
PersistentWindowState::disposing(const css::lang::EventObject
&)
137 // nothing todo here - because we hold the frame as weak reference only
140 OUString
PersistentWindowState::implst_identifyModule(const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
141 const css::uno::Reference
< css::frame::XFrame
>& xFrame
)
143 OUString sModuleName
;
145 css::uno::Reference
< css::frame::XModuleManager2
> xModuleManager
=
146 css::frame::ModuleManager::create( rxContext
);
150 sModuleName
= xModuleManager
->identify(xFrame
);
152 catch(const css::uno::RuntimeException
&)
154 catch(const css::uno::Exception
&)
155 { sModuleName
.clear(); }
160 OUString
PersistentWindowState::implst_getWindowStateFromConfig(
161 const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
162 const OUString
& sModuleName
)
164 OUString sWindowState
;
167 ::comphelper::ConfigurationHelper::readDirectKey(rxContext
,
168 "org.openoffice.Setup/",
169 "Office/Factories/*[\"" + sModuleName
+ "\"]",
170 "ooSetupFactoryWindowAttributes",
171 ::comphelper::EConfigurationModes::ReadOnly
) >>= sWindowState
;
173 catch(const css::uno::RuntimeException
&)
175 catch(const css::uno::Exception
&)
176 { sWindowState
.clear(); }
181 void PersistentWindowState::implst_setWindowStateOnConfig(
182 const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
183 const OUString
& sModuleName
, const OUString
& sWindowState
)
187 ::comphelper::ConfigurationHelper::writeDirectKey(rxContext
,
188 "org.openoffice.Setup/",
189 "Office/Factories/*[\"" + sModuleName
+ "\"]",
190 "ooSetupFactoryWindowAttributes",
191 css::uno::makeAny(sWindowState
),
192 ::comphelper::EConfigurationModes::Standard
);
194 catch(const css::uno::RuntimeException
&)
196 catch(const css::uno::Exception
&)
200 OUString
PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference
< css::awt::XWindow
>& xWindow
)
202 OUString sWindowState
;
206 // SOLAR SAFE -> ------------------------
207 SolarMutexGuard aSolarGuard
;
209 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xWindow
);
210 // check for system window is necessary to guarantee correct pointer cast!
211 if ( pWindow
&& pWindow
->IsSystemWindow() )
213 WindowStateMask
const nMask
= WindowStateMask::All
& ~WindowStateMask::Minimized
;
214 sWindowState
= OStringToOUString(
215 static_cast<SystemWindow
*>(pWindow
.get())->GetWindowState(nMask
),
216 RTL_TEXTENCODING_UTF8
);
218 // <- SOLAR SAFE ------------------------
224 void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference
< css::awt::XWindow
>& xWindow
,
225 const OUString
& sWindowState
)
229 ( sWindowState
.isEmpty() )
233 // SOLAR SAFE -> ------------------------
234 SolarMutexGuard aSolarGuard
;
236 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xWindow
);
240 // check for system and work window - it's necessary to guarantee correct pointer cast!
241 bool bSystemWindow
= pWindow
->IsSystemWindow();
242 bool bWorkWindow
= (pWindow
->GetType() == WindowType::WORKWINDOW
);
244 if (!bSystemWindow
&& !bWorkWindow
)
247 SystemWindow
* pSystemWindow
= static_cast<SystemWindow
*>(pWindow
.get());
248 WorkWindow
* pWorkWindow
= static_cast<WorkWindow
* >(pWindow
.get());
250 // don't save this special state!
251 if (pWorkWindow
->IsMinimized())
254 OUString sOldWindowState
= OStringToOUString( pSystemWindow
->GetWindowState(), RTL_TEXTENCODING_ASCII_US
);
255 if ( sOldWindowState
!= sWindowState
)
256 pSystemWindow
->SetWindowState(OUStringToOString(sWindowState
,RTL_TEXTENCODING_UTF8
));
257 // <- SOLAR SAFE ------------------------
260 } // namespace framework
262 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */