LibreOffice Module reportdesign (master) 1
propbrw.cxx
Go to the documentation of this file.
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#include <memory>
20#include <propbrw.hxx>
21#include <RptObject.hxx>
22#include <ReportController.hxx>
24#include <strings.hrc>
25#include <rptui_slotid.hrc>
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>
37
40#include <comphelper/types.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>
50
51namespace rptui
52{
53#define STD_WIN_SIZE_X 300
54#define STD_WIN_SIZE_Y 350
55
56using namespace ::com::sun::star;
57using namespace uno;
58using namespace lang;
59using namespace frame;
60using namespace beans;
61using namespace container;
62using namespace ::comphelper;
63
64
65namespace
66{
67 bool lcl_shouldEnableHelpSection( const Reference< XComponentContext >& _rxContext )
68 {
69 ::utl::OConfigurationTreeRoot aConfiguration(
71 _rxContext, "/org.openoffice.Office.ReportDesign/PropertyBrowser/" ) );
72
73 bool bEnabled = false;
74 OSL_VERIFY( aConfiguration.getNodeValue( "DirectHelp" ) >>= bEnabled );
75 return bEnabled;
76 }
77}
78
79
80// PropBrw
81
82
83PropBrw::PropBrw(const Reference< XComponentContext >& _xORB, vcl::Window* pParent, ODesignView* _pDesignView)
85 , m_xContentArea(VclPtr<VclVBox>::Create(this))
86 , m_xORB(_xORB)
87 , m_pDesignView(_pDesignView)
88 , m_pView( nullptr )
89 , m_bInitialStateChange(true)
90{
91
93 SetOutputSizePixel(aPropWinSize);
94
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();
101
102 try
103 {
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("report property browser"); // change name!
108 }
109 catch (Exception&)
110 {
111 DBG_UNHANDLED_EXCEPTION("reportdesign");
112 OSL_FAIL("PropBrw::PropBrw: could not create/initialize my frame!");
113 m_xMeAsFrame.clear();
114 }
115
116 if (m_xMeAsFrame.is())
117 {
118 try
119 {
120 ::cppu::ContextEntry_Init aHandlerContextInfo[] =
121 {
122 ::cppu::ContextEntry_Init( "ContextDocument", Any( m_pDesignView->getController().getModel() )),
123 ::cppu::ContextEntry_Init( "DialogParentWindow", Any( VCLUnoHelper::GetInterface ( this ) )),
124 ::cppu::ContextEntry_Init( "ActiveConnection", Any( m_pDesignView->getController().getConnection() ) ),
125 };
126 m_xInspectorContext.set(
127 ::cppu::createComponentContext( aHandlerContextInfo, SAL_N_ELEMENTS( aHandlerContextInfo ),
128 m_xORB ) );
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 ) );
134
135 m_xBrowserController = inspection::ObjectInspector::createWithModel(m_xInspectorContext, xInspectorModel);
136 if ( !m_xBrowserController.is() )
137 {
138 ShowServiceNotAvailableError(pParent ? pParent->GetFrameWeld() : nullptr, u"com.sun.star.inspection.ObjectInspector", true);
139 }
140 else
141 {
142 m_xBrowserController->attachFrame( Reference<XFrame>(m_xMeAsFrame, UNO_QUERY_THROW));
143 if ( bEnableHelpSection )
144 {
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 );
148 }
149 }
150 }
151 catch (Exception&)
152 {
153 DBG_UNHANDLED_EXCEPTION("reportdesign");
154 OSL_FAIL("PropBrw::PropBrw: could not create/initialize the browser controller!");
155 try
156 {
157 ::comphelper::disposeComponent(m_xBrowserController);
158 }
159 catch(Exception&) { }
160 m_xBrowserController.clear();
161 }
162 }
163
164 VclContainer::setLayoutAllocation(*m_xContentArea, Point(0, 0), aPropWinSize);
165 m_xContentArea->Show();
166
167 ::rptui::notifySystemWindow(pParent,this,::comphelper::mem_fun(&TaskPaneList::AddWindow));
168}
169
170
171PropBrw::~PropBrw()
172{
173 disposeOnce();
174}
175
176void PropBrw::dispose()
177{
178 if (m_xBrowserController.is())
179 implDetachController();
180
181 try
182 {
183 uno::Reference<container::XNameContainer> xName(m_xInspectorContext,uno::UNO_QUERY);
184 if ( xName.is() )
185 {
186 const OUString pProps[] = { OUString( "ContextDocument" )
187 , OUString( "DialogParentWindow" )
188 , OUString( "ActiveConnection" )};
189 for (const auto & i : pProps)
190 xName->removeByName(i);
191 }
192 }
193 catch(Exception&)
194 {}
195
196 ::rptui::notifySystemWindow(this,this,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
197 m_pDesignView.clear();
198 m_xContentArea.disposeAndClear();
200}
201
202void PropBrw::setCurrentPage(const OUString& _sLastActivePage)
203{
204 m_sLastActivePage = _sLastActivePage;
205}
206
207
208void PropBrw::implDetachController()
209{
210 m_sLastActivePage = getCurrentPage();
211 implSetNewObject( );
212
213 if ( m_xMeAsFrame.is() )
214 m_xMeAsFrame->setComponent( nullptr, nullptr );
215
216 if ( m_xBrowserController.is() )
217 m_xBrowserController->attachFrame( nullptr );
218
219 m_xMeAsFrame.clear();
220 m_xBrowserController.clear();
221}
222
223OUString PropBrw::getCurrentPage() const
224{
225 OUString sCurrentPage;
226 try
227 {
228 if ( m_xBrowserController.is() )
229 {
230 OSL_VERIFY( m_xBrowserController->getViewData() >>= sCurrentPage );
231 }
232
233 if ( sCurrentPage.isEmpty() )
234 sCurrentPage = m_sLastActivePage;
235 }
236 catch( const Exception& )
237 {
238 TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::getCurrentPage: caught an exception while retrieving the current page!" );
239 }
240 return sCurrentPage;
241}
242
243bool PropBrw::Close()
244{
245 m_xLastSection.clear();
246 // suspend the controller (it is allowed to veto)
247 if ( m_xMeAsFrame.is() )
248 {
249 try
250 {
251 Reference< XController > xController( m_xMeAsFrame->getController() );
252 if ( xController.is() && !xController->suspend( true ) )
253 return false;
254 }
255 catch( const Exception& )
256 {
257 TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::Close: caught an exception while asking the controller!" );
258 }
259 }
260 implDetachController();
261
262 m_pDesignView->getController().executeUnChecked(SID_PROPERTYBROWSER_LAST_PAGE,uno::Sequence< beans::PropertyValue>());
263
264 return true;
265}
266
267uno::Sequence< Reference<uno::XInterface> > PropBrw::CreateCompPropSet(const SdrMarkList& _rMarkList)
268{
269 const size_t nMarkCount = _rMarkList.GetMarkCount();
270 ::std::vector< uno::Reference< uno::XInterface> > aSets;
271 aSets.reserve(nMarkCount);
272
273 for(size_t i=0; i<nMarkCount; ++i)
274 {
275 SdrObject* pCurrent = _rMarkList.GetMark(i)->GetMarkedSdrObj();
276
277 ::std::optional<SdrObjListIter> oGroupIterator;
278 if (pCurrent->IsGroupObject())
279 {
280 oGroupIterator.emplace(pCurrent->GetSubList());
281 pCurrent = oGroupIterator->IsMore() ? oGroupIterator->Next() : nullptr;
282 }
283
284 while (pCurrent)
285 {
286 OObjectBase* pObj = dynamic_cast<OObjectBase*>(pCurrent);
287 if ( pObj )
288 aSets.push_back(CreateComponentPair(pObj));
289
290 // next element
291 pCurrent = oGroupIterator && oGroupIterator->IsMore() ? oGroupIterator->Next() : nullptr;
292 }
293 }
294 return uno::Sequence< Reference<uno::XInterface> >(aSets.data(), aSets.size());
295}
296
297void PropBrw::implSetNewObject( const uno::Sequence< Reference<uno::XInterface> >& _aObjects )
298{
299 if ( m_xBrowserController.is() )
300 {
301 try
302 {
303 m_xBrowserController->inspect(uno::Sequence< Reference<uno::XInterface> >());
304 m_xBrowserController->inspect(_aObjects);
305 }
306 catch( const Exception& )
307 {
308 TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
309 }
310 }
311 SetText( GetHeadlineName(_aObjects) );
312}
313
314
315OUString PropBrw::GetHeadlineName( const uno::Sequence< Reference<uno::XInterface> >& _aObjects )
316{
317 OUString aName;
318 if ( !_aObjects.hasElements() )
319 {
320 aName = RptResId(RID_STR_BRWTITLE_NO_PROPERTIES);
321 }
322 else if ( _aObjects.getLength() == 1 ) // single selection
323 {
324 aName = RptResId(RID_STR_BRWTITLE_PROPERTIES);
325
326 uno::Reference< container::XNameContainer > xNameCont(_aObjects[0],uno::UNO_QUERY);
327 Reference< lang::XServiceInfo > xServiceInfo( xNameCont->getByName("ReportComponent"), UNO_QUERY );
328 if ( xServiceInfo.is() )
329 {
330 TranslateId pResId;
331 if ( xServiceInfo->supportsService( SERVICE_FIXEDTEXT ) )
332 {
333 pResId = RID_STR_PROPTITLE_FIXEDTEXT;
334 }
335 else if ( xServiceInfo->supportsService( SERVICE_IMAGECONTROL ) )
336 {
337 pResId = RID_STR_PROPTITLE_IMAGECONTROL;
338 }
339 else if ( xServiceInfo->supportsService( SERVICE_FORMATTEDFIELD ) )
340 {
341 pResId = RID_STR_PROPTITLE_FORMATTED;
342 }
343 else if ( xServiceInfo->supportsService( SERVICE_SHAPE ) )
344 {
345 pResId = RID_STR_PROPTITLE_SHAPE;
346 }
347 else if ( xServiceInfo->supportsService( SERVICE_REPORTDEFINITION ) )
348 {
349 pResId = RID_STR_PROPTITLE_REPORT;
350 }
351 else if ( xServiceInfo->supportsService( SERVICE_SECTION ) )
352 {
353 pResId = RID_STR_PROPTITLE_SECTION;
354 }
355 else if ( xServiceInfo->supportsService( SERVICE_FUNCTION ) )
356 {
357 pResId = RID_STR_PROPTITLE_FUNCTION;
358 }
359 else if ( xServiceInfo->supportsService( SERVICE_GROUP ) )
360 {
361 pResId = RID_STR_PROPTITLE_GROUP;
362 }
363 else if ( xServiceInfo->supportsService( SERVICE_FIXEDLINE ) )
364 {
365 pResId = RID_STR_PROPTITLE_FIXEDLINE;
366 }
367 else
368 {
369 OSL_FAIL("Unknown service name!");
371 return aName;
372 }
373
374 aName += RptResId(pResId);
375 }
376 }
377 else // multiselection
378 {
379 aName = RptResId(RID_STR_BRWTITLE_PROPERTIES)
380 + RptResId(RID_STR_BRWTITLE_MULTISELECT);
381 }
382
383 return aName;
384}
385
386uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(OObjectBase* _pObj)
387{
388 _pObj->initializeOle();
389 return CreateComponentPair(_pObj->getAwtComponent(),_pObj->getReportComponent());
390}
391
392uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(const uno::Reference< uno::XInterface>& _xFormComponent
393 ,const uno::Reference< uno::XInterface>& _xReportComponent)
394{
395 uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get());
396 xNameCont->insertByName("FormComponent",uno::Any(_xFormComponent));
397 xNameCont->insertByName("ReportComponent",uno::Any(_xReportComponent));
398 xNameCont->insertByName("RowSet",uno::Any(uno::Reference< uno::XInterface>(m_pDesignView->getController().getRowSet())));
399
400 return xNameCont;
401}
402
403::Size PropBrw::getMinimumSize() const
404{
405 ::Size aSize;
406 Reference< awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY );
407 if( xLayoutConstrains.is() )
408 {
409 awt::Size aMinSize = xLayoutConstrains->getMinimumSize();
410 aMinSize.Height += 4;
411 aMinSize.Width += 4;
412 aSize.setHeight( aMinSize.Height );
413 aSize.setWidth( aMinSize.Width );
414 }
415 return aSize;
416}
417
418void PropBrw::Update( OSectionView* pNewView )
419{
420 try
421 {
422 if ( m_pView )
423 {
424 EndListening(m_pView->GetModel());
425 m_pView = nullptr;
426 }
427
428 // set focus on initialization
429 if ( m_bInitialStateChange )
430 {
431 // if we're just newly created, we want to have the focus
432 PostUserEvent( LINK( this, PropBrw, OnAsyncGetFocus ), nullptr, true );
433 m_bInitialStateChange = false;
434 // and additionally, we want to show the page which was active during
435 // our previous incarnation
436 if ( !m_sLastActivePage.isEmpty() && m_xBrowserController.is() )
437 {
438 try
439 {
440 m_xBrowserController->restoreViewData( Any( m_sLastActivePage ) );
441 }
442 catch( const Exception& )
443 {
444 TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
445 }
446 }
447 }
448
449 if ( !pNewView )
450 return;
451 else
452 m_pView = pNewView;
453
454 uno::Sequence< Reference<uno::XInterface> > aMarkedObjects;
455 OViewsWindow* pViews = m_pView->getReportSection()->getSectionWindow()->getViewsWindow();
456 const sal_uInt16 nSectionCount = pViews->getSectionCount();
457 for (sal_uInt16 i = 0; i < nSectionCount; ++i)
458 {
459 OSectionWindow* pSectionWindow = pViews->getSectionWindow(i);
460 if ( pSectionWindow )
461 {
462 const SdrMarkList& rMarkList = pSectionWindow->getReportSection().getSectionView().GetMarkedObjectList();
463 aMarkedObjects = ::comphelper::concatSequences(aMarkedObjects,CreateCompPropSet( rMarkList ));
464 }
465 }
466
467 if ( aMarkedObjects.hasElements() ) // multiple selection
468 {
469 m_xLastSection.clear();
470 implSetNewObject( aMarkedObjects );
471 }
472 else if ( m_xLastSection != m_pView->getReportSection()->getSection() )
473 {
474 uno::Reference< uno::XInterface> xTemp(m_pView->getReportSection()->getSection());
475 m_xLastSection = xTemp;
476 uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get() );
477 xNameCont->insertByName("ReportComponent",uno::Any(xTemp));
478 xTemp = xNameCont;
479
480 implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) );
481 }
482
483 StartListening(m_pView->GetModel());
484 }
485 catch ( Exception& )
486 {
487 TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update" );
488 }
489}
490
491void PropBrw::Update( const uno::Reference< uno::XInterface>& _xReportComponent)
492{
493 if ( m_xLastSection == _xReportComponent )
494 return;
495
496 m_xLastSection = _xReportComponent;
497 try
498 {
499 if ( m_pView )
500 {
501 EndListening(m_pView->GetModel());
502 m_pView = nullptr;
503 }
504
505 uno::Reference< uno::XInterface> xTemp(CreateComponentPair(_xReportComponent,_xReportComponent));
506 implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) );
507 }
508 catch ( Exception& )
509 {
510 TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update: Exception occurred!" );
511 }
512}
513
514IMPL_LINK_NOARG( PropBrw, OnAsyncGetFocus, void*, void )
515{
516 m_xContentArea->GrabFocus();
517}
518
519void PropBrw::LoseFocus()
520{
522 if (m_pDesignView)
523 m_pDesignView->getController().InvalidateAll();
524}
525
526}
527
528/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void dispose() override
size_t GetMarkCount() const
SdrMark * GetMark(size_t nNum) const
const SdrMarkList & GetMarkedObjectList() const
SdrObject * GetMarkedSdrObj() const
virtual SdrObjList * GetSubList() const
bool IsGroupObject() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
void AddWindow(vcl::Window *pWindow)
void RemoveWindow(vcl::Window *pWindow)
static css::uno::Reference< css::awt::XWindow > GetInterface(vcl::Window *pWindow)
static void setLayoutAllocation(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
OSectionView & getSectionView() const
OReportSection & getReportSection()
OViewsWindow * getViewsWindow()
OSectionWindow * getSectionWindow(const sal_uInt16 _nPos) const
return the section at the given position
sal_uInt16 getSectionCount() const
PropBrw(PropBrw const &)=delete
css::uno::Any getNodeValue(const OUString &_rPath) const noexcept
static OConfigurationTreeRoot createWithComponentContext(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, const OUString &_rPath, sal_Int32 _nDepth=-1, CREATION_MODE _eMode=CM_UPDATABLE)
virtual void LoseFocus()
weld::Window * GetFrameWeld() const
OUString RptResId(TranslateId aId)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
virtual void SetText(const OUString &rStr) override
OUString aName
#define SAL_N_ELEMENTS(arr)
@ Exception
int i
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
IMPL_LINK_NOARG(PropBrw, OnAsyncGetFocus, void *, void)
Definition: propbrw.cxx:514
void notifySystemWindow(vcl::Window const *pWindow, vcl::Window *pToRegister, const ::comphelper::mem_fun1_t< TaskPaneList, vcl::Window * > &rMemFunc)
notifySystemWindow adds or remove the given window _pToRegister at the Systemwindow found when search...
Definition: UITools.cxx:836
#define STD_WIN_SIZE_Y
Definition: propbrw.cxx:54
#define STD_WIN_SIZE_X
Definition: propbrw.cxx:53
void VCL_DLLPUBLIC ShowServiceNotAvailableError(weld::Widget *pParent, std::u16string_view rServiceName, bool bError)
constexpr OUStringLiteral SERVICE_SECTION
Definition: strings.hxx:30
constexpr OUStringLiteral RID_STR_CLASS_FORMATTEDFIELD
Definition: strings.hxx:18
constexpr OUStringLiteral SERVICE_GROUP
Definition: strings.hxx:31
constexpr OUStringLiteral SERVICE_FUNCTION
Definition: strings.hxx:26
constexpr OUStringLiteral SERVICE_FIXEDLINE
Definition: strings.hxx:29
constexpr OUStringLiteral SERVICE_IMAGECONTROL
Definition: strings.hxx:24
constexpr OUStringLiteral SERVICE_FIXEDTEXT
Definition: strings.hxx:22
constexpr OUStringLiteral SERVICE_FORMATTEDFIELD
Definition: strings.hxx:23
constexpr OUStringLiteral SERVICE_SHAPE
Definition: strings.hxx:28
constexpr OUStringLiteral SERVICE_REPORTDEFINITION
Definition: strings.hxx:27
Reference< XController > xController
sal_Int64 WinBits
WinBits const WB_SIZEABLE
WinBits const WB_STDMODELESS
WinBits const WB_3DLOOK