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>
29 #include <vcl/window.hxx>
30 #include <vcl/syswin.hxx>
32 #include <toolkit/helper/vclunohelper.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/wrkwin.hxx>
38 PersistentWindowState::PersistentWindowState(css::uno::Reference
< css::uno::XComponentContext
> xContext
)
39 : m_xContext (std::move(xContext
))
40 , m_bWindowStateAlreadySet(false )
44 PersistentWindowState::~PersistentWindowState()
48 void SAL_CALL
PersistentWindowState::initialize(const css::uno::Sequence
< css::uno::Any
>& lArguments
)
51 css::uno::Reference
< css::frame::XFrame
> xFrame
;
52 if (!lArguments
.hasElements())
53 throw css::lang::IllegalArgumentException(
54 "Empty argument list!",
55 static_cast< ::cppu::OWeakObject
* >(this),
58 lArguments
[0] >>= xFrame
;
60 throw css::lang::IllegalArgumentException(
61 "No valid frame specified!",
62 static_cast< ::cppu::OWeakObject
* >(this),
71 xFrame
->addFrameActionListener(this);
74 void SAL_CALL
PersistentWindowState::frameAction(const css::frame::FrameActionEvent
& aEvent
)
76 // We don't want to do this stuff when being used through LibreOfficeKit
77 if( comphelper::LibreOfficeKit::isActive() )
80 css::uno::Reference
< css::uno::XComponentContext
> xContext
;
81 css::uno::Reference
< css::frame::XFrame
> xFrame
;
82 bool bRestoreWindowState
;
85 xContext
= m_xContext
;
86 xFrame
.set(m_xFrame
.get(), css::uno::UNO_QUERY
);
87 bRestoreWindowState
= !m_bWindowStateAlreadySet
;
90 // frame already gone ? We hold it weak only ...
94 // no window -> no position and size available
95 css::uno::Reference
< css::awt::XWindow
> xWindow
= xFrame
->getContainerWindow();
99 // unknown module -> no configuration available!
100 OUString sModuleName
= PersistentWindowState::implst_identifyModule(xContext
, xFrame
);
101 if (sModuleName
.isEmpty())
104 switch(aEvent
.Action
)
106 case css::frame::FrameAction_COMPONENT_ATTACHED
:
108 if (bRestoreWindowState
)
110 OUString sWindowState
= PersistentWindowState::implst_getWindowStateFromConfig(xContext
, sModuleName
);
111 PersistentWindowState::implst_setWindowStateOnWindow(xWindow
,sWindowState
);
113 m_bWindowStateAlreadySet
= true;
118 case css::frame::FrameAction_COMPONENT_REATTACHED
:
120 // nothing todo here, because it's not allowed to change position and size
121 // of an already existing frame!
125 case css::frame::FrameAction_COMPONENT_DETACHING
:
127 OUString sWindowState
= PersistentWindowState::implst_getWindowStateFromWindow(xWindow
);
128 PersistentWindowState::implst_setWindowStateOnConfig(xContext
, sModuleName
, sWindowState
);
136 void SAL_CALL
PersistentWindowState::disposing(const css::lang::EventObject
&)
138 css::uno::Reference
< css::frame::XFrame
> xFrame(m_xFrame
.get(), css::uno::UNO_QUERY
);
140 xFrame
->removeFrameActionListener(this);
142 // nothing todo here - because we hold the frame as weak reference only
145 OUString
PersistentWindowState::implst_identifyModule(const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
146 const css::uno::Reference
< css::frame::XFrame
>& xFrame
)
148 OUString sModuleName
;
150 css::uno::Reference
< css::frame::XModuleManager2
> xModuleManager
=
151 css::frame::ModuleManager::create( rxContext
);
155 sModuleName
= xModuleManager
->identify(xFrame
);
157 catch(const css::uno::RuntimeException
&)
159 catch(const css::uno::Exception
&)
160 { sModuleName
.clear(); }
165 OUString
PersistentWindowState::implst_getWindowStateFromConfig(
166 const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
167 std::u16string_view sModuleName
)
169 OUString sWindowState
;
172 ::comphelper::ConfigurationHelper::readDirectKey(rxContext
,
173 "org.openoffice.Setup/",
174 OUString::Concat("Office/Factories/*[\"") + sModuleName
+ "\"]",
175 "ooSetupFactoryWindowAttributes",
176 ::comphelper::EConfigurationModes::ReadOnly
) >>= sWindowState
;
178 catch(const css::uno::RuntimeException
&)
180 catch(const css::uno::Exception
&)
181 { sWindowState
.clear(); }
186 void PersistentWindowState::implst_setWindowStateOnConfig(
187 const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
188 std::u16string_view sModuleName
, const OUString
& sWindowState
)
192 ::comphelper::ConfigurationHelper::writeDirectKey(rxContext
,
193 "org.openoffice.Setup/",
194 OUString::Concat("Office/Factories/*[\"") + sModuleName
+ "\"]",
195 "ooSetupFactoryWindowAttributes",
196 css::uno::Any(sWindowState
),
197 ::comphelper::EConfigurationModes::Standard
);
199 catch(const css::uno::RuntimeException
&)
201 catch(const css::uno::Exception
&)
205 OUString
PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference
< css::awt::XWindow
>& xWindow
)
207 OUString sWindowState
;
211 // SOLAR SAFE -> ------------------------
212 SolarMutexGuard aSolarGuard
;
214 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xWindow
);
215 // check for system window is necessary to guarantee correct pointer cast!
216 if ( pWindow
&& pWindow
->IsSystemWindow() )
218 vcl::WindowDataMask
const nMask
= vcl::WindowDataMask::All
& ~vcl::WindowDataMask::Minimized
;
219 sWindowState
= static_cast<SystemWindow
*>(pWindow
.get())->GetWindowState(nMask
);
221 // <- SOLAR SAFE ------------------------
227 void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference
< css::awt::XWindow
>& xWindow
,
228 std::u16string_view sWindowState
)
232 ( sWindowState
.empty() )
236 // SOLAR SAFE -> ------------------------
237 SolarMutexGuard aSolarGuard
;
239 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xWindow
);
243 // check for system and work window - it's necessary to guarantee correct pointer cast!
244 bool bSystemWindow
= pWindow
->IsSystemWindow();
245 bool bWorkWindow
= (pWindow
->GetType() == WindowType::WORKWINDOW
);
247 if (!bSystemWindow
&& !bWorkWindow
)
250 SystemWindow
* pSystemWindow
= static_cast<SystemWindow
*>(pWindow
.get());
251 WorkWindow
* pWorkWindow
= static_cast<WorkWindow
* >(pWindow
.get());
253 // don't save this special state!
254 if (pWorkWindow
->IsMinimized())
257 OUString sOldWindowState
= pSystemWindow
->GetWindowState();
258 if ( sOldWindowState
!= sWindowState
)
259 pSystemWindow
->SetWindowState(sWindowState
);
260 // <- SOLAR SAFE ------------------------
263 } // namespace framework
265 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */