LibreOffice Module framework (master) 1
persistentwindowstate.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21
22#include <com/sun/star/awt/XWindow.hpp>
23#include <com/sun/star/lang/IllegalArgumentException.hpp>
24#include <com/sun/star/frame/ModuleManager.hpp>
25
26#include <comphelper/lok.hxx>
28#include <utility>
29#include <vcl/window.hxx>
30#include <vcl/syswin.hxx>
31
33#include <vcl/svapp.hxx>
34#include <vcl/wrkwin.hxx>
35
36namespace framework{
37
38PersistentWindowState::PersistentWindowState(css::uno::Reference< css::uno::XComponentContext > xContext)
39 : m_xContext (std::move(xContext ))
40 , m_bWindowStateAlreadySet(false )
41{
42}
43
45{
46}
47
48void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
49{
50 // check arguments
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),
56 1);
57
58 lArguments[0] >>= xFrame;
59 if (!xFrame.is())
60 throw css::lang::IllegalArgumentException(
61 "No valid frame specified!",
62 static_cast< ::cppu::OWeakObject* >(this),
63 1);
64
65 {
68 }
69
70 // start listening
71 xFrame->addFrameActionListener(this);
72}
73
74void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
75{
76 // We don't want to do this stuff when being used through LibreOfficeKit
78 return;
79
80 css::uno::Reference< css::uno::XComponentContext > xContext;
81 css::uno::Reference< css::frame::XFrame > xFrame;
82 bool bRestoreWindowState;
83 {
85 xContext = m_xContext;
86 xFrame.set(m_xFrame.get(), css::uno::UNO_QUERY);
87 bRestoreWindowState = !m_bWindowStateAlreadySet;
88 }
89
90 // frame already gone ? We hold it weak only ...
91 if (!xFrame.is())
92 return;
93
94 // no window -> no position and size available
95 css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
96 if (!xWindow.is())
97 return;
98
99 // unknown module -> no configuration available!
100 OUString sModuleName = PersistentWindowState::implst_identifyModule(xContext, xFrame);
101 if (sModuleName.isEmpty())
102 return;
103
104 switch(aEvent.Action)
105 {
106 case css::frame::FrameAction_COMPONENT_ATTACHED :
107 {
108 if (bRestoreWindowState)
109 {
110 OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xContext, sModuleName);
114 }
115 }
116 break;
117
118 case css::frame::FrameAction_COMPONENT_REATTACHED :
119 {
120 // nothing todo here, because it's not allowed to change position and size
121 // of an already existing frame!
122 }
123 break;
124
125 case css::frame::FrameAction_COMPONENT_DETACHING :
126 {
127 OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
128 PersistentWindowState::implst_setWindowStateOnConfig(xContext, sModuleName, sWindowState);
129 }
130 break;
131 default:
132 break;
133 }
134}
135
136void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&)
137{
138 css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
139 if (xFrame.is())
140 xFrame->removeFrameActionListener(this);
141
142 // nothing todo here - because we hold the frame as weak reference only
143}
144
145OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
146 const css::uno::Reference< css::frame::XFrame >& xFrame)
147{
148 OUString sModuleName;
149
150 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager =
151 css::frame::ModuleManager::create( rxContext );
152
153 try
154 {
155 sModuleName = xModuleManager->identify(xFrame);
156 }
157 catch(const css::uno::RuntimeException&)
158 { throw; }
159 catch(const css::uno::Exception&)
160 { sModuleName.clear(); }
161
162 return sModuleName;
163}
164
166 const css::uno::Reference< css::uno::XComponentContext >& rxContext,
167 std::u16string_view sModuleName)
168{
169 OUString sWindowState;
170 try
171 {
173 "org.openoffice.Setup/",
174 OUString::Concat("Office/Factories/*[\"") + sModuleName + "\"]",
175 "ooSetupFactoryWindowAttributes",
177 }
178 catch(const css::uno::RuntimeException&)
179 { throw; }
180 catch(const css::uno::Exception&)
181 { sWindowState.clear(); }
182
183 return sWindowState;
184}
185
187 const css::uno::Reference< css::uno::XComponentContext >& rxContext,
188 std::u16string_view sModuleName, const OUString& sWindowState)
189{
190 try
191 {
193 "org.openoffice.Setup/",
194 OUString::Concat("Office/Factories/*[\"") + sModuleName + "\"]",
195 "ooSetupFactoryWindowAttributes",
196 css::uno::Any(sWindowState),
198 }
199 catch(const css::uno::RuntimeException&)
200 { throw; }
201 catch(const css::uno::Exception&)
202 {}
203}
204
205OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
206{
207 OUString sWindowState;
208
209 if (xWindow.is())
210 {
211 // SOLAR SAFE -> ------------------------
212 SolarMutexGuard aSolarGuard;
213
215 // check for system window is necessary to guarantee correct pointer cast!
216 if ( pWindow && pWindow->IsSystemWindow() )
217 {
218 vcl::WindowDataMask const nMask = vcl::WindowDataMask::All & ~vcl::WindowDataMask::Minimized;
219 sWindowState = static_cast<SystemWindow*>(pWindow.get())->GetWindowState(nMask);
220 }
221 // <- SOLAR SAFE ------------------------
222 }
223
224 return sWindowState;
225}
226
227void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow ,
228 std::u16string_view sWindowState)
229{
230 if (
231 (!xWindow.is() ) ||
232 ( sWindowState.empty() )
233 )
234 return;
235
236 // SOLAR SAFE -> ------------------------
237 SolarMutexGuard aSolarGuard;
238
240 if (!pWindow)
241 return;
242
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);
246
247 if (!bSystemWindow && !bWorkWindow)
248 return;
249
250 SystemWindow* pSystemWindow = static_cast<SystemWindow*>(pWindow.get());
251 WorkWindow* pWorkWindow = static_cast<WorkWindow* >(pWindow.get());
252
253 // don't save this special state!
254 if (pWorkWindow->IsMinimized())
255 return;
256
257 OUString sOldWindowState = pSystemWindow->GetWindowState();
258 if ( sOldWindowState != sWindowState )
259 pSystemWindow->SetWindowState(sWindowState);
260 // <- SOLAR SAFE ------------------------
261}
262
263} // namespace framework
264
265/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
OUString GetWindowState(vcl::WindowDataMask nMask=vcl::WindowDataMask::All) const
void SetWindowState(std::u16string_view rStr)
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
reference_type * get() const
bool IsMinimized() const
static void writeDirectKey(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const OUString &sPackage, const OUString &sRelPath, const OUString &sKey, const css::uno::Any &aValue, EConfigurationModes eMode)
static css::uno::Any readDirectKey(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const OUString &sPackage, const OUString &sRelPath, const OUString &sKey, EConfigurationModes eMode)
virtual void SAL_CALL disposing(const css::lang::EventObject &aEvent) override
PersistentWindowState(css::uno::Reference< css::uno::XComponentContext > xContext)
css::uno::Reference< css::uno::XComponentContext > m_xContext
may we need a uno service manager to create own services
static OUString implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow > &xWindow)
retrieve the window state from the container window.
static OUString implst_getWindowStateFromConfig(const css::uno::Reference< css::uno::XComponentContext > &rxContext, std::u16string_view sModuleName)
retrieve the window state from the configuration.
bool m_bWindowStateAlreadySet
we call SetWindowState one times only for the same frame!
css::uno::WeakReference< css::frame::XFrame > m_xFrame
reference to the frame which was created by the office himself
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &lArguments) override
static OUString implst_identifyModule(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::frame::XFrame > &xFrame)
identify the application module, which is used behind the component of our frame.
static void implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow > &xWindow, std::u16string_view sWindowState)
restore the position and size on the container window.
virtual void SAL_CALL frameAction(const css::frame::FrameActionEvent &aEvent) override
static void implst_setWindowStateOnConfig(const css::uno::Reference< css::uno::XComponentContext > &rxContext, std::u16string_view sModuleName, const OUString &sWindowState)
restore the position and size on the container window.
css::uno::Reference< css::uno::XComponentContext > m_xContext
WindowDataMask
Reference< XFrame > xFrame