Line data Source code
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 :
20 :
21 : #include <svtools/genericunodialog.hxx>
22 :
23 : #include <com/sun/star/beans/NamedValue.hpp>
24 : #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
25 :
26 : #include <toolkit/awt/vclxwindow.hxx>
27 : #include <cppuhelper/supportsservice.hxx>
28 : #include <cppuhelper/queryinterface.hxx>
29 : #include <cppuhelper/typeprovider.hxx>
30 : #include <comphelper/property.hxx>
31 : #include <osl/diagnose.h>
32 : #include <tools/diagnose_ex.h>
33 : #include <vcl/msgbox.hxx>
34 : #include <osl/mutex.hxx>
35 : #include <vcl/svapp.hxx>
36 :
37 : using namespace ::comphelper;
38 : using namespace ::com::sun::star::uno;
39 : using namespace ::com::sun::star::lang;
40 : using namespace ::com::sun::star::beans;
41 : using namespace ::com::sun::star::ucb;
42 :
43 :
44 : namespace svt
45 : {
46 :
47 :
48 :
49 9 : OGenericUnoDialog::OGenericUnoDialog(const Reference< XComponentContext >& _rxContext)
50 9 : :OPropertyContainer(GetBroadcastHelper())
51 : ,m_pDialog(NULL)
52 : ,m_bExecuting(false)
53 : ,m_bCanceled(false)
54 : ,m_bTitleAmbiguous(true)
55 : ,m_bInitialized( false )
56 : ,m_bNeedInitialization( false )
57 18 : ,m_aContext(_rxContext)
58 : {
59 : registerProperty(OUString(UNODIALOG_PROPERTY_TITLE), UNODIALOG_PROPERTY_ID_TITLE, PropertyAttribute::TRANSIENT,
60 9 : &m_sTitle, cppu::UnoType<decltype(m_sTitle)>::get());
61 : registerProperty(OUString(UNODIALOG_PROPERTY_PARENT), UNODIALOG_PROPERTY_ID_PARENT, PropertyAttribute::TRANSIENT,
62 9 : &m_xParent, cppu::UnoType<decltype(m_xParent)>::get());
63 9 : }
64 :
65 :
66 18 : OGenericUnoDialog::~OGenericUnoDialog()
67 : {
68 9 : if ( m_pDialog )
69 : {
70 0 : SolarMutexGuard aSolarGuard;
71 0 : ::osl::MutexGuard aGuard( m_aMutex );
72 0 : if ( m_pDialog )
73 0 : destroyDialog();
74 : }
75 9 : }
76 :
77 :
78 40 : Any SAL_CALL OGenericUnoDialog::queryInterface(const Type& _rType) throw (RuntimeException, std::exception)
79 : {
80 40 : Any aReturn = OGenericUnoDialogBase::queryInterface(_rType);
81 :
82 40 : if (!aReturn.hasValue())
83 16 : aReturn = ::cppu::queryInterface(_rType
84 : ,static_cast<XPropertySet*>(this)
85 : ,static_cast<XMultiPropertySet*>(this)
86 : ,static_cast<XFastPropertySet*>(this)
87 8 : );
88 :
89 40 : return aReturn;
90 : }
91 :
92 :
93 0 : Sequence<Type> SAL_CALL OGenericUnoDialog::getTypes( ) throw(RuntimeException, std::exception)
94 : {
95 : return ::comphelper::concatSequences(
96 : OGenericUnoDialogBase::getTypes(),
97 : getBaseTypes()
98 0 : );
99 : }
100 :
101 1 : sal_Bool SAL_CALL OGenericUnoDialog::supportsService(const OUString& ServiceName) throw(RuntimeException, std::exception)
102 : {
103 1 : return cppu::supportsService(this, ServiceName);
104 : }
105 :
106 :
107 8 : void OGenericUnoDialog::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw(Exception, std::exception)
108 : {
109 : // TODO : need some handling if we're currently executing ...
110 :
111 8 : OPropertyContainer::setFastPropertyValue_NoBroadcast(nHandle, rValue);
112 :
113 8 : if (UNODIALOG_PROPERTY_ID_TITLE == nHandle)
114 : {
115 : // from now on m_sTitle is valid
116 7 : m_bTitleAmbiguous = false;
117 :
118 7 : if (m_pDialog)
119 0 : m_pDialog->SetText(m_sTitle);
120 : }
121 8 : }
122 :
123 :
124 8 : sal_Bool OGenericUnoDialog::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) throw(IllegalArgumentException)
125 : {
126 8 : switch (nHandle)
127 : {
128 : case UNODIALOG_PROPERTY_ID_PARENT:
129 : {
130 1 : Reference<css::awt::XWindow> xNew(rValue, css::uno::UNO_QUERY);
131 1 : if (xNew != m_xParent)
132 : {
133 1 : rConvertedValue <<= xNew;
134 1 : rOldValue <<= m_xParent;
135 1 : return sal_True;
136 : }
137 0 : return sal_False;
138 : }
139 : }
140 7 : return OPropertyContainer::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
141 : }
142 :
143 :
144 2 : void SAL_CALL OGenericUnoDialog::setTitle( const OUString& _rTitle ) throw(RuntimeException, std::exception)
145 : {
146 2 : UnoDialogEntryGuard aGuard( *this );
147 :
148 : try
149 : {
150 2 : setPropertyValue(OUString(UNODIALOG_PROPERTY_TITLE), makeAny(_rTitle));
151 : }
152 0 : catch(RuntimeException&)
153 : {
154 : // allowed to pass
155 0 : throw;
156 : }
157 0 : catch( const Exception& )
158 : {
159 : DBG_UNHANDLED_EXCEPTION();
160 : // not allowed to pass
161 2 : }
162 2 : }
163 :
164 :
165 0 : bool OGenericUnoDialog::impl_ensureDialog_lck()
166 : {
167 0 : if ( m_pDialog )
168 0 : return true;
169 :
170 : // get the parameters for the dialog from the current settings
171 :
172 : // the parent window
173 0 : vcl::Window* pParent = NULL;
174 0 : VCLXWindow* pImplementation = VCLXWindow::GetImplementation(m_xParent);
175 0 : if (pImplementation)
176 0 : pParent = pImplementation->GetWindow();
177 :
178 : // the title
179 0 : OUString sTitle = m_sTitle;
180 :
181 0 : VclPtr<Dialog> pDialog = createDialog( pParent );
182 : OSL_ENSURE( pDialog, "OGenericUnoDialog::impl_ensureDialog_lck: createDialog returned nonsense!" );
183 0 : if ( !pDialog )
184 0 : return false;
185 :
186 : // do some initialisations
187 0 : if ( !m_bTitleAmbiguous )
188 0 : pDialog->SetText( sTitle );
189 :
190 : // be notified when the dialog is killed by somebody else
191 : // #i65958# / 2006-07-07 / frank.schoenheit@sun.com
192 0 : pDialog->AddEventListener( LINK( this, OGenericUnoDialog, OnDialogDying ) );
193 :
194 0 : m_pDialog = pDialog;
195 :
196 0 : return true;
197 : }
198 :
199 :
200 0 : sal_Int16 SAL_CALL OGenericUnoDialog::execute( ) throw(RuntimeException, std::exception)
201 : {
202 : // both creation and execution of the dialog must be guarded with the SolarMutex, so be generous here
203 0 : SolarMutexGuard aSolarGuard;
204 :
205 0 : Dialog* pDialogToExecute = NULL;
206 : // create the dialog, if necessary
207 : {
208 0 : UnoDialogEntryGuard aGuard( *this );
209 :
210 0 : if (m_bExecuting)
211 : throw RuntimeException(
212 : "already executing the dialog (recursive call)",
213 : *this
214 0 : );
215 :
216 0 : m_bCanceled = false;
217 0 : m_bExecuting = true;
218 :
219 0 : if ( !impl_ensureDialog_lck() )
220 0 : return 0;
221 :
222 0 : pDialogToExecute = m_pDialog;
223 : }
224 :
225 : // start execution
226 0 : sal_Int16 nReturn(0);
227 0 : if ( pDialogToExecute )
228 0 : nReturn = pDialogToExecute->Execute();
229 :
230 : {
231 0 : ::osl::MutexGuard aExecutionGuard(m_aExecutionMutex);
232 0 : if (m_bCanceled)
233 0 : nReturn = RET_CANCEL;
234 : }
235 :
236 : {
237 0 : ::osl::MutexGuard aGuard(m_aMutex);
238 :
239 : // get the settings of the dialog
240 0 : executedDialog( nReturn );
241 :
242 0 : m_bExecuting = false;
243 : }
244 :
245 : // outta here
246 0 : return nReturn;
247 : }
248 :
249 : #ifdef AWT_DIALOG
250 :
251 : void SAL_CALL OGenericUnoDialog::endExecute( ) throw(RuntimeException)
252 : {
253 : UnoDialogEntryGuard aGuard( *this );
254 : if (!m_bExecuting)
255 : throw RuntimeException();
256 :
257 : {
258 : ::osl::MutexGuard aExecutionGuard(m_aExecutionMutex);
259 : OSL_ENSURE(m_pDialog, "OGenericUnoDialog::endExecute : executing which dialog ?");
260 : // m_bExecuting is true but we have no dialog ?
261 : if (!m_pDialog)
262 : throw RuntimeException();
263 :
264 : if (!m_pDialog->IsInExecute())
265 : // we tighly missed it ... another thread finished the execution of the dialog,
266 : // but did not manage it to reset m_bExecuting, it currently tries to acquire
267 : // m_aMutex or m_aExecutionMutex
268 : // => nothing to do
269 : return;
270 :
271 : m_pDialog->EndDialog(RET_CANCEL);
272 : m_bCanceled = sal_True;
273 : }
274 : }
275 : #endif
276 :
277 :
278 0 : void OGenericUnoDialog::implInitialize(const Any& _rValue)
279 : {
280 : try
281 : {
282 0 : PropertyValue aProperty;
283 0 : NamedValue aValue;
284 0 : if ( _rValue >>= aProperty )
285 : {
286 0 : setPropertyValue( aProperty.Name, aProperty.Value );
287 : }
288 0 : else if ( _rValue >>= aValue )
289 : {
290 0 : setPropertyValue( aValue.Name, aValue.Value );
291 0 : }
292 : }
293 0 : catch(const Exception&)
294 : {
295 : DBG_UNHANDLED_EXCEPTION();
296 : }
297 0 : }
298 :
299 :
300 4 : void SAL_CALL OGenericUnoDialog::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException, std::exception)
301 : {
302 4 : ::osl::MutexGuard aGuard( m_aMutex );
303 4 : if ( m_bInitialized )
304 0 : throw AlreadyInitializedException( OUString(), *this );
305 :
306 4 : const Any* pArguments = aArguments.getConstArray();
307 4 : for (sal_Int32 i=0; i<aArguments.getLength(); ++i, ++pArguments)
308 0 : implInitialize(*pArguments);
309 :
310 4 : m_bInitialized = true;
311 4 : }
312 :
313 :
314 0 : void OGenericUnoDialog::destroyDialog()
315 : {
316 0 : m_pDialog.disposeAndClear();
317 0 : }
318 :
319 :
320 0 : IMPL_LINK( OGenericUnoDialog, OnDialogDying, VclWindowEvent*, _pEvent )
321 : {
322 : OSL_ENSURE( _pEvent->GetWindow() == m_pDialog, "OGenericUnoDialog::OnDialogDying: where does this come from?" );
323 0 : if ( _pEvent->GetId() == VCLEVENT_OBJECT_DYING )
324 0 : m_pDialog = NULL;
325 0 : return 0L;
326 : }
327 :
328 :
329 : } // namespace svt
330 :
331 :
332 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|