bump product version to 5.0.4.1
[LibreOffice.git] / reportdesign / source / ui / report / propbrw.cxx
blob6706c74cfe85ad24c74616ccaa82138526ea2ba5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
19 #include "propbrw.hxx"
20 #include "RptObject.hxx"
21 #include "ReportController.hxx"
22 #include <cppuhelper/component_context.hxx>
23 #include <RptResId.hrc>
24 #include "rptui_slotid.hrc"
25 #include <tools/debug.hxx>
26 #include <tools/diagnose_ex.h>
27 #include <com/sun/star/awt/XLayoutConstrains.hpp>
28 #include <com/sun/star/awt/PosSize.hpp>
29 #include <com/sun/star/beans/PropertyValue.hpp>
30 #include <com/sun/star/frame/Frame.hpp>
31 #include <com/sun/star/inspection/ObjectInspector.hpp>
32 #include <com/sun/star/inspection/DefaultHelpProvider.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/report/inspection/DefaultComponentInspectorModel.hpp>
35 #include <svx/svxids.hrc>
36 #include <vcl/stdtext.hxx>
37 #include <svx/svdview.hxx>
38 #include <svx/svdogrp.hxx>
39 #include <svx/svdpage.hxx>
40 #include <svx/svditer.hxx>
42 #include <toolkit/helper/vclunohelper.hxx>
43 #include <comphelper/property.hxx>
44 #include <comphelper/namecontainer.hxx>
45 #include <comphelper/stl_types.hxx>
46 #include <comphelper/types.hxx>
47 #include <comphelper/sequence.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include "SectionView.hxx"
50 #include "ReportSection.hxx"
51 #include "uistrings.hrc"
52 #include "DesignView.hxx"
53 #include "ViewsWindow.hxx"
54 #include "UITools.hxx"
55 #include <unotools/confignode.hxx>
57 namespace rptui
59 #define STD_WIN_SIZE_X 300
60 #define STD_WIN_SIZE_Y 350
62 using namespace ::com::sun::star;
63 using namespace uno;
64 using namespace lang;
65 using namespace frame;
66 using namespace beans;
67 using namespace container;
68 using namespace ::comphelper;
72 namespace
74 static bool lcl_shouldEnableHelpSection( const Reference< XComponentContext >& _rxContext )
76 const OUString sConfigName( "/org.openoffice.Office.ReportDesign/PropertyBrowser/" );
77 const OUString sPropertyName( "DirectHelp" );
79 ::utl::OConfigurationTreeRoot aConfiguration(
80 ::utl::OConfigurationTreeRoot::createWithComponentContext( _rxContext, sConfigName ) );
82 bool bEnabled = false;
83 OSL_VERIFY( aConfiguration.getNodeValue( sPropertyName ) >>= bEnabled );
84 return bEnabled;
89 // PropBrw
95 PropBrw::PropBrw(const Reference< XComponentContext >& _xORB, vcl::Window* pParent, ODesignView* _pDesignView)
96 :DockingWindow(pParent,WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_3DLOOK|WB_ROLLABLE))
97 ,m_xORB(_xORB)
98 ,m_pDesignView(_pDesignView)
99 ,m_pView( NULL )
100 ,m_bInitialStateChange(true)
103 Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
104 SetOutputSizePixel(aPropWinSize);
108 // create a frame wrapper for myself
109 m_xMeAsFrame = Frame::create( m_xORB );
110 m_xMeAsFrame->initialize( VCLUnoHelper::GetInterface ( this ) );
111 m_xMeAsFrame->setName("report property browser"); // change name!
113 catch (Exception&)
115 OSL_FAIL("PropBrw::PropBrw: could not create/initialize my frame!");
116 DBG_UNHANDLED_EXCEPTION();
117 m_xMeAsFrame.clear();
120 if (m_xMeAsFrame.is())
124 ::cppu::ContextEntry_Init aHandlerContextInfo[] =
126 ::cppu::ContextEntry_Init( OUString( "ContextDocument" ), makeAny( m_pDesignView->getController().getModel() )),
127 ::cppu::ContextEntry_Init( OUString( "DialogParentWindow" ), makeAny( VCLUnoHelper::GetInterface ( this ) )),
128 ::cppu::ContextEntry_Init( OUString( "ActiveConnection" ), makeAny( m_pDesignView->getController().getConnection() ) ),
130 m_xInspectorContext.set(
131 ::cppu::createComponentContext( aHandlerContextInfo, sizeof( aHandlerContextInfo ) / sizeof( aHandlerContextInfo[0] ),
132 m_xORB ) );
133 // create a property browser controller
134 bool bEnableHelpSection = lcl_shouldEnableHelpSection( m_xORB );
135 Reference< inspection::XObjectInspectorModel> xInspectorModel( bEnableHelpSection
136 ? report::inspection::DefaultComponentInspectorModel::createWithHelpSection( m_xInspectorContext, 3, 8 )
137 : report::inspection::DefaultComponentInspectorModel::createDefault( m_xInspectorContext ) );
139 m_xBrowserController = inspection::ObjectInspector::createWithModel(m_xInspectorContext, xInspectorModel);
140 if ( !m_xBrowserController.is() )
142 const OUString sServiceName( "com.sun.star.inspection.ObjectInspector" );
143 ShowServiceNotAvailableError(pParent, sServiceName, true);
145 else
147 m_xBrowserController->attachFrame( Reference<XFrame>(m_xMeAsFrame, UNO_QUERY_THROW));
148 m_xBrowserComponentWindow = m_xMeAsFrame->getComponentWindow();
149 OSL_ENSURE(m_xBrowserComponentWindow.is(), "PropBrw::PropBrw: attached the controller, but have no component window!");
150 if ( bEnableHelpSection )
152 uno::Reference< inspection::XObjectInspector > xInspector( m_xBrowserController, uno::UNO_QUERY_THROW );
153 uno::Reference< inspection::XObjectInspectorUI > xInspectorUI( xInspector->getInspectorUI() );
154 uno::Reference< uno::XInterface > xDefaultHelpProvider( inspection::DefaultHelpProvider::create( m_xInspectorContext, xInspectorUI ) );
158 catch (Exception&)
160 OSL_FAIL("PropBrw::PropBrw: could not create/initialize the browser controller!");
161 DBG_UNHANDLED_EXCEPTION();
164 ::comphelper::disposeComponent(m_xBrowserController);
165 ::comphelper::disposeComponent(m_xBrowserComponentWindow);
167 catch(Exception&) { }
168 m_xBrowserController.clear();
169 m_xBrowserComponentWindow.clear();
173 if (m_xBrowserComponentWindow.is())
176 m_xBrowserComponentWindow->setPosSize(0, 0, aPropWinSize.Width(), aPropWinSize.Height(),
177 awt::PosSize::WIDTH | awt::PosSize::HEIGHT | awt::PosSize::X | awt::PosSize::Y);
178 Resize();
179 m_xBrowserComponentWindow->setVisible(sal_True);
181 ::rptui::notifySystemWindow(pParent,this,::comphelper::mem_fun(&TaskPaneList::AddWindow));
186 PropBrw::~PropBrw()
188 disposeOnce();
191 void PropBrw::dispose()
193 if (m_xBrowserController.is())
194 implDetachController();
198 uno::Reference<container::XNameContainer> xName(m_xInspectorContext,uno::UNO_QUERY);
199 if ( xName.is() )
201 const OUString pProps[] = { OUString( "ContextDocument" )
202 , OUString( "DialogParentWindow" )
203 , OUString( "ActiveConnection" )};
204 for (size_t i = 0; i < sizeof(pProps)/sizeof(pProps[0]); ++i)
205 xName->removeByName(pProps[i]);
208 catch(Exception&)
211 ::rptui::notifySystemWindow(this,this,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
212 m_pDesignView.clear();
213 DockingWindow::dispose();
216 void PropBrw::setCurrentPage(const OUString& _sLastActivePage)
218 m_sLastActivePage = _sLastActivePage;
222 void PropBrw::implDetachController()
224 m_sLastActivePage = getCurrentPage();
225 implSetNewObject( );
227 if ( m_xMeAsFrame.is() )
228 m_xMeAsFrame->setComponent( NULL, NULL );
230 if ( m_xBrowserController.is() )
231 m_xBrowserController->attachFrame( NULL );
233 m_xMeAsFrame.clear();
234 m_xBrowserController.clear();
235 m_xBrowserComponentWindow.clear();
238 OUString PropBrw::getCurrentPage() const
240 OUString sCurrentPage;
243 if ( m_xBrowserController.is() )
245 OSL_VERIFY( m_xBrowserController->getViewData() >>= sCurrentPage );
248 if ( sCurrentPage.isEmpty() )
249 sCurrentPage = m_sLastActivePage;
251 catch( const Exception& )
253 OSL_FAIL( "PropBrw::getCurrentPage: caught an exception while retrieving the current page!" );
255 return sCurrentPage;
259 bool PropBrw::Close()
261 m_xLastSection.clear();
262 // suspend the controller (it is allowed to veto)
263 if ( m_xMeAsFrame.is() )
267 Reference< XController > xController( m_xMeAsFrame->getController() );
268 if ( xController.is() && !xController->suspend( sal_True ) )
269 return false;
271 catch( const Exception& )
273 OSL_FAIL( "FmPropBrw::Close: caught an exception while asking the controller!" );
276 implDetachController();
278 if( IsRollUp() )
279 RollDown();
281 m_pDesignView->getController().executeUnChecked(SID_PROPERTYBROWSER_LAST_PAGE,uno::Sequence< beans::PropertyValue>());
283 return true;
288 uno::Sequence< Reference<uno::XInterface> > PropBrw::CreateCompPropSet(const SdrMarkList& _rMarkList)
290 const size_t nMarkCount = _rMarkList.GetMarkCount();
291 ::std::vector< uno::Reference< uno::XInterface> > aSets;
292 aSets.reserve(nMarkCount);
294 for(size_t i=0; i<nMarkCount; ++i)
296 SdrObject* pCurrent = _rMarkList.GetMark(i)->GetMarkedSdrObj();
298 ::std::unique_ptr<SdrObjListIter> pGroupIterator;
299 if (pCurrent->IsGroupObject())
301 pGroupIterator.reset(new SdrObjListIter(*pCurrent->GetSubList()));
302 pCurrent = pGroupIterator->IsMore() ? pGroupIterator->Next() : NULL;
305 while (pCurrent)
307 OObjectBase* pObj = dynamic_cast<OObjectBase*>(pCurrent);
308 if ( pObj )
309 aSets.push_back(CreateComponentPair(pObj));
311 // next element
312 pCurrent = pGroupIterator.get() && pGroupIterator->IsMore() ? pGroupIterator->Next() : NULL;
315 return uno::Sequence< Reference<uno::XInterface> >(aSets.data(), aSets.size());
318 void PropBrw::implSetNewObject( const uno::Sequence< Reference<uno::XInterface> >& _aObjects )
320 if ( m_xBrowserController.is() )
324 m_xBrowserController->inspect(uno::Sequence< Reference<uno::XInterface> >());
325 m_xBrowserController->inspect(_aObjects);
327 catch( const Exception& )
329 OSL_FAIL( "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
332 SetText( GetHeadlineName(_aObjects) );
337 OUString PropBrw::GetHeadlineName( const uno::Sequence< Reference<uno::XInterface> >& _aObjects )
339 OUString aName;
340 if ( !_aObjects.getLength() )
342 aName = ModuleRes(RID_STR_BRWTITLE_NO_PROPERTIES);
344 else if ( _aObjects.getLength() == 1 ) // single selection
346 aName = ModuleRes(RID_STR_BRWTITLE_PROPERTIES);
348 uno::Reference< container::XNameContainer > xNameCont(_aObjects[0],uno::UNO_QUERY);
349 Reference< lang::XServiceInfo > xServiceInfo( xNameCont->getByName("ReportComponent"), UNO_QUERY );
350 if ( xServiceInfo.is() )
352 sal_uInt16 nResId = 0;
353 if ( xServiceInfo->supportsService( SERVICE_FIXEDTEXT ) )
355 nResId = RID_STR_PROPTITLE_FIXEDTEXT;
357 else if ( xServiceInfo->supportsService( SERVICE_IMAGECONTROL ) )
359 nResId = RID_STR_PROPTITLE_IMAGECONTROL;
361 else if ( xServiceInfo->supportsService( SERVICE_FORMATTEDFIELD ) )
363 nResId = RID_STR_PROPTITLE_FORMATTED;
365 else if ( xServiceInfo->supportsService( SERVICE_SHAPE ) )
367 nResId = RID_STR_PROPTITLE_SHAPE;
369 else if ( xServiceInfo->supportsService( SERVICE_REPORTDEFINITION ) )
371 nResId = RID_STR_PROPTITLE_REPORT;
373 else if ( xServiceInfo->supportsService( SERVICE_SECTION ) )
375 nResId = RID_STR_PROPTITLE_SECTION;
377 else if ( xServiceInfo->supportsService( SERVICE_FUNCTION ) )
379 nResId = RID_STR_PROPTITLE_FUNCTION;
381 else if ( xServiceInfo->supportsService( SERVICE_GROUP ) )
383 nResId = RID_STR_PROPTITLE_GROUP;
385 else if ( xServiceInfo->supportsService( SERVICE_FIXEDLINE ) )
387 nResId = RID_STR_PROPTITLE_FIXEDLINE;
389 else
391 OSL_FAIL("Unknown service name!");
392 nResId = RID_STR_CLASS_FORMATTEDFIELD;
395 if (nResId)
397 aName += ModuleRes(nResId);
401 else // multiselection
403 aName = ModuleRes(RID_STR_BRWTITLE_PROPERTIES);
404 aName += ModuleRes(RID_STR_BRWTITLE_MULTISELECT);
407 return aName;
410 uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(OObjectBase* _pObj)
412 _pObj->initializeOle();
413 return CreateComponentPair(_pObj->getAwtComponent(),_pObj->getReportComponent());
416 uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(const uno::Reference< uno::XInterface>& _xFormComponent
417 ,const uno::Reference< uno::XInterface>& _xReportComponent)
419 uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get());
420 xNameCont->insertByName(OUString("FormComponent"),uno::makeAny(_xFormComponent));
421 xNameCont->insertByName(OUString("ReportComponent"),uno::makeAny(_xReportComponent));
422 xNameCont->insertByName(OUString("RowSet")
423 ,uno::makeAny(uno::Reference< uno::XInterface>(m_pDesignView->getController().getRowSet())));
425 return xNameCont.get();
428 ::Size PropBrw::getMinimumSize() const
430 ::Size aSize;
431 Reference< awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY );
432 if( xLayoutConstrains.is() )
434 awt::Size aMinSize = xLayoutConstrains->getMinimumSize();
435 aMinSize.Height += 4;
436 aMinSize.Width += 4;
437 aSize.setHeight( aMinSize.Height );
438 aSize.setWidth( aMinSize.Width );
440 return aSize;
443 void PropBrw::Resize()
445 Window::Resize();
447 Reference< awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY );
448 if( xLayoutConstrains.is() )
450 ::Size aMinSize = getMinimumSize();
451 SetMinOutputSizePixel( aMinSize );
452 ::Size aSize = GetOutputSizePixel();
453 bool bResize = false;
454 if( aSize.Width() < aMinSize.Width() )
456 aSize.setWidth( aMinSize.Width() );
457 bResize = true;
459 if( aSize.Height() < aMinSize.Height() )
461 aSize.setHeight( aMinSize.Height() );
462 bResize = true;
464 if( bResize )
465 SetOutputSizePixel( aSize );
467 // adjust size
468 if (m_xBrowserComponentWindow.is())
470 Size aSize = GetOutputSizePixel();
471 m_xBrowserComponentWindow->setPosSize(0, 0, aSize.Width(), aSize.Height(),
472 awt::PosSize::WIDTH | awt::PosSize::HEIGHT);
476 void PropBrw::Update( OSectionView* pNewView )
480 if ( m_pView )
482 EndListening( *(m_pView->GetModel()) );
483 m_pView = NULL;
486 // set focus on initialization
487 if ( m_bInitialStateChange )
489 // if we're just newly created, we want to have the focus
490 PostUserEvent( LINK( this, PropBrw, OnAsyncGetFocus ), NULL, true );
491 m_bInitialStateChange = false;
492 // and additionally, we want to show the page which was active during
493 // our previous incarnation
494 if ( !m_sLastActivePage.isEmpty() && m_xBrowserController.is() )
498 m_xBrowserController->restoreViewData( makeAny( m_sLastActivePage ) );
500 catch( const Exception& )
502 OSL_FAIL( "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
507 if ( !pNewView )
508 return;
509 else
510 m_pView = pNewView;
512 uno::Sequence< Reference<uno::XInterface> > aMarkedObjects;
513 OViewsWindow* pViews = m_pView->getReportSection()->getSectionWindow()->getViewsWindow();
514 const sal_uInt16 nSectionCount = pViews->getSectionCount();
515 for (sal_uInt16 i = 0; i < nSectionCount; ++i)
517 OSectionWindow* pSectionWindow = pViews->getSectionWindow(i);
518 if ( pSectionWindow )
520 const SdrMarkList& rMarkList = pSectionWindow->getReportSection().getSectionView().GetMarkedObjectList();
521 aMarkedObjects = ::comphelper::concatSequences(aMarkedObjects,CreateCompPropSet( rMarkList ));
525 if ( aMarkedObjects.getLength() ) // multiple selection
527 m_xLastSection.clear();
528 implSetNewObject( aMarkedObjects );
530 else if ( m_xLastSection != m_pView->getReportSection()->getSection() )
532 uno::Reference< uno::XInterface> xTemp(m_pView->getReportSection()->getSection());
533 m_xLastSection = xTemp;
534 uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get() );
535 xNameCont->insertByName(OUString("ReportComponent"),uno::makeAny(xTemp));
536 xTemp = xNameCont;
538 implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) );
541 StartListening( *(m_pView->GetModel()) );
543 catch ( Exception& )
545 OSL_FAIL( "PropBrw::Update: Exception occurred!" );
549 void PropBrw::Update( const uno::Reference< uno::XInterface>& _xReportComponent)
551 if ( m_xLastSection != _xReportComponent )
553 m_xLastSection = _xReportComponent;
556 if ( m_pView )
558 EndListening( *(m_pView->GetModel()) );
559 m_pView = NULL;
562 uno::Reference< uno::XInterface> xTemp(CreateComponentPair(_xReportComponent,_xReportComponent));
563 implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) );
565 catch ( Exception& )
567 OSL_FAIL( "PropBrw::Update: Exception occurred!" );
572 IMPL_LINK_NOARG( PropBrw, OnAsyncGetFocus )
574 if (m_xBrowserComponentWindow.is())
575 m_xBrowserComponentWindow->setFocus();
576 return 0L;
579 void PropBrw::LoseFocus()
581 DockingWindow::LoseFocus();
582 if (m_pDesignView)
583 m_pDesignView->getController().InvalidateAll();
588 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */