1*6d739b60SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*6d739b60SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*6d739b60SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*6d739b60SAndrew Rist * distributed with this work for additional information
6*6d739b60SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*6d739b60SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*6d739b60SAndrew Rist * "License"); you may not use this file except in compliance
9*6d739b60SAndrew Rist * with the License. You may obtain a copy of the License at
10*6d739b60SAndrew Rist *
11*6d739b60SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*6d739b60SAndrew Rist *
13*6d739b60SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*6d739b60SAndrew Rist * software distributed under the License is distributed on an
15*6d739b60SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*6d739b60SAndrew Rist * KIND, either express or implied. See the License for the
17*6d739b60SAndrew Rist * specific language governing permissions and limitations
18*6d739b60SAndrew Rist * under the License.
19*6d739b60SAndrew Rist *
20*6d739b60SAndrew Rist *************************************************************/
21*6d739b60SAndrew Rist
22*6d739b60SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_framework.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir //_________________________________________________________________________________________________________________
28cdf0e10cSrcweir // my own includes
29cdf0e10cSrcweir //_________________________________________________________________________________________________________________
30cdf0e10cSrcweir #include <pattern/window.hxx>
31cdf0e10cSrcweir #include <helper/persistentwindowstate.hxx>
32cdf0e10cSrcweir #include <threadhelp/writeguard.hxx>
33cdf0e10cSrcweir #include <threadhelp/readguard.hxx>
34cdf0e10cSrcweir #include <macros/generic.hxx>
35cdf0e10cSrcweir #include <services.h>
36cdf0e10cSrcweir
37cdf0e10cSrcweir //_________________________________________________________________________________________________________________
38cdf0e10cSrcweir // interface includes
39cdf0e10cSrcweir //_________________________________________________________________________________________________________________
40cdf0e10cSrcweir #include <com/sun/star/awt/XWindow.hpp>
41cdf0e10cSrcweir
42cdf0e10cSrcweir #ifndef _COM_SUN_STAR_LANG_XSERVICXEINFO_HPP_
43cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
44cdf0e10cSrcweir #endif
45cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp>
46cdf0e10cSrcweir #include <com/sun/star/frame/XModuleManager.hpp>
47cdf0e10cSrcweir
48cdf0e10cSrcweir //_________________________________________________________________________________________________________________
49cdf0e10cSrcweir // other includes
50cdf0e10cSrcweir //_________________________________________________________________________________________________________________
51cdf0e10cSrcweir #include <comphelper/configurationhelper.hxx>
52cdf0e10cSrcweir #include <vcl/window.hxx>
53cdf0e10cSrcweir #include <vcl/syswin.hxx>
54cdf0e10cSrcweir
55cdf0e10cSrcweir #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
56cdf0e10cSrcweir #include <toolkit/unohlp.hxx>
57cdf0e10cSrcweir #endif
58cdf0e10cSrcweir #include <vcl/svapp.hxx>
59cdf0e10cSrcweir #include <vcl/wrkwin.hxx>
60cdf0e10cSrcweir #include <rtl/string.hxx>
61cdf0e10cSrcweir
62cdf0e10cSrcweir //_________________________________________________________________________________________________________________
63cdf0e10cSrcweir // namespace
64cdf0e10cSrcweir
65cdf0e10cSrcweir namespace framework{
66cdf0e10cSrcweir
67cdf0e10cSrcweir //_________________________________________________________________________________________________________________
68cdf0e10cSrcweir // definitions
69cdf0e10cSrcweir
70cdf0e10cSrcweir //*****************************************************************************************************************
71cdf0e10cSrcweir // XInterface, XTypeProvider
72cdf0e10cSrcweir
DEFINE_XINTERFACE_4(PersistentWindowState,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::lang::XInitialization),DIRECT_INTERFACE (css::frame::XFrameActionListener),DERIVED_INTERFACE (css::lang::XEventListener,css::frame::XFrameActionListener))73cdf0e10cSrcweir DEFINE_XINTERFACE_4(PersistentWindowState ,
74cdf0e10cSrcweir OWeakObject ,
75cdf0e10cSrcweir DIRECT_INTERFACE (css::lang::XTypeProvider ),
76cdf0e10cSrcweir DIRECT_INTERFACE (css::lang::XInitialization ),
77cdf0e10cSrcweir DIRECT_INTERFACE (css::frame::XFrameActionListener ),
78cdf0e10cSrcweir DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener))
79cdf0e10cSrcweir
80cdf0e10cSrcweir DEFINE_XTYPEPROVIDER_4(PersistentWindowState ,
81cdf0e10cSrcweir css::lang::XTypeProvider ,
82cdf0e10cSrcweir css::lang::XInitialization ,
83cdf0e10cSrcweir css::frame::XFrameActionListener,
84cdf0e10cSrcweir css::lang::XEventListener )
85cdf0e10cSrcweir
86cdf0e10cSrcweir //*****************************************************************************************************************
87cdf0e10cSrcweir PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
88cdf0e10cSrcweir : ThreadHelpBase (&Application::GetSolarMutex())
89cdf0e10cSrcweir , m_xSMGR (xSMGR )
90cdf0e10cSrcweir , m_bWindowStateAlreadySet(sal_False )
91cdf0e10cSrcweir {
92cdf0e10cSrcweir }
93cdf0e10cSrcweir
94cdf0e10cSrcweir //*****************************************************************************************************************
~PersistentWindowState()95cdf0e10cSrcweir PersistentWindowState::~PersistentWindowState()
96cdf0e10cSrcweir {
97cdf0e10cSrcweir }
98cdf0e10cSrcweir
99cdf0e10cSrcweir //*****************************************************************************************************************
initialize(const css::uno::Sequence<css::uno::Any> & lArguments)100cdf0e10cSrcweir void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
101cdf0e10cSrcweir throw(css::uno::Exception ,
102cdf0e10cSrcweir css::uno::RuntimeException)
103cdf0e10cSrcweir {
104cdf0e10cSrcweir // check arguments
105cdf0e10cSrcweir css::uno::Reference< css::frame::XFrame > xFrame;
106cdf0e10cSrcweir if (lArguments.getLength() < 1)
107cdf0e10cSrcweir throw css::lang::IllegalArgumentException(
108cdf0e10cSrcweir DECLARE_ASCII("Empty argument list!"),
109cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >(this),
110cdf0e10cSrcweir 1);
111cdf0e10cSrcweir
112cdf0e10cSrcweir lArguments[0] >>= xFrame;
113cdf0e10cSrcweir if (!xFrame.is())
114cdf0e10cSrcweir throw css::lang::IllegalArgumentException(
115cdf0e10cSrcweir DECLARE_ASCII("No valid frame specified!"),
116cdf0e10cSrcweir static_cast< ::cppu::OWeakObject* >(this),
117cdf0e10cSrcweir 1);
118cdf0e10cSrcweir
119cdf0e10cSrcweir // SAFE -> ----------------------------------
120cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock);
121cdf0e10cSrcweir // hold the frame as weak reference(!) so it can die everytimes :-)
122cdf0e10cSrcweir m_xFrame = xFrame;
123cdf0e10cSrcweir aWriteLock.unlock();
124cdf0e10cSrcweir // <- SAFE ----------------------------------
125cdf0e10cSrcweir
126cdf0e10cSrcweir // start listening
127cdf0e10cSrcweir xFrame->addFrameActionListener(this);
128cdf0e10cSrcweir }
129cdf0e10cSrcweir
130cdf0e10cSrcweir //*****************************************************************************************************************
frameAction(const css::frame::FrameActionEvent & aEvent)131cdf0e10cSrcweir void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
132cdf0e10cSrcweir throw(css::uno::RuntimeException)
133cdf0e10cSrcweir {
134cdf0e10cSrcweir // SAFE -> ----------------------------------
135cdf0e10cSrcweir ReadGuard aReadLock(m_aLock);
136cdf0e10cSrcweir css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ;
137cdf0e10cSrcweir css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
138cdf0e10cSrcweir sal_Bool bRestoreWindowState = !m_bWindowStateAlreadySet;
139cdf0e10cSrcweir aReadLock.unlock();
140cdf0e10cSrcweir // <- SAFE ----------------------------------
141cdf0e10cSrcweir
142cdf0e10cSrcweir // frame already gone ? We hold it weak only ...
143cdf0e10cSrcweir if (!xFrame.is())
144cdf0e10cSrcweir return;
145cdf0e10cSrcweir
146cdf0e10cSrcweir // no window -> no position and size available
147cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
148cdf0e10cSrcweir if (!xWindow.is())
149cdf0e10cSrcweir return;
150cdf0e10cSrcweir
151cdf0e10cSrcweir // unknown module -> no configuration available!
152cdf0e10cSrcweir ::rtl::OUString sModuleName = PersistentWindowState::implst_identifyModule(xSMGR, xFrame);
153cdf0e10cSrcweir if (!sModuleName.getLength())
154cdf0e10cSrcweir return;
155cdf0e10cSrcweir
156cdf0e10cSrcweir switch(aEvent.Action)
157cdf0e10cSrcweir {
158cdf0e10cSrcweir case css::frame::FrameAction_COMPONENT_ATTACHED :
159cdf0e10cSrcweir {
160cdf0e10cSrcweir if (bRestoreWindowState)
161cdf0e10cSrcweir {
162cdf0e10cSrcweir ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xSMGR, sModuleName);
163cdf0e10cSrcweir PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState);
164cdf0e10cSrcweir // SAFE -> ----------------------------------
165cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock);
166cdf0e10cSrcweir m_bWindowStateAlreadySet = sal_True;
167cdf0e10cSrcweir aWriteLock.unlock();
168cdf0e10cSrcweir // <- SAFE ----------------------------------
169cdf0e10cSrcweir }
170cdf0e10cSrcweir }
171cdf0e10cSrcweir break;
172cdf0e10cSrcweir
173cdf0e10cSrcweir case css::frame::FrameAction_COMPONENT_REATTACHED :
174cdf0e10cSrcweir {
175cdf0e10cSrcweir // nothing todo here, because its not allowed to change position and size
176cdf0e10cSrcweir // of an alredy existing frame!
177cdf0e10cSrcweir }
178cdf0e10cSrcweir break;
179cdf0e10cSrcweir
180cdf0e10cSrcweir case css::frame::FrameAction_COMPONENT_DETACHING :
181cdf0e10cSrcweir {
182cdf0e10cSrcweir ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
183cdf0e10cSrcweir PersistentWindowState::implst_setWindowStateOnConfig(xSMGR, sModuleName, sWindowState);
184cdf0e10cSrcweir }
185cdf0e10cSrcweir break;
186cdf0e10cSrcweir default:
187cdf0e10cSrcweir break;
188cdf0e10cSrcweir }
189cdf0e10cSrcweir }
190cdf0e10cSrcweir
191cdf0e10cSrcweir //*****************************************************************************************************************
disposing(const css::lang::EventObject &)192cdf0e10cSrcweir void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&)
193cdf0e10cSrcweir throw(css::uno::RuntimeException)
194cdf0e10cSrcweir {
195cdf0e10cSrcweir // nothing todo here - because we hold the frame as weak reference only
196cdf0e10cSrcweir }
197cdf0e10cSrcweir
198cdf0e10cSrcweir //*****************************************************************************************************************
implst_identifyModule(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,const css::uno::Reference<css::frame::XFrame> & xFrame)199cdf0e10cSrcweir ::rtl::OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
200cdf0e10cSrcweir const css::uno::Reference< css::frame::XFrame >& xFrame)
201cdf0e10cSrcweir {
202cdf0e10cSrcweir ::rtl::OUString sModuleName;
203cdf0e10cSrcweir
204cdf0e10cSrcweir css::uno::Reference< css::frame::XModuleManager > xModuleManager(
205cdf0e10cSrcweir xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
206cdf0e10cSrcweir css::uno::UNO_QUERY_THROW);
207cdf0e10cSrcweir
208cdf0e10cSrcweir try
209cdf0e10cSrcweir {
210cdf0e10cSrcweir sModuleName = xModuleManager->identify(xFrame);
211cdf0e10cSrcweir }
212cdf0e10cSrcweir catch(const css::uno::RuntimeException& exRun)
213cdf0e10cSrcweir { throw exRun; }
214cdf0e10cSrcweir catch(const css::uno::Exception&)
215cdf0e10cSrcweir { sModuleName = ::rtl::OUString(); }
216cdf0e10cSrcweir
217cdf0e10cSrcweir return sModuleName;
218cdf0e10cSrcweir }
219cdf0e10cSrcweir
220cdf0e10cSrcweir //*****************************************************************************************************************
implst_getWindowStateFromConfig(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,const::rtl::OUString & sModuleName)221cdf0e10cSrcweir ::rtl::OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
222cdf0e10cSrcweir const ::rtl::OUString& sModuleName)
223cdf0e10cSrcweir {
224cdf0e10cSrcweir ::rtl::OUString sWindowState;
225cdf0e10cSrcweir
226cdf0e10cSrcweir ::rtl::OUStringBuffer sRelPathBuf(256);
227cdf0e10cSrcweir sRelPathBuf.appendAscii("Office/Factories/*[\"");
228cdf0e10cSrcweir sRelPathBuf.append (sModuleName );
229cdf0e10cSrcweir sRelPathBuf.appendAscii("\"]" );
230cdf0e10cSrcweir
231cdf0e10cSrcweir ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
232cdf0e10cSrcweir ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
233cdf0e10cSrcweir ::rtl::OUString sKey = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");
234cdf0e10cSrcweir
235cdf0e10cSrcweir try
236cdf0e10cSrcweir {
237cdf0e10cSrcweir ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
238cdf0e10cSrcweir sPackage,
239cdf0e10cSrcweir sRelPath,
240cdf0e10cSrcweir sKey,
241cdf0e10cSrcweir ::comphelper::ConfigurationHelper::E_READONLY) >>= sWindowState;
242cdf0e10cSrcweir }
243cdf0e10cSrcweir catch(const css::uno::RuntimeException& exRun)
244cdf0e10cSrcweir { throw exRun; }
245cdf0e10cSrcweir catch(const css::uno::Exception&)
246cdf0e10cSrcweir { sWindowState = ::rtl::OUString(); }
247cdf0e10cSrcweir
248cdf0e10cSrcweir return sWindowState;
249cdf0e10cSrcweir }
250cdf0e10cSrcweir
251cdf0e10cSrcweir //*****************************************************************************************************************
implst_setWindowStateOnConfig(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,const::rtl::OUString & sModuleName,const::rtl::OUString & sWindowState)252cdf0e10cSrcweir void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
253cdf0e10cSrcweir const ::rtl::OUString& sModuleName ,
254cdf0e10cSrcweir const ::rtl::OUString& sWindowState)
255cdf0e10cSrcweir {
256cdf0e10cSrcweir ::rtl::OUStringBuffer sRelPathBuf(256);
257cdf0e10cSrcweir sRelPathBuf.appendAscii("Office/Factories/*[\"");
258cdf0e10cSrcweir sRelPathBuf.append (sModuleName );
259cdf0e10cSrcweir sRelPathBuf.appendAscii("\"]" );
260cdf0e10cSrcweir
261cdf0e10cSrcweir ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
262cdf0e10cSrcweir ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
263cdf0e10cSrcweir ::rtl::OUString sKey = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");
264cdf0e10cSrcweir
265cdf0e10cSrcweir try
266cdf0e10cSrcweir {
267cdf0e10cSrcweir ::comphelper::ConfigurationHelper::writeDirectKey(xSMGR,
268cdf0e10cSrcweir sPackage,
269cdf0e10cSrcweir sRelPath,
270cdf0e10cSrcweir sKey,
271cdf0e10cSrcweir css::uno::makeAny(sWindowState),
272cdf0e10cSrcweir ::comphelper::ConfigurationHelper::E_STANDARD);
273cdf0e10cSrcweir }
274cdf0e10cSrcweir catch(const css::uno::RuntimeException& exRun)
275cdf0e10cSrcweir { throw exRun; }
276cdf0e10cSrcweir catch(const css::uno::Exception&)
277cdf0e10cSrcweir {}
278cdf0e10cSrcweir }
279cdf0e10cSrcweir
280cdf0e10cSrcweir //*****************************************************************************************************************
implst_getWindowStateFromWindow(const css::uno::Reference<css::awt::XWindow> & xWindow)281cdf0e10cSrcweir ::rtl::OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
282cdf0e10cSrcweir {
283cdf0e10cSrcweir ::rtl::OUString sWindowState;
284cdf0e10cSrcweir
285cdf0e10cSrcweir if (xWindow.is())
286cdf0e10cSrcweir {
287cdf0e10cSrcweir // SOLAR SAFE -> ------------------------
288cdf0e10cSrcweir ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());
289cdf0e10cSrcweir
290cdf0e10cSrcweir Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
291cdf0e10cSrcweir // check for system window is neccessary to guarantee correct pointer cast!
292cdf0e10cSrcweir if (
293cdf0e10cSrcweir (pWindow ) &&
294cdf0e10cSrcweir (pWindow->IsSystemWindow())
295cdf0e10cSrcweir )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir sal_uLong nMask = WINDOWSTATE_MASK_ALL;
298cdf0e10cSrcweir nMask &= ~(WINDOWSTATE_MASK_MINIMIZED);
299cdf0e10cSrcweir sWindowState = B2U_ENC(
300cdf0e10cSrcweir ((SystemWindow*)pWindow)->GetWindowState(nMask),
301cdf0e10cSrcweir RTL_TEXTENCODING_UTF8);
302cdf0e10cSrcweir }
303cdf0e10cSrcweir
304cdf0e10cSrcweir aSolarLock.clear();
305cdf0e10cSrcweir // <- SOLAR SAFE ------------------------
306cdf0e10cSrcweir }
307cdf0e10cSrcweir
308cdf0e10cSrcweir return sWindowState;
309cdf0e10cSrcweir }
310cdf0e10cSrcweir
311cdf0e10cSrcweir
312cdf0e10cSrcweir //*********************************************************************************************************
implst_setWindowStateOnWindow(const css::uno::Reference<css::awt::XWindow> & xWindow,const::rtl::OUString & sWindowState)313cdf0e10cSrcweir void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow ,
314cdf0e10cSrcweir const ::rtl::OUString& sWindowState)
315cdf0e10cSrcweir {
316cdf0e10cSrcweir if (
317cdf0e10cSrcweir (!xWindow.is() ) ||
318cdf0e10cSrcweir ( sWindowState.getLength() < 1)
319cdf0e10cSrcweir )
320cdf0e10cSrcweir return;
321cdf0e10cSrcweir
322cdf0e10cSrcweir // SOLAR SAFE -> ------------------------
323cdf0e10cSrcweir ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());
324cdf0e10cSrcweir
325cdf0e10cSrcweir Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
326cdf0e10cSrcweir if (!pWindow)
327cdf0e10cSrcweir return;
328cdf0e10cSrcweir
329cdf0e10cSrcweir // check for system and work window - its neccessary to guarantee correct pointer cast!
330cdf0e10cSrcweir sal_Bool bSystemWindow = pWindow->IsSystemWindow();
331cdf0e10cSrcweir sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW);
332cdf0e10cSrcweir
333cdf0e10cSrcweir if (!bSystemWindow && !bWorkWindow)
334cdf0e10cSrcweir return;
335cdf0e10cSrcweir
336cdf0e10cSrcweir SystemWindow* pSystemWindow = (SystemWindow*)pWindow;
337cdf0e10cSrcweir WorkWindow* pWorkWindow = (WorkWindow* )pWindow;
338cdf0e10cSrcweir
339cdf0e10cSrcweir // dont save this special state!
340cdf0e10cSrcweir if (pWorkWindow->IsMinimized())
341cdf0e10cSrcweir return;
342cdf0e10cSrcweir
343cdf0e10cSrcweir ::rtl::OUString sOldWindowState = ::rtl::OStringToOUString( pSystemWindow->GetWindowState(), RTL_TEXTENCODING_ASCII_US );
344cdf0e10cSrcweir if ( sOldWindowState != sWindowState )
345cdf0e10cSrcweir pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));
346cdf0e10cSrcweir
347cdf0e10cSrcweir aSolarLock.clear();
348cdf0e10cSrcweir // <- SOLAR SAFE ------------------------
349cdf0e10cSrcweir }
350cdf0e10cSrcweir
351cdf0e10cSrcweir } // namespace framework
352