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 <comphelper/diagnose_ex.hxx>
27 #include <com/sun/star/awt/XLayoutConstrains.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <com/sun/star/frame/Frame.hpp>
30 #include <com/sun/star/inspection/ObjectInspector.hpp>
31 #include <com/sun/star/inspection/DefaultHelpProvider.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <com/sun/star/report/inspection/DefaultComponentInspectorModel.hpp>
34 #include <vcl/stdtext.hxx>
35 #include <vcl/weld.hxx>
36 #include <svx/svditer.hxx>
38 #include <toolkit/helper/vclunohelper.hxx>
39 #include <comphelper/namecontainer.hxx>
40 #include <comphelper/types.hxx>
41 #include <comphelper/sequence.hxx>
42 #include <core_resource.hxx>
43 #include <SectionView.hxx>
44 #include <ReportSection.hxx>
45 #include <strings.hxx>
46 #include <DesignView.hxx>
47 #include <ViewsWindow.hxx>
48 #include <UITools.hxx>
49 #include <unotools/confignode.hxx>
53 #define STD_WIN_SIZE_X 300
54 #define STD_WIN_SIZE_Y 350
56 using namespace ::com::sun::star
;
59 using namespace frame
;
60 using namespace beans
;
61 using namespace container
;
62 using namespace ::comphelper
;
67 bool lcl_shouldEnableHelpSection( const Reference
< XComponentContext
>& _rxContext
)
69 ::utl::OConfigurationTreeRoot
aConfiguration(
70 ::utl::OConfigurationTreeRoot::createWithComponentContext(
71 _rxContext
, u
"/org.openoffice.Office.ReportDesign/PropertyBrowser/"_ustr
) );
73 bool bEnabled
= false;
74 OSL_VERIFY( aConfiguration
.getNodeValue( u
"DirectHelp"_ustr
) >>= bEnabled
);
83 PropBrw::PropBrw(const Reference
< XComponentContext
>& _xORB
, vcl::Window
* pParent
, ODesignView
* _pDesignView
)
84 : DockingWindow(pParent
,WinBits(WB_STDMODELESS
|WB_SIZEABLE
|WB_3DLOOK
))
85 , m_xContentArea(VclPtr
<VclVBox
>::Create(this))
87 , m_pDesignView(_pDesignView
)
89 , m_bInitialStateChange(true)
92 Size
aPropWinSize(STD_WIN_SIZE_X
,STD_WIN_SIZE_Y
);
93 SetOutputSizePixel(aPropWinSize
);
95 // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
96 // transparent children of the widget
97 m_xContentArea
->SetControlBackground(m_xContentArea
->GetSettings().GetStyleSettings().GetWindowColor());
98 m_xContentArea
->SetBackground(m_xContentArea
->GetControlBackground());
99 m_xContentArea
->SetStyle(m_xContentArea
->GetStyle() & ~WB_CLIPCHILDREN
);
100 m_xContentArea
->Show();
104 // create a frame wrapper for myself
105 m_xMeAsFrame
= Frame::create( m_xORB
);
106 m_xMeAsFrame
->initialize(VCLUnoHelper::GetInterface(m_xContentArea
));
107 m_xMeAsFrame
->setName(u
"report property browser"_ustr
); // change name!
111 DBG_UNHANDLED_EXCEPTION("reportdesign");
112 OSL_FAIL("PropBrw::PropBrw: could not create/initialize my frame!");
113 m_xMeAsFrame
.clear();
116 if (m_xMeAsFrame
.is())
120 ::cppu::ContextEntry_Init aHandlerContextInfo
[] =
122 ::cppu::ContextEntry_Init( u
"ContextDocument"_ustr
, Any( m_pDesignView
->getController().getModel() )),
123 ::cppu::ContextEntry_Init( u
"DialogParentWindow"_ustr
, Any( VCLUnoHelper::GetInterface ( this ) )),
124 ::cppu::ContextEntry_Init( u
"ActiveConnection"_ustr
, Any( m_pDesignView
->getController().getConnection() ) ),
126 m_xInspectorContext
.set(
127 ::cppu::createComponentContext( aHandlerContextInfo
, SAL_N_ELEMENTS( aHandlerContextInfo
),
129 // create a property browser controller
130 bool bEnableHelpSection
= lcl_shouldEnableHelpSection( m_xORB
);
131 Reference
< inspection::XObjectInspectorModel
> xInspectorModel( bEnableHelpSection
132 ? report::inspection::DefaultComponentInspectorModel::createWithHelpSection( m_xInspectorContext
, 3, 8 )
133 : report::inspection::DefaultComponentInspectorModel::createDefault( m_xInspectorContext
) );
135 m_xBrowserController
= inspection::ObjectInspector::createWithModel(m_xInspectorContext
, xInspectorModel
);
136 if ( !m_xBrowserController
.is() )
138 ShowServiceNotAvailableError(pParent
? pParent
->GetFrameWeld() : nullptr, u
"com.sun.star.inspection.ObjectInspector", true);
142 m_xBrowserController
->attachFrame( Reference
<XFrame
>(m_xMeAsFrame
, UNO_QUERY_THROW
));
143 if ( bEnableHelpSection
)
145 uno::Reference
< inspection::XObjectInspector
> xInspector( m_xBrowserController
, uno::UNO_SET_THROW
);
146 uno::Reference
< inspection::XObjectInspectorUI
> xInspectorUI( xInspector
->getInspectorUI() );
147 inspection::DefaultHelpProvider::create( m_xInspectorContext
, xInspectorUI
);
153 DBG_UNHANDLED_EXCEPTION("reportdesign");
154 OSL_FAIL("PropBrw::PropBrw: could not create/initialize the browser controller!");
157 ::comphelper::disposeComponent(m_xBrowserController
);
159 catch(Exception
&) { }
160 m_xBrowserController
.clear();
164 VclContainer::setLayoutAllocation(*m_xContentArea
, Point(0, 0), aPropWinSize
);
165 m_xContentArea
->Show();
167 ::rptui::notifySystemWindow(pParent
,this,::comphelper::mem_fun(&TaskPaneList::AddWindow
));
176 void PropBrw::dispose()
178 if (m_xBrowserController
.is())
179 implDetachController();
183 uno::Reference
<container::XNameContainer
> xName(m_xInspectorContext
,uno::UNO_QUERY
);
186 const OUString pProps
[] = { u
"ContextDocument"_ustr
187 , u
"DialogParentWindow"_ustr
188 , u
"ActiveConnection"_ustr
};
189 for (const auto & i
: pProps
)
190 xName
->removeByName(i
);
196 ::rptui::notifySystemWindow(this,this,::comphelper::mem_fun(&TaskPaneList::RemoveWindow
));
197 m_pDesignView
.clear();
198 m_xContentArea
.disposeAndClear();
199 DockingWindow::dispose();
202 void PropBrw::setCurrentPage(const OUString
& _sLastActivePage
)
204 m_sLastActivePage
= _sLastActivePage
;
208 void PropBrw::implDetachController()
210 m_sLastActivePage
= getCurrentPage();
213 if ( m_xMeAsFrame
.is() )
214 m_xMeAsFrame
->setComponent( nullptr, nullptr );
216 if ( m_xBrowserController
.is() )
217 m_xBrowserController
->attachFrame( nullptr );
219 m_xMeAsFrame
.clear();
220 m_xBrowserController
.clear();
223 OUString
PropBrw::getCurrentPage() const
225 OUString sCurrentPage
;
228 if ( m_xBrowserController
.is() )
230 OSL_VERIFY( m_xBrowserController
->getViewData() >>= sCurrentPage
);
233 if ( sCurrentPage
.isEmpty() )
234 sCurrentPage
= m_sLastActivePage
;
236 catch( const Exception
& )
238 TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::getCurrentPage: caught an exception while retrieving the current page!" );
243 bool PropBrw::Close()
245 m_xLastSection
.clear();
246 // suspend the controller (it is allowed to veto)
247 if ( m_xMeAsFrame
.is() )
251 Reference
< XController
> xController( m_xMeAsFrame
->getController() );
252 if ( xController
.is() && !xController
->suspend( true ) )
255 catch( const Exception
& )
257 TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::Close: caught an exception while asking the controller!" );
260 implDetachController();
262 m_pDesignView
->getController().executeUnChecked(SID_PROPERTYBROWSER_LAST_PAGE
,uno::Sequence
< beans::PropertyValue
>());
267 uno::Sequence
< Reference
<uno::XInterface
> > PropBrw::CreateCompPropSet(const SdrMarkList
& _rMarkList
)
269 const size_t nMarkCount
= _rMarkList
.GetMarkCount();
270 ::std::vector
< uno::Reference
< uno::XInterface
> > aSets
;
271 aSets
.reserve(nMarkCount
);
273 for(size_t i
=0; i
<nMarkCount
; ++i
)
275 SdrObject
* pCurrent
= _rMarkList
.GetMark(i
)->GetMarkedSdrObj();
278 ::std::optional
<SdrObjListIter
> oGroupIterator
;
279 if (pCurrent
->IsGroupObject())
281 oGroupIterator
.emplace(pCurrent
->GetSubList());
282 pCurrent
= oGroupIterator
->IsMore() ? oGroupIterator
->Next() : nullptr;
287 OObjectBase
* pObj
= dynamic_cast<OObjectBase
*>(pCurrent
);
289 aSets
.push_back(CreateComponentPair(pObj
));
292 pCurrent
= oGroupIterator
&& oGroupIterator
->IsMore() ? oGroupIterator
->Next() : nullptr;
295 return uno::Sequence
< Reference
<uno::XInterface
> >(aSets
.data(), aSets
.size());
298 void PropBrw::implSetNewObject( const uno::Sequence
< Reference
<uno::XInterface
> >& _aObjects
)
300 if ( m_xBrowserController
.is() )
304 m_xBrowserController
->inspect(uno::Sequence
< Reference
<uno::XInterface
> >());
305 m_xBrowserController
->inspect(_aObjects
);
307 catch( const Exception
& )
309 TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
312 SetText( GetHeadlineName(_aObjects
) );
316 OUString
PropBrw::GetHeadlineName( const uno::Sequence
< Reference
<uno::XInterface
> >& _aObjects
)
319 if ( !_aObjects
.hasElements() )
321 aName
= RptResId(RID_STR_BRWTITLE_NO_PROPERTIES
);
323 else if ( _aObjects
.getLength() == 1 ) // single selection
325 aName
= RptResId(RID_STR_BRWTITLE_PROPERTIES
);
327 uno::Reference
< container::XNameContainer
> xNameCont(_aObjects
[0],uno::UNO_QUERY
);
328 Reference
< lang::XServiceInfo
> xServiceInfo( xNameCont
->getByName(u
"ReportComponent"_ustr
), UNO_QUERY
);
329 if ( xServiceInfo
.is() )
332 if ( xServiceInfo
->supportsService( SERVICE_FIXEDTEXT
) )
334 pResId
= RID_STR_PROPTITLE_FIXEDTEXT
;
336 else if ( xServiceInfo
->supportsService( SERVICE_IMAGECONTROL
) )
338 pResId
= RID_STR_PROPTITLE_IMAGECONTROL
;
340 else if ( xServiceInfo
->supportsService( SERVICE_FORMATTEDFIELD
) )
342 pResId
= RID_STR_PROPTITLE_FORMATTED
;
344 else if ( xServiceInfo
->supportsService( SERVICE_SHAPE
) )
346 pResId
= RID_STR_PROPTITLE_SHAPE
;
348 else if ( xServiceInfo
->supportsService( SERVICE_REPORTDEFINITION
) )
350 pResId
= RID_STR_PROPTITLE_REPORT
;
352 else if ( xServiceInfo
->supportsService( SERVICE_SECTION
) )
354 pResId
= RID_STR_PROPTITLE_SECTION
;
356 else if ( xServiceInfo
->supportsService( SERVICE_FUNCTION
) )
358 pResId
= RID_STR_PROPTITLE_FUNCTION
;
360 else if ( xServiceInfo
->supportsService( SERVICE_GROUP
) )
362 pResId
= RID_STR_PROPTITLE_GROUP
;
364 else if ( xServiceInfo
->supportsService( SERVICE_FIXEDLINE
) )
366 pResId
= RID_STR_PROPTITLE_FIXEDLINE
;
370 OSL_FAIL("Unknown service name!");
371 aName
+= RID_STR_CLASS_FORMATTEDFIELD
;
375 aName
+= RptResId(pResId
);
378 else // multiselection
380 aName
= RptResId(RID_STR_BRWTITLE_PROPERTIES
)
381 + RptResId(RID_STR_BRWTITLE_MULTISELECT
);
387 uno::Reference
< uno::XInterface
> PropBrw::CreateComponentPair(OObjectBase
* _pObj
)
389 _pObj
->initializeOle();
390 return CreateComponentPair(_pObj
->getAwtComponent(),_pObj
->getReportComponent());
393 uno::Reference
< uno::XInterface
> PropBrw::CreateComponentPair(const uno::Reference
< uno::XInterface
>& _xFormComponent
394 ,const uno::Reference
< uno::XInterface
>& _xReportComponent
)
396 uno::Reference
< container::XNameContainer
> xNameCont
= ::comphelper::NameContainer_createInstance(cppu::UnoType
<XInterface
>::get());
397 xNameCont
->insertByName(u
"FormComponent"_ustr
,uno::Any(_xFormComponent
));
398 xNameCont
->insertByName(u
"ReportComponent"_ustr
,uno::Any(_xReportComponent
));
399 xNameCont
->insertByName(u
"RowSet"_ustr
,uno::Any(uno::Reference
< uno::XInterface
>(m_pDesignView
->getController().getRowSet())));
404 ::Size
PropBrw::getMinimumSize() const
407 Reference
< awt::XLayoutConstrains
> xLayoutConstrains( m_xBrowserController
, UNO_QUERY
);
408 if( xLayoutConstrains
.is() )
410 awt::Size aMinSize
= xLayoutConstrains
->getMinimumSize();
411 aMinSize
.Height
+= 4;
413 aSize
.setHeight( aMinSize
.Height
);
414 aSize
.setWidth( aMinSize
.Width
);
419 void PropBrw::Update( OSectionView
* pNewView
)
425 EndListening(m_pView
->GetModel());
429 // set focus on initialization
430 if ( m_bInitialStateChange
)
432 // if we're just newly created, we want to have the focus
433 PostUserEvent( LINK( this, PropBrw
, OnAsyncGetFocus
), nullptr, true );
434 m_bInitialStateChange
= false;
435 // and additionally, we want to show the page which was active during
436 // our previous incarnation
437 if ( !m_sLastActivePage
.isEmpty() && m_xBrowserController
.is() )
441 m_xBrowserController
->restoreViewData( Any( m_sLastActivePage
) );
443 catch( const Exception
& )
445 TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
455 uno::Sequence
< Reference
<uno::XInterface
> > aMarkedObjects
;
456 OViewsWindow
* pViews
= m_pView
->getReportSection()->getSectionWindow()->getViewsWindow();
457 const sal_uInt16 nSectionCount
= pViews
->getSectionCount();
458 for (sal_uInt16 i
= 0; i
< nSectionCount
; ++i
)
460 OSectionWindow
* pSectionWindow
= pViews
->getSectionWindow(i
);
461 if ( pSectionWindow
)
463 const SdrMarkList
& rMarkList
= pSectionWindow
->getReportSection().getSectionView().GetMarkedObjectList();
464 aMarkedObjects
= ::comphelper::concatSequences(aMarkedObjects
,CreateCompPropSet( rMarkList
));
468 if ( aMarkedObjects
.hasElements() ) // multiple selection
470 m_xLastSection
.clear();
471 implSetNewObject( aMarkedObjects
);
473 else if ( m_xLastSection
!= m_pView
->getReportSection()->getSection() )
475 uno::Reference
< uno::XInterface
> xTemp(m_pView
->getReportSection()->getSection());
476 m_xLastSection
= xTemp
;
477 uno::Reference
< container::XNameContainer
> xNameCont
= ::comphelper::NameContainer_createInstance(cppu::UnoType
<XInterface
>::get() );
478 xNameCont
->insertByName(u
"ReportComponent"_ustr
,uno::Any(xTemp
));
481 implSetNewObject( uno::Sequence
< uno::Reference
< uno::XInterface
> >(&xTemp
,1) );
484 StartListening(m_pView
->GetModel());
488 TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update" );
492 void PropBrw::Update( const uno::Reference
< uno::XInterface
>& _xReportComponent
)
494 if ( m_xLastSection
== _xReportComponent
)
497 m_xLastSection
= _xReportComponent
;
502 EndListening(m_pView
->GetModel());
506 uno::Reference
< uno::XInterface
> xTemp(CreateComponentPair(_xReportComponent
,_xReportComponent
));
507 implSetNewObject( uno::Sequence
< uno::Reference
< uno::XInterface
> >(&xTemp
,1) );
511 TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update: Exception occurred!" );
515 IMPL_LINK_NOARG( PropBrw
, OnAsyncGetFocus
, void*, void )
517 m_xContentArea
->GrabFocus();
520 void PropBrw::LoseFocus()
522 DockingWindow::LoseFocus();
524 m_pDesignView
->getController().InvalidateAll();
529 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */