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>
23 #include <com/sun/star/awt/XWindow.hpp>
24 #include <com/sun/star/lang/IllegalArgumentException.hpp>
25 #include <com/sun/star/frame/ModuleManager.hpp>
27 #include <comphelper/lok.hxx>
28 #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>
35 #include <rtl/string.hxx>
39 PersistentWindowState::PersistentWindowState(const css::uno::Reference
< css::uno::XComponentContext
>& xContext
)
40 : m_xContext (xContext
)
41 , m_bWindowStateAlreadySet(false )
45 PersistentWindowState::~PersistentWindowState()
49 void SAL_CALL
PersistentWindowState::initialize(const css::uno::Sequence
< css::uno::Any
>& lArguments
)
52 css::uno::Reference
< css::frame::XFrame
> xFrame
;
53 if (!lArguments
.hasElements())
54 throw css::lang::IllegalArgumentException(
55 "Empty argument list!",
56 static_cast< ::cppu::OWeakObject
* >(this),
59 lArguments
[0] >>= xFrame
;
61 throw css::lang::IllegalArgumentException(
62 "No valid frame specified!",
63 static_cast< ::cppu::OWeakObject
* >(this),
72 xFrame
->addFrameActionListener(this);
75 void SAL_CALL
PersistentWindowState::frameAction(const css::frame::FrameActionEvent
& aEvent
)
77 // We don't want to do this stuff when being used through LibreOfficeKit
78 if( comphelper::LibreOfficeKit::isActive() )
81 css::uno::Reference
< css::uno::XComponentContext
> xContext
;
82 css::uno::Reference
< css::frame::XFrame
> xFrame
;
83 bool bRestoreWindowState
;
86 xContext
= m_xContext
;
87 xFrame
.set(m_xFrame
.get(), css::uno::UNO_QUERY
);
88 bRestoreWindowState
= !m_bWindowStateAlreadySet
;
91 // frame already gone ? We hold it weak only ...
95 // no window -> no position and size available
96 css::uno::Reference
< css::awt::XWindow
> xWindow
= xFrame
->getContainerWindow();
100 // unknown module -> no configuration available!
101 OUString sModuleName
= PersistentWindowState::implst_identifyModule(xContext
, xFrame
);
102 if (sModuleName
.isEmpty())
105 switch(aEvent
.Action
)
107 case css::frame::FrameAction_COMPONENT_ATTACHED
:
109 if (bRestoreWindowState
)
111 OUString sWindowState
= PersistentWindowState::implst_getWindowStateFromConfig(xContext
, sModuleName
);
112 PersistentWindowState::implst_setWindowStateOnWindow(xWindow
,sWindowState
);
114 m_bWindowStateAlreadySet
= true;
119 case css::frame::FrameAction_COMPONENT_REATTACHED
:
121 // nothing todo here, because it's not allowed to change position and size
122 // of an already existing frame!
126 case css::frame::FrameAction_COMPONENT_DETACHING
:
128 OUString sWindowState
= PersistentWindowState::implst_getWindowStateFromWindow(xWindow
);
129 PersistentWindowState::implst_setWindowStateOnConfig(xContext
, sModuleName
, sWindowState
);
137 void SAL_CALL
PersistentWindowState::disposing(const css::lang::EventObject
&)
139 // nothing todo here - because we hold the frame as weak reference only
142 OUString
PersistentWindowState::implst_identifyModule(const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
143 const css::uno::Reference
< css::frame::XFrame
>& xFrame
)
145 OUString sModuleName
;
147 css::uno::Reference
< css::frame::XModuleManager2
> xModuleManager
=
148 css::frame::ModuleManager::create( rxContext
);
152 sModuleName
= xModuleManager
->identify(xFrame
);
154 catch(const css::uno::RuntimeException
&)
156 catch(const css::uno::Exception
&)
157 { sModuleName
.clear(); }
162 OUString
PersistentWindowState::implst_getWindowStateFromConfig(
163 const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
164 const OUString
& sModuleName
)
166 OUString sWindowState
;
169 ::comphelper::ConfigurationHelper::readDirectKey(rxContext
,
170 "org.openoffice.Setup/",
171 "Office/Factories/*[\"" + sModuleName
+ "\"]",
172 "ooSetupFactoryWindowAttributes",
173 ::comphelper::EConfigurationModes::ReadOnly
) >>= sWindowState
;
175 catch(const css::uno::RuntimeException
&)
177 catch(const css::uno::Exception
&)
178 { sWindowState
.clear(); }
183 void PersistentWindowState::implst_setWindowStateOnConfig(
184 const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
185 const OUString
& sModuleName
, const OUString
& sWindowState
)
189 ::comphelper::ConfigurationHelper::writeDirectKey(rxContext
,
190 "org.openoffice.Setup/",
191 "Office/Factories/*[\"" + sModuleName
+ "\"]",
192 "ooSetupFactoryWindowAttributes",
193 css::uno::makeAny(sWindowState
),
194 ::comphelper::EConfigurationModes::Standard
);
196 catch(const css::uno::RuntimeException
&)
198 catch(const css::uno::Exception
&)
202 OUString
PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference
< css::awt::XWindow
>& xWindow
)
204 OUString sWindowState
;
208 // SOLAR SAFE -> ------------------------
209 SolarMutexGuard aSolarGuard
;
211 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xWindow
);
212 // check for system window is necessary to guarantee correct pointer cast!
213 if ( pWindow
&& pWindow
->IsSystemWindow() )
215 WindowStateMask
const nMask
= WindowStateMask::All
& ~WindowStateMask::Minimized
;
216 sWindowState
= OStringToOUString(
217 static_cast<SystemWindow
*>(pWindow
.get())->GetWindowState(nMask
),
218 RTL_TEXTENCODING_UTF8
);
220 // <- SOLAR SAFE ------------------------
226 void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference
< css::awt::XWindow
>& xWindow
,
227 const OUString
& sWindowState
)
231 ( sWindowState
.isEmpty() )
235 // SOLAR SAFE -> ------------------------
236 SolarMutexGuard aSolarGuard
;
238 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xWindow
);
242 // check for system and work window - it's necessary to guarantee correct pointer cast!
243 bool bSystemWindow
= pWindow
->IsSystemWindow();
244 bool bWorkWindow
= (pWindow
->GetType() == WindowType::WORKWINDOW
);
246 if (!bSystemWindow
&& !bWorkWindow
)
249 SystemWindow
* pSystemWindow
= static_cast<SystemWindow
*>(pWindow
.get());
250 WorkWindow
* pWorkWindow
= static_cast<WorkWindow
* >(pWindow
.get());
252 // don't save this special state!
253 if (pWorkWindow
->IsMinimized())
256 OUString sOldWindowState
= OStringToOUString( pSystemWindow
->GetWindowState(), RTL_TEXTENCODING_ASCII_US
);
257 if ( sOldWindowState
!= sWindowState
)
258 pSystemWindow
->SetWindowState(OUStringToOString(sWindowState
,RTL_TEXTENCODING_UTF8
));
259 // <- SOLAR SAFE ------------------------
262 } // namespace framework
264 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */