1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 //_________________________________________________________________________________________________________________
28 //	my own includes
29 //_________________________________________________________________________________________________________________
30 #include <helper/tagwindowasmodified.hxx>
31 #include <pattern/window.hxx>
32 #include <threadhelp/writeguard.hxx>
33 #include <threadhelp/readguard.hxx>
34 #include <macros/generic.hxx>
35 #include <services.h>
36 
37 //_________________________________________________________________________________________________________________
38 //	interface includes
39 //_________________________________________________________________________________________________________________
40 #include <com/sun/star/awt/XWindow.hpp>
41 
42 #ifndef _COM_SUN_STAR_LANG_XSERVICXEINFO_HPP_
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #endif
45 #include <com/sun/star/util/XModifyBroadcaster.hpp>
46 #include <com/sun/star/util/XModifiable.hpp>
47 #include <com/sun/star/frame/FrameAction.hpp>
48 
49 //_________________________________________________________________________________________________________________
50 //	other includes
51 //_________________________________________________________________________________________________________________
52 
53 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
54 #include <toolkit/helper/vclunohelper.hxx>
55 #endif
56 #include <vcl/window.hxx>
57 #include <vcl/syswin.hxx>
58 #include <vcl/svapp.hxx>
59 #include <vcl/wrkwin.hxx>
60 #include <tools/wintypes.hxx>
61 
62 //_________________________________________________________________________________________________________________
63 //	namespace
64 
65 namespace framework{
66 
67 //_________________________________________________________________________________________________________________
68 //	definitions
69 
70 //*****************************************************************************************************************
71 //  XInterface, XTypeProvider
72 
DEFINE_XINTERFACE_4(TagWindowAsModified,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::lang::XInitialization),DIRECT_INTERFACE (css::util::XModifyListener),DERIVED_INTERFACE (css::lang::XEventListener,css::util::XModifyListener))73 DEFINE_XINTERFACE_4(TagWindowAsModified                                                     ,
74                     OWeakObject                                                             ,
75                     DIRECT_INTERFACE (css::lang::XTypeProvider                             ),
76                     DIRECT_INTERFACE (css::lang::XInitialization                           ),
77                     DIRECT_INTERFACE (css::util::XModifyListener                           ),
78                     DERIVED_INTERFACE(css::lang::XEventListener, css::util::XModifyListener))
79 
80 DEFINE_XTYPEPROVIDER_4(TagWindowAsModified        ,
81                        css::lang::XTypeProvider   ,
82                        css::lang::XInitialization ,
83                        css::util::XModifyListener ,
84                        css::lang::XEventListener  )
85 
86 //*****************************************************************************************************************
87 TagWindowAsModified::TagWindowAsModified(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
88     : ThreadHelpBase          (&Application::GetSolarMutex())
89     , m_xSMGR                 (xSMGR                        )
90 {
91 }
92 
93 //*****************************************************************************************************************
~TagWindowAsModified()94 TagWindowAsModified::~TagWindowAsModified()
95 {
96 }
97 
98 //*****************************************************************************************************************
initialize(const css::uno::Sequence<css::uno::Any> & lArguments)99 void SAL_CALL TagWindowAsModified::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
100     throw(css::uno::Exception       ,
101           css::uno::RuntimeException)
102 {
103     css::uno::Reference< css::frame::XFrame > xFrame;
104 
105     if (lArguments.getLength() > 0)
106         lArguments[0] >>= xFrame;
107 
108     if ( ! xFrame.is ())
109         return;
110 
111     // SAFE -> ----------------------------------
112     WriteGuard aWriteLock(m_aLock);
113     m_xFrame = xFrame ;
114     aWriteLock.unlock();
115     // <- SAFE ----------------------------------
116 
117     xFrame->addFrameActionListener(this);
118     impl_update (xFrame);
119 }
120 
121 //*****************************************************************************************************************
modified(const css::lang::EventObject & aEvent)122 void SAL_CALL TagWindowAsModified::modified(const css::lang::EventObject& aEvent)
123     throw(css::uno::RuntimeException)
124 {
125     // SAFE -> ----------------------------------
126     ReadGuard aReadLock(m_aLock);
127 
128     css::uno::Reference< css::util::XModifiable > xModel (m_xModel.get (), css::uno::UNO_QUERY);
129     css::uno::Reference< css::awt::XWindow >      xWindow(m_xWindow.get(), css::uno::UNO_QUERY);
130     if (
131         ( ! xModel.is  ()       ) ||
132         ( ! xWindow.is ()       ) ||
133         (aEvent.Source != xModel)
134        )
135         return;
136 
137     aReadLock.unlock();
138     // <- SAFE ----------------------------------
139 
140     ::sal_Bool bModified = xModel->isModified ();
141 
142     // SYNCHRONIZED ->
143     ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex());
144 
145     Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
146     if ( ! pWindow)
147         return;
148 
149     sal_Bool bSystemWindow = pWindow->IsSystemWindow();
150     sal_Bool bWorkWindow   = (pWindow->GetType() == WINDOW_WORKWINDOW);
151     if (!bSystemWindow && !bWorkWindow)
152         return;
153 
154     if (bModified)
155         pWindow->SetExtendedStyle(WB_EXT_DOCMODIFIED);
156     else
157         pWindow->SetExtendedStyle( ! WB_EXT_DOCMODIFIED);
158 
159     aSolarGuard.clear();
160     // <- SYNCHRONIZED
161 }
162 
163 //*****************************************************************************************************************
frameAction(const css::frame::FrameActionEvent & aEvent)164 void SAL_CALL TagWindowAsModified::frameAction(const css::frame::FrameActionEvent& aEvent)
165     throw(css::uno::RuntimeException)
166 {
167     if (
168         (aEvent.Action != css::frame::FrameAction_COMPONENT_REATTACHED) &&
169         (aEvent.Action != css::frame::FrameAction_COMPONENT_ATTACHED  )
170        )
171         return;
172 
173     // SAFE -> ----------------------------------
174     WriteGuard aWriteLock(m_aLock);
175 
176     css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
177     if (
178         ( ! xFrame.is ()        ) ||
179         (aEvent.Source != xFrame)
180        )
181         return;
182 
183     aWriteLock.unlock();
184     // <- SAFE ----------------------------------
185 
186     impl_update (xFrame);
187 }
188 
189 //*****************************************************************************************************************
disposing(const css::lang::EventObject & aEvent)190 void SAL_CALL TagWindowAsModified::disposing(const css::lang::EventObject& aEvent)
191     throw(css::uno::RuntimeException)
192 {
193     // SAFE -> ----------------------------------
194     WriteGuard aWriteLock(m_aLock);
195 
196     css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
197     if (
198         (xFrame.is ()           ) &&
199         (aEvent.Source == xFrame)
200        )
201     {
202         m_xFrame = css::uno::Reference< css::frame::XFrame >();
203         return;
204     }
205 
206     css::uno::Reference< css::frame::XModel > xModel(m_xModel.get(), css::uno::UNO_QUERY);
207     if (
208         (xModel.is ()           ) &&
209         (aEvent.Source == xModel)
210        )
211     {
212         m_xModel = css::uno::Reference< css::frame::XModel >();
213         return;
214     }
215 
216     aWriteLock.unlock();
217     // <- SAFE ----------------------------------
218 }
219 
220 //*****************************************************************************************************************
impl_update(const css::uno::Reference<css::frame::XFrame> & xFrame)221 void TagWindowAsModified::impl_update (const css::uno::Reference< css::frame::XFrame >& xFrame)
222 {
223     if ( ! xFrame.is ())
224         return;
225 
226     css::uno::Reference< css::awt::XWindow >       xWindow     = xFrame->getContainerWindow ();
227     css::uno::Reference< css::frame::XController > xController = xFrame->getController ();
228     css::uno::Reference< css::frame::XModel >      xModel ;
229     if (xController.is ())
230         xModel = xController->getModel ();
231 
232     if (
233         ( ! xWindow.is ()) ||
234         ( ! xModel.is  ())
235        )
236         return;
237 
238     // SAFE -> ----------------------------------
239     WriteGuard aWriteLock(m_aLock);
240     // Note: frame was set as member outside ! we have to refresh connections
241     // regarding window and model only here.
242     m_xWindow = xWindow;
243     m_xModel  = xModel ;
244     aWriteLock.unlock();
245     // <- SAFE ----------------------------------
246 
247     css::uno::Reference< css::util::XModifyBroadcaster > xModifiable(xModel, css::uno::UNO_QUERY);
248     if (xModifiable.is ())
249         xModifiable->addModifyListener (this);
250 }
251 
252 } // namespace framework
253