1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <propbrw.hxx>
21 #include <RptObject.hxx>
22 #include <ReportController.hxx>
23 #include <cppuhelper/component_context.hxx>
24 #include <strings.hrc>
25 #include <rptui_slotid.hrc>
26 #include <tools/debug.hxx>
27 #include <tools/diagnose_ex.h>
28 #include <com/sun/star/awt/XLayoutConstrains.hpp>
29 #include <com/sun/star/awt/PosSize.hpp>
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/frame/Frame.hpp>
32 #include <com/sun/star/inspection/ObjectInspector.hpp>
33 #include <com/sun/star/inspection/DefaultHelpProvider.hpp>
34 #include <com/sun/star/lang/XServiceInfo.hpp>
35 #include <com/sun/star/report/inspection/DefaultComponentInspectorModel.hpp>
36 #include <svx/svxids.hrc>
37 #include <vcl/stdtext.hxx>
38 #include <vcl/weld.hxx>
39 #include <svx/svdview.hxx>
40 #include <svx/svdogrp.hxx>
41 #include <svx/svdpage.hxx>
42 #include <svx/svditer.hxx>
44 #include <toolkit/helper/vclunohelper.hxx>
45 #include <comphelper/namecontainer.hxx>
46 #include <comphelper/types.hxx>
47 #include <comphelper/sequence.hxx>
48 #include <core_resource.hxx>
49 #include <SectionView.hxx>
50 #include <ReportSection.hxx>
51 #include <strings.hxx>
52 #include <DesignView.hxx>
53 #include <ViewsWindow.hxx>
54 #include <UITools.hxx>
55 #include <unotools/confignode.hxx>
59 #define STD_WIN_SIZE_X 300
60 #define STD_WIN_SIZE_Y 350
62 using namespace ::com::sun::star
;
65 using namespace frame
;
66 using namespace beans
;
67 using namespace container
;
68 using namespace ::comphelper
;
73 bool lcl_shouldEnableHelpSection( const Reference
< XComponentContext
>& _rxContext
)
75 ::utl::OConfigurationTreeRoot
aConfiguration(
76 ::utl::OConfigurationTreeRoot::createWithComponentContext(
77 _rxContext
, "/org.openoffice.Office.ReportDesign/PropertyBrowser/" ) );
79 bool bEnabled
= false;
80 OSL_VERIFY( aConfiguration
.getNodeValue( "DirectHelp" ) >>= bEnabled
);
89 PropBrw::PropBrw(const Reference
< XComponentContext
>& _xORB
, vcl::Window
* pParent
, ODesignView
* _pDesignView
)
90 :DockingWindow(pParent
,WinBits(WB_STDMODELESS
|WB_SIZEABLE
|WB_3DLOOK
|WB_ROLLABLE
))
92 ,m_pDesignView(_pDesignView
)
94 ,m_bInitialStateChange(true)
97 Size
aPropWinSize(STD_WIN_SIZE_X
,STD_WIN_SIZE_Y
);
98 SetOutputSizePixel(aPropWinSize
);
102 // create a frame wrapper for myself
103 m_xMeAsFrame
= Frame::create( m_xORB
);
104 m_xMeAsFrame
->initialize( VCLUnoHelper::GetInterface ( this ) );
105 m_xMeAsFrame
->setName("report property browser"); // change name!
109 DBG_UNHANDLED_EXCEPTION("reportdesign");
110 OSL_FAIL("PropBrw::PropBrw: could not create/initialize my frame!");
111 m_xMeAsFrame
.clear();
114 if (m_xMeAsFrame
.is())
118 ::cppu::ContextEntry_Init aHandlerContextInfo
[] =
120 ::cppu::ContextEntry_Init( "ContextDocument", makeAny( m_pDesignView
->getController().getModel() )),
121 ::cppu::ContextEntry_Init( "DialogParentWindow", makeAny( VCLUnoHelper::GetInterface ( this ) )),
122 ::cppu::ContextEntry_Init( "ActiveConnection", makeAny( m_pDesignView
->getController().getConnection() ) ),
124 m_xInspectorContext
.set(
125 ::cppu::createComponentContext( aHandlerContextInfo
, SAL_N_ELEMENTS( aHandlerContextInfo
),
127 // create a property browser controller
128 bool bEnableHelpSection
= lcl_shouldEnableHelpSection( m_xORB
);
129 Reference
< inspection::XObjectInspectorModel
> xInspectorModel( bEnableHelpSection
130 ? report::inspection::DefaultComponentInspectorModel::createWithHelpSection( m_xInspectorContext
, 3, 8 )
131 : report::inspection::DefaultComponentInspectorModel::createDefault( m_xInspectorContext
) );
133 m_xBrowserController
= inspection::ObjectInspector::createWithModel(m_xInspectorContext
, xInspectorModel
);
134 if ( !m_xBrowserController
.is() )
136 const OUString
sServiceName( "com.sun.star.inspection.ObjectInspector" );
137 ShowServiceNotAvailableError(pParent
? pParent
->GetFrameWeld() : nullptr, sServiceName
, true);
141 m_xBrowserController
->attachFrame( Reference
<XFrame
>(m_xMeAsFrame
, UNO_QUERY_THROW
));
142 m_xBrowserComponentWindow
= m_xMeAsFrame
->getComponentWindow();
143 OSL_ENSURE(m_xBrowserComponentWindow
.is(), "PropBrw::PropBrw: attached the controller, but have no component window!");
144 if ( bEnableHelpSection
)
146 uno::Reference
< inspection::XObjectInspector
> xInspector( m_xBrowserController
, uno::UNO_SET_THROW
);
147 uno::Reference
< inspection::XObjectInspectorUI
> xInspectorUI( xInspector
->getInspectorUI() );
148 uno::Reference
< uno::XInterface
> xDefaultHelpProvider( inspection::DefaultHelpProvider::create( m_xInspectorContext
, xInspectorUI
) );
154 DBG_UNHANDLED_EXCEPTION("reportdesign");
155 OSL_FAIL("PropBrw::PropBrw: could not create/initialize the browser controller!");
158 ::comphelper::disposeComponent(m_xBrowserController
);
159 ::comphelper::disposeComponent(m_xBrowserComponentWindow
);
161 catch(Exception
&) { }
162 m_xBrowserController
.clear();
163 m_xBrowserComponentWindow
.clear();
167 if (m_xBrowserComponentWindow
.is())
170 m_xBrowserComponentWindow
->setPosSize(0, 0, aPropWinSize
.Width(), aPropWinSize
.Height(),
171 awt::PosSize::WIDTH
| awt::PosSize::HEIGHT
| awt::PosSize::X
| awt::PosSize::Y
);
173 m_xBrowserComponentWindow
->setVisible(true);
175 ::rptui::notifySystemWindow(pParent
,this,::comphelper::mem_fun(&TaskPaneList::AddWindow
));
184 void PropBrw::dispose()
186 if (m_xBrowserController
.is())
187 implDetachController();
191 uno::Reference
<container::XNameContainer
> xName(m_xInspectorContext
,uno::UNO_QUERY
);
194 const OUString pProps
[] = { OUString( "ContextDocument" )
195 , OUString( "DialogParentWindow" )
196 , OUString( "ActiveConnection" )};
197 for (const auto & i
: pProps
)
198 xName
->removeByName(i
);
204 ::rptui::notifySystemWindow(this,this,::comphelper::mem_fun(&TaskPaneList::RemoveWindow
));
205 m_pDesignView
.clear();
206 DockingWindow::dispose();
209 void PropBrw::setCurrentPage(const OUString
& _sLastActivePage
)
211 m_sLastActivePage
= _sLastActivePage
;
215 void PropBrw::implDetachController()
217 m_sLastActivePage
= getCurrentPage();
220 if ( m_xMeAsFrame
.is() )
221 m_xMeAsFrame
->setComponent( nullptr, nullptr );
223 if ( m_xBrowserController
.is() )
224 m_xBrowserController
->attachFrame( nullptr );
226 m_xMeAsFrame
.clear();
227 m_xBrowserController
.clear();
228 m_xBrowserComponentWindow
.clear();
231 OUString
PropBrw::getCurrentPage() const
233 OUString sCurrentPage
;
236 if ( m_xBrowserController
.is() )
238 OSL_VERIFY( m_xBrowserController
->getViewData() >>= sCurrentPage
);
241 if ( sCurrentPage
.isEmpty() )
242 sCurrentPage
= m_sLastActivePage
;
244 catch( const Exception
& )
246 OSL_FAIL( "PropBrw::getCurrentPage: caught an exception while retrieving the current page!" );
252 bool PropBrw::Close()
254 m_xLastSection
.clear();
255 // suspend the controller (it is allowed to veto)
256 if ( m_xMeAsFrame
.is() )
260 Reference
< XController
> xController( m_xMeAsFrame
->getController() );
261 if ( xController
.is() && !xController
->suspend( true ) )
264 catch( const Exception
& )
266 OSL_FAIL( "FmPropBrw::Close: caught an exception while asking the controller!" );
269 implDetachController();
274 m_pDesignView
->getController().executeUnChecked(SID_PROPERTYBROWSER_LAST_PAGE
,uno::Sequence
< beans::PropertyValue
>());
280 uno::Sequence
< Reference
<uno::XInterface
> > PropBrw::CreateCompPropSet(const SdrMarkList
& _rMarkList
)
282 const size_t nMarkCount
= _rMarkList
.GetMarkCount();
283 ::std::vector
< uno::Reference
< uno::XInterface
> > aSets
;
284 aSets
.reserve(nMarkCount
);
286 for(size_t i
=0; i
<nMarkCount
; ++i
)
288 SdrObject
* pCurrent
= _rMarkList
.GetMark(i
)->GetMarkedSdrObj();
290 ::std::unique_ptr
<SdrObjListIter
> pGroupIterator
;
291 if (pCurrent
->IsGroupObject())
293 pGroupIterator
.reset(new SdrObjListIter(pCurrent
->GetSubList()));
294 pCurrent
= pGroupIterator
->IsMore() ? pGroupIterator
->Next() : nullptr;
299 OObjectBase
* pObj
= dynamic_cast<OObjectBase
*>(pCurrent
);
301 aSets
.push_back(CreateComponentPair(pObj
));
304 pCurrent
= pGroupIterator
.get() && pGroupIterator
->IsMore() ? pGroupIterator
->Next() : nullptr;
307 return uno::Sequence
< Reference
<uno::XInterface
> >(aSets
.data(), aSets
.size());
310 void PropBrw::implSetNewObject( const uno::Sequence
< Reference
<uno::XInterface
> >& _aObjects
)
312 if ( m_xBrowserController
.is() )
316 m_xBrowserController
->inspect(uno::Sequence
< Reference
<uno::XInterface
> >());
317 m_xBrowserController
->inspect(_aObjects
);
319 catch( const Exception
& )
321 OSL_FAIL( "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
324 SetText( GetHeadlineName(_aObjects
) );
328 OUString
PropBrw::GetHeadlineName( const uno::Sequence
< Reference
<uno::XInterface
> >& _aObjects
)
331 if ( !_aObjects
.hasElements() )
333 aName
= RptResId(RID_STR_BRWTITLE_NO_PROPERTIES
);
335 else if ( _aObjects
.getLength() == 1 ) // single selection
337 aName
= RptResId(RID_STR_BRWTITLE_PROPERTIES
);
339 uno::Reference
< container::XNameContainer
> xNameCont(_aObjects
[0],uno::UNO_QUERY
);
340 Reference
< lang::XServiceInfo
> xServiceInfo( xNameCont
->getByName("ReportComponent"), UNO_QUERY
);
341 if ( xServiceInfo
.is() )
344 if ( xServiceInfo
->supportsService( SERVICE_FIXEDTEXT
) )
346 pResId
= RID_STR_PROPTITLE_FIXEDTEXT
;
348 else if ( xServiceInfo
->supportsService( SERVICE_IMAGECONTROL
) )
350 pResId
= RID_STR_PROPTITLE_IMAGECONTROL
;
352 else if ( xServiceInfo
->supportsService( SERVICE_FORMATTEDFIELD
) )
354 pResId
= RID_STR_PROPTITLE_FORMATTED
;
356 else if ( xServiceInfo
->supportsService( SERVICE_SHAPE
) )
358 pResId
= RID_STR_PROPTITLE_SHAPE
;
360 else if ( xServiceInfo
->supportsService( SERVICE_REPORTDEFINITION
) )
362 pResId
= RID_STR_PROPTITLE_REPORT
;
364 else if ( xServiceInfo
->supportsService( SERVICE_SECTION
) )
366 pResId
= RID_STR_PROPTITLE_SECTION
;
368 else if ( xServiceInfo
->supportsService( SERVICE_FUNCTION
) )
370 pResId
= RID_STR_PROPTITLE_FUNCTION
;
372 else if ( xServiceInfo
->supportsService( SERVICE_GROUP
) )
374 pResId
= RID_STR_PROPTITLE_GROUP
;
376 else if ( xServiceInfo
->supportsService( SERVICE_FIXEDLINE
) )
378 pResId
= RID_STR_PROPTITLE_FIXEDLINE
;
382 OSL_FAIL("Unknown service name!");
383 aName
+= RID_STR_CLASS_FORMATTEDFIELD
;
387 aName
+= RptResId(pResId
);
390 else // multiselection
392 aName
= RptResId(RID_STR_BRWTITLE_PROPERTIES
);
393 aName
+= RptResId(RID_STR_BRWTITLE_MULTISELECT
);
399 uno::Reference
< uno::XInterface
> PropBrw::CreateComponentPair(OObjectBase
* _pObj
)
401 _pObj
->initializeOle();
402 return CreateComponentPair(_pObj
->getAwtComponent(),_pObj
->getReportComponent());
405 uno::Reference
< uno::XInterface
> PropBrw::CreateComponentPair(const uno::Reference
< uno::XInterface
>& _xFormComponent
406 ,const uno::Reference
< uno::XInterface
>& _xReportComponent
)
408 uno::Reference
< container::XNameContainer
> xNameCont
= ::comphelper::NameContainer_createInstance(cppu::UnoType
<XInterface
>::get());
409 xNameCont
->insertByName("FormComponent",uno::makeAny(_xFormComponent
));
410 xNameCont
->insertByName("ReportComponent",uno::makeAny(_xReportComponent
));
411 xNameCont
->insertByName("RowSet",uno::makeAny(uno::Reference
< uno::XInterface
>(m_pDesignView
->getController().getRowSet())));
413 return xNameCont
.get();
416 ::Size
PropBrw::getMinimumSize() const
419 Reference
< awt::XLayoutConstrains
> xLayoutConstrains( m_xBrowserController
, UNO_QUERY
);
420 if( xLayoutConstrains
.is() )
422 awt::Size aMinSize
= xLayoutConstrains
->getMinimumSize();
423 aMinSize
.Height
+= 4;
425 aSize
.setHeight( aMinSize
.Height
);
426 aSize
.setWidth( aMinSize
.Width
);
431 void PropBrw::Resize()
435 Reference
< awt::XLayoutConstrains
> xLayoutConstrains( m_xBrowserController
, UNO_QUERY
);
436 if( xLayoutConstrains
.is() )
438 ::Size aMinSize
= getMinimumSize();
439 SetMinOutputSizePixel( aMinSize
);
440 ::Size aSize
= GetOutputSizePixel();
441 bool bResize
= false;
442 if( aSize
.Width() < aMinSize
.Width() )
444 aSize
.setWidth( aMinSize
.Width() );
447 if( aSize
.Height() < aMinSize
.Height() )
449 aSize
.setHeight( aMinSize
.Height() );
453 SetOutputSizePixel( aSize
);
456 if (m_xBrowserComponentWindow
.is())
458 Size aSize
= GetOutputSizePixel();
459 m_xBrowserComponentWindow
->setPosSize(0, 0, aSize
.Width(), aSize
.Height(),
460 awt::PosSize::WIDTH
| awt::PosSize::HEIGHT
);
464 void PropBrw::Update( OSectionView
* pNewView
)
470 EndListening( *(m_pView
->GetModel()) );
474 // set focus on initialization
475 if ( m_bInitialStateChange
)
477 // if we're just newly created, we want to have the focus
478 PostUserEvent( LINK( this, PropBrw
, OnAsyncGetFocus
), nullptr, true );
479 m_bInitialStateChange
= false;
480 // and additionally, we want to show the page which was active during
481 // our previous incarnation
482 if ( !m_sLastActivePage
.isEmpty() && m_xBrowserController
.is() )
486 m_xBrowserController
->restoreViewData( makeAny( m_sLastActivePage
) );
488 catch( const Exception
& )
490 OSL_FAIL( "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
500 uno::Sequence
< Reference
<uno::XInterface
> > aMarkedObjects
;
501 OViewsWindow
* pViews
= m_pView
->getReportSection()->getSectionWindow()->getViewsWindow();
502 const sal_uInt16 nSectionCount
= pViews
->getSectionCount();
503 for (sal_uInt16 i
= 0; i
< nSectionCount
; ++i
)
505 OSectionWindow
* pSectionWindow
= pViews
->getSectionWindow(i
);
506 if ( pSectionWindow
)
508 const SdrMarkList
& rMarkList
= pSectionWindow
->getReportSection().getSectionView().GetMarkedObjectList();
509 aMarkedObjects
= ::comphelper::concatSequences(aMarkedObjects
,CreateCompPropSet( rMarkList
));
513 if ( aMarkedObjects
.hasElements() ) // multiple selection
515 m_xLastSection
.clear();
516 implSetNewObject( aMarkedObjects
);
518 else if ( m_xLastSection
!= m_pView
->getReportSection()->getSection() )
520 uno::Reference
< uno::XInterface
> xTemp(m_pView
->getReportSection()->getSection());
521 m_xLastSection
= xTemp
;
522 uno::Reference
< container::XNameContainer
> xNameCont
= ::comphelper::NameContainer_createInstance(cppu::UnoType
<XInterface
>::get() );
523 xNameCont
->insertByName("ReportComponent",uno::makeAny(xTemp
));
526 implSetNewObject( uno::Sequence
< uno::Reference
< uno::XInterface
> >(&xTemp
,1) );
529 StartListening( *(m_pView
->GetModel()) );
533 OSL_FAIL( "PropBrw::Update: Exception occurred!" );
537 void PropBrw::Update( const uno::Reference
< uno::XInterface
>& _xReportComponent
)
539 if ( m_xLastSection
!= _xReportComponent
)
541 m_xLastSection
= _xReportComponent
;
546 EndListening( *(m_pView
->GetModel()) );
550 uno::Reference
< uno::XInterface
> xTemp(CreateComponentPair(_xReportComponent
,_xReportComponent
));
551 implSetNewObject( uno::Sequence
< uno::Reference
< uno::XInterface
> >(&xTemp
,1) );
555 OSL_FAIL( "PropBrw::Update: Exception occurred!" );
560 IMPL_LINK_NOARG( PropBrw
, OnAsyncGetFocus
, void*, void )
562 if (m_xBrowserComponentWindow
.is())
563 m_xBrowserComponentWindow
->setFocus();
566 void PropBrw::LoseFocus()
568 DockingWindow::LoseFocus();
570 m_pDesignView
->getController().InvalidateAll();
575 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */