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 "propbrw.hxx"
22 : #include "basidesh.hxx"
23 : #include "dlgedobj.hxx"
24 : #include "iderid.hxx"
25 : #include "baside3.hxx"
26 :
27 : #include "dlgresid.hrc"
28 : #include <svx/svxids.hrc>
29 :
30 : #include <com/sun/star/awt/PosSize.hpp>
31 : #include <com/sun/star/frame/Frame.hpp>
32 : #include <com/sun/star/inspection/XObjectInspector.hpp>
33 : #include <com/sun/star/lang/XServiceInfo.hpp>
34 : #include <comphelper/types.hxx>
35 : #include <cppuhelper/component_context.hxx>
36 : #include <svx/svditer.hxx>
37 : #include <svx/svdview.hxx>
38 : #include <toolkit/helper/vclunohelper.hxx>
39 : #include <tools/diagnose_ex.h>
40 : #include <vcl/stdtext.hxx>
41 :
42 : #include <boost/scoped_ptr.hpp>
43 :
44 : namespace basctl
45 : {
46 :
47 : using namespace ::com::sun::star;
48 : using namespace ::com::sun::star::uno;
49 : using namespace ::com::sun::star::lang;
50 : using namespace ::com::sun::star::frame;
51 : using namespace ::com::sun::star::beans;
52 : using namespace ::com::sun::star::container;
53 : using namespace ::comphelper;
54 :
55 :
56 0 : void PropBrw::Update( const SfxViewShell* pShell )
57 : {
58 0 : Shell const* pIdeShell = dynamic_cast<Shell const*>(pShell);
59 : OSL_ENSURE( pIdeShell || !pShell, "PropBrw::Update: invalid shell!" );
60 0 : if (pIdeShell)
61 0 : ImplUpdate(pIdeShell->GetCurrentDocument(), pIdeShell->GetCurDlgView());
62 0 : else if (pShell)
63 0 : ImplUpdate(NULL, pShell->GetDrawView());
64 : else
65 0 : ImplUpdate(NULL, NULL);
66 0 : }
67 :
68 :
69 : namespace
70 : {
71 :
72 : const long STD_WIN_SIZE_X = 300;
73 : const long STD_WIN_SIZE_Y = 350;
74 :
75 : const long STD_MIN_SIZE_X = 250;
76 : const long STD_MIN_SIZE_Y = 250;
77 :
78 : const long WIN_BORDER = 2;
79 :
80 : } // namespace
81 :
82 :
83 : DBG_NAME(PropBrw)
84 :
85 :
86 0 : PropBrw::PropBrw (DialogWindowLayout& rLayout_):
87 : DockingWindow(&rLayout_),
88 : m_bInitialStateChange(true),
89 0 : m_xContextDocument(SfxViewShell::Current() ? SfxViewShell::Current()->GetCurrentDocument() : Reference<XModel>()),
90 : rLayout(rLayout_),
91 0 : pView(0)
92 : {
93 : DBG_CTOR(PropBrw,NULL);
94 :
95 0 : Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
96 0 : SetMinOutputSizePixel(Size(STD_MIN_SIZE_X,STD_MIN_SIZE_Y));
97 0 : SetOutputSizePixel(aPropWinSize);
98 :
99 : try
100 : {
101 : // create a frame wrapper for myself
102 0 : m_xMeAsFrame = frame::Frame::create( comphelper::getProcessComponentContext() );
103 0 : m_xMeAsFrame->initialize( VCLUnoHelper::GetInterface ( this ) );
104 0 : m_xMeAsFrame->setName( "form property browser" ); // change name!
105 : }
106 0 : catch (const Exception&)
107 : {
108 : OSL_FAIL("PropBrw::PropBrw: could not create/initialize my frame!");
109 0 : m_xMeAsFrame.clear();
110 : }
111 :
112 0 : ImplReCreateController();
113 0 : }
114 :
115 :
116 0 : void PropBrw::ImplReCreateController()
117 : {
118 : OSL_PRECOND( m_xMeAsFrame.is(), "PropBrw::ImplCreateController: no frame for myself!" );
119 0 : if ( !m_xMeAsFrame.is() )
120 0 : return;
121 :
122 0 : if ( m_xBrowserController.is() )
123 0 : ImplDestroyController();
124 :
125 : try
126 : {
127 0 : Reference< XComponentContext > xOwnContext = comphelper::getProcessComponentContext();
128 :
129 : // a ComponentContext for the
130 : ::cppu::ContextEntry_Init aHandlerContextInfo[] =
131 : {
132 : ::cppu::ContextEntry_Init( "DialogParentWindow", makeAny( VCLUnoHelper::GetInterface ( this ) ) ),
133 : ::cppu::ContextEntry_Init( "ContextDocument", makeAny( m_xContextDocument ) )
134 0 : };
135 : Reference< XComponentContext > xInspectorContext(
136 0 : ::cppu::createComponentContext( aHandlerContextInfo, SAL_N_ELEMENTS( aHandlerContextInfo ), xOwnContext ) );
137 :
138 : // create a property browser controller
139 0 : Reference< XMultiComponentFactory > xFactory( xInspectorContext->getServiceManager(), UNO_QUERY_THROW );
140 0 : static const OUString s_sControllerServiceName( "com.sun.star.awt.PropertyBrowserController" );
141 0 : m_xBrowserController = Reference< XPropertySet >(
142 0 : xFactory->createInstanceWithContext( s_sControllerServiceName, xInspectorContext ), UNO_QUERY
143 0 : );
144 0 : if ( !m_xBrowserController.is() )
145 : {
146 0 : ShowServiceNotAvailableError( GetParent(), s_sControllerServiceName, true );
147 : }
148 : else
149 : {
150 0 : Reference< XController > xAsXController( m_xBrowserController, UNO_QUERY );
151 : DBG_ASSERT(xAsXController.is(), "PropBrw::PropBrw: invalid controller object!");
152 0 : if (!xAsXController.is())
153 : {
154 0 : ::comphelper::disposeComponent(m_xBrowserController);
155 0 : m_xBrowserController.clear();
156 : }
157 : else
158 : {
159 0 : xAsXController->attachFrame( Reference<XFrame>(m_xMeAsFrame,UNO_QUERY_THROW) );
160 0 : m_xBrowserComponentWindow = m_xMeAsFrame->getComponentWindow();
161 : DBG_ASSERT(m_xBrowserComponentWindow.is(), "PropBrw::PropBrw: attached the controller, but have no component window!");
162 0 : }
163 : }
164 :
165 0 : Point aPropWinPos = Point( WIN_BORDER, WIN_BORDER );
166 0 : Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
167 0 : aPropWinSize.Width() -= (2*WIN_BORDER);
168 0 : aPropWinSize.Height() -= (2*WIN_BORDER);
169 :
170 0 : if ( m_xBrowserComponentWindow.is() )
171 : {
172 0 : m_xBrowserComponentWindow->setPosSize(aPropWinPos.X(), aPropWinPos.Y(), aPropWinSize.Width(), aPropWinSize.Height(),
173 : ::com::sun::star::awt::PosSize::WIDTH | ::com::sun::star::awt::PosSize::HEIGHT |
174 0 : ::com::sun::star::awt::PosSize::X | ::com::sun::star::awt::PosSize::Y);
175 0 : m_xBrowserComponentWindow->setVisible(true);
176 0 : }
177 : }
178 0 : catch (const Exception&)
179 : {
180 : OSL_FAIL("PropBrw::PropBrw: could not create/initialize the browser controller!");
181 : try
182 : {
183 0 : ::comphelper::disposeComponent(m_xBrowserController);
184 0 : ::comphelper::disposeComponent(m_xBrowserComponentWindow);
185 : }
186 0 : catch(const Exception&)
187 : {
188 : }
189 :
190 0 : m_xBrowserController.clear();
191 0 : m_xBrowserComponentWindow.clear();
192 : }
193 :
194 0 : Resize();
195 : }
196 :
197 :
198 0 : PropBrw::~PropBrw()
199 : {
200 0 : if ( m_xBrowserController.is() )
201 0 : ImplDestroyController();
202 0 : rLayout.RemovePropertyBrowser();
203 :
204 : DBG_DTOR(PropBrw,NULL);
205 0 : }
206 :
207 :
208 0 : void PropBrw::ImplDestroyController()
209 : {
210 0 : implSetNewObject( Reference< XPropertySet >() );
211 :
212 0 : if ( m_xMeAsFrame.is() )
213 0 : m_xMeAsFrame->setComponent( NULL, NULL );
214 :
215 0 : Reference< XController > xAsXController( m_xBrowserController, UNO_QUERY );
216 0 : if ( xAsXController.is() )
217 0 : xAsXController->attachFrame( NULL );
218 :
219 : try
220 : {
221 0 : ::comphelper::disposeComponent( m_xBrowserController );
222 : }
223 0 : catch( const Exception& )
224 : {
225 : DBG_UNHANDLED_EXCEPTION();
226 : }
227 :
228 0 : m_xBrowserController.clear();
229 0 : }
230 :
231 :
232 0 : sal_Bool PropBrw::Close()
233 : {
234 0 : ImplDestroyController();
235 :
236 0 : if( IsRollUp() )
237 0 : RollDown();
238 :
239 0 : return DockingWindow::Close();
240 : }
241 :
242 :
243 : Sequence< Reference< XInterface > >
244 0 : PropBrw::CreateMultiSelectionSequence( const SdrMarkList& _rMarkList )
245 : {
246 0 : Sequence< Reference< XInterface > > aSeq;
247 0 : InterfaceArray aInterfaces;
248 :
249 0 : sal_uInt32 nMarkCount = _rMarkList.GetMarkCount();
250 0 : for( sal_uInt32 i = 0 ; i < nMarkCount ; i++ )
251 : {
252 0 : SdrObject* pCurrent = _rMarkList.GetMark(i)->GetMarkedSdrObj();
253 :
254 0 : boost::scoped_ptr<SdrObjListIter> pGroupIterator;
255 0 : if (pCurrent->IsGroupObject())
256 : {
257 0 : pGroupIterator.reset(new SdrObjListIter(*pCurrent->GetSubList()));
258 0 : pCurrent = pGroupIterator->IsMore() ? pGroupIterator->Next() : NULL;
259 : }
260 :
261 0 : while (pCurrent)
262 : {
263 0 : if (DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pCurrent))
264 : {
265 0 : Reference< XInterface > xControlInterface(pDlgEdObj->GetUnoControlModel(), UNO_QUERY);
266 0 : if (xControlInterface.is())
267 0 : aInterfaces.push_back(xControlInterface);
268 : }
269 :
270 : // next element
271 0 : pCurrent = pGroupIterator && pGroupIterator->IsMore() ? pGroupIterator->Next() : NULL;
272 : }
273 0 : }
274 :
275 0 : sal_Int32 nCount = aInterfaces.size();
276 0 : aSeq.realloc( nCount );
277 0 : Reference< XInterface >* pInterfaces = aSeq.getArray();
278 0 : for( sal_Int32 i = 0 ; i < nCount ; i++ )
279 0 : pInterfaces[i] = aInterfaces[i];
280 :
281 0 : return aSeq;
282 : }
283 :
284 :
285 0 : void PropBrw::implSetNewObjectSequence
286 : ( const Sequence< Reference< XInterface > >& _rObjectSeq )
287 : {
288 0 : Reference< inspection::XObjectInspector > xObjectInspector(m_xBrowserController, UNO_QUERY);
289 0 : if ( xObjectInspector.is() )
290 : {
291 0 : xObjectInspector->inspect( _rObjectSeq );
292 :
293 0 : OUString aText = IDE_RESSTR(RID_STR_BRWTITLE_PROPERTIES);
294 0 : aText += IDE_RESSTR(RID_STR_BRWTITLE_MULTISELECT);
295 0 : SetText( aText );
296 0 : }
297 0 : }
298 :
299 :
300 0 : void PropBrw::implSetNewObject( const Reference< XPropertySet >& _rxObject )
301 : {
302 0 : if ( m_xBrowserController.is() )
303 : {
304 0 : m_xBrowserController->setPropertyValue( "IntrospectedObject",
305 : makeAny( _rxObject )
306 0 : );
307 :
308 : // set the new title according to the selected object
309 0 : SetText( GetHeadlineName( _rxObject ) );
310 : }
311 0 : }
312 :
313 :
314 0 : OUString PropBrw::GetHeadlineName( const Reference< XPropertySet >& _rxObject )
315 : {
316 0 : OUString aName;
317 0 : Reference< lang::XServiceInfo > xServiceInfo( _rxObject, UNO_QUERY );
318 :
319 0 : if (xServiceInfo.is()) // single selection
320 : {
321 0 : sal_uInt16 nResId = 0;
322 0 : aName = IDE_RESSTR(RID_STR_BRWTITLE_PROPERTIES);
323 :
324 0 : if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlDialogModel" ) )
325 : {
326 0 : nResId = RID_STR_CLASS_DIALOG;
327 : }
328 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlButtonModel" ) )
329 : {
330 0 : nResId = RID_STR_CLASS_BUTTON;
331 : }
332 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) )
333 : {
334 0 : nResId = RID_STR_CLASS_RADIOBUTTON;
335 : }
336 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) )
337 : {
338 0 : nResId = RID_STR_CLASS_CHECKBOX;
339 : }
340 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) )
341 : {
342 0 : nResId = RID_STR_CLASS_LISTBOX;
343 : }
344 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) )
345 : {
346 0 : nResId = RID_STR_CLASS_COMBOBOX;
347 : }
348 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) )
349 : {
350 0 : nResId = RID_STR_CLASS_GROUPBOX;
351 : }
352 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlEditModel" ) )
353 : {
354 0 : nResId = RID_STR_CLASS_EDIT;
355 : }
356 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
357 : {
358 0 : nResId = RID_STR_CLASS_FIXEDTEXT;
359 : }
360 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) )
361 : {
362 0 : nResId = RID_STR_CLASS_IMAGECONTROL;
363 : }
364 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) )
365 : {
366 0 : nResId = RID_STR_CLASS_PROGRESSBAR;
367 : }
368 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) )
369 : {
370 0 : nResId = RID_STR_CLASS_SCROLLBAR;
371 : }
372 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ) )
373 : {
374 0 : nResId = RID_STR_CLASS_FIXEDLINE;
375 : }
376 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ) )
377 : {
378 0 : nResId = RID_STR_CLASS_DATEFIELD;
379 : }
380 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ) )
381 : {
382 0 : nResId = RID_STR_CLASS_TIMEFIELD;
383 : }
384 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ) )
385 : {
386 0 : nResId = RID_STR_CLASS_NUMERICFIELD;
387 : }
388 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ) )
389 : {
390 0 : nResId = RID_STR_CLASS_CURRENCYFIELD;
391 : }
392 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
393 : {
394 0 : nResId = RID_STR_CLASS_FORMATTEDFIELD;
395 : }
396 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ) )
397 : {
398 0 : nResId = RID_STR_CLASS_PATTERNFIELD;
399 : }
400 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFileControlModel" ) )
401 : {
402 0 : nResId = RID_STR_CLASS_FILECONTROL;
403 : }
404 0 : else if ( xServiceInfo->supportsService( "com.sun.star.awt.tree.TreeControlModel" ) )
405 : {
406 0 : nResId = RID_STR_CLASS_TREECONTROL;
407 : }
408 : else
409 : {
410 0 : nResId = RID_STR_CLASS_CONTROL;
411 : }
412 :
413 0 : if (nResId)
414 : {
415 0 : aName += IDE_RESSTR(nResId);
416 : }
417 : }
418 0 : else if (!_rxObject.is()) // no properties
419 : {
420 0 : aName = IDE_RESSTR(RID_STR_BRWTITLE_NO_PROPERTIES);
421 : }
422 :
423 0 : return aName;
424 : }
425 :
426 :
427 0 : void PropBrw::Resize()
428 : {
429 0 : DockingWindow::Resize();
430 :
431 : // adjust size
432 0 : Size aSize_ = GetOutputSizePixel();
433 0 : Size aPropWinSize( aSize_ );
434 0 : aPropWinSize.Width() -= (2*WIN_BORDER);
435 0 : aPropWinSize.Height() -= (2*WIN_BORDER);
436 :
437 0 : if (m_xBrowserComponentWindow.is())
438 : {
439 0 : m_xBrowserComponentWindow->setPosSize(0, 0, aPropWinSize.Width(), aPropWinSize.Height(),
440 0 : ::com::sun::star::awt::PosSize::WIDTH | ::com::sun::star::awt::PosSize::HEIGHT);
441 : }
442 0 : }
443 :
444 :
445 0 : void PropBrw::ImplUpdate( const Reference< XModel >& _rxContextDocument, SdrView* pNewView )
446 : {
447 0 : Reference< XModel > xContextDocument( _rxContextDocument );
448 :
449 : // if we should simply "empty" ourself, assume the context document didn't change
450 0 : if ( !pNewView )
451 : {
452 : OSL_ENSURE( !_rxContextDocument.is(), "PropBrw::ImplUpdate: no view, but a document?!" );
453 0 : xContextDocument = m_xContextDocument;
454 : }
455 :
456 0 : if ( xContextDocument != m_xContextDocument )
457 : {
458 0 : m_xContextDocument = xContextDocument;
459 0 : ImplReCreateController();
460 : }
461 :
462 : try
463 : {
464 0 : if ( pView )
465 : {
466 0 : EndListening( *(pView->GetModel()) );
467 0 : pView = NULL;
468 : }
469 :
470 0 : if ( !pNewView )
471 0 : return;
472 :
473 0 : pView = pNewView;
474 :
475 : // set focus on initialization
476 0 : if ( m_bInitialStateChange )
477 : {
478 0 : if ( m_xBrowserComponentWindow.is() )
479 0 : m_xBrowserComponentWindow->setFocus();
480 0 : m_bInitialStateChange = false;
481 : }
482 :
483 0 : const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
484 0 : sal_uInt32 nMarkCount = rMarkList.GetMarkCount();
485 :
486 0 : if ( nMarkCount == 0 )
487 : {
488 0 : EndListening( *(pView->GetModel()) );
489 0 : pView = NULL;
490 0 : implSetNewObject( NULL );
491 0 : return;
492 : }
493 :
494 0 : Reference< XPropertySet > xNewObject;
495 0 : Sequence< Reference< XInterface > > aNewObjects;
496 0 : if ( nMarkCount == 1 )
497 : {
498 0 : if (DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(rMarkList.GetMark(0)->GetMarkedSdrObj()))
499 : {
500 0 : if ( pDlgEdObj->IsGroupObject() ) // group object
501 0 : aNewObjects = CreateMultiSelectionSequence( rMarkList );
502 : else // single selection
503 0 : xNewObject = xNewObject.query( pDlgEdObj->GetUnoControlModel() );
504 : }
505 : }
506 0 : else if ( nMarkCount > 1 ) // multiple selection
507 : {
508 0 : aNewObjects = CreateMultiSelectionSequence( rMarkList );
509 : }
510 :
511 0 : if ( aNewObjects.getLength() )
512 0 : implSetNewObjectSequence( aNewObjects );
513 : else
514 0 : implSetNewObject( xNewObject );
515 :
516 0 : StartListening( *(pView->GetModel()) );
517 : }
518 0 : catch ( const PropertyVetoException& ) { /* silence */ }
519 0 : catch ( const Exception& )
520 : {
521 : DBG_UNHANDLED_EXCEPTION();
522 0 : }
523 : }
524 :
525 0 : } // namespace basctl
526 :
527 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|