Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <pattern/window.hxx>
30 : : #include <helper/persistentwindowstate.hxx>
31 : : #include <threadhelp/writeguard.hxx>
32 : : #include <threadhelp/readguard.hxx>
33 : : #include <macros/generic.hxx>
34 : : #include <services.h>
35 : :
36 : : #include <com/sun/star/awt/XWindow.hpp>
37 : :
38 : : #include <com/sun/star/lang/XServiceInfo.hpp>
39 : : #include <com/sun/star/lang/IllegalArgumentException.hpp>
40 : : #include <com/sun/star/frame/XModuleManager.hpp>
41 : :
42 : : #include <comphelper/configurationhelper.hxx>
43 : : #include <vcl/window.hxx>
44 : : #include <vcl/syswin.hxx>
45 : :
46 : : #include <toolkit/unohlp.hxx>
47 : : #include <vcl/svapp.hxx>
48 : : #include <vcl/wrkwin.hxx>
49 : : #include <rtl/string.hxx>
50 : :
51 : :
52 : : namespace framework{
53 : :
54 : :
55 : : //*****************************************************************************************************************
56 : : // XInterface, XTypeProvider
57 : :
58 [ + + ][ + - ]: 131344 : DEFINE_XINTERFACE_4(PersistentWindowState ,
59 : : OWeakObject ,
60 : : DIRECT_INTERFACE (css::lang::XTypeProvider ),
61 : : DIRECT_INTERFACE (css::lang::XInitialization ),
62 : : DIRECT_INTERFACE (css::frame::XFrameActionListener ),
63 : : DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener))
64 : :
65 [ # # ][ # # ]: 0 : DEFINE_XTYPEPROVIDER_4(PersistentWindowState ,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
66 : : css::lang::XTypeProvider ,
67 : : css::lang::XInitialization ,
68 : : css::frame::XFrameActionListener,
69 : : css::lang::XEventListener )
70 : :
71 : : //*****************************************************************************************************************
72 : 1743 : PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
73 [ + - ]: 1743 : : ThreadHelpBase (&Application::GetSolarMutex())
74 : : , m_xSMGR (xSMGR )
75 [ + - ][ + - ]: 3486 : , m_bWindowStateAlreadySet(sal_False )
76 : : {
77 : 1743 : }
78 : :
79 : : //*****************************************************************************************************************
80 [ + - ][ + - ]: 1652 : PersistentWindowState::~PersistentWindowState()
[ + - ]
81 : : {
82 [ - + ]: 3304 : }
83 : :
84 : : //*****************************************************************************************************************
85 : 1743 : void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
86 : : throw(css::uno::Exception ,
87 : : css::uno::RuntimeException)
88 : : {
89 : : // check arguments
90 : 1743 : css::uno::Reference< css::frame::XFrame > xFrame;
91 [ - + ]: 1743 : if (lArguments.getLength() < 1)
92 : : throw css::lang::IllegalArgumentException(
93 : : DECLARE_ASCII("Empty argument list!"),
94 : : static_cast< ::cppu::OWeakObject* >(this),
95 [ # # ][ # # ]: 0 : 1);
[ # # ]
96 : :
97 [ + - ]: 1743 : lArguments[0] >>= xFrame;
98 [ - + ]: 1743 : if (!xFrame.is())
99 : : throw css::lang::IllegalArgumentException(
100 : : DECLARE_ASCII("No valid frame specified!"),
101 : : static_cast< ::cppu::OWeakObject* >(this),
102 [ # # ][ # # ]: 0 : 1);
[ # # ]
103 : :
104 : : // SAFE -> ----------------------------------
105 [ + - ]: 1743 : WriteGuard aWriteLock(m_aLock);
106 : : // hold the frame as weak reference(!) so it can die everytimes :-)
107 [ + - ]: 1743 : m_xFrame = xFrame;
108 [ + - ]: 1743 : aWriteLock.unlock();
109 : : // <- SAFE ----------------------------------
110 : :
111 : : // start listening
112 [ + - ][ + - ]: 1743 : xFrame->addFrameActionListener(this);
[ + - ][ + - ]
113 : 1743 : }
114 : :
115 : : //*****************************************************************************************************************
116 : 9575 : void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
117 : : throw(css::uno::RuntimeException)
118 : : {
119 : : // SAFE -> ----------------------------------
120 [ + - ]: 9575 : ReadGuard aReadLock(m_aLock);
121 : 9575 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ;
122 [ + - ][ + - ]: 9575 : css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
123 : 9575 : sal_Bool bRestoreWindowState = !m_bWindowStateAlreadySet;
124 [ + - ]: 9575 : aReadLock.unlock();
125 : : // <- SAFE ----------------------------------
126 : :
127 : : // frame already gone ? We hold it weak only ...
128 [ - + ]: 9575 : if (!xFrame.is())
129 : : return;
130 : :
131 : : // no window -> no position and size available
132 [ + - ][ + - ]: 9575 : css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
133 [ - + ]: 9575 : if (!xWindow.is())
134 : : return;
135 : :
136 : : // unknown module -> no configuration available!
137 [ + - ]: 9575 : ::rtl::OUString sModuleName = PersistentWindowState::implst_identifyModule(xSMGR, xFrame);
138 [ + + ]: 9575 : if (sModuleName.isEmpty())
139 : : return;
140 : :
141 [ + + + + ]: 5953 : switch(aEvent.Action)
142 : : {
143 : : case css::frame::FrameAction_COMPONENT_ATTACHED :
144 : : {
145 [ + - ]: 1743 : if (bRestoreWindowState)
146 : : {
147 [ + - ]: 1743 : ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xSMGR, sModuleName);
148 [ + - ]: 1743 : PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState);
149 : : // SAFE -> ----------------------------------
150 [ + - ]: 1743 : WriteGuard aWriteLock(m_aLock);
151 : 1743 : m_bWindowStateAlreadySet = sal_True;
152 [ + - ][ + - ]: 1743 : aWriteLock.unlock();
153 : : // <- SAFE ----------------------------------
154 : : }
155 : : }
156 : 1743 : break;
157 : :
158 : : case css::frame::FrameAction_COMPONENT_REATTACHED :
159 : : {
160 : : // nothing todo here, because its not allowed to change position and size
161 : : // of an alredy existing frame!
162 : : }
163 : 18 : break;
164 : :
165 : : case css::frame::FrameAction_COMPONENT_DETACHING :
166 : : {
167 [ + - ]: 1638 : ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
168 [ + - ]: 1638 : PersistentWindowState::implst_setWindowStateOnConfig(xSMGR, sModuleName, sWindowState);
169 : : }
170 : 1638 : break;
171 : : default:
172 : 5953 : break;
173 [ + + ][ + + ]: 9575 : }
[ + + ][ + + ]
[ + - ][ + + ]
174 : : }
175 : :
176 : : //*****************************************************************************************************************
177 : 1652 : void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&)
178 : : throw(css::uno::RuntimeException)
179 : : {
180 : : // nothing todo here - because we hold the frame as weak reference only
181 : 1652 : }
182 : :
183 : : //*****************************************************************************************************************
184 : 9575 : ::rtl::OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
185 : : const css::uno::Reference< css::frame::XFrame >& xFrame)
186 : : {
187 : 9575 : ::rtl::OUString sModuleName;
188 : :
189 : : css::uno::Reference< css::frame::XModuleManager > xModuleManager(
190 [ + - ]: 9575 : xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
191 [ + - ][ + - ]: 9575 : css::uno::UNO_QUERY_THROW);
[ + - ]
192 : :
193 : : try
194 : : {
195 [ + + ][ + - ]: 9575 : sModuleName = xModuleManager->identify(xFrame);
196 : : }
197 [ - - + ]: 3622 : catch(const css::uno::RuntimeException&)
198 : 0 : { throw; }
199 [ + - ]: 7244 : catch(const css::uno::Exception&)
200 : 3622 : { sModuleName = ::rtl::OUString(); }
201 : :
202 : 9575 : return sModuleName;
203 : : }
204 : :
205 : : //*****************************************************************************************************************
206 : 1743 : ::rtl::OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
207 : : const ::rtl::OUString& sModuleName)
208 : : {
209 : 1743 : ::rtl::OUString sWindowState;
210 : :
211 : 1743 : ::rtl::OUStringBuffer sRelPathBuf(256);
212 [ + - ]: 1743 : sRelPathBuf.appendAscii("Office/Factories/*[\"");
213 [ + - ]: 1743 : sRelPathBuf.append (sModuleName );
214 [ + - ]: 1743 : sRelPathBuf.appendAscii("\"]" );
215 : :
216 : 1743 : ::rtl::OUString sPackage("org.openoffice.Setup/");
217 [ + - ]: 1743 : ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
218 : 1743 : ::rtl::OUString sKey("ooSetupFactoryWindowAttributes");
219 : :
220 : : try
221 : : {
222 : : ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
223 : : sPackage,
224 : : sRelPath,
225 : : sKey,
226 [ + - ]: 1743 : ::comphelper::ConfigurationHelper::E_READONLY) >>= sWindowState;
227 : : }
228 [ # # # ]: 0 : catch(const css::uno::RuntimeException&)
229 : 0 : { throw; }
230 [ # # ]: 0 : catch(const css::uno::Exception&)
231 : 0 : { sWindowState = ::rtl::OUString(); }
232 : :
233 : 1743 : return sWindowState;
234 : : }
235 : :
236 : : //*****************************************************************************************************************
237 : 1638 : void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
238 : : const ::rtl::OUString& sModuleName ,
239 : : const ::rtl::OUString& sWindowState)
240 : : {
241 : 1638 : ::rtl::OUStringBuffer sRelPathBuf(256);
242 [ + - ]: 1638 : sRelPathBuf.appendAscii("Office/Factories/*[\"");
243 [ + - ]: 1638 : sRelPathBuf.append (sModuleName );
244 [ + - ]: 1638 : sRelPathBuf.appendAscii("\"]" );
245 : :
246 : 1638 : ::rtl::OUString sPackage("org.openoffice.Setup/");
247 [ + - ]: 1638 : ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
248 : 1638 : ::rtl::OUString sKey("ooSetupFactoryWindowAttributes");
249 : :
250 : : try
251 : : {
252 : : ::comphelper::ConfigurationHelper::writeDirectKey(xSMGR,
253 : : sPackage,
254 : : sRelPath,
255 : : sKey,
256 : : css::uno::makeAny(sWindowState),
257 [ + - ][ + - ]: 1638 : ::comphelper::ConfigurationHelper::E_STANDARD);
258 : : }
259 [ # # # ]: 0 : catch(const css::uno::RuntimeException&)
260 : 0 : { throw; }
261 [ # # ]: 0 : catch(const css::uno::Exception&)
262 : 1638 : {}
263 : 1638 : }
264 : :
265 : : //*****************************************************************************************************************
266 : 1638 : ::rtl::OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
267 : : {
268 : 1638 : ::rtl::OUString sWindowState;
269 : :
270 [ + - ]: 1638 : if (xWindow.is())
271 : : {
272 : : // SOLAR SAFE -> ------------------------
273 [ + - ]: 1638 : SolarMutexGuard aSolarGuard;
274 : :
275 [ + - ]: 1638 : Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
276 : : // check for system window is neccessary to guarantee correct pointer cast!
277 [ + - ][ + - ]: 3276 : if (
[ + - ]
278 : : (pWindow ) &&
279 [ + - ]: 1638 : (pWindow->IsSystemWindow())
280 : : )
281 : : {
282 : 1638 : sal_uLong nMask = WINDOWSTATE_MASK_ALL;
283 : 1638 : nMask &= ~(WINDOWSTATE_MASK_MINIMIZED);
284 : : sWindowState = rtl::OStringToOUString(
285 : : ((SystemWindow*)pWindow)->GetWindowState(nMask),
286 [ + - ][ + - ]: 1638 : RTL_TEXTENCODING_UTF8);
287 [ + - ]: 1638 : }
288 : : // <- SOLAR SAFE ------------------------
289 : : }
290 : :
291 : 1638 : return sWindowState;
292 : : }
293 : :
294 : :
295 : : //*********************************************************************************************************
296 : 1743 : void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow ,
297 : : const ::rtl::OUString& sWindowState)
298 : : {
299 [ + + ]: 3486 : if (
[ + - + + ]
300 : 1743 : (!xWindow.is() ) ||
301 : 1743 : ( sWindowState.isEmpty() )
302 : : )
303 : : return;
304 : :
305 : : // SOLAR SAFE -> ------------------------
306 [ + - ]: 1650 : SolarMutexGuard aSolarGuard;
307 : :
308 [ + - ]: 1650 : Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
309 [ - + ]: 1650 : if (!pWindow)
310 : : return;
311 : :
312 : : // check for system and work window - its neccessary to guarantee correct pointer cast!
313 [ + - ]: 1650 : sal_Bool bSystemWindow = pWindow->IsSystemWindow();
314 [ + - ]: 1650 : sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW);
315 : :
316 [ - + ][ # # ]: 1650 : if (!bSystemWindow && !bWorkWindow)
317 : : return;
318 : :
319 : 1650 : SystemWindow* pSystemWindow = (SystemWindow*)pWindow;
320 : 1650 : WorkWindow* pWorkWindow = (WorkWindow* )pWindow;
321 : :
322 : : // dont save this special state!
323 [ + - ][ - + ]: 1650 : if (pWorkWindow->IsMinimized())
324 : : return;
325 : :
326 [ + - ][ + - ]: 1650 : ::rtl::OUString sOldWindowState = ::rtl::OStringToOUString( pSystemWindow->GetWindowState(), RTL_TEXTENCODING_ASCII_US );
327 [ + + ]: 1650 : if ( sOldWindowState != sWindowState )
328 [ + - ][ + - ]: 1743 : pSystemWindow->SetWindowState(rtl::OUStringToOString(sWindowState,RTL_TEXTENCODING_UTF8));
[ + - ][ + - ]
329 : : // <- SOLAR SAFE ------------------------
330 : : }
331 : :
332 : : } // namespace framework
333 : :
334 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|