summaryrefslogtreecommitdiffstats
path: root/reportdesign/source/ui
diff options
context:
space:
mode:
Diffstat (limited to 'reportdesign/source/ui')
-rw-r--r--reportdesign/source/ui/dlg/AddField.cxx352
-rw-r--r--reportdesign/source/ui/dlg/CondFormat.cxx449
-rw-r--r--reportdesign/source/ui/dlg/Condition.cxx379
-rw-r--r--reportdesign/source/ui/dlg/Condition.hxx183
-rw-r--r--reportdesign/source/ui/dlg/DateTime.cxx208
-rw-r--r--reportdesign/source/ui/dlg/Formula.cxx274
-rw-r--r--reportdesign/source/ui/dlg/GroupExchange.cxx68
-rw-r--r--reportdesign/source/ui/dlg/GroupExchange.hxx43
-rw-r--r--reportdesign/source/ui/dlg/GroupsSorting.cxx1181
-rw-r--r--reportdesign/source/ui/dlg/Navigator.cxx836
-rw-r--r--reportdesign/source/ui/dlg/PageNumber.cxx105
-rw-r--r--reportdesign/source/ui/dlg/dlgpage.cxx78
-rw-r--r--reportdesign/source/ui/inc/AddField.hxx116
-rw-r--r--reportdesign/source/ui/inc/ColorChanger.hxx50
-rw-r--r--reportdesign/source/ui/inc/ColorListener.hxx75
-rw-r--r--reportdesign/source/ui/inc/ColumnInfo.hxx45
-rw-r--r--reportdesign/source/ui/inc/CondFormat.hxx152
-rw-r--r--reportdesign/source/ui/inc/DataProviderHandler.hxx114
-rw-r--r--reportdesign/source/ui/inc/DateTime.hxx81
-rw-r--r--reportdesign/source/ui/inc/DefaultInspection.hxx89
-rw-r--r--reportdesign/source/ui/inc/DesignView.hxx257
-rw-r--r--reportdesign/source/ui/inc/EndMarker.hxx46
-rw-r--r--reportdesign/source/ui/inc/FixedTextColor.hxx61
-rw-r--r--reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx61
-rw-r--r--reportdesign/source/ui/inc/Formula.hxx112
-rw-r--r--reportdesign/source/ui/inc/FunctionHelper.hxx105
-rw-r--r--reportdesign/source/ui/inc/GeometryHandler.hxx307
-rw-r--r--reportdesign/source/ui/inc/GroupsSorting.hxx144
-rw-r--r--reportdesign/source/ui/inc/IReportControllerObserver.hxx45
-rw-r--r--reportdesign/source/ui/inc/MarkedSection.hxx57
-rw-r--r--reportdesign/source/ui/inc/Navigator.hxx45
-rw-r--r--reportdesign/source/ui/inc/PageNumber.hxx59
-rw-r--r--reportdesign/source/ui/inc/ReportComponentHandler.hxx97
-rw-r--r--reportdesign/source/ui/inc/ReportController.hxx450
-rw-r--r--reportdesign/source/ui/inc/ReportControllerObserver.hxx110
-rw-r--r--reportdesign/source/ui/inc/ReportDefines.hxx33
-rw-r--r--reportdesign/source/ui/inc/ReportSection.hxx164
-rw-r--r--reportdesign/source/ui/inc/ReportWindow.hxx221
-rw-r--r--reportdesign/source/ui/inc/RptUndo.hxx135
-rw-r--r--reportdesign/source/ui/inc/ScrollHelper.hxx210
-rw-r--r--reportdesign/source/ui/inc/SectionView.hxx74
-rw-r--r--reportdesign/source/ui/inc/SectionWindow.hxx132
-rw-r--r--reportdesign/source/ui/inc/StartMarker.hxx82
-rw-r--r--reportdesign/source/ui/inc/UITools.hxx181
-rw-r--r--reportdesign/source/ui/inc/ViewsWindow.hxx294
-rw-r--r--reportdesign/source/ui/inc/dlgedclip.hxx81
-rw-r--r--reportdesign/source/ui/inc/dlgedfac.hxx41
-rw-r--r--reportdesign/source/ui/inc/dlgedfunc.hxx155
-rw-r--r--reportdesign/source/ui/inc/dlgpage.hxx46
-rw-r--r--reportdesign/source/ui/inc/metadata.hxx148
-rw-r--r--reportdesign/source/ui/inc/propbrw.hxx103
-rw-r--r--reportdesign/source/ui/inc/statusbarcontroller.hxx77
-rw-r--r--reportdesign/source/ui/inspection/DataProviderHandler.cxx513
-rw-r--r--reportdesign/source/ui/inspection/DefaultInspection.cxx214
-rw-r--r--reportdesign/source/ui/inspection/GeometryHandler.cxx2215
-rw-r--r--reportdesign/source/ui/inspection/ReportComponentHandler.cxx199
-rw-r--r--reportdesign/source/ui/inspection/metadata.cxx293
-rw-r--r--reportdesign/source/ui/misc/ColorListener.cxx96
-rw-r--r--reportdesign/source/ui/misc/FunctionHelper.cxx268
-rw-r--r--reportdesign/source/ui/misc/RptUndo.cxx385
-rw-r--r--reportdesign/source/ui/misc/UITools.cxx1064
-rw-r--r--reportdesign/source/ui/misc/statusbarcontroller.cxx222
-rw-r--r--reportdesign/source/ui/report/DesignView.cxx686
-rw-r--r--reportdesign/source/ui/report/EndMarker.cxx99
-rw-r--r--reportdesign/source/ui/report/FixedTextColor.cxx193
-rw-r--r--reportdesign/source/ui/report/FormattedFieldBeautifier.cxx177
-rw-r--r--reportdesign/source/ui/report/ReportController.cxx4365
-rw-r--r--reportdesign/source/ui/report/ReportControllerObserver.cxx342
-rw-r--r--reportdesign/source/ui/report/ReportSection.cxx805
-rw-r--r--reportdesign/source/ui/report/ReportWindow.cxx433
-rw-r--r--reportdesign/source/ui/report/ScrollHelper.cxx412
-rw-r--r--reportdesign/source/ui/report/SectionView.cxx250
-rw-r--r--reportdesign/source/ui/report/SectionWindow.cxx391
-rw-r--r--reportdesign/source/ui/report/StartMarker.cxx304
-rw-r--r--reportdesign/source/ui/report/ViewsWindow.cxx1673
-rw-r--r--reportdesign/source/ui/report/dlgedclip.cxx91
-rw-r--r--reportdesign/source/ui/report/dlgedfac.cxx99
-rw-r--r--reportdesign/source/ui/report/dlgedfunc.cxx894
-rw-r--r--reportdesign/source/ui/report/propbrw.cxx528
79 files changed, 26222 insertions, 0 deletions
diff --git a/reportdesign/source/ui/dlg/AddField.cxx b/reportdesign/source/ui/dlg/AddField.cxx
new file mode 100644
index 000000000..6bf3cd1f0
--- /dev/null
+++ b/reportdesign/source/ui/dlg/AddField.cxx
@@ -0,0 +1,352 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <AddField.hxx>
+#include <UITools.hxx>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/XDocumentDataSource.hpp>
+
+#include <vcl/svapp.hxx>
+
+#include <tools/diagnose_ex.h>
+
+#include <connectivity/dbtools.hxx>
+#include <core_resource.hxx>
+#include <helpids.h>
+#include <strings.hrc>
+#include <strings.hxx>
+
+#include <comphelper/sequence.hxx>
+
+namespace rptui
+{
+
+using namespace ::com::sun::star;
+using namespace sdbc;
+using namespace sdb;
+using namespace uno;
+using namespace datatransfer;
+using namespace beans;
+using namespace lang;
+using namespace container;
+using namespace ::svx;
+
+IMPL_LINK(OAddFieldWindow, DragBeginHdl, bool&, rUnsetDragIcon, bool)
+{
+ rUnsetDragIcon = false;
+ if (m_xListBox->get_selected_index() == -1)
+ {
+ // no drag without a field
+ return true;
+ }
+
+ m_xHelper->setDescriptors(getSelectedFieldDescriptors());
+ return false;
+}
+
+OAddFieldWindow::OAddFieldWindow(weld::Window* pParent, const uno::Reference< beans::XPropertySet >& xRowSet)
+ : GenericDialogController(pParent, "modules/dbreport/ui/floatingfield.ui", "FloatingField")
+ , ::comphelper::OPropertyChangeListener(m_aMutex)
+ , ::comphelper::OContainerListener(m_aMutex)
+ , m_xRowSet(xRowSet)
+ , m_xActions(m_xBuilder->weld_toolbar("toolbox"))
+ , m_xListBox(m_xBuilder->weld_tree_view("treeview"))
+ , m_xHelpText(m_xBuilder->weld_label("helptext"))
+ , m_nCommandType(0)
+ , m_bEscapeProcessing(false)
+{
+ m_xListBox->set_help_id(HID_RPT_FIELD_SEL);
+ m_xListBox->set_selection_mode(SelectionMode::Multiple);
+ m_xHelper.set(new svx::OMultiColumnTransferable);
+ rtl::Reference<TransferDataContainer> xHelper(m_xHelper);
+ m_xListBox->enable_drag_source(xHelper, DND_ACTION_COPYMOVE | DND_ACTION_LINK);
+ m_xListBox->connect_drag_begin(LINK(this, OAddFieldWindow, DragBeginHdl));
+
+ m_xDialog->connect_container_focus_changed(LINK(this, OAddFieldWindow, FocusChangeHdl));
+
+ m_xDialog->set_help_id(HID_RPT_FIELD_SEL_WIN);
+
+ m_xActions->connect_clicked(LINK(this, OAddFieldWindow, OnSortAction));
+ m_xActions->set_item_active("up", true);
+ m_xListBox->make_sorted();
+ m_xActions->set_item_sensitive("insert", false);
+
+ m_xListBox->connect_row_activated(LINK( this, OAddFieldWindow, OnDoubleClickHdl ) );
+ m_xListBox->connect_changed(LINK( this, OAddFieldWindow, OnSelectHdl ) );
+ m_xListBox->set_size_request(m_xListBox->get_approximate_digit_width() * 45, m_xListBox->get_height_rows(8));
+
+ if (!m_xRowSet.is())
+ return;
+
+ try
+ {
+ // be notified when the settings of report definition change
+ m_pChangeListener = new ::comphelper::OPropertyChangeMultiplexer( this, m_xRowSet );
+ m_pChangeListener->addProperty( PROPERTY_COMMAND );
+ m_pChangeListener->addProperty( PROPERTY_COMMANDTYPE );
+ m_pChangeListener->addProperty( PROPERTY_ESCAPEPROCESSING );
+ m_pChangeListener->addProperty( PROPERTY_FILTER );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+OAddFieldWindow::~OAddFieldWindow()
+{
+ m_aListBoxData.clear();
+ if (m_pChangeListener.is())
+ m_pChangeListener->dispose();
+ if ( m_pContainerListener.is() )
+ m_pContainerListener->dispose();
+}
+
+IMPL_LINK_NOARG(OAddFieldWindow, FocusChangeHdl, weld::Container&, void)
+{
+ if (m_xDialog->has_toplevel_focus())
+ m_xListBox->grab_focus();
+}
+
+uno::Sequence< beans::PropertyValue > OAddFieldWindow::getSelectedFieldDescriptors()
+{
+ std::vector<beans::PropertyValue> aArgs;
+
+ m_xListBox->selected_foreach([this, &aArgs](weld::TreeIter& rEntry){
+ // build a descriptor for the currently selected field
+ svx::ODataAccessDescriptor aDescriptor;
+ fillDescriptor(rEntry, aDescriptor);
+ aArgs.push_back(beans::PropertyValue());
+ aArgs.back().Value <<= aDescriptor.createPropertyValueSequence();
+
+ return false;
+ });
+
+ return comphelper::containerToSequence(aArgs);
+}
+
+void OAddFieldWindow::_propertyChanged( const beans::PropertyChangeEvent& _evt )
+{
+ OSL_ENSURE( _evt.Source == m_xRowSet, "OAddFieldWindow::_propertyChanged: where did this come from?" );
+ Update();
+}
+
+void OAddFieldWindow::addToList(const uno::Sequence< OUString >& rEntries)
+{
+ for (const OUString& rEntry : rEntries)
+ {
+ m_aListBoxData.emplace_back(new ColumnInfo(rEntry));
+ OUString sId(weld::toId(m_aListBoxData.back().get()));
+ m_xListBox->append(sId, rEntry);
+ }
+}
+
+void OAddFieldWindow::addToList(const uno::Reference< container::XNameAccess>& i_xColumns)
+{
+ const uno::Sequence< OUString > aEntries = i_xColumns->getElementNames();
+ for ( const OUString& rEntry : aEntries )
+ {
+ uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(rEntry),UNO_QUERY_THROW);
+ OUString sLabel;
+ if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) )
+ xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
+ m_aListBoxData.emplace_back(new ColumnInfo(rEntry, sLabel));
+ OUString sId(weld::toId(m_aListBoxData.back().get()));
+ if ( !sLabel.isEmpty() )
+ m_xListBox->append(sId, sLabel);
+ else
+ m_xListBox->append(sId, rEntry);
+ }
+}
+
+void OAddFieldWindow::Update()
+{
+ SolarMutexGuard aSolarGuard;
+
+ if ( m_pContainerListener.is() )
+ m_pContainerListener->dispose();
+ m_pContainerListener = nullptr;
+ m_xColumns.clear();
+
+ try
+ {
+ // ListBox loeschen
+ m_xListBox->clear();
+ m_aListBoxData.clear();
+ const OString aIds[] = { "up", "down" };
+ for (size_t j = 0; j< std::size(aIds); ++j)
+ m_xActions->set_item_sensitive(aIds[j], false);
+
+ OUString aTitle(RptResId(RID_STR_FIELDSELECTION));
+ m_xDialog->set_title(aTitle);
+ if ( m_xRowSet.is() )
+ {
+ OUString sCommand( m_aCommandName );
+ sal_Int32 nCommandType( m_nCommandType );
+ bool bEscapeProcessing( m_bEscapeProcessing );
+ OUString sFilter( m_sFilter );
+
+ OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
+ OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nCommandType );
+ OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_ESCAPEPROCESSING ) >>= bEscapeProcessing );
+ OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_FILTER ) >>= sFilter );
+
+ m_aCommandName = sCommand;
+ m_nCommandType = nCommandType;
+ m_bEscapeProcessing = bEscapeProcessing;
+ m_sFilter = sFilter;
+
+ // add the columns to the list
+ uno::Reference< sdbc::XConnection> xCon = getConnection();
+ if ( xCon.is() && !m_aCommandName.isEmpty() )
+ m_xColumns = dbtools::getFieldsByCommandDescriptor( xCon, GetCommandType(), GetCommand(), m_xHoldAlive );
+ if ( m_xColumns.is() )
+ {
+ addToList(m_xColumns);
+ uno::Reference< container::XContainer> xContainer(m_xColumns,uno::UNO_QUERY);
+ if ( xContainer.is() )
+ m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
+ }
+
+ // add the parameter columns to the list
+ uno::Reference< css::sdbc::XRowSet > xRowSet(m_xRowSet,uno::UNO_QUERY);
+ Sequence< OUString > aParamNames( getParameterNames( xRowSet ) );
+ addToList(aParamNames);
+
+ // set title
+ aTitle += " " + m_aCommandName;
+ m_xDialog->set_title(aTitle);
+ if ( !m_aCommandName.isEmpty() )
+ {
+ for (size_t i = 0; i < std::size(aIds); ++i)
+ m_xActions->set_item_sensitive(aIds[i], true);
+ }
+ OnSelectHdl(*m_xListBox);
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+uno::Reference< sdbc::XConnection> OAddFieldWindow::getConnection() const
+{
+ return uno::Reference< sdbc::XConnection>(m_xRowSet->getPropertyValue( PROPERTY_ACTIVECONNECTION ),uno::UNO_QUERY);
+}
+
+void OAddFieldWindow::fillDescriptor(const weld::TreeIter& rSelected, svx::ODataAccessDescriptor& rDescriptor)
+{
+ if (!m_xColumns.is())
+ return;
+
+ uno::Reference<container::XChild> xChild(getConnection(),uno::UNO_QUERY);
+ if ( xChild.is( ) )
+ {
+ uno::Reference<sdb::XDocumentDataSource> xDocument( xChild->getParent(), uno::UNO_QUERY );
+ if ( xDocument.is() )
+ {
+ uno::Reference<frame::XModel> xModel(xDocument->getDatabaseDocument(),uno::UNO_QUERY);
+ if ( xModel.is() )
+ rDescriptor[ DataAccessDescriptorProperty::DatabaseLocation ] <<= xModel->getURL();
+ }
+ }
+
+ rDescriptor[ svx::DataAccessDescriptorProperty::Command ] <<= GetCommand();
+ rDescriptor[ svx::DataAccessDescriptorProperty::CommandType ] <<= GetCommandType();
+ rDescriptor[ svx::DataAccessDescriptorProperty::EscapeProcessing ] <<= m_bEscapeProcessing;
+ rDescriptor[ svx::DataAccessDescriptorProperty::Connection ] <<= getConnection();
+
+ ColumnInfo* pInfo = weld::fromId<ColumnInfo*>(m_xListBox->get_id(rSelected));
+ rDescriptor[ svx::DataAccessDescriptorProperty::ColumnName ] <<= pInfo->sColumnName;
+ if ( m_xColumns->hasByName( pInfo->sColumnName ) )
+ rDescriptor[ svx::DataAccessDescriptorProperty::ColumnObject ] = m_xColumns->getByName(pInfo->sColumnName);
+}
+
+void OAddFieldWindow::_elementInserted( const container::ContainerEvent& _rEvent )
+{
+ OUString sName;
+ if ( !((_rEvent.Accessor >>= sName) && m_xColumns->hasByName(sName)) )
+ return;
+
+ uno::Reference< beans::XPropertySet> xColumn(m_xColumns->getByName(sName),UNO_QUERY_THROW);
+ OUString sLabel;
+ if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) )
+ xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
+ m_aListBoxData.emplace_back(new ColumnInfo(sName, sLabel));
+ OUString sId(weld::toId(m_aListBoxData.back().get()));
+ if (!sLabel.isEmpty())
+ m_xListBox->append(sId, sLabel);
+ else
+ m_xListBox->append(sId, sName);
+}
+
+void OAddFieldWindow::_elementRemoved( const container::ContainerEvent& /*_rEvent*/ )
+{
+ m_xListBox->clear();
+ m_aListBoxData.clear();
+ if ( m_xColumns.is() )
+ addToList(m_xColumns);
+}
+
+void OAddFieldWindow::_elementReplaced( const container::ContainerEvent& /*_rEvent*/ )
+{
+}
+
+IMPL_LINK_NOARG( OAddFieldWindow, OnSelectHdl, weld::TreeView&, void )
+{
+ m_xActions->set_item_sensitive("insert", m_xListBox->get_selected_index() != -1);
+}
+
+IMPL_LINK_NOARG( OAddFieldWindow, OnDoubleClickHdl, weld::TreeView&, bool )
+{
+ m_aCreateLink.Call(*this);
+ return true;
+}
+
+IMPL_LINK(OAddFieldWindow, OnSortAction, const OString&, rCurItem, void)
+{
+ if (rCurItem == "insert")
+ {
+ OnDoubleClickHdl(*m_xListBox);
+ return;
+ }
+
+ const OString aIds[] = { "up", "down" };
+
+ if (rCurItem == "delete")
+ {
+ for (size_t j = 0; j< std::size(aIds); ++j)
+ m_xActions->set_item_active(aIds[j], false);
+
+ m_xListBox->make_unsorted();
+ Update();
+ return;
+ }
+
+ for (size_t j = 0; j< std::size(aIds); ++j)
+ m_xActions->set_item_active(aIds[j], rCurItem == aIds[j]);
+
+ m_xListBox->make_sorted();
+ if (m_xActions->get_item_active("down"))
+ m_xListBox->set_sort_order(false);
+}
+
+} // namespace rptui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/CondFormat.cxx b/reportdesign/source/ui/dlg/CondFormat.cxx
new file mode 100644
index 000000000..5c593c3a0
--- /dev/null
+++ b/reportdesign/source/ui/dlg/CondFormat.cxx
@@ -0,0 +1,449 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <CondFormat.hxx>
+
+#include <strings.hxx>
+#include <strings.hrc>
+#include <core_resource.hxx>
+#include <ReportController.hxx>
+#include "Condition.hxx"
+
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <o3tl/safeint.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <tools/diagnose_ex.h>
+
+#include <comphelper/property.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+#include <algorithm>
+#include <UndoActions.hxx>
+
+
+namespace rptui
+{
+
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::beans::PropertyValue;
+ using ::com::sun::star::uno::Any;
+
+ using namespace ::com::sun::star::report;
+
+ void ConditionalFormattingDialog::impl_setPrefHeight(bool bFirst)
+ {
+ if (!m_bConstructed && !bFirst)
+ return;
+
+ //allow dialog to resize itself
+ size_t nCount = impl_getConditionCount();
+ if (!nCount)
+ return;
+
+ auto nHeight = m_aConditions[0]->get_preferred_size().Height();
+ size_t nVisibleConditions = ::std::min(nCount, MAX_CONDITIONS);
+ nHeight *= nVisibleConditions;
+ nHeight += 2;
+ if (nHeight != m_xScrollWindow->get_size_request().Height())
+ {
+ m_xScrollWindow->set_size_request(-1, nHeight);
+ if (!bFirst)
+ m_xDialog->resize_to_request();
+ }
+ }
+
+ ConditionalFormattingDialog::ConditionalFormattingDialog(
+ weld::Window* _pParent, const Reference< XReportControlModel >& _rxFormatConditions, ::rptui::OReportController& _rController)
+ : GenericDialogController(_pParent, "modules/dbreport/ui/condformatdialog.ui", "CondFormat")
+ , m_rController(_rController)
+ , m_xFormatConditions(_rxFormatConditions)
+ , m_bConstructed(false)
+ , m_xScrollWindow(m_xBuilder->weld_scrolled_window("scrolledwindow"))
+ , m_xConditionPlayground(m_xBuilder->weld_box("condPlaygroundDrawingarea"))
+ {
+ OSL_ENSURE( m_xFormatConditions.is(), "ConditionalFormattingDialog::ConditionalFormattingDialog: ReportControlModel is NULL -> Prepare for GPF!" );
+
+ m_xCopy.set( m_xFormatConditions->createClone(), UNO_QUERY_THROW );
+
+ m_xScrollWindow->connect_vadjustment_changed(LINK(this, ConditionalFormattingDialog, OnScroll));
+
+ impl_initializeConditions();
+
+ impl_setPrefHeight(true);
+
+ m_bConstructed = true;
+ }
+
+ ConditionalFormattingDialog::~ConditionalFormattingDialog()
+ {
+ }
+
+ void ConditionalFormattingDialog::impl_updateConditionIndicies()
+ {
+ sal_Int32 nIndex = 0;
+ for (const auto& rxCondition : m_aConditions)
+ {
+ rxCondition->setConditionIndex( nIndex, impl_getConditionCount() );
+ m_xConditionPlayground->reorder_child(rxCondition->get_widget(), nIndex);
+ ++nIndex;
+ }
+ }
+
+ void ConditionalFormattingDialog::impl_conditionCountChanged()
+ {
+ if ( m_aConditions.empty() )
+ impl_addCondition_nothrow( 0 );
+
+ impl_setPrefHeight(false);
+
+ impl_updateConditionIndicies();
+ impl_layoutAll();
+ }
+
+ void ConditionalFormattingDialog::addCondition( size_t _nAddAfterIndex )
+ {
+ OSL_PRECOND( _nAddAfterIndex < impl_getConditionCount(), "ConditionalFormattingDialog::addCondition: illegal condition index!" );
+ impl_addCondition_nothrow( _nAddAfterIndex + 1 );
+ }
+
+
+ void ConditionalFormattingDialog::deleteCondition( size_t _nCondIndex )
+ {
+ impl_deleteCondition_nothrow( _nCondIndex );
+ }
+
+
+ void ConditionalFormattingDialog::impl_addCondition_nothrow( size_t _nNewCondIndex )
+ {
+ try
+ {
+ if ( _nNewCondIndex > o3tl::make_unsigned(m_xCopy->getCount()) )
+ throw IllegalArgumentException();
+
+ Reference< XFormatCondition > xCond = m_xCopy->createFormatCondition();
+ ::comphelper::copyProperties(m_xCopy, xCond);
+ m_xCopy->insertByIndex( _nNewCondIndex, Any( xCond ) );
+ auto xCon = std::make_unique<Condition>(m_xConditionPlayground.get(), m_xDialog.get(), *this, m_rController);
+ xCon->setCondition(xCond);
+ m_xConditionPlayground->reorder_child(xCon->get_widget(), _nNewCondIndex);
+ m_aConditions.insert(m_aConditions.begin() + _nNewCondIndex, std::move(xCon));
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+
+ impl_conditionCountChanged();
+
+ impl_ensureConditionVisible( _nNewCondIndex );
+ }
+
+ void ConditionalFormattingDialog::impl_focusCondition( size_t _nCondIndex )
+ {
+ OSL_PRECOND( _nCondIndex < impl_getConditionCount(),
+ "ConditionalFormattingDialog::impl_focusCondition: illegal index!" );
+
+ impl_ensureConditionVisible( _nCondIndex );
+ m_aConditions[ _nCondIndex ]->grab_focus();
+ }
+
+ void ConditionalFormattingDialog::impl_deleteCondition_nothrow( size_t _nCondIndex )
+ {
+ OSL_PRECOND( _nCondIndex < impl_getConditionCount(),
+ "ConditionalFormattingDialog::impl_deleteCondition_nothrow: illegal index!" );
+
+ bool bLastCondition = ( impl_getConditionCount() == 1 );
+
+ bool bSetNewFocus = false;
+ size_t nNewFocusIndex( _nCondIndex );
+ try
+ {
+ if ( !bLastCondition )
+ m_xCopy->removeByIndex( _nCondIndex );
+
+ Conditions::iterator pos = m_aConditions.begin() + _nCondIndex;
+ if ( bLastCondition )
+ {
+ Reference< XFormatCondition > xFormatCondition( m_xCopy->getByIndex( 0 ), UNO_QUERY_THROW );
+ xFormatCondition->setFormula( OUString() );
+ (*pos)->setCondition( xFormatCondition );
+ }
+ else
+ {
+ bSetNewFocus = (*pos)->has_focus();
+
+ auto xMovedCondition = std::move(*pos);
+ m_aConditions.erase(pos);
+ m_xConditionPlayground->move(xMovedCondition->get_widget(), nullptr);
+ }
+
+ if ( bSetNewFocus )
+ {
+ if ( nNewFocusIndex >= impl_getConditionCount() )
+ nNewFocusIndex = impl_getConditionCount() - 1;
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+
+ impl_conditionCountChanged();
+ if ( bSetNewFocus )
+ impl_focusCondition( nNewFocusIndex );
+ }
+
+
+ void ConditionalFormattingDialog::impl_moveCondition_nothrow( size_t _nCondIndex, bool _bMoveUp )
+ {
+ size_t nOldConditionIndex( _nCondIndex );
+ size_t nNewConditionIndex( _bMoveUp ? _nCondIndex - 1 : _nCondIndex + 1 );
+
+ // do this in two steps, so we don't become inconsistent if any of the UNO actions fails
+ Any aMovedCondition;
+ std::unique_ptr<Condition> xMovedCondition;
+ try
+ {
+ aMovedCondition = m_xCopy->getByIndex( static_cast<sal_Int32>(nOldConditionIndex) );
+ m_xCopy->removeByIndex( static_cast<sal_Int32>(nOldConditionIndex) );
+
+ Conditions::iterator aRemovePos( m_aConditions.begin() + nOldConditionIndex );
+ xMovedCondition = std::move(*aRemovePos);
+ m_aConditions.erase( aRemovePos );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ return;
+ }
+
+ try
+ {
+ m_xCopy->insertByIndex( static_cast<sal_Int32>(nNewConditionIndex), aMovedCondition );
+ m_aConditions.insert(m_aConditions.begin() + nNewConditionIndex, std::move(xMovedCondition));
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+
+ // at least the two swapped conditions need to know their new index
+ impl_updateConditionIndicies();
+
+ // ensure the moved condition is visible
+ impl_ensureConditionVisible( nNewConditionIndex );
+ }
+
+ IMPL_LINK_NOARG(ConditionalFormattingDialog, OnScroll, weld::ScrolledWindow&, void)
+ {
+ size_t nFirstCondIndex( impl_getFirstVisibleConditionIndex() );
+ size_t nFocusCondIndex = impl_getFocusedConditionIndex( nFirstCondIndex );
+
+ if ( nFocusCondIndex < nFirstCondIndex )
+ impl_focusCondition( nFirstCondIndex );
+ else if ( nFocusCondIndex >= nFirstCondIndex + MAX_CONDITIONS )
+ impl_focusCondition( nFirstCondIndex + MAX_CONDITIONS - 1 );
+ }
+
+ void ConditionalFormattingDialog::impl_layoutAll()
+ {
+ // scrollbar visibility
+ if ( m_aConditions.size() <= MAX_CONDITIONS )
+ // normalize the position, so it can, in all situations, be used as top index
+ m_xScrollWindow->vadjustment_set_value(0);
+ }
+
+ void ConditionalFormattingDialog::impl_initializeConditions()
+ {
+ try
+ {
+ sal_Int32 nCount = m_xCopy->getCount();
+ for ( sal_Int32 i = 0; i < nCount ; ++i )
+ {
+ auto xCon = std::make_unique<Condition>(m_xConditionPlayground.get(), m_xDialog.get(), *this, m_rController);
+ Reference< XFormatCondition > xCond( m_xCopy->getByIndex(i), UNO_QUERY );
+ m_xConditionPlayground->reorder_child(xCon->get_widget(), i);
+ xCon->setCondition(xCond);
+ xCon->updateToolbar(xCond);
+ m_aConditions.push_back(std::move(xCon));
+ }
+ }
+ catch(Exception&)
+ {
+ OSL_FAIL("Can not access format condition!");
+ }
+
+ impl_conditionCountChanged();
+ }
+
+ void ConditionalFormattingDialog::applyCommand(size_t _nCondIndex, sal_uInt16 _nCommandId, const ::Color& rColor)
+ {
+ OSL_PRECOND( _nCommandId, "ConditionalFormattingDialog::applyCommand: illegal command id!" );
+ try
+ {
+ Reference< XReportControlFormat > xReportControlFormat( m_xCopy->getByIndex( _nCondIndex ), UNO_QUERY_THROW );
+
+ Sequence< PropertyValue > aArgs{
+ comphelper::makePropertyValue(REPORTCONTROLFORMAT, xReportControlFormat),
+ comphelper::makePropertyValue(CURRENT_WINDOW, m_xDialog->GetXWindow()),
+ comphelper::makePropertyValue(PROPERTY_FONTCOLOR, rColor)
+ };
+
+ // we use this way to create undo actions
+ m_rController.executeUnChecked(_nCommandId,aArgs);
+ m_aConditions[ _nCondIndex ]->updateToolbar(xReportControlFormat);
+ }
+ catch( Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ }
+
+
+ void ConditionalFormattingDialog::moveConditionUp( size_t _nCondIndex )
+ {
+ OSL_PRECOND( _nCondIndex > 0, "ConditionalFormattingDialog::moveConditionUp: cannot move up the first condition!" );
+ if ( _nCondIndex > 0 )
+ impl_moveCondition_nothrow( _nCondIndex, true );
+ }
+
+
+ void ConditionalFormattingDialog::moveConditionDown( size_t _nCondIndex )
+ {
+ OSL_PRECOND( _nCondIndex < impl_getConditionCount(), "ConditionalFormattingDialog::moveConditionDown: cannot move down the last condition!" );
+ if ( _nCondIndex < impl_getConditionCount() )
+ impl_moveCondition_nothrow( _nCondIndex, false );
+ }
+
+ OUString ConditionalFormattingDialog::getDataField() const
+ {
+ OUString sDataField;
+ try
+ {
+ sDataField = m_xFormatConditions->getDataField();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ return sDataField;
+ }
+
+ short ConditionalFormattingDialog::run()
+ {
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ {
+ const OUString sUndoAction( RptResId( RID_STR_UNDO_CONDITIONAL_FORMATTING ) );
+ const UndoContext aUndoContext( m_rController.getUndoManager(), sUndoAction );
+ try
+ {
+ sal_Int32 j(0), i(0);
+ for ( Conditions::const_iterator cond = m_aConditions.begin();
+ cond != m_aConditions.end();
+ ++cond, ++i
+ )
+ {
+ Reference< XFormatCondition > xCond( m_xCopy->getByIndex(i), UNO_QUERY_THROW );
+ (*cond)->fillFormatCondition( xCond );
+
+ if ( (*cond)->isEmpty() )
+ continue;
+
+ Reference< XFormatCondition > xNewCond;
+ bool bAppend = j >= m_xFormatConditions->getCount();
+ if ( bAppend )
+ {
+ xNewCond = m_xFormatConditions->createFormatCondition();
+ m_xFormatConditions->insertByIndex( i, Any( xNewCond ) );
+ }
+ else
+ xNewCond.set( m_xFormatConditions->getByIndex(j), UNO_QUERY );
+ ++j;
+
+ ::comphelper::copyProperties(xCond, xNewCond);
+ }
+
+ for ( sal_Int32 k = m_xFormatConditions->getCount()-1; k >= j; --k )
+ m_xFormatConditions->removeByIndex(k);
+
+ ::comphelper::copyProperties( m_xCopy, m_xFormatConditions );
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ nRet = RET_NO;
+ }
+ }
+ return nRet;
+ }
+
+ size_t ConditionalFormattingDialog::impl_getFirstVisibleConditionIndex() const
+ {
+ auto nHeight = m_aConditions[0]->get_preferred_size().Height();
+ return m_xScrollWindow->vadjustment_get_value() / nHeight;
+ }
+
+ size_t ConditionalFormattingDialog::impl_getLastVisibleConditionIndex() const
+ {
+ return ::std::min( impl_getFirstVisibleConditionIndex() + MAX_CONDITIONS, impl_getConditionCount() ) - 1;
+ }
+
+ size_t ConditionalFormattingDialog::impl_getFocusedConditionIndex( sal_Int32 _nFallBackIfNone ) const
+ {
+ auto cond = std::find_if(m_aConditions.begin(), m_aConditions.end(),
+ [](const std::unique_ptr<Condition>& rxCondition) { return rxCondition->has_focus(); });
+ if (cond != m_aConditions.end())
+ return static_cast<size_t>(std::distance(m_aConditions.begin(), cond));
+ return _nFallBackIfNone;
+ }
+
+ void ConditionalFormattingDialog::impl_scrollTo( size_t nTopCondIndex )
+ {
+ OSL_PRECOND( nTopCondIndex + MAX_CONDITIONS <= impl_getConditionCount(),
+ "ConditionalFormattingDialog::impl_scrollTo: illegal index!" );
+
+ auto nHeight = m_aConditions[0]->get_preferred_size().Height();
+ m_xScrollWindow->vadjustment_set_value(nTopCondIndex * nHeight);
+ OnScroll(*m_xScrollWindow);
+ }
+
+ void ConditionalFormattingDialog::impl_ensureConditionVisible( size_t _nCondIndex )
+ {
+ OSL_PRECOND( _nCondIndex < impl_getConditionCount(),
+ "ConditionalFormattingDialog::impl_ensureConditionVisible: illegal index!" );
+
+ if ( _nCondIndex < impl_getFirstVisibleConditionIndex() )
+ impl_scrollTo( _nCondIndex );
+ else if ( _nCondIndex > impl_getLastVisibleConditionIndex() )
+ impl_scrollTo( _nCondIndex - MAX_CONDITIONS + 1 );
+ }
+
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/Condition.cxx b/reportdesign/source/ui/dlg/Condition.cxx
new file mode 100644
index 000000000..392b9d5e8
--- /dev/null
+++ b/reportdesign/source/ui/dlg/Condition.cxx
@@ -0,0 +1,379 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "Condition.hxx"
+#include <UITools.hxx>
+#include <CondFormat.hxx>
+#include <core_resource.hxx>
+#include <strings.hrc>
+#include <ReportController.hxx>
+#include <reportformula.hxx>
+
+#include <svx/PaletteManager.hxx>
+#include <svx/svxids.hrc>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+
+#include <tools/diagnose_ex.h>
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+ConditionField::ConditionField(Condition* pParent, std::unique_ptr<weld::Entry> xSubEdit,
+ std::unique_ptr<weld::Button> xFormula)
+ : m_pParent(pParent)
+ , m_xSubEdit(std::move(xSubEdit))
+ , m_xFormula(std::move(xFormula))
+{
+ m_xFormula->set_label("...");
+ m_xFormula->connect_clicked( LINK( this, ConditionField, OnFormula ) );
+}
+
+IMPL_LINK_NOARG(ConditionField, OnFormula, weld::Button&, void)
+{
+ OUString sFormula(m_xSubEdit->get_text());
+ const sal_Int32 nLen = sFormula.getLength();
+ if ( nLen )
+ {
+ ReportFormula aFormula( sFormula );
+ sFormula = aFormula.getCompleteFormula();
+ }
+ uno::Reference< awt::XWindow> xInspectorWindow = m_pParent->GetXWindow();
+ uno::Reference< beans::XPropertySet> xProp(m_pParent->getController().getRowSet(),uno::UNO_QUERY);
+ if ( rptui::openDialogFormula_nothrow( sFormula, m_pParent->getController().getContext(),xInspectorWindow,xProp ) )
+ {
+ ReportFormula aFormula( sFormula );
+ m_xSubEdit->set_text(aFormula.getUndecoratedContent());
+ }
+}
+
+ConditionColorWrapper::ConditionColorWrapper(Condition* pControl, sal_uInt16 nSlotId)
+ : mpControl(pControl)
+ , mnSlotId(nSlotId)
+{
+}
+
+void ConditionColorWrapper::operator()(
+ [[maybe_unused]] const OUString& /*rCommand*/, const svx::NamedThemedColor& rNamedColor)
+{
+ mpControl->ApplyCommand(mnSlotId, rNamedColor.ToNamedColor());
+}
+
+// = Condition
+Condition::Condition(weld::Container* pParent, weld::Window* pDialog, IConditionalFormatAction& _rAction, ::rptui::OReportController& _rController)
+ : m_xPaletteManager(std::make_shared<PaletteManager>())
+ , m_aBackColorWrapper(this, SID_BACKGROUND_COLOR)
+ , m_aForeColorWrapper(this, SID_ATTR_CHAR_COLOR2)
+ , m_rController(_rController)
+ , m_rAction(_rAction)
+ , m_nCondIndex(0)
+ , m_pDialog(pDialog)
+ , m_xBuilder(Application::CreateBuilder(pParent, "modules/dbreport/ui/conditionwin.ui"))
+ , m_xContainer(m_xBuilder->weld_container("ConditionWin"))
+ , m_xHeader(m_xBuilder->weld_label("headerLabel"))
+ , m_xConditionType(m_xBuilder->weld_combo_box("typeCombobox"))
+ , m_xOperationList(m_xBuilder->weld_combo_box("opCombobox"))
+ , m_xOperandGlue(m_xBuilder->weld_label("andLabel"))
+ , m_xActions(m_xBuilder->weld_toolbar("formatToolbox"))
+ , m_xPreview(new weld::CustomWeld(*m_xBuilder, "previewDrawingarea", m_aPreview))
+ , m_xMoveUp(m_xBuilder->weld_button("upButton"))
+ , m_xMoveDown(m_xBuilder->weld_button("downButton"))
+ , m_xAddCondition(m_xBuilder->weld_button("addButton"))
+ , m_xRemoveCondition(m_xBuilder->weld_button("removeButton"))
+{
+ m_xCondLHS.reset(new ConditionField(this, m_xBuilder->weld_entry("lhsEntry"), m_xBuilder->weld_button("lhsButton")));
+ m_xCondRHS.reset(new ConditionField(this, m_xBuilder->weld_entry("rhsEntry"), m_xBuilder->weld_button("rhsButton")));
+
+ m_xCondLHS->grab_focus();
+
+ m_xConditionType->connect_changed( LINK( this, Condition, OnTypeSelected ) );
+
+ m_xOperationList->connect_changed( LINK( this, Condition, OnOperationSelected ) );
+
+ m_xActions->connect_clicked(LINK(this, Condition, OnFormatAction));
+
+ m_xMoveUp->connect_clicked( LINK( this, Condition, OnConditionAction ) );
+ m_xMoveDown->connect_clicked( LINK( this, Condition, OnConditionAction ) );
+ m_xAddCondition->connect_clicked( LINK( this, Condition, OnConditionAction ) );
+ m_xRemoveCondition->connect_clicked( LINK( this, Condition, OnConditionAction ) );
+
+ m_xConditionType->set_active(0);
+ m_xOperationList->set_active(0);
+
+ SetBackgroundDropdownClick();
+ SetForegroundDropdownClick();
+
+ m_xContainer->show();
+
+ ConditionalExpressionFactory::getKnownConditionalExpressions( m_aConditionalExpressions );
+}
+
+sal_uInt16 Condition::mapToolbarItemToSlotId(std::string_view rItemId)
+{
+ if (rItemId == "bold")
+ return SID_ATTR_CHAR_WEIGHT;
+ if (rItemId == "italic")
+ return SID_ATTR_CHAR_POSTURE;
+ if (rItemId == "underline")
+ return SID_ATTR_CHAR_UNDERLINE;
+ if (rItemId == "background")
+ return SID_BACKGROUND_COLOR;
+ if (rItemId == "foreground")
+ return SID_ATTR_CHAR_COLOR2;
+ if (rItemId == "fontdialog")
+ return SID_CHAR_DLG;
+ return 0;
+}
+
+Condition::~Condition()
+{
+}
+
+void Condition::SetBackgroundDropdownClick()
+{
+ m_xBackColorFloat.reset(new ColorWindow(
+ OUString() /*m_aCommandURL*/,
+ m_xPaletteManager,
+ m_aColorStatus,
+ SID_BACKGROUND_COLOR,
+ nullptr,
+ MenuOrToolMenuButton(m_xActions.get(), "background"),
+ [this]{ return m_pDialog; },
+ m_aBackColorWrapper));
+
+ m_xActions->set_item_popover("background", m_xBackColorFloat->getTopLevel());
+}
+
+void Condition::SetForegroundDropdownClick()
+{
+ m_xForeColorFloat.reset(new ColorWindow(
+ OUString() /*m_aCommandURL*/,
+ m_xPaletteManager,
+ m_aColorStatus,
+ SID_ATTR_CHAR_COLOR2,
+ nullptr,
+ MenuOrToolMenuButton(m_xActions.get(), "foreground"),
+ [this]{ return m_pDialog; },
+ m_aForeColorWrapper));
+
+ m_xActions->set_item_popover("foreground", m_xForeColorFloat->getTopLevel());
+}
+
+
+IMPL_LINK(Condition, OnFormatAction, const OString&, rIdent, void)
+{
+ ApplyCommand(mapToolbarItemToSlotId(rIdent),
+ NamedColor(COL_AUTO, "#" + COL_AUTO.AsRGBHexString()));
+}
+
+IMPL_LINK(Condition, OnConditionAction, weld::Button&, rClickedButton, void)
+{
+ if ( &rClickedButton == m_xMoveUp.get() )
+ m_rAction.moveConditionUp( getConditionIndex() );
+ else if ( &rClickedButton == m_xMoveDown.get() )
+ m_rAction.moveConditionDown( getConditionIndex() );
+ else if ( &rClickedButton == m_xAddCondition.get() )
+ m_rAction.addCondition( getConditionIndex() );
+ else if ( &rClickedButton == m_xRemoveCondition.get() )
+ m_rAction.deleteCondition( getConditionIndex() );
+}
+
+void Condition::ApplyCommand( sal_uInt16 _nCommandId, const NamedColor& rNamedColor )
+{
+ m_rAction.applyCommand( m_nCondIndex, _nCommandId, rNamedColor.first );
+}
+
+IMPL_LINK_NOARG( Condition, OnTypeSelected, weld::ComboBox&, void )
+{
+ impl_layoutOperands();
+}
+
+IMPL_LINK_NOARG( Condition, OnOperationSelected, weld::ComboBox&, void )
+{
+ impl_layoutOperands();
+}
+
+void Condition::impl_layoutOperands()
+{
+ const ConditionType eType( impl_getCurrentConditionType() );
+ const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() );
+
+ const bool bIsExpression = ( eType == eExpression );
+ const bool bHaveRHS =
+ ( ( eType == eFieldValueComparison )
+ && ( ( eOperation == eBetween )
+ || ( eOperation == eNotBetween )
+ )
+ );
+
+ // the "condition type" list box
+ m_xOperationList->set_visible( !bIsExpression );
+ m_xOperandGlue->set_visible( bHaveRHS );
+ m_xCondRHS->set_visible( bHaveRHS );
+}
+
+void Condition::impl_setCondition( const OUString& _rConditionFormula )
+{
+ // determine the condition's type and comparison operation
+ ConditionType eType( eFieldValueComparison );
+ ComparisonOperation eOperation( eBetween );
+
+ // LHS and RHS, matched below
+ OUString sLHS, sRHS;
+
+ if ( !_rConditionFormula.isEmpty() )
+ {
+ // the unprefixed expression which forms the condition
+ ReportFormula aFormula( _rConditionFormula );
+ OSL_ENSURE( aFormula.getType() == ReportFormula::Expression, "Condition::setCondition: illegal formula!" );
+ OUString sExpression;
+ if ( aFormula.getType() == ReportFormula::Expression )
+ sExpression = aFormula.getExpression();
+ // as fallback, if the below matching does not succeed, assume
+ // the whole expression is the LHS
+ eType = eExpression;
+ sLHS = sExpression;
+
+ // the data field (or expression) to which our control is bound
+ const ReportFormula aFieldContentFormula( m_rAction.getDataField() );
+ const OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
+
+ // check whether one of the Field Value Expression Factories recognizes the expression
+ for (const auto& [rOperation, rxConditionalExpression] : m_aConditionalExpressions)
+ {
+ if ( rxConditionalExpression->matchExpression( sExpression, sUnprefixedFieldContent, sLHS, sRHS ) )
+ {
+ eType = eFieldValueComparison;
+ eOperation = rOperation;
+ break;
+ }
+ }
+ }
+
+ // update UI
+ m_xConditionType->set_active(static_cast<sal_uInt16>(eType));
+ m_xOperationList->set_active(static_cast<sal_uInt16>(eOperation));
+ m_xCondLHS->set_text( sLHS );
+ m_xCondRHS->set_text( sRHS );
+
+ // re-layout
+ impl_layoutOperands();
+}
+
+
+void Condition::setCondition( const uno::Reference< report::XFormatCondition >& _rxCondition )
+{
+ OSL_PRECOND( _rxCondition.is(), "Condition::setCondition: empty condition object!" );
+ if ( !_rxCondition.is() )
+ return;
+
+ OUString sConditionFormula;
+ try
+ {
+ if ( _rxCondition.is() )
+ sConditionFormula = _rxCondition->getFormula();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ impl_setCondition( sConditionFormula );
+ updateToolbar( _rxCondition );
+}
+
+
+void Condition::updateToolbar(const uno::Reference< report::XReportControlFormat >& _xReportControlFormat)
+{
+ OString aItems[] = { "bold", "italic", "underline", "fontdialog" };
+
+ OSL_ENSURE(_xReportControlFormat.is(),"XReportControlFormat is NULL!");
+ if ( !_xReportControlFormat.is() )
+ return;
+
+ for (size_t j = 0; j < SAL_N_ELEMENTS(aItems); ++j)
+ {
+ m_xActions->set_item_active(aItems[j], OReportController::isFormatCommandEnabled(mapToolbarItemToSlotId(aItems[j]),
+ _xReportControlFormat));
+ }
+
+ try
+ {
+ vcl::Font aBaseFont( Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetAppFont() );
+ SvxFont aFont( VCLUnoHelper::CreateFont( _xReportControlFormat->getFontDescriptor(), aBaseFont ) );
+ aFont.SetFontHeight(o3tl::convert(aFont.GetFontHeight(), o3tl::Length::pt, o3tl::Length::twip));
+ aFont.SetEmphasisMark( static_cast< FontEmphasisMark >( _xReportControlFormat->getControlTextEmphasis() ) );
+ aFont.SetRelief( static_cast< FontRelief >( _xReportControlFormat->getCharRelief() ) );
+ aFont.SetColor( Color(ColorTransparency, _xReportControlFormat->getCharColor()) );
+ m_aPreview.SetFont( aFont, aFont, aFont );
+ m_aPreview.SetTextLineColor( Color( ColorTransparency, _xReportControlFormat->getCharUnderlineColor() ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+void Condition::fillFormatCondition(const uno::Reference< report::XFormatCondition >& _xCondition)
+{
+ const ConditionType eType( impl_getCurrentConditionType() );
+ const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() );
+
+ const OUString sLHS( m_xCondLHS->get_text() );
+ const OUString sRHS( m_xCondRHS->get_text() );
+
+ OUString sUndecoratedFormula( sLHS );
+
+ if ( eType == eFieldValueComparison )
+ {
+ ReportFormula aFieldContentFormula( m_rAction.getDataField() );
+ OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() );
+
+ PConditionalExpression pFactory( m_aConditionalExpressions[ eOperation ] );
+ sUndecoratedFormula = pFactory->assembleExpression( sUnprefixedFieldContent, sLHS, sRHS );
+ }
+
+ ReportFormula aFormula( ReportFormula::Expression, sUndecoratedFormula );
+ _xCondition->setFormula( aFormula.getCompleteFormula() );
+}
+
+void Condition::setConditionIndex( size_t _nCondIndex, size_t _nCondCount )
+{
+ m_nCondIndex = _nCondIndex;
+ OUString sHeader( RptResId( STR_NUMBERED_CONDITION ) );
+ sHeader = sHeader.replaceFirst( "$number$", OUString::number( _nCondIndex + 1) );
+ m_xHeader->set_label( sHeader );
+
+ m_xMoveUp->set_sensitive(_nCondIndex > 0);
+ OSL_PRECOND( _nCondCount > 0, "Condition::setConditionIndex: having no conditions at all is nonsense!" );
+ m_xMoveDown->set_sensitive(_nCondIndex < _nCondCount - 1);
+}
+
+bool Condition::isEmpty() const
+{
+ return m_xCondLHS->get_text().isEmpty();
+}
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/Condition.hxx b/reportdesign/source/ui/dlg/Condition.hxx
new file mode 100644
index 000000000..2e25d343d
--- /dev/null
+++ b/reportdesign/source/ui/dlg/Condition.hxx
@@ -0,0 +1,183 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_CONDITION_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_CONDITION_HXX
+
+#include <conditionalexpression.hxx>
+
+#include <com/sun/star/report/XFormatCondition.hpp>
+
+#include <svx/colorwindow.hxx>
+#include <svx/fntctrl.hxx>
+
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+
+#include <memory>
+
+namespace rptui
+{
+ class OColorPopup;
+ class OReportController;
+ class IConditionalFormatAction;
+ class Condition;
+
+ class ConditionField
+ {
+ Condition* m_pParent;
+ std::unique_ptr<weld::Entry> m_xSubEdit;
+ std::unique_ptr<weld::Button> m_xFormula;
+
+ DECL_LINK(OnFormula, weld::Button&, void);
+ public:
+ ConditionField(Condition* pParent, std::unique_ptr<weld::Entry> xSubEdit, std::unique_ptr<weld::Button> xFormula);
+ void grab_focus() { m_xSubEdit->grab_focus(); }
+ void set_visible(bool bShow) { m_xSubEdit->set_visible(bShow); m_xFormula->set_visible(bShow); }
+ void set_text(const OUString& rText) { m_xSubEdit->set_text(rText); }
+ OUString get_text() const { return m_xSubEdit->get_text(); }
+ };
+
+ class ConditionColorWrapper
+ {
+ public:
+ ConditionColorWrapper(Condition* pControl, sal_uInt16 nSlotId);
+ void operator()(const OUString& rCommand, const svx::NamedThemedColor& rColor);
+ // ColorSelectFunction signature
+ private:
+ Condition* mpControl;
+ sal_uInt16 mnSlotId;
+ };
+
+ //= Condition
+
+ class Condition
+ {
+ std::shared_ptr<PaletteManager> m_xPaletteManager;
+ ColorStatus m_aColorStatus;
+ ConditionColorWrapper m_aBackColorWrapper;
+ ConditionColorWrapper m_aForeColorWrapper;
+
+ ::rptui::OReportController& m_rController;
+ IConditionalFormatAction& m_rAction;
+
+ size_t m_nCondIndex;
+
+ ConditionalExpressions m_aConditionalExpressions;
+
+ SvxFontPrevWindow m_aPreview;
+ weld::Window* m_pDialog;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Container> m_xContainer;
+ std::unique_ptr<weld::Label> m_xHeader;
+ std::unique_ptr<weld::ComboBox> m_xConditionType;
+ std::unique_ptr<weld::ComboBox> m_xOperationList;
+ std::unique_ptr<ConditionField> m_xCondLHS;
+ std::unique_ptr<weld::Label> m_xOperandGlue;
+ std::unique_ptr<ConditionField> m_xCondRHS;
+ std::unique_ptr<weld::Toolbar> m_xActions;
+ std::unique_ptr<weld::CustomWeld> m_xPreview;
+ std::unique_ptr<weld::Button> m_xMoveUp;
+ std::unique_ptr<weld::Button> m_xMoveDown;
+ std::unique_ptr<weld::Button> m_xAddCondition;
+ std::unique_ptr<weld::Button> m_xRemoveCondition;
+ std::unique_ptr<ColorWindow> m_xBackColorFloat;
+ std::unique_ptr<ColorWindow> m_xForeColorFloat;
+
+ void SetBackgroundDropdownClick();
+ void SetForegroundDropdownClick();
+
+ DECL_LINK( OnFormatAction, const OString&, void );
+ DECL_LINK( OnConditionAction, weld::Button&, void );
+
+ public:
+ Condition(weld::Container* pParent, weld::Window* pDialog, IConditionalFormatAction& rAction, ::rptui::OReportController& rController);
+ ~Condition();
+
+ /** sets the props at the control
+ @param _xCondition the source
+ */
+ void setCondition(const css::uno::Reference< css::report::XFormatCondition >& _xCondition);
+
+ /** fills from the control
+ _xCondition the destination
+ */
+ void fillFormatCondition(const css::uno::Reference< css::report::XFormatCondition >& _xCondition);
+
+ /** updates the toolbar
+ _xCondition the destination
+ */
+ void updateToolbar(const css::uno::Reference< css::report::XReportControlFormat >& _xCondition);
+
+ /// tells the condition its new index within the dialog's condition array
+ void setConditionIndex( size_t _nCondIndex, size_t _nCondCount );
+
+ /// returns the condition's index within the dialog's condition array
+ size_t getConditionIndex() const { return m_nCondIndex; }
+
+ /** determines whether the condition is actually empty
+ */
+ bool isEmpty() const;
+
+ /** forward to the parent class
+ */
+ void ApplyCommand( sal_uInt16 _nCommandId, const NamedColor& rNamedColor );
+
+ ::rptui::OReportController& getController() const { return m_rController; }
+
+ static sal_uInt16 mapToolbarItemToSlotId(std::string_view rItemId);
+
+ css::uno::Reference<css::awt::XWindow> GetXWindow() const { return m_pDialog->GetXWindow(); }
+
+ void grab_focus() { m_xContainer->grab_focus(); }
+ bool has_focus() const { return m_xContainer->has_focus(); }
+ Size get_preferred_size() const { return m_xContainer->get_preferred_size(); }
+ weld::Widget* get_widget() const { return m_xContainer.get(); }
+
+ private:
+ void impl_layoutOperands();
+
+ inline ConditionType
+ impl_getCurrentConditionType() const;
+
+ inline ComparisonOperation
+ impl_getCurrentComparisonOperation() const;
+
+ void impl_setCondition( const OUString& _rConditionFormula );
+
+ private:
+ DECL_LINK( OnTypeSelected, weld::ComboBox&, void );
+ DECL_LINK( OnOperationSelected, weld::ComboBox&, void );
+ };
+
+ inline ConditionType Condition::impl_getCurrentConditionType() const
+ {
+ return sal::static_int_cast<ConditionType>(m_xConditionType->get_active());
+ }
+
+ inline ComparisonOperation Condition::impl_getCurrentComparisonOperation() const
+ {
+ return sal::static_int_cast<ComparisonOperation>(m_xOperationList->get_active());
+ }
+
+} // namespace rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_CONDITION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/DateTime.cxx b/reportdesign/source/ui/dlg/DateTime.cxx
new file mode 100644
index 000000000..01cc62d1e
--- /dev/null
+++ b/reportdesign/source/ui/dlg/DateTime.cxx
@@ -0,0 +1,208 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <DateTime.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <rptui_slotid.hrc>
+#include <connectivity/dbconversion.hxx>
+#include <unotools/syslocale.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <vcl/svapp.hxx>
+#include <strings.hxx>
+#include <ReportController.hxx>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatPreviewer.hpp>
+#include <algorithm>
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace ::comphelper;
+
+
+
+ODateTimeDialog::ODateTimeDialog(weld::Window* _pParent, const uno::Reference< report::XSection >& _xHoldAlive,
+ OReportController* _pController)
+ : GenericDialogController(_pParent, "modules/dbreport/ui/datetimedialog.ui", "DateTimeDialog")
+
+ , m_pController(_pController)
+ , m_xHoldAlive(_xHoldAlive)
+ , m_xDate(m_xBuilder->weld_check_button("date"))
+ , m_xFTDateFormat(m_xBuilder->weld_label("datelistbox_label"))
+ , m_xDateListBox(m_xBuilder->weld_combo_box("datelistbox"))
+ , m_xTime(m_xBuilder->weld_check_button("time"))
+ , m_xFTTimeFormat(m_xBuilder->weld_label("timelistbox_label"))
+ , m_xTimeListBox(m_xBuilder->weld_combo_box("timelistbox"))
+ , m_xPB_OK(m_xBuilder->weld_button("ok"))
+{
+ try
+ {
+ SvtSysLocale aSysLocale;
+ m_nLocale = aSysLocale.GetLanguageTag().getLocale();
+ // Fill listbox with all well known date types
+ InsertEntry(util::NumberFormat::DATE);
+ InsertEntry(util::NumberFormat::TIME);
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ m_xDateListBox->set_active(0);
+ m_xTimeListBox->set_active(0);
+
+ weld::CheckButton* aCheckBoxes[] = { m_xDate.get(), m_xTime.get() };
+ for (weld::CheckButton* pCheckBox : aCheckBoxes)
+ pCheckBox->connect_toggled(LINK(this,ODateTimeDialog,CBClickHdl));
+ CBClickHdl(*m_xTime);
+}
+
+void ODateTimeDialog::InsertEntry(sal_Int16 _nNumberFormatId)
+{
+ const bool bTime = util::NumberFormat::TIME == _nNumberFormatId;
+ weld::ComboBox* pListBox = m_xDateListBox.get();
+ if (bTime)
+ pListBox = m_xTimeListBox.get();
+
+ const uno::Reference< util::XNumberFormatter> xNumberFormatter = m_pController->getReportNumberFormatter();
+ const uno::Reference< util::XNumberFormats> xFormats = xNumberFormatter->getNumberFormatsSupplier()->getNumberFormats();
+ const uno::Sequence<sal_Int32> aFormatKeys = xFormats->queryKeys(_nNumberFormatId,m_nLocale,true);
+ for (const sal_Int32 nFormatKey : aFormatKeys)
+ {
+ pListBox->append(OUString::number(nFormatKey), getFormatStringByKey(nFormatKey,xFormats,bTime));
+ }
+}
+
+short ODateTimeDialog::run()
+{
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK && (m_xDate->get_active() || m_xTime->get_active()))
+ {
+ try
+ {
+ sal_Int32 nLength = 0;
+ uno::Sequence<beans::PropertyValue> aValues( 6 );
+ auto pValues = aValues.getArray();
+ pValues[nLength].Name = PROPERTY_SECTION;
+ pValues[nLength++].Value <<= m_xHoldAlive;
+
+ pValues[nLength].Name = PROPERTY_TIME_STATE;
+ pValues[nLength++].Value <<= m_xTime->get_active();
+
+ pValues[nLength].Name = PROPERTY_DATE_STATE;
+ pValues[nLength++].Value <<= m_xDate->get_active();
+
+ pValues[nLength].Name = PROPERTY_FORMATKEYDATE;
+ pValues[nLength++].Value <<= getFormatKey(true);
+
+ pValues[nLength].Name = PROPERTY_FORMATKEYTIME;
+ pValues[nLength++].Value <<= getFormatKey(false);
+
+ OutputDevice* pDefDev = Application::GetDefaultDevice();
+ sal_Int32 nWidth = 0;
+ if ( m_xDate->get_active() )
+ {
+ OUString sDateFormat = m_xDateListBox->get_active_text();
+ nWidth = OutputDevice::LogicToLogic(pDefDev->PixelToLogic(Size(pDefDev->GetCtrlTextWidth(sDateFormat),0)).Width(),
+ pDefDev->GetMapMode().GetMapUnit(),MapUnit::Map100thMM);
+ }
+ if ( m_xTime->get_active() )
+ {
+ OUString sDateFormat = m_xTimeListBox->get_active_text();
+ nWidth = ::std::max<sal_Int32>(OutputDevice::LogicToLogic(pDefDev->PixelToLogic(Size(pDefDev->GetCtrlTextWidth(sDateFormat),0)).Width(),
+ pDefDev->GetMapMode().GetMapUnit(),MapUnit::Map100thMM),nWidth);
+ }
+
+ if ( nWidth > 4000 )
+ {
+ pValues[nLength].Name = PROPERTY_WIDTH;
+ pValues[nLength++].Value <<= nWidth;
+ }
+
+ m_pController->executeChecked(SID_DATETIME,aValues);
+ }
+ catch (const uno::Exception&)
+ {
+ nRet = RET_NO;
+ }
+ }
+ return nRet;
+}
+
+OUString ODateTimeDialog::getFormatStringByKey(::sal_Int32 _nNumberFormatKey,const uno::Reference< util::XNumberFormats>& _xFormats,bool _bTime)
+{
+ uno::Reference< beans::XPropertySet> xFormSet = _xFormats->getByKey(_nNumberFormatKey);
+ OSL_ENSURE(xFormSet.is(),"XPropertySet is null!");
+ OUString sFormat;
+ xFormSet->getPropertyValue("FormatString") >>= sFormat;
+
+ double nValue = 0;
+ if ( _bTime )
+ {
+ tools::Time aCurrentTime( tools::Time::SYSTEM );
+ nValue = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(aCurrentTime.GetTime()));
+ }
+ else
+ {
+ Date aCurrentDate( Date::SYSTEM );
+ static css::util::Date STANDARD_DB_DATE(30,12,1899);
+ nValue = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(aCurrentDate.GetDate()),STANDARD_DB_DATE);
+ }
+
+ uno::Reference< util::XNumberFormatPreviewer> xPreviewer(m_pController->getReportNumberFormatter(),uno::UNO_QUERY);
+ OSL_ENSURE(xPreviewer.is(),"XNumberFormatPreviewer is null!");
+ return xPreviewer->convertNumberToPreviewString(sFormat,nValue,m_nLocale,true);
+}
+
+IMPL_LINK_NOARG(ODateTimeDialog, CBClickHdl, weld::Toggleable&, void)
+{
+ const bool bDate = m_xDate->get_active();
+ m_xFTDateFormat->set_sensitive(bDate);
+ m_xDateListBox->set_sensitive(bDate);
+
+ const bool bTime = m_xTime->get_active();
+ m_xFTTimeFormat->set_sensitive(bTime);
+ m_xTimeListBox->set_sensitive(bTime);
+
+ if (!bDate && !bTime)
+ {
+ m_xPB_OK->set_sensitive(false);
+ }
+ else
+ {
+ m_xPB_OK->set_sensitive(true);
+ }
+}
+
+sal_Int32 ODateTimeDialog::getFormatKey(bool _bDate) const
+{
+ sal_Int32 nFormatKey;
+ if ( _bDate )
+ {
+ nFormatKey = m_xDateListBox->get_active_id().toInt32();
+ }
+ else
+ {
+ nFormatKey = m_xTimeListBox->get_active_id().toInt32();
+ }
+ return nFormatKey;
+}
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/Formula.cxx b/reportdesign/source/ui/dlg/Formula.cxx
new file mode 100644
index 000000000..f2b95e0df
--- /dev/null
+++ b/reportdesign/source/ui/dlg/Formula.cxx
@@ -0,0 +1,274 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotools/viewoptions.hxx>
+#include <formula/formdata.hxx>
+#include <formula/funcutl.hxx>
+#include <formula/tokenarray.hxx>
+#include <formula/FormulaCompiler.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+#include <memory>
+
+#include <Formula.hxx>
+#include <AddField.hxx>
+#include <helpids.h>
+
+
+namespace rptui
+{
+ using namespace formula;
+ using namespace ::com::sun::star;
+
+
+// initialization / shared functions for the dialog
+
+
+FormulaDialog::FormulaDialog(weld::Window* pParent
+ , const uno::Reference<lang::XMultiServiceFactory>& _xServiceFactory
+ , const std::shared_ptr< IFunctionManager >& _pFunctionMgr
+ , const OUString& _sFormula
+ , const css::uno::Reference < css::beans::XPropertySet >& _xRowSet
+ , svl::SharedStringPool& rStrPool )
+ : FormulaModalDialog( pParent, _pFunctionMgr.get(),this)
+ ,m_aFunctionManager(_pFunctionMgr)
+ ,m_xFormulaData(new FormEditData())
+ ,m_xRowSet(_xRowSet)
+ ,m_pEdit(nullptr)
+ ,m_sFormula("=")
+ ,m_nStart(0)
+ ,m_nEnd(1)
+ ,mrStringPool(rStrPool)
+{
+ if ( !_sFormula.isEmpty() )
+ {
+ if ( _sFormula[0] != '=' )
+ m_sFormula += _sFormula;
+ else
+ m_sFormula = _sFormula;
+ }
+ m_xParser.set(_xServiceFactory->createInstance("org.libreoffice.report.pentaho.SOFormulaParser"),uno::UNO_QUERY);
+ if ( m_xParser.is() )
+ m_xOpCodeMapper = m_xParser->getFormulaOpCodeMapper();
+ fill();
+}
+
+void FormulaDialog::notifyChange()
+{
+}
+
+void FormulaDialog::fill()
+{
+ SetMeText(m_sFormula);
+ Update(m_sFormula);
+ CheckMatrix(m_sFormula);
+ Update();
+}
+
+FormulaDialog::~FormulaDialog()
+{
+ if ( m_xAddField )
+ {
+ SvtViewOptions aDlgOpt( EViewType::Window, HID_RPT_FIELD_SEL_WIN );
+ aDlgOpt.SetWindowState(OStringToOUString(m_xAddField->getDialog()->get_window_state(WindowStateMask::X | WindowStateMask::Y | WindowStateMask::State | WindowStateMask::Minimized), RTL_TEXTENCODING_ASCII_US));
+
+ if (m_xAddField->getDialog()->get_visible())
+ m_xAddField->response(RET_CANCEL);
+
+ m_xAddField.reset();
+ }
+
+ StoreFormEditData(m_xFormulaData.get());
+ m_pEdit = nullptr;
+}
+
+// functions for right side
+
+bool FormulaDialog::calculateValue( const OUString& rStrExp, OUString& rStrResult, bool /*bMatrixFormula*/ )
+{
+ rStrResult = rStrExp;
+ return false;
+}
+
+std::shared_ptr<formula::FormulaCompiler> FormulaDialog::getCompiler() const
+{
+ return nullptr;
+}
+
+std::unique_ptr<formula::FormulaCompiler> FormulaDialog::createCompiler( formula::FormulaTokenArray& rArray ) const
+{
+ return std::unique_ptr<formula::FormulaCompiler>(new FormulaCompiler(rArray));
+}
+
+void FormulaDialog::doClose(bool _bOk)
+{
+ response(_bOk ? RET_OK : RET_CANCEL);
+}
+
+void FormulaDialog::insertEntryToLRUList(const IFunctionDescription* /*_pDesc*/)
+{
+}
+void FormulaDialog::showReference(const OUString& /*_sFormula*/)
+{
+}
+void FormulaDialog::dispatch(bool /*_bOK*/, bool /*_bMatrixChecked*/)
+{
+}
+void FormulaDialog::setDispatcherLock( bool /*bLock*/ )
+{
+}
+void FormulaDialog::deleteFormData()
+{
+}
+void FormulaDialog::clear()
+{
+}
+void FormulaDialog::switchBack()
+{
+}
+FormEditData* FormulaDialog::getFormEditData() const
+{
+ return m_xFormulaData.get();
+}
+void FormulaDialog::setCurrentFormula(const OUString& _sReplacement)
+{
+ const sal_Int32 nOldLen = m_nEnd - m_nStart;
+ const sal_Int32 nNewLen = _sReplacement.getLength();
+ if (nOldLen)
+ m_sFormula = m_sFormula.replaceAt( m_nStart, nOldLen, u"" );
+ if (nNewLen)
+ m_sFormula = m_sFormula.replaceAt( m_nStart, 0, _sReplacement );
+ m_nEnd = m_nStart + nNewLen;
+}
+void FormulaDialog::setSelection(sal_Int32 _nStart, sal_Int32 _nEnd)
+{
+ if ( _nStart <= _nEnd )
+ {
+ m_nStart = _nStart;
+ m_nEnd = _nEnd;
+ }
+ else
+ {
+ m_nEnd = _nStart;
+ m_nStart = _nEnd;
+ }
+}
+void FormulaDialog::getSelection(sal_Int32& _nStart, sal_Int32& _nEnd) const
+{
+ _nStart = m_nStart;
+ _nEnd = m_nEnd;
+}
+OUString FormulaDialog::getCurrentFormula() const
+{
+ return m_sFormula;
+}
+IFunctionManager* FormulaDialog::getFunctionManager()
+{
+ return m_aFunctionManager.get();
+}
+
+void FormulaDialog::ShowReference(const OUString& /*_sRef*/)
+{
+}
+
+void FormulaDialog::HideReference( bool /*bDoneRefMode*/)
+{
+}
+
+void FormulaDialog::ReleaseFocus( RefEdit* /*pEdit*/)
+{
+}
+
+void FormulaDialog::ToggleCollapsed( RefEdit* _pEdit, RefButton* _pButton)
+{
+ ::std::pair<RefButton*,RefEdit*> aPair = RefInputStartBefore( _pEdit, _pButton );
+ m_pEdit = aPair.second;
+ if ( m_pEdit )
+ m_pEdit->GetWidget()->hide();
+ if ( aPair.first )
+ aPair.first->GetWidget()->hide();
+
+ if (!m_xAddField)
+ {
+ m_xAddField = std::make_shared<OAddFieldWindow>(m_xDialog.get(), m_xRowSet);
+ m_xAddField->SetCreateHdl(LINK( this, FormulaDialog, OnClickHdl ) );
+ SvtViewOptions aDlgOpt( EViewType::Window, HID_RPT_FIELD_SEL_WIN );
+ if ( aDlgOpt.Exists() )
+ {
+ m_xAddField->getDialog()->set_window_state(OUStringToOString(aDlgOpt.GetWindowState(), RTL_TEXTENCODING_ASCII_US));
+
+ }
+
+ m_xAddField->Update();
+ }
+ RefInputStartAfter();
+
+ if (!m_xAddField->getDialog()->get_visible())
+ weld::DialogController::runAsync(m_xAddField, [this](sal_Int32 /*nResult*/) { m_xAddField.reset(); });
+}
+
+IMPL_LINK( FormulaDialog, OnClickHdl, OAddFieldWindow& ,_rAddFieldDlg, void)
+{
+ const uno::Sequence< beans::PropertyValue > aArgs = _rAddFieldDlg.getSelectedFieldDescriptors();
+ // we use this way to create undo actions
+ if ( m_pEdit && aArgs.getLength() == 1)
+ {
+ uno::Sequence< beans::PropertyValue > aValue;
+ aArgs[0].Value >>= aValue;
+ svx::ODataAccessDescriptor aDescriptor(aValue);
+ OUString sName;
+ aDescriptor[ svx::DataAccessDescriptorProperty::ColumnName ] >>= sName;
+ if ( !sName.isEmpty() )
+ {
+ sName = "[" + sName + "]";
+ m_pEdit->SetText(sName);
+ }
+ }
+ m_pEdit = nullptr;
+ if (_rAddFieldDlg.getDialog()->get_visible())
+ _rAddFieldDlg.response(RET_CANCEL);
+ RefInputDoneAfter();
+}
+
+uno::Reference< sheet::XFormulaParser> FormulaDialog::getFormulaParser() const
+{
+ return m_xParser;
+}
+
+uno::Reference< sheet::XFormulaOpCodeMapper> FormulaDialog::getFormulaOpCodeMapper() const
+{
+ return m_xOpCodeMapper;
+}
+
+table::CellAddress FormulaDialog::getReferencePosition() const
+{
+ return table::CellAddress();
+}
+
+::std::unique_ptr<formula::FormulaTokenArray> FormulaDialog::convertToTokenArray(const uno::Sequence< sheet::FormulaToken >& _aTokenList)
+{
+ ::std::unique_ptr<formula::FormulaTokenArray> pArray(new FormulaTokenArray());
+ pArray->Fill(_aTokenList, mrStringPool, nullptr);
+ return pArray;
+}
+
+} // rptui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/GroupExchange.cxx b/reportdesign/source/ui/dlg/GroupExchange.cxx
new file mode 100644
index 000000000..7b749c3f4
--- /dev/null
+++ b/reportdesign/source/ui/dlg/GroupExchange.cxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include "GroupExchange.hxx"
+#include <sot/formats.hxx>
+#include <osl/diagnose.h>
+
+namespace rptui
+{
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+
+ SotClipboardFormatId OGroupExchange::getReportGroupId()
+ {
+ static SotClipboardFormatId s_nReportFormat = static_cast<SotClipboardFormatId>(-1);
+ if ( static_cast<SotClipboardFormatId>(-1) == s_nReportFormat )
+ {
+ s_nReportFormat = SotExchange::RegisterFormatName("application/x-openoffice;windows_formatname=\"reportdesign.GroupFormat\"");
+ OSL_ENSURE(static_cast<SotClipboardFormatId>(-1) != s_nReportFormat, "Bad exchange id!");
+ }
+ return s_nReportFormat;
+ }
+ OGroupExchange::OGroupExchange(const uno::Sequence< uno::Any >& _aGroupRow)
+ : m_aGroupRow(_aGroupRow)
+ {
+ }
+
+ void OGroupExchange::AddSupportedFormats()
+ {
+ if ( m_aGroupRow.hasElements() )
+ {
+ AddFormat(OGroupExchange::getReportGroupId());
+ }
+ }
+
+ bool OGroupExchange::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
+ {
+ SotClipboardFormatId nFormat = SotExchange::GetFormat(rFlavor);
+ if(nFormat == OGroupExchange::getReportGroupId() )
+ {
+ return SetAny(uno::Any(m_aGroupRow));
+ }
+ return false;
+ }
+
+ void OGroupExchange::ObjectReleased()
+ {
+ m_aGroupRow.realloc(0);
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/GroupExchange.hxx b/reportdesign/source/ui/dlg/GroupExchange.hxx
new file mode 100644
index 000000000..6154e75ae
--- /dev/null
+++ b/reportdesign/source/ui/dlg/GroupExchange.hxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_GROUPEXCHANGE_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_GROUPEXCHANGE_HXX
+
+#include <vcl/transfer.hxx>
+
+namespace rptui
+{
+ /** clipboard class for group rows in the groups and sorting dialog
+ */
+ class OGroupExchange : public TransferableHelper
+ {
+ css::uno::Sequence< css::uno::Any> m_aGroupRow;
+ public:
+ explicit OGroupExchange(const css::uno::Sequence< css::uno::Any>& _aGroupRow);
+
+ static SotClipboardFormatId getReportGroupId();
+ protected:
+ virtual void AddSupportedFormats() override;
+ virtual bool GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc ) override;
+ virtual void ObjectReleased() override;
+ };
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_GROUPEXCHANGE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/GroupsSorting.cxx b/reportdesign/source/ui/dlg/GroupsSorting.cxx
new file mode 100644
index 000000000..e0599d83a
--- /dev/null
+++ b/reportdesign/source/ui/dlg/GroupsSorting.cxx
@@ -0,0 +1,1181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <GroupsSorting.hxx>
+#include <svtools/editbrowsebox.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XContainerListener.hpp>
+#include <com/sun/star/report/GroupOn.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+
+#include <strings.hrc>
+#include <rptui_slotid.hrc>
+#include <core_resource.hxx>
+#include <helpids.h>
+#include "GroupExchange.hxx"
+#include <UITools.hxx>
+#include <UndoActions.hxx>
+#include <strings.hxx>
+#include <ReportController.hxx>
+#include <ColumnInfo.hxx>
+
+#include <comphelper/propertyvalue.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <vcl/commandevent.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <algorithm>
+
+#define HANDLE_ID 0
+#define FIELD_EXPRESSION 1
+#define GROUPS_START_LEN 5
+#define NO_GROUP -1
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace svt;
+using namespace ::comphelper;
+
+ static void lcl_addToList_throw( weld::ComboBox& _rListBox, ::std::vector<ColumnInfo>& o_aColumnList,const uno::Reference< container::XNameAccess>& i_xColumns )
+ {
+ const uno::Sequence< OUString > aEntries = i_xColumns->getElementNames();
+ for ( const OUString& rEntry : aEntries )
+ {
+ uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(rEntry),uno::UNO_QUERY_THROW);
+ OUString sLabel;
+ if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) )
+ xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
+ o_aColumnList.emplace_back(rEntry,sLabel );
+ if ( !sLabel.isEmpty() )
+ _rListBox.append_text( sLabel );
+ else
+ _rListBox.append_text( rEntry );
+ }
+ }
+
+/**
+ * Separated out from OFieldExpressionControl to prevent collision of ref-counted base classes
+ */
+class OFieldExpressionControl;
+
+namespace {
+
+class OFieldExpressionControlContainerListener : public ::cppu::WeakImplHelper< container::XContainerListener >
+{
+ VclPtr<OFieldExpressionControl> mpParent;
+public:
+ explicit OFieldExpressionControlContainerListener(OFieldExpressionControl* pParent) : mpParent(pParent) {}
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
+ // XContainerListener
+ virtual void SAL_CALL elementInserted(const css::container::ContainerEvent& rEvent) override;
+ virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent& rEvent) override;
+ virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent& rEvent) override;
+};
+
+}
+
+class OFieldExpressionControl : public ::svt::EditBrowseBox
+{
+ ::osl::Mutex m_aMutex;
+ ::std::vector<sal_Int32> m_aGroupPositions;
+ ::std::vector<ColumnInfo> m_aColumnInfo;
+ VclPtr< ::svt::ComboBoxControl> m_pComboCell;
+ sal_Int32 m_nDataPos;
+ sal_Int32 m_nCurrentPos;
+ ImplSVEvent * m_nDeleteEvent;
+ OGroupsSortingDialog* m_pParent;
+ bool m_bIgnoreEvent;
+ rtl::Reference<OFieldExpressionControlContainerListener> aContainerListener;
+
+public:
+ OFieldExpressionControl(OGroupsSortingDialog* pParentDialog, const css::uno::Reference<css::awt::XWindow> &rParent);
+ virtual ~OFieldExpressionControl() override;
+ virtual void dispose() override;
+
+ // XContainerListener
+ /// @throws css::uno::RuntimeException
+ void elementInserted(const css::container::ContainerEvent& rEvent);
+ /// @throws css::uno::RuntimeException
+ void elementRemoved(const css::container::ContainerEvent& rEvent);
+
+ virtual Size GetOptimalSize() const override;
+
+ void fillColumns(const uno::Reference< container::XNameAccess>& _xColumns);
+ void lateInit();
+ bool IsDeleteAllowed( ) const;
+ void DeleteRows();
+
+ sal_Int32 getGroupPosition(sal_Int32 _nRow) const { return _nRow != BROWSER_ENDOFSELECTION ? m_aGroupPositions[_nRow] : sal_Int32(NO_GROUP); }
+
+ /** returns the sequence with the selected groups
+ */
+ uno::Sequence<uno::Any> fillSelectedGroups();
+
+ /** move groups given by _aGroups
+ */
+ void moveGroups(const uno::Sequence<uno::Any>& _aGroups,sal_Int32 _nRow,bool _bSelect = true);
+
+ virtual bool CursorMoving(sal_Int32 nNewRow, sal_uInt16 nNewCol) override;
+ using ::svt::EditBrowseBox::GetRowCount;
+protected:
+ virtual bool IsTabAllowed(bool bForward) const override;
+
+ virtual void InitController( ::svt::CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol ) override;
+ virtual ::svt::CellController* GetController( sal_Int32 nRow, sal_uInt16 nCol ) override;
+ virtual void PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColId ) const override;
+ virtual bool SeekRow( sal_Int32 nRow ) override;
+ virtual bool SaveModified() override;
+ virtual OUString GetCellText( sal_Int32 nRow, sal_uInt16 nColId ) const override;
+ virtual RowStatus GetRowStatus(sal_Int32 nRow) const override;
+
+ virtual void KeyInput(const KeyEvent& rEvt) override;
+ virtual void Command( const CommandEvent& rEvt ) override;
+
+ // D&D
+ virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ) override;
+ virtual sal_Int8 AcceptDrop( const BrowserAcceptDropEvent& rEvt ) override;
+ virtual sal_Int8 ExecuteDrop( const BrowserExecuteDropEvent& rEvt ) override;
+
+ using BrowseBox::AcceptDrop;
+ using BrowseBox::ExecuteDrop;
+
+private:
+
+ DECL_LINK( CBChangeHdl, weld::ComboBox&, void);
+
+public:
+ DECL_LINK( DelayedDelete, void*, void );
+
+};
+
+
+void OFieldExpressionControlContainerListener::disposing(const css::lang::EventObject& )
+{}
+
+void OFieldExpressionControlContainerListener::elementInserted(const css::container::ContainerEvent& rEvent)
+{ mpParent->elementInserted(rEvent); }
+
+void OFieldExpressionControlContainerListener::elementReplaced(const css::container::ContainerEvent& )
+{}
+
+void OFieldExpressionControlContainerListener::elementRemoved(const css::container::ContainerEvent& rEvent)
+{ mpParent->elementRemoved(rEvent); }
+
+OFieldExpressionControl::OFieldExpressionControl(OGroupsSortingDialog* pParentDialog, const css::uno::Reference<css::awt::XWindow> &rParent)
+ :EditBrowseBox( VCLUnoHelper::GetWindow(rParent), EditBrowseBoxFlags::NONE, WB_TABSTOP,
+ BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION | BrowserMode::AUTOSIZE_LASTCOL |
+ BrowserMode::KEEPHIGHLIGHT | BrowserMode::HLINES | BrowserMode::VLINES)
+ ,m_aGroupPositions(GROUPS_START_LEN,-1)
+ ,m_pComboCell(nullptr)
+ ,m_nDataPos(-1)
+ ,m_nCurrentPos(-1)
+ ,m_nDeleteEvent(nullptr)
+ ,m_pParent(pParentDialog)
+ ,m_bIgnoreEvent(false)
+ ,aContainerListener(new OFieldExpressionControlContainerListener(this))
+{
+ SetBorderStyle(WindowBorderStyle::MONO);
+}
+
+OFieldExpressionControl::~OFieldExpressionControl()
+{
+ disposeOnce();
+}
+
+void OFieldExpressionControl::dispose()
+{
+ uno::Reference< report::XGroups > xGroups = m_pParent->getGroups();
+ xGroups->removeContainerListener(aContainerListener);
+
+ // delete events from queue
+ if( m_nDeleteEvent )
+ Application::RemoveUserEvent( m_nDeleteEvent );
+
+ m_pComboCell.disposeAndClear();
+ m_pParent = nullptr;
+ ::svt::EditBrowseBox::dispose();
+}
+
+uno::Sequence<uno::Any> OFieldExpressionControl::fillSelectedGroups()
+{
+ uno::Sequence<uno::Any> aList;
+ ::std::vector<uno::Any> vClipboardList;
+ vClipboardList.reserve(GetSelectRowCount());
+
+ uno::Reference<report::XGroups> xGroups = m_pParent->getGroups();
+ sal_Int32 nCount = xGroups->getCount();
+ if ( nCount >= 1 )
+ {
+ for( tools::Long nIndex=FirstSelectedRow(); nIndex != SFX_ENDOFSELECTION; nIndex=NextSelectedRow() )
+ {
+ try
+ {
+ if ( m_aGroupPositions[nIndex] != NO_GROUP )
+ {
+ uno::Reference< report::XGroup> xOrgGroup(xGroups->getByIndex(m_aGroupPositions[nIndex]),uno::UNO_QUERY);
+ /*uno::Reference< report::XGroup> xCopy = xGroups->createGroup();
+ ::comphelper::copyProperties(xOrgGroup.get(),xCopy.get());*/
+ vClipboardList.push_back( uno::Any(xOrgGroup) );
+ }
+ }
+ catch(uno::Exception&)
+ {
+ OSL_FAIL("Can not access group!");
+ }
+ }
+ if ( !vClipboardList.empty() )
+ aList = uno::Sequence< uno::Any >(vClipboardList.data(), vClipboardList.size());
+ }
+ return aList;
+}
+
+void OFieldExpressionControl::StartDrag( sal_Int8 /*_nAction*/ , const Point& /*_rPosPixel*/ )
+{
+ if ( m_pParent && !m_pParent->isReadOnly( ) )
+ {
+ uno::Sequence<uno::Any> aClipboardList = fillSelectedGroups();
+
+ if( aClipboardList.hasElements() )
+ {
+ rtl::Reference<OGroupExchange> pData = new OGroupExchange(aClipboardList);
+ pData->StartDrag(this, DND_ACTION_MOVE );
+ }
+ }
+}
+
+sal_Int8 OFieldExpressionControl::AcceptDrop( const BrowserAcceptDropEvent& rEvt )
+{
+ sal_Int8 nAction = DND_ACTION_NONE;
+ if ( IsEditing() )
+ {
+ weld::ComboBox& rComboBox = m_pComboCell->get_widget();
+ sal_Int32 nPos = rComboBox.get_active();
+ if (nPos != -1 || !rComboBox.get_active_text().isEmpty())
+ SaveModified();
+ DeactivateCell();
+ }
+ if ( IsDropFormatSupported( OGroupExchange::getReportGroupId() ) && m_pParent->getGroups()->getCount() > 1 && rEvt.GetWindow() == &GetDataWindow() )
+ {
+ nAction = DND_ACTION_MOVE;
+ }
+ return nAction;
+}
+
+sal_Int8 OFieldExpressionControl::ExecuteDrop( const BrowserExecuteDropEvent& rEvt )
+{
+ sal_Int8 nAction = DND_ACTION_NONE;
+ if ( IsDropFormatSupported( OGroupExchange::getReportGroupId() ) )
+ {
+ sal_Int32 nRow = GetRowAtYPosPixel(rEvt.maPosPixel.Y(), false);
+ SetNoSelection();
+
+ TransferableDataHelper aDropped( rEvt.maDropEvent.Transferable );
+ uno::Any aDrop = aDropped.GetAny(OGroupExchange::getReportGroupId(), OUString());
+ uno::Sequence< uno::Any > aGroups;
+ aDrop >>= aGroups;
+ if ( aGroups.hasElements() )
+ {
+ moveGroups(aGroups,nRow);
+ nAction = DND_ACTION_MOVE;
+ }
+ }
+ return nAction;
+}
+
+void OFieldExpressionControl::moveGroups(const uno::Sequence<uno::Any>& _aGroups,sal_Int32 _nRow,bool _bSelect)
+{
+ if ( !_aGroups.hasElements() )
+ return;
+
+ m_bIgnoreEvent = true;
+ {
+ sal_Int32 nRow = _nRow;
+ const OUString sUndoAction(RptResId(RID_STR_UNDO_MOVE_GROUP));
+ const UndoContext aUndoContext( m_pParent->m_pController->getUndoManager(), sUndoAction );
+
+ uno::Reference< report::XGroups> xGroups = m_pParent->getGroups();
+ for(const uno::Any& rGroup : _aGroups)
+ {
+ uno::Reference< report::XGroup> xGroup(rGroup,uno::UNO_QUERY);
+ if ( xGroup.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
+ PROPERTY_GROUP, xGroup) };
+ // we use this way to create undo actions
+ m_pParent->m_pController->executeChecked(SID_GROUP_REMOVE,aArgs);
+ aArgs.realloc(2);
+ auto pArgs = aArgs.getArray();
+ if ( nRow > xGroups->getCount() )
+ nRow = xGroups->getCount();
+ if ( _bSelect )
+ SelectRow(nRow);
+ pArgs[1].Name = PROPERTY_POSITIONY;
+ pArgs[1].Value <<= nRow;
+ m_pParent->m_pController->executeChecked(SID_GROUP_APPEND,aArgs);
+ ++nRow;
+ }
+ }
+ }
+ m_bIgnoreEvent = false;
+ Invalidate();
+}
+
+void OFieldExpressionControl::fillColumns(const uno::Reference< container::XNameAccess>& _xColumns)
+{
+ weld::ComboBox& rComboBox = m_pComboCell->get_widget();
+ rComboBox.clear();
+ if ( _xColumns.is() )
+ lcl_addToList_throw(rComboBox, m_aColumnInfo, _xColumns);
+}
+
+void OFieldExpressionControl::lateInit()
+{
+ uno::Reference< report::XGroups > xGroups = m_pParent->getGroups();
+ sal_Int32 nGroupsCount = xGroups->getCount();
+ m_aGroupPositions.resize(::std::max<sal_Int32>(nGroupsCount,sal_Int32(GROUPS_START_LEN)),NO_GROUP);
+ ::std::vector<sal_Int32>::iterator aIter = m_aGroupPositions.begin();
+ for (sal_Int32 i = 0; i < nGroupsCount; ++i,++aIter)
+ *aIter = i;
+
+ if ( ColCount() == 0 )
+ {
+ vcl::Font aFont( GetDataWindow().GetFont() );
+ aFont.SetWeight( WEIGHT_NORMAL );
+ GetDataWindow().SetFont( aFont );
+
+ // Set font of the headline to light
+ aFont = GetFont();
+ aFont.SetWeight( WEIGHT_LIGHT );
+ SetFont(aFont);
+
+ InsertHandleColumn(static_cast<sal_uInt16>(GetTextWidth(OUString('0')) * 4)/*, sal_True */);
+ InsertDataColumn( FIELD_EXPRESSION, RptResId(STR_RPT_EXPRESSION), 100);
+
+ m_pComboCell = VclPtr<ComboBoxControl>::Create( &GetDataWindow() );
+ weld::ComboBox& rComboBox = m_pComboCell->get_widget();
+ rComboBox.connect_changed(LINK(this,OFieldExpressionControl,CBChangeHdl));
+ m_pComboCell->SetHelpId(HID_RPT_FIELDEXPRESSION);
+
+ m_pComboCell->SetFocusInHdl(LINK(m_pParent, OGroupsSortingDialog, OnControlFocusGot));
+
+
+ // set browse mode
+ BrowserMode nMode(BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION | BrowserMode::KEEPHIGHLIGHT |
+ BrowserMode::HLINES | BrowserMode::VLINES | BrowserMode::AUTOSIZE_LASTCOL | BrowserMode::AUTO_VSCROLL | BrowserMode::AUTO_HSCROLL);
+ if( m_pParent->isReadOnly() )
+ nMode |= BrowserMode::HIDECURSOR;
+ SetMode(nMode);
+ xGroups->addContainerListener(aContainerListener);
+ }
+ else
+ // not the first call
+ RowRemoved(0, GetRowCount());
+
+ RowInserted(0, m_aGroupPositions.size());
+}
+
+IMPL_LINK_NOARG( OFieldExpressionControl, CBChangeHdl, weld::ComboBox&, void )
+{
+ SaveModified();
+}
+
+bool OFieldExpressionControl::IsTabAllowed(bool /*bForward*/) const
+{
+ return false;
+}
+
+bool OFieldExpressionControl::SaveModified()
+{
+ sal_Int32 nRow = GetCurRow();
+ if ( nRow == BROWSER_ENDOFSELECTION )
+ return true;
+
+ try
+ {
+ bool bAppend = false;
+ uno::Reference< report::XGroup> xGroup;
+ if ( m_aGroupPositions[nRow] == NO_GROUP )
+ {
+ bAppend = true;
+ OUString sUndoAction(RptResId(RID_STR_UNDO_APPEND_GROUP));
+ m_pParent->m_pController->getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) );
+ xGroup = m_pParent->getGroups()->createGroup();
+ xGroup->setHeaderOn(true);
+
+ // find position where to insert the new group
+ sal_Int32 nGroupPos = 0;
+ ::std::vector<sal_Int32>::iterator aIter = m_aGroupPositions.begin();
+ ::std::vector<sal_Int32>::const_iterator aEnd = m_aGroupPositions.begin() + nRow;
+ for(;aIter != aEnd;++aIter)
+ if ( *aIter != NO_GROUP )
+ nGroupPos = *aIter + 1;
+ uno::Sequence< beans::PropertyValue > aArgs{
+ comphelper::makePropertyValue(PROPERTY_GROUP, xGroup),
+ comphelper::makePropertyValue(PROPERTY_POSITIONY, nGroupPos)
+ };
+ m_bIgnoreEvent = true;
+ m_pParent->m_pController->executeChecked(SID_GROUP_APPEND,aArgs);
+ m_bIgnoreEvent = false;
+ OSL_ENSURE(*aIter == NO_GROUP ,"Illegal iterator!");
+ *aIter++ = nGroupPos;
+
+ aEnd = m_aGroupPositions.end();
+ for(;aIter != aEnd;++aIter)
+ if ( *aIter != NO_GROUP )
+ ++*aIter;
+ }
+ else
+ xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]);
+ if ( xGroup.is() )
+ {
+ weld::ComboBox& rComboBox = m_pComboCell->get_widget();
+ sal_Int32 nPos = rComboBox.get_active();
+ OUString sExpression;
+ if (nPos == -1)
+ sExpression = rComboBox.get_active_text();
+ else
+ {
+ sExpression = m_aColumnInfo[nPos].sColumnName;
+ }
+ xGroup->setExpression( sExpression );
+
+ ::rptui::adjustSectionName(xGroup,nPos);
+
+ if ( bAppend )
+ m_pParent->m_pController->getUndoManager().LeaveListAction();
+ }
+
+ if (Controller().is())
+ Controller()->SaveValue();
+ if ( GetRowCount() == m_pParent->getGroups()->getCount() )
+ {
+ RowInserted( GetRowCount()-1);
+ m_aGroupPositions.push_back(NO_GROUP);
+ }
+
+ GoToRow(nRow);
+ m_pParent->DisplayData(nRow);
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "OFieldExpressionControl::SaveModified");
+ }
+
+ return true;
+}
+
+OUString OFieldExpressionControl::GetCellText( sal_Int32 nRow, sal_uInt16 /*nColId*/ ) const
+{
+ OUString sText;
+ if ( nRow != BROWSER_ENDOFSELECTION && m_aGroupPositions[nRow] != NO_GROUP )
+ {
+ try
+ {
+ uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]);
+ OUString sExpression = xGroup->getExpression();
+
+ auto aIter = std::find_if(m_aColumnInfo.begin(), m_aColumnInfo.end(),
+ [&sExpression](const ColumnInfo& rColumnInfo) { return rColumnInfo.sColumnName == sExpression; });
+ if (aIter != m_aColumnInfo.end() && !aIter->sLabel.isEmpty())
+ sExpression = aIter->sLabel;
+ sText = sExpression;
+ }
+ catch (const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while getting expression value from the group");
+ }
+ }
+ return sText;
+}
+
+void OFieldExpressionControl::InitController( CellControllerRef& /*rController*/, sal_Int32 nRow, sal_uInt16 nColumnId )
+{
+ weld::ComboBox& rComboBox = m_pComboCell->get_widget();
+ rComboBox.set_entry_text(GetCellText(nRow, nColumnId));
+}
+
+bool OFieldExpressionControl::CursorMoving(sal_Int32 nNewRow, sal_uInt16 nNewCol)
+{
+
+ if (!EditBrowseBox::CursorMoving(nNewRow, nNewCol))
+ return false;
+ m_nDataPos = nNewRow;
+ tools::Long nOldDataPos = GetCurRow();
+ InvalidateStatusCell( m_nDataPos );
+ InvalidateStatusCell( nOldDataPos );
+
+ m_pParent->SaveData( nOldDataPos );
+ m_pParent->DisplayData( m_nDataPos );
+ return true;
+}
+
+CellController* OFieldExpressionControl::GetController( sal_Int32 /*nRow*/, sal_uInt16 /*nColumnId*/ )
+{
+ ComboBoxCellController* pCellController = new ComboBoxCellController( m_pComboCell );
+ pCellController->GetComboBox().set_entry_editable(m_pParent->m_pController->isEditable());
+ return pCellController;
+}
+
+bool OFieldExpressionControl::SeekRow( sal_Int32 _nRow )
+{
+ // the basis class needs the call, because that's how the class knows which line will be painted
+ EditBrowseBox::SeekRow(_nRow);
+ m_nCurrentPos = _nRow;
+ return true;
+}
+
+void OFieldExpressionControl::PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId ) const
+{
+ OUString aText =GetCellText( m_nCurrentPos, nColumnId );
+
+ Point aPos( rRect.TopLeft() );
+ Size aTextSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight() );
+
+ if( aPos.X() < rRect.Left() || aPos.X() + aTextSize.Width() > rRect.Right() ||
+ aPos.Y() < rRect.Top() || aPos.Y() + aTextSize.Height() > rRect.Bottom() )
+ rDev.SetClipRegion(vcl::Region(rRect));
+
+ rDev.DrawText( aPos, aText );
+
+ if( rDev.IsClipRegion() )
+ rDev.SetClipRegion();
+}
+
+EditBrowseBox::RowStatus OFieldExpressionControl::GetRowStatus(sal_Int32 nRow) const
+{
+ if (nRow >= 0 && nRow == m_nDataPos)
+ return EditBrowseBox::CURRENT;
+ if ( nRow != BROWSER_ENDOFSELECTION && nRow < static_cast<tools::Long>(m_aGroupPositions.size()) && m_aGroupPositions[nRow] != NO_GROUP )
+ {
+ try
+ {
+ uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]);
+ return (xGroup->getHeaderOn() || xGroup->getFooterOn())? EditBrowseBox::HEADERFOOTER : EditBrowseBox::CLEAN;
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while try to get a group!");
+ }
+ }
+ return EditBrowseBox::CLEAN;
+}
+
+// XContainerListener
+
+void OFieldExpressionControl::elementInserted(const container::ContainerEvent& evt)
+{
+ if ( m_bIgnoreEvent )
+ return;
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( m_aMutex );
+ sal_Int32 nGroupPos = 0;
+ if ( !(evt.Accessor >>= nGroupPos) )
+ return;
+
+ if ( nGroupPos >= GetRowCount() )
+ {
+ sal_Int32 nAddedRows = nGroupPos - GetRowCount();
+ RowInserted(nAddedRows);
+ for (sal_Int32 i = 0; i < nAddedRows; ++i)
+ m_aGroupPositions.push_back(NO_GROUP);
+ m_aGroupPositions[nGroupPos] = nGroupPos;
+ }
+ else
+ {
+ ::std::vector<sal_Int32>::iterator aFind = m_aGroupPositions.begin()+ nGroupPos;
+ if ( aFind == m_aGroupPositions.end() )
+ aFind = ::std::find(m_aGroupPositions.begin(),m_aGroupPositions.end(),NO_GROUP);
+
+ if ( aFind != m_aGroupPositions.end() )
+ {
+ if ( *aFind != NO_GROUP )
+ aFind = m_aGroupPositions.insert(aFind,nGroupPos);
+ else
+ *aFind = nGroupPos;
+
+ ::std::vector<sal_Int32>::const_iterator aEnd = m_aGroupPositions.end();
+ for(++aFind;aFind != aEnd;++aFind)
+ if ( *aFind != NO_GROUP )
+ ++*aFind;
+ }
+ }
+ Invalidate();
+}
+
+void OFieldExpressionControl::elementRemoved(const container::ContainerEvent& evt)
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bIgnoreEvent )
+ return;
+
+ sal_Int32 nGroupPos = 0;
+ if ( !(evt.Accessor >>= nGroupPos) )
+ return;
+
+ std::vector<sal_Int32>::iterator aEnd = m_aGroupPositions.end();
+ std::vector<sal_Int32>::iterator aFind = std::find(m_aGroupPositions.begin(), aEnd, nGroupPos);
+ if (aFind != aEnd)
+ {
+ *aFind = NO_GROUP;
+ for(++aFind;aFind != aEnd;++aFind)
+ if ( *aFind != NO_GROUP )
+ --*aFind;
+ Invalidate();
+ }
+}
+
+bool OFieldExpressionControl::IsDeleteAllowed( ) const
+{
+ return !m_pParent->isReadOnly() && GetSelectRowCount() > 0;
+}
+
+void OFieldExpressionControl::KeyInput( const KeyEvent& rEvt )
+{
+ if (IsDeleteAllowed())
+ {
+ if (rEvt.GetKeyCode().GetCode() == KEY_DELETE && // Delete rows
+ !rEvt.GetKeyCode().IsShift() &&
+ !rEvt.GetKeyCode().IsMod1())
+ {
+ DeleteRows();
+ return;
+ }
+ }
+ EditBrowseBox::KeyInput(rEvt);
+}
+
+void OFieldExpressionControl::Command(const CommandEvent& rEvt)
+{
+ switch (rEvt.GetCommand())
+ {
+ case CommandEventId::ContextMenu:
+ {
+ if (!rEvt.IsMouseEvent())
+ {
+ EditBrowseBox::Command(rEvt);
+ return;
+ }
+
+ sal_uInt16 nColId = GetColumnId(GetColumnAtXPosPixel(rEvt.GetMousePosPixel().X()));
+
+ if ( nColId == HANDLE_ID )
+ {
+ bool bEnable = false;
+ tools::Long nIndex = FirstSelectedRow();
+ while( nIndex != SFX_ENDOFSELECTION && !bEnable )
+ {
+ if ( m_aGroupPositions[nIndex] != NO_GROUP )
+ bEnable = true;
+ nIndex = NextSelectedRow();
+ }
+
+ ::tools::Rectangle aRect(rEvt.GetMousePosPixel(), Size(1, 1));
+ weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect);
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "modules/dbreport/ui/groupsortmenu.ui"));
+ std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu("menu"));
+ xContextMenu->set_sensitive("delete", IsDeleteAllowed() && bEnable);
+ if (!xContextMenu->popup_at_rect(pPopupParent, aRect).isEmpty())
+ {
+ if( m_nDeleteEvent )
+ Application::RemoveUserEvent( m_nDeleteEvent );
+ m_nDeleteEvent = Application::PostUserEvent( LINK(this, OFieldExpressionControl, DelayedDelete), nullptr, true );
+ }
+ }
+ [[fallthrough]];
+ }
+ default:
+ EditBrowseBox::Command(rEvt);
+ }
+
+}
+
+void OFieldExpressionControl::DeleteRows()
+{
+
+ bool bIsEditing = IsEditing();
+ if (bIsEditing)
+ {
+ DeactivateCell();
+ }
+ tools::Long nIndex = FirstSelectedRow();
+ if (nIndex == SFX_ENDOFSELECTION)
+ {
+ nIndex = GetCurRow();
+ }
+ bool bFirstTime = true;
+
+ tools::Long nOldDataPos = nIndex;
+ m_bIgnoreEvent = true;
+ while( nIndex >= 0 )
+ {
+ if ( m_aGroupPositions[nIndex] != NO_GROUP )
+ {
+ if ( bFirstTime )
+ {
+ bFirstTime = false;
+ OUString sUndoAction(RptResId(RID_STR_UNDO_REMOVE_SELECTION));
+ m_pParent->m_pController->getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) );
+ }
+
+ sal_Int32 nGroupPos = m_aGroupPositions[nIndex];
+ uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(nGroupPos);
+ uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
+ PROPERTY_GROUP, xGroup) };
+ // we use this way to create undo actions
+ m_pParent->m_pController->executeChecked(SID_GROUP_REMOVE,aArgs);
+
+ std::vector<sal_Int32>::iterator aEnd = m_aGroupPositions.end();
+ std::vector<sal_Int32>::iterator aFind = std::find(m_aGroupPositions.begin(), aEnd, nGroupPos);
+ if (aFind != aEnd)
+ {
+ *aFind = NO_GROUP;
+ for(++aFind;aFind != aEnd;++aFind)
+ if ( *aFind != NO_GROUP )
+ --*aFind;
+ }
+ }
+ nIndex = NextSelectedRow();
+ }
+
+ if ( !bFirstTime )
+ m_pParent->m_pController->getUndoManager().LeaveListAction();
+
+ m_nDataPos = GetCurRow();
+ InvalidateStatusCell( nOldDataPos );
+ InvalidateStatusCell( m_nDataPos );
+ ActivateCell();
+ m_pParent->DisplayData( m_nDataPos );
+ m_bIgnoreEvent = false;
+ Invalidate();
+}
+
+IMPL_LINK_NOARG( OFieldExpressionControl, DelayedDelete, void*, void )
+{
+ m_nDeleteEvent = nullptr;
+ DeleteRows();
+}
+
+Size OFieldExpressionControl::GetOptimalSize() const
+{
+ return LogicToPixel(Size(106, 75), MapMode(MapUnit::MapAppFont));
+}
+
+OGroupsSortingDialog::OGroupsSortingDialog(weld::Window* pParent, bool bReadOnly,
+ OReportController* pController)
+ : GenericDialogController(pParent, "modules/dbreport/ui/floatingsort.ui", "FloatingSort")
+ , OPropertyChangeListener(m_aMutex)
+ , m_pController(pController)
+ , m_xGroups(m_pController->getReportDefinition()->getGroups())
+ , m_bReadOnly(bReadOnly)
+ , m_xToolBox(m_xBuilder->weld_toolbar("toolbox"))
+ , m_xProperties(m_xBuilder->weld_widget("properties"))
+ , m_xOrderLst(m_xBuilder->weld_combo_box("sorting"))
+ , m_xHeaderLst(m_xBuilder->weld_combo_box("header"))
+ , m_xFooterLst(m_xBuilder->weld_combo_box("footer"))
+ , m_xGroupOnLst(m_xBuilder->weld_combo_box("group"))
+ , m_xGroupIntervalEd(m_xBuilder->weld_spin_button("interval"))
+ , m_xKeepTogetherLst(m_xBuilder->weld_combo_box("keep"))
+ , m_xHelpWindow(m_xBuilder->weld_label("helptext"))
+ , m_xBox(m_xBuilder->weld_container("box"))
+ , m_xTableCtrlParent(m_xBox->CreateChildFrame())
+ , m_xFieldExpression(VclPtr<OFieldExpressionControl>::Create(this, m_xTableCtrlParent))
+{
+ m_xHelpWindow->set_size_request(-1, m_xHelpWindow->get_text_height() * 4);
+ m_xFieldExpression->set_hexpand(true);
+ m_xFieldExpression->set_vexpand(true);
+
+ weld::Widget* pControlsLst[] = { m_xHeaderLst.get(), m_xFooterLst.get(), m_xGroupOnLst.get(),
+ m_xKeepTogetherLst.get(), m_xOrderLst.get(), m_xGroupIntervalEd.get() };
+ for (weld::Widget* i : pControlsLst)
+ {
+ i->connect_focus_in(LINK(this, OGroupsSortingDialog, OnWidgetFocusGot));
+ i->show();
+ }
+
+ m_xGroupIntervalEd->connect_focus_out(LINK(this, OGroupsSortingDialog, OnWidgetFocusLost));
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(pControlsLst) - 1; ++i)
+ dynamic_cast<weld::ComboBox&>(*pControlsLst[i]).connect_changed(LINK(this,OGroupsSortingDialog,LBChangeHdl));
+
+ m_pReportListener = new OPropertyChangeMultiplexer(this, m_pController->getReportDefinition());
+ m_pReportListener->addProperty(PROPERTY_COMMAND);
+ m_pReportListener->addProperty(PROPERTY_COMMANDTYPE);
+
+ m_xFieldExpression->lateInit();
+ fillColumns();
+ Size aPrefSize = m_xFieldExpression->GetOptimalSize();
+ m_xBox->set_size_request(aPrefSize.Width(), aPrefSize.Height());
+ m_xFieldExpression->Show();
+
+ m_xToolBox->connect_clicked(LINK(this, OGroupsSortingDialog, OnFormatAction));
+
+ checkButtons(0);
+}
+
+OGroupsSortingDialog::~OGroupsSortingDialog()
+{
+ m_pReportListener->dispose();
+ if ( m_pCurrentGroupListener.is() )
+ m_pCurrentGroupListener->dispose();
+ m_xFieldExpression.disposeAndClear();
+ m_xTableCtrlParent->dispose();
+ m_xTableCtrlParent.clear();
+}
+
+void OGroupsSortingDialog::UpdateData( )
+{
+ m_xFieldExpression->Invalidate();
+ sal_Int32 nCurRow = m_xFieldExpression->GetCurRow();
+ m_xFieldExpression->DeactivateCell();
+ m_xFieldExpression->ActivateCell(nCurRow, m_xFieldExpression->GetCurColumnId());
+ DisplayData(nCurRow);
+}
+
+void OGroupsSortingDialog::DisplayData( sal_Int32 _nRow )
+{
+ const sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(_nRow);
+ const bool bEmpty = nGroupPos == NO_GROUP;
+ m_xProperties->set_sensitive(!bEmpty);
+
+ checkButtons(_nRow);
+
+ if ( m_pCurrentGroupListener.is() )
+ m_pCurrentGroupListener->dispose();
+ m_pCurrentGroupListener = nullptr;
+ if (!bEmpty)
+ {
+ uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos);
+
+ m_pCurrentGroupListener = new OPropertyChangeMultiplexer(this, xGroup);
+ m_pCurrentGroupListener->addProperty(PROPERTY_HEADERON);
+ m_pCurrentGroupListener->addProperty(PROPERTY_FOOTERON);
+
+ displayGroup(xGroup);
+ }
+}
+
+void OGroupsSortingDialog::SaveData( sal_Int32 _nRow)
+{
+ sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(_nRow);
+ if ( nGroupPos == NO_GROUP )
+ return;
+
+ uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos);
+ if (m_xHeaderLst->get_value_changed_from_saved())
+ xGroup->setHeaderOn( m_xHeaderLst->get_active() == 0 );
+ if (m_xFooterLst->get_value_changed_from_saved())
+ xGroup->setFooterOn( m_xFooterLst->get_active() == 0 );
+ if (m_xKeepTogetherLst->get_value_changed_from_saved())
+ xGroup->setKeepTogether( m_xKeepTogetherLst->get_active() );
+ if (m_xGroupOnLst->get_value_changed_from_saved())
+ {
+ auto nGroupOn = m_xGroupOnLst->get_active_id().toInt32();
+ xGroup->setGroupOn( nGroupOn );
+ }
+ if (m_xGroupIntervalEd->get_value_changed_from_saved())
+ {
+ xGroup->setGroupInterval(m_xGroupIntervalEd->get_value());
+ m_xGroupIntervalEd->save_value();
+ }
+ if ( m_xOrderLst->get_value_changed_from_saved() )
+ xGroup->setSortAscending( m_xOrderLst->get_active() == 0 );
+
+ weld::ComboBox* pControls[] = { m_xHeaderLst.get(), m_xFooterLst.get(), m_xGroupOnLst.get(),
+ m_xKeepTogetherLst.get(), m_xOrderLst.get() };
+ for (weld::ComboBox* pControl : pControls)
+ pControl->save_value();
+}
+
+sal_Int32 OGroupsSortingDialog::getColumnDataType(const OUString& _sColumnName)
+{
+ sal_Int32 nDataType = sdbc::DataType::VARCHAR;
+ try
+ {
+ if ( !m_xColumns.is() )
+ fillColumns();
+ if ( m_xColumns.is() && m_xColumns->hasByName(_sColumnName) )
+ {
+ uno::Reference< beans::XPropertySet> xColumn(m_xColumns->getByName(_sColumnName),uno::UNO_QUERY);
+ if ( xColumn.is() )
+ xColumn->getPropertyValue(PROPERTY_TYPE) >>= nDataType;
+ }
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while getting the type of a column");
+ }
+
+ return nDataType;
+}
+
+IMPL_LINK_NOARG(OGroupsSortingDialog, OnControlFocusGot, LinkParamNone*, void )
+{
+ m_xHelpWindow->set_label(RptResId(STR_RPT_HELP_FIELD));
+}
+
+IMPL_LINK(OGroupsSortingDialog, OnWidgetFocusGot, weld::Widget&, rControl, void )
+{
+ const std::pair<weld::Widget*, TranslateId> pControls[] = {
+ { m_xHeaderLst.get(), STR_RPT_HELP_HEADER },
+ { m_xFooterLst.get(), STR_RPT_HELP_FOOTER },
+ { m_xGroupOnLst.get(), STR_RPT_HELP_GROUPON },
+ { m_xGroupIntervalEd.get(), STR_RPT_HELP_INTERVAL },
+ { m_xKeepTogetherLst.get(), STR_RPT_HELP_KEEP },
+ { m_xOrderLst.get(), STR_RPT_HELP_SORT }
+ };
+ for (size_t i = 0; i < SAL_N_ELEMENTS(pControls); ++i)
+ {
+ if (&rControl == pControls[i].first)
+ {
+ weld::ComboBox* pListBox = dynamic_cast<weld::ComboBox*>( &rControl );
+ if ( pListBox )
+ pListBox->save_value();
+ weld::SpinButton* pNumericField = dynamic_cast<weld::SpinButton*>(&rControl);
+ if ( pNumericField )
+ pNumericField->save_value();
+ //shows the text given by the id in the multiline edit
+ m_xHelpWindow->set_label(RptResId(pControls[i].second));
+ break;
+ }
+ }
+}
+
+IMPL_LINK_NOARG(OGroupsSortingDialog, OnWidgetFocusLost, weld::Widget&, void)
+{
+ if (m_xFieldExpression)
+ {
+ if (m_xGroupIntervalEd->get_value_changed_from_saved())
+ SaveData(m_xFieldExpression->GetCurRow());
+ }
+}
+
+IMPL_LINK(OGroupsSortingDialog, OnFormatAction, const OString&, rCommand, void)
+{
+ if ( !m_xFieldExpression )
+ return;
+
+ tools::Long nIndex = m_xFieldExpression->GetCurrRow();
+ sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(nIndex);
+ uno::Sequence<uno::Any> aClipboardList;
+ if ( nIndex >= 0 && nGroupPos != NO_GROUP )
+ {
+ aClipboardList = { m_xGroups->getByIndex(nGroupPos) };
+ }
+ if (rCommand == "up")
+ {
+ --nIndex;
+ }
+ if (rCommand == "down")
+ {
+ ++nIndex;
+ }
+ if (rCommand == "delete")
+ {
+ Application::PostUserEvent(LINK(m_xFieldExpression, OFieldExpressionControl, DelayedDelete));
+ }
+ else
+ {
+ if ( nIndex >= 0 && aClipboardList.hasElements() )
+ {
+ m_xFieldExpression->SetNoSelection();
+ m_xFieldExpression->moveGroups(aClipboardList,nIndex,false);
+ m_xFieldExpression->DeactivateCell();
+ m_xFieldExpression->GoToRow(nIndex);
+ m_xFieldExpression->ActivateCell(nIndex, m_xFieldExpression->GetCurColumnId());
+ DisplayData(nIndex);
+ }
+ }
+}
+
+IMPL_LINK( OGroupsSortingDialog, LBChangeHdl, weld::ComboBox&, rListBox, void )
+{
+ if ( !rListBox.get_value_changed_from_saved() )
+ return;
+
+ sal_Int32 nRow = m_xFieldExpression->GetCurRow();
+ sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(nRow);
+ if (&rListBox != m_xHeaderLst.get() && &rListBox != m_xFooterLst.get())
+ {
+ if ( rListBox.get_value_changed_from_saved() )
+ SaveData(nRow);
+ if ( &rListBox == m_xGroupOnLst.get() )
+ m_xGroupIntervalEd->set_sensitive(rListBox.get_active() != 0);
+ }
+ else if ( nGroupPos != NO_GROUP )
+ {
+ uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos);
+ const OUString aHeaderFooterOnName(( m_xHeaderLst.get() == &rListBox )
+ ? std::u16string_view(PROPERTY_HEADERON)
+ : std::u16string_view(PROPERTY_FOOTERON));
+ uno::Sequence< beans::PropertyValue > aArgs{
+ comphelper::makePropertyValue(aHeaderFooterOnName, rListBox.get_active() == 0),
+ comphelper::makePropertyValue(PROPERTY_GROUP, xGroup)
+ };
+ m_pController->executeChecked(m_xHeaderLst.get() == &rListBox ? SID_GROUPHEADER : SID_GROUPFOOTER, aArgs);
+ m_xFieldExpression->InvalidateHandleColumn();
+ }
+}
+
+void OGroupsSortingDialog::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
+{
+ uno::Reference< report::XGroup > xGroup(_rEvent.Source,uno::UNO_QUERY);
+ if ( xGroup.is() )
+ displayGroup(xGroup);
+ else
+ fillColumns();
+}
+
+void OGroupsSortingDialog::fillColumns()
+{
+ m_xColumns = m_pController->getColumns();
+ m_xFieldExpression->fillColumns(m_xColumns);
+}
+
+void OGroupsSortingDialog::displayGroup(const uno::Reference<report::XGroup>& _xGroup)
+{
+ m_xHeaderLst->set_active(_xGroup->getHeaderOn() ? 0 : 1 );
+ m_xFooterLst->set_active(_xGroup->getFooterOn() ? 0 : 1 );
+ sal_Int32 nDataType = getColumnDataType(_xGroup->getExpression());
+
+ // first clear whole group on list
+ while (m_xGroupOnLst->get_count() > 1 )
+ {
+ m_xGroupOnLst->remove(1);
+ }
+
+ switch(nDataType)
+ {
+ case sdbc::DataType::LONGVARCHAR:
+ case sdbc::DataType::VARCHAR:
+ case sdbc::DataType::CHAR:
+ m_xGroupOnLst->append(OUString::number(report::GroupOn::PREFIX_CHARACTERS), RptResId(STR_RPT_PREFIXCHARS));
+ break;
+ case sdbc::DataType::DATE:
+ case sdbc::DataType::TIME:
+ case sdbc::DataType::TIMESTAMP:
+ {
+ const TranslateId aIds[] = { STR_RPT_YEAR, STR_RPT_QUARTER,STR_RPT_MONTH,STR_RPT_WEEK,STR_RPT_DAY,STR_RPT_HOUR,STR_RPT_MINUTE };
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
+ {
+ m_xGroupOnLst->append(OUString::number(i+2), RptResId(aIds[i]));
+ }
+ }
+ break;
+ default:
+ m_xGroupOnLst->append(OUString::number(report::GroupOn::INTERVAL), RptResId(STR_RPT_INTERVAL));
+ break;
+ }
+ sal_Int32 nPos = 0;
+ switch(_xGroup->getGroupOn())
+ {
+ case report::GroupOn::DEFAULT:
+ nPos = 0;
+ break;
+ case report::GroupOn::PREFIX_CHARACTERS:
+ nPos = 1;
+ break;
+ case report::GroupOn::YEAR:
+ nPos = 1;
+ break;
+ case report::GroupOn::QUARTAL:
+ nPos = 2;
+ break;
+ case report::GroupOn::MONTH:
+ nPos = 3;
+ break;
+ case report::GroupOn::WEEK:
+ nPos = 4;
+ break;
+ case report::GroupOn::DAY:
+ nPos = 5;
+ break;
+ case report::GroupOn::HOUR:
+ nPos = 6;
+ break;
+ case report::GroupOn::MINUTE:
+ nPos = 7;
+ break;
+ case report::GroupOn::INTERVAL:
+ nPos = 1;
+ break;
+ default:
+ nPos = 0;
+ }
+ m_xGroupOnLst->set_active(nPos);
+ m_xGroupIntervalEd->set_value(_xGroup->getGroupInterval());
+ m_xGroupIntervalEd->save_value();
+ m_xGroupIntervalEd->set_sensitive( nPos != 0 );
+ m_xKeepTogetherLst->set_active(_xGroup->getKeepTogether());
+ m_xOrderLst->set_active(_xGroup->getSortAscending() ? 0 : 1);
+
+ weld::ComboBox* pControls[] = { m_xHeaderLst.get(), m_xFooterLst.get(), m_xGroupOnLst.get(),
+ m_xKeepTogetherLst.get(), m_xOrderLst.get() };
+ for (weld::ComboBox* pControl : pControls)
+ pControl->save_value();
+
+ bool bReadOnly = !m_pController->isEditable();
+ for (weld::ComboBox* pControl : pControls)
+ pControl->set_sensitive(!bReadOnly);
+ m_xGroupIntervalEd->set_editable(!bReadOnly);
+}
+
+void OGroupsSortingDialog::checkButtons(sal_Int32 _nRow)
+{
+ sal_Int32 nGroupCount = m_xGroups->getCount();
+ sal_Int32 nRowCount = m_xFieldExpression->GetRowCount();
+ bool bEnabled = nGroupCount > 1;
+
+ if (bEnabled && _nRow > 0 )
+ {
+ m_xToolBox->set_item_sensitive("up", true);
+ }
+ else
+ {
+ m_xToolBox->set_item_sensitive("up", false);
+ }
+ if (bEnabled && _nRow < (nRowCount - 1) )
+ {
+ m_xToolBox->set_item_sensitive("down", true);
+ }
+ else
+ {
+ m_xToolBox->set_item_sensitive("down", false);
+ }
+
+ sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(_nRow);
+ if ( nGroupPos != NO_GROUP )
+ {
+ bool bEnableDelete = nGroupCount > 0;
+ m_xToolBox->set_item_sensitive("delete", bEnableDelete);
+ }
+ else
+ {
+ m_xToolBox->set_item_sensitive("delete", false);
+ }
+}
+
+} // rptui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/Navigator.cxx b/reportdesign/source/ui/dlg/Navigator.cxx
new file mode 100644
index 000000000..e05c2a54b
--- /dev/null
+++ b/reportdesign/source/ui/dlg/Navigator.cxx
@@ -0,0 +1,836 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <Navigator.hxx>
+
+#include <strings.hxx>
+#include <bitmaps.hlst>
+#include <ReportController.hxx>
+#include <UITools.hxx>
+#include <reportformula.hxx>
+#include <com/sun/star/report/XReportDefinition.hpp>
+#include <com/sun/star/report/XFixedText.hpp>
+#include <com/sun/star/report/XFixedLine.hpp>
+#include <com/sun/star/report/XFormattedField.hpp>
+#include <com/sun/star/report/XImageControl.hpp>
+#include <com/sun/star/report/XShape.hpp>
+#include <helpids.h>
+#include <strings.hrc>
+#include <rptui_slotid.hrc>
+#include <comphelper/propmultiplex.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/containermultiplexer.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <comphelper/SelectionMultiplex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/commandevent.hxx>
+#include <ReportVisitor.hxx>
+#include <core_resource.hxx>
+#include <rtl/ref.hxx>
+#include <svx/svxids.hrc>
+
+#include <memory>
+#include <string_view>
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace utl;
+using namespace ::comphelper;
+
+static OUString lcl_getImageId(const uno::Reference< report::XReportComponent>& _xElement)
+{
+ OUString sId;
+ uno::Reference< report::XFixedLine> xFixedLine(_xElement,uno::UNO_QUERY);
+ if ( uno::Reference< report::XFixedText>(_xElement,uno::UNO_QUERY).is() )
+ sId = RID_SVXBMP_FM_FIXEDTEXT;
+ else if ( xFixedLine.is() )
+ sId = xFixedLine->getOrientation() ? OUString(RID_SVXBMP_INSERT_VFIXEDLINE) : OUString(RID_SVXBMP_INSERT_HFIXEDLINE);
+ else if ( uno::Reference< report::XFormattedField>(_xElement,uno::UNO_QUERY).is() )
+ sId = RID_SVXBMP_FM_EDIT;
+ else if ( uno::Reference< report::XImageControl>(_xElement,uno::UNO_QUERY).is() )
+ sId = RID_SVXBMP_FM_IMAGECONTROL;
+ else if ( uno::Reference< report::XShape>(_xElement,uno::UNO_QUERY).is() )
+ sId = RID_SVXBMP_DRAWTBX_CS_BASIC;
+ return sId;
+}
+
+static OUString lcl_getName(const uno::Reference< beans::XPropertySet>& _xElement)
+{
+ OSL_ENSURE(_xElement.is(),"Found report element which is NULL!");
+ OUString sTempName;
+ _xElement->getPropertyValue(PROPERTY_NAME) >>= sTempName;
+ OUStringBuffer sName(sTempName);
+ uno::Reference< report::XFixedText> xFixedText(_xElement,uno::UNO_QUERY);
+ uno::Reference< report::XReportControlModel> xReportModel(_xElement,uno::UNO_QUERY);
+ if ( xFixedText.is() )
+ {
+ sName.append(" : ");
+ sName.append(xFixedText->getLabel());
+ }
+ else if ( xReportModel.is() && _xElement->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) )
+ {
+ ReportFormula aFormula( xReportModel->getDataField() );
+ if ( aFormula.isValid() )
+ {
+ sName.append(" : ");
+ sName.append( aFormula.getUndecoratedContent() );
+ }
+ }
+ return sName.makeStringAndClear();
+}
+
+namespace {
+
+class NavigatorTree : public ::cppu::BaseMutex
+ , public reportdesign::ITraverseReport
+ , public comphelper::OSelectionChangeListener
+ , public ::comphelper::OPropertyChangeListener
+{
+ class UserData;
+ friend class UserData;
+ class UserData : public ::cppu::BaseMutex
+ ,public ::comphelper::OPropertyChangeListener
+ ,public ::comphelper::OContainerListener
+ {
+ uno::Reference< uno::XInterface > m_xContent;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pListener;
+ ::rtl::Reference< comphelper::OContainerListenerAdapter> m_pContainerListener;
+ NavigatorTree* m_pTree;
+ public:
+ UserData(NavigatorTree* pTree, const uno::Reference<uno::XInterface>& xContent);
+ virtual ~UserData() override;
+
+ const uno::Reference< uno::XInterface >& getContent() const { return m_xContent; }
+ void setContent(const uno::Reference< uno::XInterface >& _xContent) { m_xContent = _xContent; }
+
+ protected:
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) override;
+
+ // OContainerListener
+ virtual void _elementInserted( const container::ContainerEvent& _rEvent ) override;
+ virtual void _elementRemoved( const container::ContainerEvent& Event ) override;
+ virtual void _elementReplaced( const container::ContainerEvent& _rEvent ) override;
+ virtual void _disposing(const lang::EventObject& _rSource) override;
+ };
+
+ std::unique_ptr<weld::TreeView> m_xTreeView;
+ OReportController& m_rController;
+ std::unique_ptr<weld::TreeIter> m_xMasterReport;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener;
+ ::rtl::Reference< comphelper::OSelectionChangeMultiplexer> m_pSelectionListener;
+
+ void insertEntry(const OUString& rName, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition, const UserData* pData, weld::TreeIter& rRet);
+
+ void traverseSection(const uno::Reference<report::XSection>& xSection, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition = -1);
+ void traverseFunctions(const uno::Reference< report::XFunctions>& xFunctions, const weld::TreeIter* pParent);
+
+protected:
+ // OSelectionChangeListener
+ virtual void _disposing(const lang::EventObject& _rSource) override;
+
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) override;
+
+ // OContainerListener Helper
+ void _elementInserted( const container::ContainerEvent& _rEvent );
+ void _elementRemoved( const container::ContainerEvent& Event );
+ void _elementReplaced( const container::ContainerEvent& _rEvent );
+
+public:
+ NavigatorTree(std::unique_ptr<weld::TreeView>, OReportController& rController);
+ virtual ~NavigatorTree() override;
+
+ DECL_LINK(OnEntrySelDesel, weld::TreeView&, void);
+ DECL_LINK(CommandHdl, const CommandEvent&, bool);
+
+ virtual void _selectionChanged( const lang::EventObject& aEvent ) override;
+
+ // ITraverseReport
+ virtual void traverseReport(const uno::Reference< report::XReportDefinition>& xReport) override;
+ virtual void traverseReportFunctions(const uno::Reference< report::XFunctions>& xFunctions) override;
+ virtual void traverseReportHeader(const uno::Reference< report::XSection>& xSection) override;
+ virtual void traverseReportFooter(const uno::Reference< report::XSection>& xSection) override;
+ virtual void traversePageHeader(const uno::Reference< report::XSection>& xSection) override;
+ virtual void traversePageFooter(const uno::Reference< report::XSection>& xSection) override;
+
+ virtual void traverseGroups(const uno::Reference< report::XGroups>& xGroups) override;
+ virtual void traverseGroup(const uno::Reference< report::XGroup>& xGroup) override;
+ virtual void traverseGroupFunctions(const uno::Reference< report::XFunctions>& xFunctions) override;
+ virtual void traverseGroupHeader(const uno::Reference< report::XSection>& xSection) override;
+ virtual void traverseGroupFooter(const uno::Reference< report::XSection>& xSection) override;
+
+ virtual void traverseDetail(const uno::Reference< report::XSection>& xSection) override;
+
+ bool find(const uno::Reference<uno::XInterface>& xContent, weld::TreeIter& rIter);
+ void removeEntry(const weld::TreeIter& rEntry, bool bRemove = true);
+
+ void grab_focus() { m_xTreeView->grab_focus(); }
+
+ void set_text(const weld::TreeIter& rIter, const OUString& rStr)
+ {
+ m_xTreeView->set_text(rIter, rStr);
+ }
+
+ void expand_row(const weld::TreeIter& rIter)
+ {
+ m_xTreeView->expand_row(rIter);
+ }
+
+ std::unique_ptr<weld::TreeIter> make_iterator() const
+ {
+ return m_xTreeView->make_iterator();
+ }
+
+ int iter_n_children(const weld::TreeIter& rIter) const
+ {
+ return m_xTreeView->iter_n_children(rIter);
+ }
+};
+
+}
+
+NavigatorTree::NavigatorTree(std::unique_ptr<weld::TreeView> xTreeView, OReportController& rController)
+ : OPropertyChangeListener(m_aMutex)
+ , m_xTreeView(std::move(xTreeView))
+ , m_rController(rController)
+{
+ m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 25, m_xTreeView->get_height_rows(18));
+
+ m_pReportListener = new OPropertyChangeMultiplexer(this,m_rController.getReportDefinition());
+ m_pReportListener->addProperty(PROPERTY_PAGEHEADERON);
+ m_pReportListener->addProperty(PROPERTY_PAGEFOOTERON);
+ m_pReportListener->addProperty(PROPERTY_REPORTHEADERON);
+ m_pReportListener->addProperty(PROPERTY_REPORTFOOTERON);
+
+ m_pSelectionListener = new OSelectionChangeMultiplexer(this,&m_rController);
+
+ m_xTreeView->set_help_id(HID_REPORT_NAVIGATOR_TREE);
+
+ m_xTreeView->set_selection_mode(SelectionMode::Multiple);
+
+ m_xTreeView->connect_changed(LINK(this, NavigatorTree, OnEntrySelDesel));
+ m_xTreeView->connect_popup_menu(LINK(this, NavigatorTree, CommandHdl));
+}
+
+NavigatorTree::~NavigatorTree()
+{
+ m_xTreeView->all_foreach([this](weld::TreeIter& rIter) {
+ UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(rIter));
+ delete pData;
+ return false;
+ });
+ m_pSelectionListener->dispose();
+ m_pReportListener->dispose();
+}
+
+namespace
+{
+ sal_uInt16 mapIdent(std::string_view rIdent)
+ {
+ if (rIdent == "sorting")
+ return SID_SORTINGANDGROUPING;
+ else if (rIdent == "page")
+ return SID_PAGEHEADERFOOTER;
+ else if (rIdent == "report")
+ return SID_REPORTHEADERFOOTER;
+ else if (rIdent == "function")
+ return SID_RPT_NEW_FUNCTION;
+ else if (rIdent == "properties")
+ return SID_SHOW_PROPERTYBROWSER;
+ else if (rIdent == "delete")
+ return SID_DELETE;
+ return 0;
+ }
+}
+
+IMPL_LINK(NavigatorTree, CommandHdl, const CommandEvent&, rEvt, bool)
+{
+ bool bHandled = false;
+ switch( rEvt.GetCommand())
+ {
+ case CommandEventId::ContextMenu:
+ {
+ UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_selected_id());
+ if (!pData)
+ break;
+
+ uno::Reference< report::XFunctionsSupplier> xSupplier(pData->getContent(),uno::UNO_QUERY);
+ uno::Reference< report::XFunctions> xFunctions(pData->getContent(),uno::UNO_QUERY);
+ uno::Reference< report::XGroup> xGroup(pData->getContent(),uno::UNO_QUERY);
+ bool bDeleteAllowed = m_rController.isEditable() && (xGroup.is() ||
+ uno::Reference< report::XFunction>(pData->getContent(),uno::UNO_QUERY).is());
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), "modules/dbreport/ui/navigatormenu.ui"));
+ std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu("menu"));
+
+ const OString aIds[] = { "sorting", "page", "report", "function", "properties", "delete" };
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
+ {
+ sal_uInt16 nSId = mapIdent(aIds[i]);
+
+ if (aIds[i] == "page" || aIds[i] == "report" || aIds[i] == "properties")
+ xContextMenu->set_active(aIds[i], m_rController.isCommandChecked(nSId));
+ bool bEnabled = m_rController.isCommandEnabled(nSId);
+ if (nSId == SID_RPT_NEW_FUNCTION)
+ xContextMenu->set_sensitive(aIds[i], m_rController.isEditable() && (xSupplier.is() || xFunctions.is()));
+ // special condition, check for function and group
+ else if (nSId == SID_DELETE)
+ xContextMenu->set_sensitive(aIds[i], bDeleteAllowed);
+ else
+ xContextMenu->set_sensitive(aIds[i], bEnabled);
+ }
+
+ // the point that was clicked on
+ ::Point aWhere(rEvt.GetMousePosPixel());
+ OString sCurItemIdent = xContextMenu->popup_at_rect(m_xTreeView.get(), tools::Rectangle(aWhere, Size(1,1)));
+ if (!sCurItemIdent.isEmpty())
+ {
+ sal_uInt16 nId = mapIdent(sCurItemIdent);
+ uno::Sequence< beans::PropertyValue> aArgs;
+ if ( nId == SID_RPT_NEW_FUNCTION )
+ {
+ aArgs.realloc(1);
+ aArgs.getArray()[0].Value <<= (xFunctions.is() ? xFunctions : xSupplier->getFunctions());
+ }
+ else if ( nId == SID_DELETE )
+ {
+ if ( xGroup.is() )
+ nId = SID_GROUP_REMOVE;
+ aArgs = { comphelper::makePropertyValue(PROPERTY_GROUP, pData->getContent()) };
+ }
+ m_rController.executeUnChecked(nId,aArgs);
+ }
+
+ bHandled = true;
+ }
+ break;
+ default: break;
+ }
+
+ return bHandled;
+}
+
+IMPL_LINK_NOARG(NavigatorTree, OnEntrySelDesel, weld::TreeView&, void)
+{
+ if ( !m_pSelectionListener->locked() )
+ {
+ m_pSelectionListener->lock();
+ std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
+ bool bEntry = m_xTreeView->get_cursor(xEntry.get());
+ uno::Any aSelection;
+ if (bEntry && m_xTreeView->is_selected(*xEntry))
+ aSelection <<= weld::fromId<UserData*>(m_xTreeView->get_id(*xEntry))->getContent();
+ m_rController.select(aSelection);
+ m_pSelectionListener->unlock();
+ }
+}
+
+void NavigatorTree::_selectionChanged( const lang::EventObject& aEvent )
+{
+ m_pSelectionListener->lock();
+ uno::Reference< view::XSelectionSupplier> xSelectionSupplier(aEvent.Source,uno::UNO_QUERY);
+ uno::Any aSec = xSelectionSupplier->getSelection();
+ uno::Sequence< uno::Reference< report::XReportComponent > > aSelection;
+ aSec >>= aSelection;
+ std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
+ if ( !aSelection.hasElements() )
+ {
+ uno::Reference< uno::XInterface> xSelection(aSec,uno::UNO_QUERY);
+ bool bEntry = find(xSelection, *xEntry);
+ if (bEntry && !m_xTreeView->is_selected(*xEntry))
+ {
+ m_xTreeView->select(*xEntry);
+ m_xTreeView->set_cursor(*xEntry);
+ }
+ else if (!bEntry)
+ m_xTreeView->unselect_all();
+ }
+ else
+ {
+ for (const uno::Reference<report::XReportComponent>& rElem : std::as_const(aSelection))
+ {
+ bool bEntry = find(rElem, *xEntry);
+ if (bEntry && !m_xTreeView->is_selected(*xEntry))
+ {
+ m_xTreeView->select(*xEntry);
+ m_xTreeView->set_cursor(*xEntry);
+ }
+ }
+ }
+ m_pSelectionListener->unlock();
+}
+
+void NavigatorTree::insertEntry(const OUString& rName, const weld::TreeIter* pParent, const OUString& rImageId,
+ int nPosition, const UserData* pData, weld::TreeIter& rRet)
+{
+ OUString sId = pData ? weld::toId(pData) : OUString();
+ m_xTreeView->insert(pParent, nPosition, &rName, &sId, nullptr, nullptr, false, &rRet);
+ if (!rImageId.isEmpty())
+ m_xTreeView->set_image(rRet, rImageId);
+}
+
+void NavigatorTree::traverseSection(const uno::Reference<report::XSection>& xSection, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition)
+{
+ std::unique_ptr<weld::TreeIter> xSectionIter = m_xTreeView->make_iterator();
+ std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
+ insertEntry(xSection->getName(), pParent, rImageId, nPosition, new UserData(this, xSection), *xSectionIter);
+ const sal_Int32 nCount = xSection->getCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference< report::XReportComponent> xElement(xSection->getByIndex(i), uno::UNO_QUERY_THROW);
+ insertEntry(lcl_getName(xElement), xSectionIter.get(), lcl_getImageId(xElement), -1, new UserData(this, xElement), *xScratch);
+ uno::Reference< report::XReportDefinition> xSubReport(xElement,uno::UNO_QUERY);
+ if ( xSubReport.is() )
+ {
+ bool bMasterReport = find(xSection->getReportDefinition(), *xScratch);
+ if (!bMasterReport)
+ m_xMasterReport.reset();
+ else
+ m_xMasterReport = m_xTreeView->make_iterator(xScratch.get());
+ reportdesign::OReportVisitor aSubVisitor(this);
+ aSubVisitor.start(xSubReport);
+ }
+ }
+}
+
+void NavigatorTree::traverseFunctions(const uno::Reference< report::XFunctions>& xFunctions, const weld::TreeIter* pParent)
+{
+ std::unique_ptr<weld::TreeIter> xFunctionIter = m_xTreeView->make_iterator();
+ std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
+ insertEntry(RptResId(RID_STR_FUNCTIONS), pParent, RID_SVXBMP_RPT_NEW_FUNCTION, -1, new UserData(this, xFunctions), *xFunctionIter);
+ const sal_Int32 nCount = xFunctions->getCount();
+ for (sal_Int32 i = 0; i< nCount; ++i)
+ {
+ uno::Reference< report::XFunction> xElement(xFunctions->getByIndex(i),uno::UNO_QUERY);
+ insertEntry(xElement->getName(), xFunctionIter.get(), RID_SVXBMP_RPT_NEW_FUNCTION, -1, new UserData(this,xElement), *xScratch);
+ }
+}
+
+bool NavigatorTree::find(const uno::Reference<uno::XInterface>& xContent, weld::TreeIter& rRet)
+{
+ bool bRet = false;
+ if (xContent.is())
+ {
+ m_xTreeView->all_foreach([this, &xContent, &bRet, &rRet](weld::TreeIter& rIter) {
+ UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(rIter));
+ if (pData->getContent() == xContent)
+ {
+ m_xTreeView->copy_iterator(rIter, rRet);
+ bRet = true;
+ return true;
+ }
+ return false;
+ });
+ }
+ return bRet;
+}
+
+// ITraverseReport
+
+void NavigatorTree::traverseReport(const uno::Reference< report::XReportDefinition>& xReport)
+{
+ std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
+ insertEntry(xReport->getName(), m_xMasterReport.get(), RID_SVXBMP_SELECT_REPORT,-1, new UserData(this, xReport), *xScratch);
+}
+
+void NavigatorTree::traverseReportFunctions(const uno::Reference< report::XFunctions>& xFunctions)
+{
+ std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
+ bool bReport = find(xFunctions->getParent(), *xReport);
+ if (!bReport)
+ xReport.reset();
+ traverseFunctions(xFunctions, xReport.get());
+}
+
+void NavigatorTree::traverseReportHeader(const uno::Reference< report::XSection>& xSection)
+{
+ std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
+ bool bReport = find(xSection->getReportDefinition(), *xReport);
+ if (!bReport)
+ xReport.reset();
+ traverseSection(xSection, xReport.get(), RID_SVXBMP_REPORTHEADERFOOTER);
+}
+
+void NavigatorTree::traverseReportFooter(const uno::Reference< report::XSection>& xSection)
+{
+ std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
+ bool bReport = find(xSection->getReportDefinition(), *xReport);
+ if (!bReport)
+ xReport.reset();
+ traverseSection(xSection, xReport.get(), RID_SVXBMP_REPORTHEADERFOOTER);
+}
+
+void NavigatorTree::traversePageHeader(const uno::Reference< report::XSection>& xSection)
+{
+ std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
+ bool bReport = find(xSection->getReportDefinition(), *xReport);
+ if (!bReport)
+ xReport.reset();
+ traverseSection(xSection, xReport.get(), RID_SVXBMP_PAGEHEADERFOOTER);
+}
+
+void NavigatorTree::traversePageFooter(const uno::Reference< report::XSection>& xSection)
+{
+ std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
+ bool bReport = find(xSection->getReportDefinition(), *xReport);
+ if (!bReport)
+ xReport.reset();
+ traverseSection(xSection, xReport.get(), RID_SVXBMP_PAGEHEADERFOOTER);
+}
+
+void NavigatorTree::traverseGroups(const uno::Reference< report::XGroups>& xGroups)
+{
+ std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
+ bool bReport = find(xGroups->getReportDefinition(), *xReport);
+ if (!bReport)
+ xReport.reset();
+ std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
+ insertEntry(RptResId(RID_STR_GROUPS), xReport.get(), RID_SVXBMP_SORTINGANDGROUPING, -1, new UserData(this, xGroups), *xScratch);
+}
+
+void NavigatorTree::traverseGroup(const uno::Reference< report::XGroup>& xGroup)
+{
+ uno::Reference< report::XGroups> xGroups(xGroup->getParent(),uno::UNO_QUERY);
+ std::unique_ptr<weld::TreeIter> xGroupsIter = m_xTreeView->make_iterator();
+ bool bGroups = find(xGroups, *xGroupsIter);
+ OSL_ENSURE(bGroups, "No Groups inserted so far. Why!");
+ if (!bGroups)
+ xGroupsIter.reset();
+ std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
+ insertEntry(xGroup->getExpression(), xGroupsIter.get(), RID_SVXBMP_GROUP, rptui::getPositionInIndexAccess(xGroups,xGroup), new UserData(this,xGroup), *xScratch);
+}
+
+void NavigatorTree::traverseGroupFunctions(const uno::Reference< report::XFunctions>& xFunctions)
+{
+ std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
+ bool bReport = find(xFunctions->getParent(), *xReport);
+ if (!bReport)
+ xReport.reset();
+ traverseFunctions(xFunctions, xReport.get());
+}
+
+void NavigatorTree::traverseGroupHeader(const uno::Reference< report::XSection>& xSection)
+{
+ std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
+ bool bReport = find(xSection->getGroup(), *xReport);
+ OSL_ENSURE(bReport, "No group found");
+ if (!bReport)
+ xReport.reset();
+ traverseSection(xSection, xReport.get(), RID_SVXBMP_GROUPHEADER, 1);
+}
+
+void NavigatorTree::traverseGroupFooter(const uno::Reference< report::XSection>& xSection)
+{
+ std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
+ bool bReport = find(xSection->getGroup(), *xReport);
+ OSL_ENSURE(bReport, "No group found");
+ if (!bReport)
+ xReport.reset();
+ traverseSection(xSection, xReport.get(), RID_SVXBMP_GROUPFOOTER);
+}
+
+void NavigatorTree::traverseDetail(const uno::Reference< report::XSection>& xSection)
+{
+ uno::Reference< report::XReportDefinition> xReport = xSection->getReportDefinition();
+ std::unique_ptr<weld::TreeIter> xParent = m_xTreeView->make_iterator();
+ bool bParent = find(xReport, *xParent);
+ if (!bParent)
+ xParent.reset();
+ traverseSection(xSection, xParent.get(), RID_SVXBMP_ICON_DETAIL);
+}
+
+void NavigatorTree::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
+{
+ uno::Reference< report::XReportDefinition> xReport(_rEvent.Source,uno::UNO_QUERY);
+ if ( !xReport.is() )
+ return;
+
+ bool bEnabled = false;
+ _rEvent.NewValue >>= bEnabled;
+ if ( !bEnabled )
+ return;
+
+ std::unique_ptr<weld::TreeIter> xParent = m_xTreeView->make_iterator();
+ bool bParent = find(xReport, *xParent);
+ if (!bParent)
+ xParent.reset();
+ if ( _rEvent.PropertyName == PROPERTY_REPORTHEADERON )
+ {
+ sal_uLong nPos = xReport->getReportHeaderOn() ? 2 : 1;
+ traverseSection(xReport->getReportHeader(),xParent.get(),RID_SVXBMP_REPORTHEADERFOOTER,nPos);
+ }
+ else if ( _rEvent.PropertyName == PROPERTY_PAGEHEADERON )
+ {
+ traverseSection(xReport->getPageHeader(),xParent.get(), RID_SVXBMP_PAGEHEADERFOOTER,1);
+ }
+ else if ( _rEvent.PropertyName == PROPERTY_PAGEFOOTERON )
+ traverseSection(xReport->getPageFooter(),xParent.get(), RID_SVXBMP_PAGEHEADERFOOTER);
+ else if ( _rEvent.PropertyName == PROPERTY_REPORTFOOTERON )
+ {
+ int nPos = -1;
+ if (xReport->getPageFooterOn() && xParent)
+ nPos = m_xTreeView->iter_n_children(*xParent) - 1;
+ traverseSection(xReport->getReportFooter(),xParent.get(),RID_SVXBMP_REPORTHEADERFOOTER,nPos);
+ }
+}
+
+void NavigatorTree::_elementInserted( const container::ContainerEvent& _rEvent )
+{
+ std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
+ bool bEntry = find(_rEvent.Source, *xEntry);
+ if (!bEntry)
+ xEntry.reset();
+ uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY_THROW);
+ OUString sName;
+ uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
+ if ( xInfo.is() )
+ {
+ if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
+ xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
+ else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
+ xProp->getPropertyValue(PROPERTY_EXPRESSION) >>= sName;
+ }
+ uno::Reference< report::XGroup> xGroup(xProp,uno::UNO_QUERY);
+ if ( xGroup.is() )
+ {
+ reportdesign::OReportVisitor aSubVisitor(this);
+ aSubVisitor.start(xGroup);
+ }
+ else
+ {
+ uno::Reference< report::XReportComponent> xElement(xProp,uno::UNO_QUERY);
+ if ( xProp.is() )
+ sName = lcl_getName(xProp);
+ std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
+ insertEntry(sName, xEntry.get(), (!xElement.is() ? OUString(RID_SVXBMP_RPT_NEW_FUNCTION) : lcl_getImageId(xElement)),
+ -1, new UserData(this,xProp), *xScratch);
+ }
+ if (bEntry && !m_xTreeView->get_row_expanded(*xEntry))
+ m_xTreeView->expand_row(*xEntry);
+}
+
+void NavigatorTree::_elementRemoved( const container::ContainerEvent& _rEvent )
+{
+ uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY);
+ std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
+ bool bEntry = find(xProp, *xEntry);
+ OSL_ENSURE(bEntry,"NavigatorTree::_elementRemoved: No Entry found!");
+
+ if (bEntry)
+ {
+ removeEntry(*xEntry);
+ }
+}
+
+void NavigatorTree::_elementReplaced( const container::ContainerEvent& _rEvent )
+{
+ uno::Reference<beans::XPropertySet> xProp(_rEvent.ReplacedElement,uno::UNO_QUERY);
+ std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
+ bool bEntry = find(xProp, *xEntry);
+ if (bEntry)
+ {
+ UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(*xEntry));
+ xProp.set(_rEvent.Element,uno::UNO_QUERY);
+ pData->setContent(xProp);
+ OUString sName;
+ xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
+ m_xTreeView->set_text(*xEntry, sName);
+ }
+}
+
+void NavigatorTree::_disposing(const lang::EventObject& _rSource)
+{
+ std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
+ if (find(_rSource.Source, *xEntry))
+ removeEntry(*xEntry);
+}
+
+void NavigatorTree::removeEntry(const weld::TreeIter& rEntry, bool bRemove)
+{
+ std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator(&rEntry);
+ bool bChild = m_xTreeView->iter_children(*xChild);
+ while (bChild)
+ {
+ removeEntry(*xChild, false);
+ bChild = m_xTreeView->iter_next_sibling(*xChild);
+ }
+ delete weld::fromId<UserData*>(m_xTreeView->get_id(rEntry));
+ if (bRemove)
+ m_xTreeView->remove(rEntry);
+}
+
+NavigatorTree::UserData::UserData(NavigatorTree* pTree,const uno::Reference<uno::XInterface>& xContent)
+ : OPropertyChangeListener(m_aMutex)
+ , OContainerListener(m_aMutex)
+ , m_xContent(xContent)
+ , m_pTree(pTree)
+{
+ uno::Reference<beans::XPropertySet> xProp(m_xContent,uno::UNO_QUERY);
+ if ( xProp.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
+ if ( xInfo.is() )
+ {
+ m_pListener = new ::comphelper::OPropertyChangeMultiplexer(this,xProp);
+ if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
+ m_pListener->addProperty(PROPERTY_NAME);
+ else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
+ m_pListener->addProperty(PROPERTY_EXPRESSION);
+ if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) )
+ m_pListener->addProperty(PROPERTY_DATAFIELD);
+ if ( xInfo->hasPropertyByName(PROPERTY_LABEL) )
+ m_pListener->addProperty(PROPERTY_LABEL);
+ if ( xInfo->hasPropertyByName(PROPERTY_HEADERON) )
+ m_pListener->addProperty(PROPERTY_HEADERON);
+ if ( xInfo->hasPropertyByName(PROPERTY_FOOTERON) )
+ m_pListener->addProperty(PROPERTY_FOOTERON);
+ }
+ }
+ uno::Reference< container::XContainer> xContainer(m_xContent,uno::UNO_QUERY);
+ if ( xContainer.is() )
+ {
+ m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
+ }
+}
+
+NavigatorTree::UserData::~UserData()
+{
+ if ( m_pContainerListener.is() )
+ m_pContainerListener->dispose();
+ if ( m_pListener.is() )
+ m_pListener->dispose();
+}
+
+// OPropertyChangeListener
+void NavigatorTree::UserData::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
+{
+ std::unique_ptr<weld::TreeIter> xEntry = m_pTree->make_iterator();
+ bool bEntry = m_pTree->find(_rEvent.Source, *xEntry);
+ OSL_ENSURE(bEntry,"No entry could be found! Why not!");
+ if (!bEntry)
+ return;
+ const bool bFooterOn = (PROPERTY_FOOTERON == _rEvent.PropertyName);
+ try
+ {
+ if ( bFooterOn || PROPERTY_HEADERON == _rEvent.PropertyName )
+ {
+ sal_Int32 nPos = 1;
+ uno::Reference< report::XGroup> xGroup(_rEvent.Source,uno::UNO_QUERY);
+ ::std::function<bool(OGroupHelper *)> pIsOn = ::std::mem_fn(&OGroupHelper::getHeaderOn);
+ ::std::function<uno::Reference<report::XSection>(OGroupHelper *)> pMemFunSection = ::std::mem_fn(&OGroupHelper::getHeader);
+ if ( bFooterOn )
+ {
+ pIsOn = ::std::mem_fn(&OGroupHelper::getFooterOn);
+ pMemFunSection = ::std::mem_fn(&OGroupHelper::getFooter);
+ nPos = m_pTree->iter_n_children(*xEntry) - 1;
+ }
+
+ OGroupHelper aGroupHelper(xGroup);
+ if ( pIsOn(&aGroupHelper) )
+ {
+ if ( bFooterOn )
+ ++nPos;
+ m_pTree->traverseSection(pMemFunSection(&aGroupHelper),xEntry.get(),bFooterOn ? OUString(RID_SVXBMP_GROUPFOOTER) : OUString(RID_SVXBMP_GROUPHEADER),nPos);
+ }
+ }
+ else if ( PROPERTY_EXPRESSION == _rEvent.PropertyName)
+ {
+ OUString sNewName;
+ _rEvent.NewValue >>= sNewName;
+ m_pTree->set_text(*xEntry, sNewName);
+ }
+ else if ( PROPERTY_DATAFIELD == _rEvent.PropertyName || PROPERTY_LABEL == _rEvent.PropertyName || PROPERTY_NAME == _rEvent.PropertyName )
+ {
+ uno::Reference<beans::XPropertySet> xProp(_rEvent.Source,uno::UNO_QUERY);
+ m_pTree->set_text(*xEntry, lcl_getName(xProp));
+ }
+ }
+ catch(const uno::Exception &)
+ {}
+}
+
+void NavigatorTree::UserData::_elementInserted( const container::ContainerEvent& _rEvent )
+{
+ m_pTree->_elementInserted( _rEvent );
+}
+
+void NavigatorTree::UserData::_elementRemoved( const container::ContainerEvent& _rEvent )
+{
+ m_pTree->_elementRemoved( _rEvent );
+}
+
+void NavigatorTree::UserData::_elementReplaced( const container::ContainerEvent& _rEvent )
+{
+ m_pTree->_elementReplaced( _rEvent );
+}
+
+void NavigatorTree::UserData::_disposing(const lang::EventObject& _rSource)
+{
+ m_pTree->_disposing( _rSource );
+}
+
+class ONavigatorImpl
+{
+public:
+ ONavigatorImpl(OReportController& rController, weld::Builder& rBuilder);
+ ONavigatorImpl(const ONavigatorImpl&) = delete;
+ ONavigatorImpl& operator=(const ONavigatorImpl&) = delete;
+
+ uno::Reference< report::XReportDefinition> m_xReport;
+ std::unique_ptr<NavigatorTree> m_xNavigatorTree;
+};
+
+ONavigatorImpl::ONavigatorImpl(OReportController& rController, weld::Builder& rBuilder)
+ : m_xReport(rController.getReportDefinition())
+ , m_xNavigatorTree(std::make_unique<NavigatorTree>(rBuilder.weld_tree_view("treeview"), rController))
+{
+ reportdesign::OReportVisitor aVisitor(m_xNavigatorTree.get());
+ aVisitor.start(m_xReport);
+ std::unique_ptr<weld::TreeIter> xScratch = m_xNavigatorTree->make_iterator();
+ if (m_xNavigatorTree->find(m_xReport, *xScratch))
+ m_xNavigatorTree->expand_row(*xScratch);
+ lang::EventObject aEvent(rController);
+ m_xNavigatorTree->_selectionChanged(aEvent);
+}
+
+ONavigator::ONavigator(weld::Window* pParent, OReportController& rController)
+ : GenericDialogController(pParent, "modules/dbreport/ui/floatingnavigator.ui", "FloatingNavigator")
+{
+ m_pImpl.reset(new ONavigatorImpl(rController, *m_xBuilder));
+ m_pImpl->m_xNavigatorTree->grab_focus();
+
+ m_xDialog->connect_container_focus_changed(LINK(this, ONavigator, FocusChangeHdl));
+}
+
+ONavigator::~ONavigator()
+{
+}
+
+IMPL_LINK_NOARG(ONavigator, FocusChangeHdl, weld::Container&, void)
+{
+ if (m_xDialog->has_toplevel_focus())
+ m_pImpl->m_xNavigatorTree->grab_focus();
+}
+
+} // rptui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/PageNumber.cxx b/reportdesign/source/ui/dlg/PageNumber.cxx
new file mode 100644
index 000000000..2d18077ab
--- /dev/null
+++ b/reportdesign/source/ui/dlg/PageNumber.cxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <PageNumber.hxx>
+#include <rptui_slotid.hrc>
+#include <RptDef.hxx>
+
+#include <strings.hxx>
+#include <ReportController.hxx>
+#include <comphelper/propertysequence.hxx>
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace ::comphelper;
+
+
+
+OPageNumberDialog::OPageNumberDialog(weld::Window* pParent,
+ const uno::Reference< report::XReportDefinition >& _xHoldAlive,
+ OReportController* _pController)
+ : GenericDialogController(pParent, "modules/dbreport/ui/pagenumberdialog.ui", "PageNumberDialog")
+ , m_pController(_pController)
+ , m_xHoldAlive(_xHoldAlive)
+ , m_xPageN(m_xBuilder->weld_radio_button("pagen"))
+ , m_xPageNofM(m_xBuilder->weld_radio_button("pagenofm"))
+ , m_xTopPage(m_xBuilder->weld_radio_button("toppage"))
+ , m_xBottomPage(m_xBuilder->weld_radio_button("bottompage"))
+ , m_xAlignmentLst(m_xBuilder->weld_combo_box("alignment"))
+ , m_xShowNumberOnFirstPage(m_xBuilder->weld_check_button("shownumberonfirstpage"))
+{
+ m_xShowNumberOnFirstPage->hide();
+}
+
+OPageNumberDialog::~OPageNumberDialog()
+{
+}
+
+short OPageNumberDialog::run()
+{
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ {
+ try
+ {
+ sal_Int32 nControlMaxSize = 3000;
+ sal_Int32 nPosX = 0;
+ sal_Int32 nPos2X = 0;
+ awt::Size aRptSize = getStyleProperty<awt::Size>(m_xHoldAlive,PROPERTY_PAPERSIZE);
+ switch (m_xAlignmentLst->get_active())
+ {
+ case 0: // left
+ nPosX = getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_LEFTMARGIN);
+ break;
+ case 1: // middle
+ nPosX = getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_LEFTMARGIN) + (aRptSize.Width - getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_LEFTMARGIN) - getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_RIGHTMARGIN) - nControlMaxSize) / 2;
+ break;
+ case 2: // right
+ nPosX = (aRptSize.Width - getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_RIGHTMARGIN) - nControlMaxSize);
+ break;
+ case 3: // inner
+ case 4: // outer
+ nPosX = getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_LEFTMARGIN);
+ nPos2X = (aRptSize.Width - getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_RIGHTMARGIN) - nControlMaxSize);
+ break;
+ default:
+ break;
+ }
+ if (m_xAlignmentLst->get_active() > 2)
+ nPosX = nPos2X;
+
+ uno::Sequence<beans::PropertyValue> aValues( comphelper::InitPropertySequence({
+ { PROPERTY_POSITION, uno::Any(awt::Point(nPosX,0)) },
+ { PROPERTY_PAGEHEADERON, uno::Any(m_xTopPage->get_active()) },
+ { PROPERTY_STATE, uno::Any(m_xPageNofM->get_active()) }
+ }));
+
+ m_pController->executeChecked(SID_INSERT_FLD_PGNUMBER,aValues);
+ }
+ catch(uno::Exception&)
+ {
+ }
+ }
+ return nRet;
+}
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/dlg/dlgpage.cxx b/reportdesign/source/ui/dlg/dlgpage.cxx
new file mode 100644
index 000000000..c4fb41c46
--- /dev/null
+++ b/reportdesign/source/ui/dlg/dlgpage.cxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <svx/dialogs.hrc>
+#include <sfx2/sfxdlg.hxx>
+#include <dlgpage.hxx>
+#include <svl/cjkoptions.hxx>
+#include <osl/diagnose.h>
+
+namespace rptui
+{
+/*************************************************************************
+|*
+|* constructor of the tab dialogs: Add the page to the dialog
+|*
+\************************************************************************/
+
+ORptPageDialog::ORptPageDialog(weld::Window* pParent, const SfxItemSet* pAttr, const OUString &rDialog)
+ : SfxTabDialogController(pParent, "modules/dbreport/ui/" +
+ rDialog.toAsciiLowerCase() + ".ui", rDialog.toUtf8(), pAttr)
+{
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+
+ if (rDialog == "BackgroundDialog")
+ {
+ AddTabPage("background", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), nullptr );
+ }
+ else if (rDialog == "PageDialog")
+ {
+ AddTabPage("page", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_PAGE ), nullptr );
+ AddTabPage("background", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), nullptr );
+ }
+ else if (rDialog == "CharDialog")
+ {
+ AddTabPage("font", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_NAME ), nullptr );
+ AddTabPage("fonteffects", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_EFFECTS ), nullptr );
+ AddTabPage("position", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_POSITION ), nullptr );
+ AddTabPage("asianlayout", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_TWOLINES ), nullptr );
+ AddTabPage("background", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), nullptr );
+ AddTabPage("alignment", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_ALIGNMENT ), nullptr );
+ }
+ else
+ OSL_FAIL("Unknown page id");
+
+ if ( !SvtCJKOptions::IsDoubleLinesEnabled() )
+ RemoveTabPage("asianlayout");
+}
+
+void ORptPageDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ if (rId == "background")
+ {
+ rPage.PageCreated(aSet);
+ }
+}
+
+} // namespace rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/AddField.hxx b/reportdesign/source/ui/inc/AddField.hxx
new file mode 100644
index 000000000..5a388d49a
--- /dev/null
+++ b/reportdesign/source/ui/inc/AddField.hxx
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ADDFIELD_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ADDFIELD_HXX
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <comphelper/propmultiplex.hxx>
+#include <comphelper/containermultiplexer.hxx>
+
+#include <svx/dataaccessdescriptor.hxx>
+#include <svx/dbaexchange.hxx>
+#include <cppuhelper/basemutex.hxx>
+
+#include <vcl/weld.hxx>
+
+#include <rtl/ref.hxx>
+
+#include "ColumnInfo.hxx"
+
+namespace rptui
+{
+
+class OAddFieldWindow;
+
+class OAddFieldWindow : public weld::GenericDialogController
+ , public ::cppu::BaseMutex
+ , public ::comphelper::OPropertyChangeListener
+ , public ::comphelper::OContainerListener
+{
+ css::uno::Reference< css::lang::XComponent> m_xHoldAlive;
+ css::uno::Reference< css::container::XNameAccess> m_xColumns;
+ css::uno::Reference< css::beans::XPropertySet > m_xRowSet;
+
+ std::unique_ptr<weld::Toolbar> m_xActions;
+ std::unique_ptr<weld::TreeView> m_xListBox;
+ std::unique_ptr<weld::Label> m_xHelpText;
+
+ Link<OAddFieldWindow&,void> m_aCreateLink;
+ OUString m_aCommandName;
+ OUString m_sFilter;
+ sal_Int32 m_nCommandType;
+ bool m_bEscapeProcessing;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pChangeListener;
+ ::rtl::Reference< comphelper::OContainerListenerAdapter> m_pContainerListener;
+ ::rtl::Reference< svx::OMultiColumnTransferable > m_xHelper;
+
+ std::vector<std::unique_ptr<ColumnInfo>> m_aListBoxData;
+
+ DECL_LINK( OnDoubleClickHdl, weld::TreeView&, bool );
+ DECL_LINK( OnSelectHdl, weld::TreeView&, void );
+ DECL_LINK( DragBeginHdl, bool&, bool );
+ DECL_LINK( OnSortAction, const OString&, void );
+ DECL_LINK( FocusChangeHdl, weld::Container&, void );
+
+ void addToList(const css::uno::Sequence<OUString>& rEntries);
+ void addToList(const css::uno::Reference<css::container::XNameAccess>& i_xColumns);
+
+ OAddFieldWindow(const OAddFieldWindow&) = delete;
+ void operator =(const OAddFieldWindow&) = delete;
+public:
+ OAddFieldWindow(weld::Window* pParent,
+ const css::uno::Reference< css::beans::XPropertySet >& xRowSet);
+
+ virtual ~OAddFieldWindow() override;
+
+ const OUString& GetCommand() const { return m_aCommandName; }
+ sal_Int32 GetCommandType() const { return m_nCommandType; }
+ void SetCreateHdl(const Link<OAddFieldWindow&,void>& _aCreateLink) { m_aCreateLink = _aCreateLink; }
+
+ css::uno::Reference< css::sdbc::XConnection> getConnection() const;
+
+ css::uno::Sequence< css::beans::PropertyValue > getSelectedFieldDescriptors();
+
+ /// Updates the current field list
+ void Update();
+
+ /** fills the descriptor with the column name, column object, command and command type
+ *
+ * \param rSelected the currently selected
+ * \param rDescriptor the descriptor will be filled
+ */
+ void fillDescriptor(const weld::TreeIter& rSelected, svx::ODataAccessDescriptor& rDescriptor);
+
+private:
+ // FmXChangeListener
+ virtual void _propertyChanged(const css::beans::PropertyChangeEvent& evt) override;
+ // OContainerListener
+ virtual void _elementInserted( const css::container::ContainerEvent& _rEvent ) override;
+ virtual void _elementRemoved( const css::container::ContainerEvent& _rEvent ) override;
+ virtual void _elementReplaced( const css::container::ContainerEvent& _rEvent ) override;
+};
+
+} // rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ADDFIELD_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ColorChanger.hxx b/reportdesign/source/ui/inc/ColorChanger.hxx
new file mode 100644
index 000000000..34a336b01
--- /dev/null
+++ b/reportdesign/source/ui/inc/ColorChanger.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORCHANGER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORCHANGER_HXX
+
+#include <vcl/outdev.hxx>
+
+namespace rptui
+{
+
+ //= ColorChanger
+
+ class ColorChanger final
+ {
+ VclPtr<OutputDevice> m_pDev;
+
+ public:
+ ColorChanger( OutputDevice* _pDev, const Color& _rNewLineColor, const Color& _rNewFillColor )
+ :m_pDev( _pDev )
+ {
+ m_pDev->Push( vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR );
+ m_pDev->SetLineColor( _rNewLineColor );
+ m_pDev->SetFillColor( _rNewFillColor );
+ }
+
+ ~ColorChanger()
+ {
+ m_pDev->Pop();
+ }
+ };
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORCHANGER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ColorListener.hxx b/reportdesign/source/ui/inc/ColorListener.hxx
new file mode 100644
index 000000000..0f8a89aca
--- /dev/null
+++ b/reportdesign/source/ui/inc/ColorListener.hxx
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORLISTENER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORLISTENER_HXX
+
+#include <vcl/window.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svtools/extcolorcfg.hxx>
+#include <tools/link.hxx>
+
+namespace rptui
+{
+ class OColorListener : public vcl::Window, public SfxListener
+ {
+ OColorListener(const OColorListener&) = delete;
+ void operator =(const OColorListener&) = delete;
+ protected:
+ Link<OColorListener&,void> m_aCollapsedLink;
+ svtools::ColorConfig m_aColorConfig;
+ svtools::ExtendedColorConfig m_aExtendedColorConfig;
+ OUString m_sColorEntry;
+ Color m_nColor;
+ Color m_nTextBoundaries;
+ bool m_bCollapsed;
+ bool m_bMarked;
+
+ virtual void ImplInitSettings() = 0;
+ protected:
+ virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
+ public:
+ OColorListener(vcl::Window* _pParent,const OUString& _sColorEntry);
+ virtual ~OColorListener() override;
+ virtual void dispose() override;
+
+ // SfxListener
+ virtual void Notify(SfxBroadcaster & rBc, SfxHint const & rHint) override;
+
+ /** set the marker as marked or not marked
+ @param _bMark set the new state of the marker
+ */
+ void setMarked(bool _bMark);
+
+ /** returns if the section is marked
+ */
+ bool isMarked() const { return m_bMarked; }
+
+ void setCollapsedHdl(const Link<OColorListener&,void>& _aLink ){ m_aCollapsedLink = _aLink; }
+ bool isCollapsed() const { return m_bCollapsed; }
+
+ /** collapse or expand
+ *
+ * \param _bCollapsed
+ */
+ virtual void setCollapsed(bool _bCollapsed);
+ };
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORLISTENER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ColumnInfo.hxx b/reportdesign/source/ui/inc/ColumnInfo.hxx
new file mode 100644
index 000000000..65062f9dc
--- /dev/null
+++ b/reportdesign/source/ui/inc/ColumnInfo.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLUMNINFO_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLUMNINFO_HXX
+
+#include <rtl/ustring.hxx>
+
+namespace rptui
+{
+ struct ColumnInfo
+ {
+ OUString sColumnName;
+ OUString sLabel;
+ ColumnInfo(const OUString& i_sColumnName,const OUString& i_sLabel)
+ : sColumnName(i_sColumnName)
+ , sLabel(i_sLabel)
+ {
+ }
+ ColumnInfo(const OUString& i_sColumnName)
+ : sColumnName(i_sColumnName)
+ {
+ }
+ };
+
+} // namespace rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLUMNINFO_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/CondFormat.hxx b/reportdesign/source/ui/inc/CondFormat.hxx
new file mode 100644
index 000000000..9b648be10
--- /dev/null
+++ b/reportdesign/source/ui/inc/CondFormat.hxx
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_CONDFORMAT_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_CONDFORMAT_HXX
+
+#include <com/sun/star/report/XReportControlModel.hpp>
+#include <vcl/weld.hxx>
+#include <vector>
+
+namespace rptui
+{
+
+
+ constexpr size_t MAX_CONDITIONS = 3;
+
+ class OReportController;
+ class Condition;
+
+
+ //= IConditionalFormatAction
+
+ class SAL_NO_VTABLE IConditionalFormatAction
+ {
+ public:
+ virtual void addCondition( size_t _nAddAfterIndex ) = 0;
+ virtual void deleteCondition( size_t _nCondIndex ) = 0;
+ virtual void applyCommand( size_t _nCondIndex, sal_uInt16 _nCommandId, const ::Color& rColor ) = 0;
+ virtual void moveConditionUp( size_t _nCondIndex ) = 0;
+ virtual void moveConditionDown( size_t _nCondIndex ) = 0;
+ virtual OUString getDataField() const = 0;
+
+ protected:
+ ~IConditionalFormatAction() {}
+ };
+
+ /*************************************************************************
+ |*
+ |* Conditional formatting dialog
+ |*
+ \************************************************************************/
+ class ConditionalFormattingDialog : public weld::GenericDialogController
+ , public IConditionalFormatAction
+ {
+ typedef ::std::vector< std::unique_ptr<Condition> > Conditions;
+
+ ::rptui::OReportController& m_rController;
+ css::uno::Reference< css::report::XReportControlModel >
+ m_xFormatConditions;
+ css::uno::Reference< css::report::XReportControlModel >
+ m_xCopy;
+
+ bool m_bConstructed;
+
+ std::unique_ptr<weld::ScrolledWindow> m_xScrollWindow;
+ std::unique_ptr<weld::Box> m_xConditionPlayground;
+ Conditions m_aConditions;
+
+ public:
+ ConditionalFormattingDialog(
+ weld::Window* pParent,
+ const css::uno::Reference< css::report::XReportControlModel>& _xHoldAlive,
+ ::rptui::OReportController& _rController
+ );
+ virtual ~ConditionalFormattingDialog() override;
+ // Dialog overridables
+ virtual short run() override;
+
+ // IConditionalFormatAction overridables
+ virtual void addCondition( size_t _nAddAfterIndex ) override;
+ virtual void deleteCondition( size_t _nCondIndex ) override;
+ virtual void applyCommand( size_t _nCondIndex, sal_uInt16 _nCommandId, const ::Color& rColor ) override;
+ virtual void moveConditionUp( size_t _nCondIndex ) override;
+ virtual void moveConditionDown( size_t _nCondIndex ) override;
+ virtual OUString getDataField() const override;
+
+ private:
+ DECL_LINK(OnScroll, weld::ScrolledWindow&, void);
+
+ private:
+ /// returns the current number of conditions
+ size_t impl_getConditionCount() const { return m_aConditions.size(); }
+
+ /** adds a condition
+ @param _nNewCondIndex
+ the index of the to-be-inserted condition
+ */
+ void impl_addCondition_nothrow( size_t _nNewCondIndex );
+
+ /// deletes the condition with the given index
+ void impl_deleteCondition_nothrow( size_t _nCondIndex );
+
+ /// moves the condition with the given index one position
+ void impl_moveCondition_nothrow( size_t _nCondIndex, bool _bMoveUp );
+
+ /// does the dialog layouting
+ void impl_layoutAll();
+
+ /// called when the number of conditions has changed in any way
+ void impl_conditionCountChanged();
+
+ /// initializes the conditions from m_xCopy
+ void impl_initializeConditions();
+
+ /// tells all our Condition instances their new index
+ void impl_updateConditionIndicies();
+
+ /// returns the number of the condition which has the (child path) focus
+ size_t impl_getFocusedConditionIndex( sal_Int32 _nFallBackIfNone ) const;
+
+ /// returns the index of the first visible condition
+ size_t impl_getFirstVisibleConditionIndex() const;
+
+ /// returns the index of the last visible condition
+ size_t impl_getLastVisibleConditionIndex() const;
+
+ /// focuses the condition with the given index, making it visible if necessary
+ void impl_focusCondition( size_t _nCondIndex );
+
+ /// scrolls the condition with the given index to the top position
+ void impl_scrollTo( size_t _nTopCondIndex );
+
+ /// ensures the condition with the given index is visible
+ void impl_ensureConditionVisible( size_t _nCondIndex );
+
+ /// set the preferred height of the action_area
+ void impl_setPrefHeight(bool bFirst);
+ };
+
+
+} // namespace rptui
+
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_CONDFORMAT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/DataProviderHandler.hxx b/reportdesign/source/ui/inc/DataProviderHandler.hxx
new file mode 100644
index 000000000..05dd693a9
--- /dev/null
+++ b/reportdesign/source/ui/inc/DataProviderHandler.hxx
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATAPROVIDERHANDLER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATAPROVIDERHANDLER_HXX
+
+#include <sal/config.h>
+
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/basemutex.hxx>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/inspection/XPropertyHandler.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
+#include <com/sun/star/report/XReportComponent.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+
+namespace rptui
+{
+
+
+ class OPropertyInfoService;
+
+ typedef ::cppu::WeakComponentImplHelper< css::inspection::XPropertyHandler
+ , css::lang::XServiceInfo> DataProviderHandler_Base;
+
+ class DataProviderHandler:
+ private ::cppu::BaseMutex,
+ public DataProviderHandler_Base
+ {
+ public:
+ explicit DataProviderHandler(css::uno::Reference< css::uno::XComponentContext > const & context);
+ private:
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName( ) override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ // css::lang::XComponent:
+ virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & xListener) override;
+ virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override;
+
+ // css::inspection::XPropertyHandler:
+ virtual void SAL_CALL inspect(const css::uno::Reference< css::uno::XInterface > & Component) override;
+ virtual css::uno::Any SAL_CALL getPropertyValue(const OUString & PropertyName) override;
+ virtual void SAL_CALL setPropertyValue(const OUString & PropertyName, const css::uno::Any & Value) override;
+ virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString & PropertyName) override;
+ virtual css::inspection::LineDescriptor SAL_CALL describePropertyLine(const OUString& PropertyName, const css::uno::Reference< css::inspection::XPropertyControlFactory >& ControlFactory ) override;
+ virtual css::uno::Any SAL_CALL convertToPropertyValue(const OUString & PropertyName, const css::uno::Any & ControlValue) override;
+ virtual css::uno::Any SAL_CALL convertToControlValue(const OUString & PropertyName, const css::uno::Any & PropertyValue, const css::uno::Type & ControlValueType) override;
+ virtual void SAL_CALL addPropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & Listener) override;
+ virtual void SAL_CALL removePropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & _rxListener) override;
+ virtual css::uno::Sequence< css::beans::Property > SAL_CALL getSupportedProperties() override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupersededProperties() override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getActuatingProperties() override;
+ virtual sal_Bool SAL_CALL isComposable(const OUString & PropertyName) override;
+ virtual css::inspection::InteractiveSelectionResult SAL_CALL onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, css::uno::Any & out_Data, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI) override;
+ virtual void SAL_CALL actuatingPropertyChanged(const OUString & ActuatingPropertyName, const css::uno::Any & NewValue, const css::uno::Any & OldValue, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit) override;
+ virtual sal_Bool SAL_CALL suspend(sal_Bool Suspend) override;
+
+ protected:
+ virtual ~DataProviderHandler() override {}
+ private:
+ DataProviderHandler(DataProviderHandler const &) = delete;
+ void operator =(DataProviderHandler const &) = delete;
+
+
+ bool impl_dialogLinkedFields_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const;
+ bool impl_dialogChartType_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const;
+ void impl_updateChartTitle_throw(const css::uno::Any& _aValue);
+
+ // override WeakComponentImplHelperBase::disposing()
+ // This function is called upon disposing the component,
+ // if your component needs special work when it becomes
+ // disposed, do it here.
+ virtual void SAL_CALL disposing() override;
+
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::inspection::XPropertyHandler > m_xFormComponentHandler; /// delegatee
+ css::uno::Reference< css::chart2::data::XDatabaseDataProvider> m_xDataProvider; /// inspectee
+ css::uno::Reference< css::uno::XInterface > m_xFormComponent; /// inspectee
+ css::uno::Reference< css::report::XReportComponent > m_xReportComponent; /// inspectee
+ css::uno::Reference< css::chart2::XChartDocument> m_xChartModel;
+ css::uno::Reference< css::beans::XPropertyChangeListener > m_xMasterDetails;
+ /// type converter, needed on various occasions
+ css::uno::Reference< css::script::XTypeConverter > m_xTypeConverter;
+ };
+
+} // namespace rptui
+
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATAPROVIDERHANDLER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/DateTime.hxx b/reportdesign/source/ui/inc/DateTime.hxx
new file mode 100644
index 000000000..df9fbfe87
--- /dev/null
+++ b/reportdesign/source/ui/inc/DateTime.hxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATETIME_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATETIME_HXX
+
+#include <vcl/weld.hxx>
+#include <com/sun/star/report/XSection.hpp>
+#include <com/sun/star/util/XNumberFormats.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+
+namespace rptui
+{
+class OReportController;
+/*************************************************************************
+|*
+|* Groups and Sorting dialog
+|*
+\************************************************************************/
+class ODateTimeDialog : public weld::GenericDialogController
+{
+ ::rptui::OReportController* m_pController;
+ css::uno::Reference< css::report::XSection>
+ m_xHoldAlive;
+ css::lang::Locale m_nLocale;
+
+ std::unique_ptr<weld::CheckButton> m_xDate;
+ std::unique_ptr<weld::Label> m_xFTDateFormat;
+ std::unique_ptr<weld::ComboBox> m_xDateListBox;
+ std::unique_ptr<weld::CheckButton> m_xTime;
+ std::unique_ptr<weld::Label> m_xFTTimeFormat;
+ std::unique_ptr<weld::ComboBox> m_xTimeListBox;
+ std::unique_ptr<weld::Button> m_xPB_OK;
+
+ /** returns the format string
+ *
+ * \param _nNumberFormatKey the number format key
+ * \param _xFormats
+ * \param _bTime
+ * \return
+ */
+ OUString getFormatStringByKey(::sal_Int32 _nNumberFormatKey,const css::uno::Reference< css::util::XNumberFormats>& _xFormats,bool _bTime);
+
+ /** returns the number format key
+ @param _nNumberFormatIndex the number format index @see css::i18n::NumberFormatIndex
+ */
+ sal_Int32 getFormatKey(bool _bDate) const;
+
+ DECL_LINK(CBClickHdl, weld::Toggleable&, void);
+ ODateTimeDialog(const ODateTimeDialog&) = delete;
+ void operator =(const ODateTimeDialog&) = delete;
+
+ // fill methods
+ void InsertEntry(sal_Int16 _nNumberFormatId);
+public:
+ ODateTimeDialog(weld::Window* pParent,
+ const css::uno::Reference< css::report::XSection>& _xHoldAlive,
+ ::rptui::OReportController* _pController);
+ virtual short run() override;
+};
+
+} // namespace rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATETIME_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/DefaultInspection.hxx b/reportdesign/source/ui/inc/DefaultInspection.hxx
new file mode 100644
index 000000000..3f32725c5
--- /dev/null
+++ b/reportdesign/source/ui/inc/DefaultInspection.hxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DEFAULTINSPECTION_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DEFAULTINSPECTION_HXX
+
+#include <com/sun/star/inspection/XObjectInspectorModel.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <cppuhelper/implbase3.hxx>
+
+
+namespace rptui
+{
+
+ class OPropertyInfoService;
+
+ //= DefaultComponentInspectorModel
+
+ typedef ::cppu::WeakAggImplHelper3 < css::inspection::XObjectInspectorModel
+ , css::lang::XServiceInfo
+ , css::lang::XInitialization
+ > DefaultComponentInspectorModel_Base;
+ class DefaultComponentInspectorModel final : public DefaultComponentInspectorModel_Base
+ {
+ private:
+ ::osl::Mutex m_aMutex;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::inspection::XObjectInspectorModel > m_xComponent; /// delegatee
+ bool m_bConstructed;
+ bool m_bHasHelpSection;
+ bool m_bIsReadOnly;
+ sal_Int32 m_nMinHelpTextLines;
+ sal_Int32 m_nMaxHelpTextLines;
+
+ DefaultComponentInspectorModel(const DefaultComponentInspectorModel&) = delete;
+ DefaultComponentInspectorModel& operator=(const DefaultComponentInspectorModel&) = delete;
+
+ virtual ~DefaultComponentInspectorModel() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName( ) override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ // XObjectInspectorModel
+ virtual css::uno::Sequence< css::uno::Any > SAL_CALL getHandlerFactories() override;
+ virtual sal_Bool SAL_CALL getHasHelpSection() override;
+ virtual ::sal_Int32 SAL_CALL getMinHelpTextLines() override;
+ virtual ::sal_Int32 SAL_CALL getMaxHelpTextLines() override;
+ virtual sal_Bool SAL_CALL getIsReadOnly() override;
+ virtual void SAL_CALL setIsReadOnly( sal_Bool _isreadonly ) override;
+
+ virtual css::uno::Sequence< css::inspection::PropertyCategoryDescriptor > SAL_CALL describeCategories( ) override;
+ virtual ::sal_Int32 SAL_CALL getPropertyOrderIndex( const OUString& PropertyName ) override;
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
+
+ // Service constructors
+ void createWithHelpSection( sal_Int32 _nMinHelpTextLines, sal_Int32 _nMaxHelpTextLines );
+
+ public:
+ DefaultComponentInspectorModel( const css::uno::Reference< css::uno::XComponentContext >& _rxContext);
+ };
+
+
+} // namespace rptui
+
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DEFAULTINSPECTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/DesignView.hxx b/reportdesign/source/ui/inc/DesignView.hxx
new file mode 100644
index 000000000..def0495c1
--- /dev/null
+++ b/reportdesign/source/ui/inc/DesignView.hxx
@@ -0,0 +1,257 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DESIGNVIEW_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DESIGNVIEW_HXX
+
+#include <dbaccess/dataview.hxx>
+#include <com/sun/star/report/XSection.hpp>
+#include <com/sun/star/report/XReportComponent.hpp>
+#include <tools/link.hxx>
+#include <tools/gen.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/idle.hxx>
+#include <svl/SfxBroadcaster.hxx>
+#include "ReportDefines.hxx"
+#include <vcl/splitwin.hxx>
+#include "MarkedSection.hxx"
+#include "ScrollHelper.hxx"
+
+class KeyEvent;
+class MouseEvent;
+class Timer;
+namespace vcl { class Window; }
+
+namespace rptui
+{
+ class OSectionView;
+ class OReportController;
+ class PropBrw;
+ class OAddFieldWindow;
+ class ONavigator;
+
+
+ class ODesignView : public dbaui::ODataView, public SfxBroadcaster, public IMarkedSection
+ {
+ private:
+ VclPtr<SplitWindow> m_aSplitWin;
+
+ css::uno::Reference< css::uno::XInterface> m_xReportComponent;
+ OReportController& m_rReportController;
+ VclPtr<OScrollWindowHelper> m_aScrollWindow;
+ VclPtr<vcl::Window> m_pTaskPane;
+ VclPtr<PropBrw> m_pPropWin;
+ std::shared_ptr<OAddFieldWindow> m_xAddField;
+ OSectionView* m_pCurrentView;
+ std::shared_ptr<ONavigator> m_xReportExplorer;
+ Idle m_aMarkIdle;
+ DlgEdMode m_eMode;
+ SdrObjKind m_eActObj;
+ Size m_aGridSizeCoarse;
+ Size m_aGridSizeFine;
+ bool m_bDeleted;
+
+
+ DECL_LINK(MarkTimeout, Timer *, void);
+ DECL_LINK( SplitHdl, SplitWindow*, void );
+
+ void ImplInitSettings();
+
+ ODesignView(ODesignView const &) = delete;
+ void operator =(ODesignView const &) = delete;
+ protected:
+ // return the Rectangle where I can paint myself
+ virtual void resizeDocumentView(tools::Rectangle& rRect) override;
+ // return the Rectangle where I can paint myself
+ virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
+
+ public:
+ ODesignView(vcl::Window* pParent,
+ const css::uno::Reference< css::uno::XComponentContext >&,
+ OReportController& _rController);
+ virtual ~ODesignView() override;
+ virtual void dispose() override;
+
+ // Window overrides
+ virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
+ virtual bool PreNotify( NotifyEvent& rNEvt ) override;
+ virtual void GetFocus() override;
+
+ virtual void initialize() override;
+
+ OReportController& getController() const { return m_rReportController; }
+
+ void SetMode( DlgEdMode m_eMode );
+ void SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType = OUString());
+ SdrObjKind GetInsertObj() const { return m_eActObj;}
+ OUString const & GetInsertObjString() const;
+ DlgEdMode GetMode() const { return m_eMode; }
+
+ /** cuts the current selection in this section
+ */
+ void Cut();
+
+ /** copies the current selection in this section
+ */
+ void Copy();
+
+ /** returns if paste is allowed
+ *
+ * \return <TRUE/> if paste is allowed
+ */
+ bool IsPasteAllowed() const;
+
+ /** paste a new control in this section
+ */
+ void Paste();
+
+ /** Deletes the current selection in this section
+ *
+ */
+ void Delete();
+
+ /** align all marked objects in all sections
+ */
+ void alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection);
+
+ /** All objects will be marked.
+ */
+ void SelectAll(const SdrObjKind _nObjectType);
+
+ /// checks if a selection exists
+ bool HasSelection() const;
+
+ void UpdatePropertyBrowserDelayed(OSectionView& _rView);
+
+ sal_uInt16 getSectionCount() const;
+
+ /** removes the section at the given position.
+ *
+ * \param _nPosition Zero based.
+ */
+ void removeSection(sal_uInt16 _nPosition);
+
+ /** adds a new section at position _nPosition.
+ If the section is <NULL/> nothing happens.
+ If the position is grater than the current elements, the section will be appended.
+ */
+ void addSection(const css::uno::Reference< css::report::XSection >& _xSection
+ ,const OUString& _sColorEntry
+ ,sal_uInt16 _nPosition = USHRT_MAX);
+
+ const Size& getGridSizeCoarse() const { return m_aGridSizeCoarse; }
+ const Size& getGridSizeFine() const { return m_aGridSizeFine; }
+ void setGridSnap(bool bOn);
+ void setDragStripes(bool bOn);
+ /** turns the grid on or off
+ *
+ * \param _bGridVisible
+ */
+ void toggleGrid(bool _bGridVisible);
+
+ void togglePropertyBrowser(bool _bToggleOn);
+
+ bool isAddFieldVisible() const;
+ void toggleAddField();
+
+ bool isReportExplorerVisible() const;
+ void toggleReportExplorer();
+
+ /** shows or hides the ruler.
+ */
+ void showRuler(bool _bShow);
+
+ /** unmark all objects on the views.
+ */
+ void unmarkAllObjects();
+
+ /** triggers the property browser with the section
+ @param _xReportComponent the report component
+ */
+ void showProperties( const css::uno::Reference< css::uno::XInterface>& _xReportComponent);
+ css::uno::Any getCurrentlyShownProperty() const;
+
+ /** returns the current section or the detail section if no section was selected previously
+ */
+ css::uno::Reference< css::report::XSection > getCurrentSection() const;
+
+ /** returns the current control report model or <NULL/>
+ */
+ css::uno::Reference< css::report::XReportComponent > getCurrentControlModel() const;
+
+ // IMarkedSection
+ OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const override;
+ OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const;
+ virtual void markSection(const sal_uInt16 _nPos) override;
+
+ /** fills the positions of all collapsed sections.
+ *
+ * \param _rCollapsedPositions Out parameter which holds afterwards all positions of the collapsed sections.
+ */
+ void fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const;
+
+ /** collapse all sections given by their position
+ *
+ * \param _aCollapsedSections The position of the sections which should be collapsed.
+ */
+ void collapseSections(const css::uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections);
+
+ OUString getCurrentPage() const;
+ void setCurrentPage(const OUString& _sLastActivePage);
+
+ /** checks if the keycode is known by the child windows
+ @param _rCode the keycode
+ @return <TRUE/> if the keycode is handled otherwise <FALSE/>
+ */
+ bool handleKeyEvent(const KeyEvent& _rEvent);
+
+ /** set the section as marked or not marked
+ @param _pSectionView the section where to set the marked flag
+ @param _bMark the marked flag
+ */
+ void setMarked(const css::uno::Reference< css::report::XSection>& _xSection,bool _bMark);
+ void setMarked(const css::uno::Sequence< css::uno::Reference< css::report::XReportComponent> >& _xShape,bool _bMark);
+
+ /** returns if the view handles the event by itself
+ *
+ * \return <FALSE/> is the event is not handled by the view otherwise <TRUE/>
+ */
+ bool isHandleEvent() const;
+
+ sal_uInt32 getMarkedObjectCount() const;
+
+ /** zoom the ruler and view windows
+ */
+ void zoom(const Fraction& _aZoom);
+
+ /** fills the vector with all selected control models
+ /param _rSelection The vector will be filled and will not be cleared before.
+ */
+ void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const;
+
+ /** calculates the zoom factor.
+ @param _eType which kind of zoom is needed
+ */
+ sal_uInt16 getZoomFactor(SvxZoomType _eType) const;
+ };
+
+} //rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DESIGNVIEW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/EndMarker.hxx b/reportdesign/source/ui/inc/EndMarker.hxx
new file mode 100644
index 000000000..a48eb8106
--- /dev/null
+++ b/reportdesign/source/ui/inc/EndMarker.hxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ENDMARKER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ENDMARKER_HXX
+
+#include "ColorListener.hxx"
+
+namespace rptui
+{
+ /** \class OEndMarker
+ * \brief Defines the right side of a graphical section.
+ */
+ class OEndMarker : public OColorListener
+ {
+ OEndMarker(OEndMarker const &) = delete;
+ void operator =(OEndMarker const &) = delete;
+ protected:
+ virtual void ImplInitSettings() override;
+ public:
+ OEndMarker(vcl::Window* _pParent,const OUString& _sColorEntry);
+ virtual ~OEndMarker() override;
+
+ // windows
+ virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
+ virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
+ };
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ENDMARKER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/FixedTextColor.hxx b/reportdesign/source/ui/inc/FixedTextColor.hxx
new file mode 100644
index 000000000..fa76a52df
--- /dev/null
+++ b/reportdesign/source/ui/inc/FixedTextColor.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FIXEDTEXTCOLOR_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FIXEDTEXTCOLOR_HXX
+
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/report/XFixedText.hpp>
+#include <tools/color.hxx>
+
+#include "IReportControllerObserver.hxx"
+
+namespace rptui
+{
+ class OReportController;
+
+ class FixedTextColor : public IReportControllerObserver
+ {
+ const OReportController& m_rReportController;
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::awt::XVclWindowPeer > getVclWindowPeer(const css::uno::Reference< css::report::XFixedText >& _xComponent);
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::awt::XControl > getXControl(const css::uno::Reference< css::report::XFixedText >& _xFixedText);
+
+ static void setPropertyTextColor(const css::uno::Reference< css::awt::XVclWindowPeer >& _xVclWindowPeer, Color _nFormatKey);
+
+ public:
+ FixedTextColor(const OReportController & _aObserver);
+ virtual ~FixedTextColor() override;
+
+ void notifyPropertyChange( const css::beans::PropertyChangeEvent& _rEvent ) override;
+ void notifyElementInserted( const css::uno::Reference< css::uno::XInterface >& _rxElement ) override;
+ void handle( const css::uno::Reference< css::uno::XInterface >& _rxElement ) override;
+
+ };
+
+} // namespace rptui
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx b/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx
new file mode 100644
index 000000000..455dfd396
--- /dev/null
+++ b/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMATTEDFIELDBEAUTIFIER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMATTEDFIELDBEAUTIFIER_HXX
+
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <com/sun/star/report/XReportComponent.hpp>
+#include <tools/color.hxx>
+
+#include "IReportControllerObserver.hxx"
+
+namespace rptui
+{
+ class OReportController;
+
+ class FormattedFieldBeautifier : public IReportControllerObserver
+ {
+ const OReportController& m_rReportController;
+ Color m_nTextColor;
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::awt::XVclWindowPeer > getVclWindowPeer(const css::uno::Reference< css::report::XReportComponent >& _xComponent);
+
+ void setPlaceholderText( const css::uno::Reference< css::uno::XInterface >& _rxComponent );
+ void setPlaceholderText( const css::uno::Reference< css::awt::XVclWindowPeer >& _xVclWindowPeer, const OUString& _rText );
+
+ Color getTextColor();
+
+ public:
+ FormattedFieldBeautifier(const OReportController & _aObserver);
+ virtual ~FormattedFieldBeautifier() override;
+
+ void notifyPropertyChange( const css::beans::PropertyChangeEvent& _rEvent ) override;
+ void notifyElementInserted( const css::uno::Reference< css::uno::XInterface >& _rxElement ) override;
+ void handle( const css::uno::Reference< css::uno::XInterface >& _rxElement ) override;
+ };
+
+} // namespace rptui
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/Formula.hxx b/reportdesign/source/ui/inc/Formula.hxx
new file mode 100644
index 000000000..8ec93075b
--- /dev/null
+++ b/reportdesign/source/ui/inc/Formula.hxx
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMULA_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMULA_HXX
+
+#include <formula/formula.hxx>
+#include <formula/IControlReferenceHandler.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/report/meta/XFormulaParser.hpp>
+#include <memory>
+
+namespace com::sun::star::lang {
+ class XMultiServiceFactory;
+}
+
+namespace svl {
+
+class SharedStringPool;
+
+}
+
+namespace rptui
+{
+
+class OAddFieldWindow;
+
+
+class FormulaDialog : public formula::FormulaModalDialog,
+ public formula::IControlReferenceHandler
+{
+ std::shared_ptr<formula::IFunctionManager> m_aFunctionManager;
+ std::unique_ptr<formula::FormEditData> m_xFormulaData;
+ std::shared_ptr<OAddFieldWindow> m_xAddField;
+ css::uno::Reference < css::beans::XPropertySet > m_xRowSet;
+ css::uno::Reference< css::report::meta::XFormulaParser> m_xParser;
+ css::uno::Reference< css::sheet::XFormulaOpCodeMapper> m_xOpCodeMapper;
+ formula::RefEdit* m_pEdit;
+ OUString m_sFormula;
+ sal_Int32 m_nStart;
+ sal_Int32 m_nEnd;
+
+ svl::SharedStringPool& mrStringPool;
+
+ DECL_LINK( OnClickHdl, OAddFieldWindow&, void );
+public:
+ FormulaDialog( weld::Window* pParent
+ , const css::uno::Reference< css::lang::XMultiServiceFactory>& _xServiceFactory
+ , const std::shared_ptr< formula::IFunctionManager >& _pFunctionMgr
+ , const OUString& _sFormula
+ , const css::uno::Reference < css::beans::XPropertySet >& _xRowSet
+ , svl::SharedStringPool& rStrPool );
+
+ virtual ~FormulaDialog() override;
+
+ // IFormulaEditorHelper
+ virtual void notifyChange() override;
+ virtual void fill() override;
+ virtual bool calculateValue(const OUString& _sExpression, OUString& _rResult, bool bMatrixFormula) override;
+ virtual std::shared_ptr<formula::FormulaCompiler> getCompiler() const override;
+ virtual std::unique_ptr<formula::FormulaCompiler> createCompiler( formula::FormulaTokenArray& rArray ) const override;
+ virtual void doClose(bool _bOk) override;
+ virtual void insertEntryToLRUList(const formula::IFunctionDescription* pDesc) override;
+ virtual void showReference(const OUString& _sFormula) override;
+ virtual void dispatch(bool _bOK, bool _bMatrixChecked) override;
+ virtual void setDispatcherLock( bool bLock ) override;
+ virtual void deleteFormData() override;
+ virtual void clear() override;
+ virtual void switchBack() override;
+ virtual formula::FormEditData* getFormEditData() const override;
+ virtual void setCurrentFormula(const OUString& _sReplacement) override;
+ virtual void setSelection(sal_Int32 _nStart, sal_Int32 _nEnd) override;
+ virtual void getSelection(sal_Int32& _nStart, sal_Int32& _nEnd) const override;
+ virtual OUString getCurrentFormula() const override;
+
+ virtual formula::IFunctionManager* getFunctionManager() override;
+ virtual css::uno::Reference< css::sheet::XFormulaParser> getFormulaParser() const override;
+ virtual css::uno::Reference< css::sheet::XFormulaOpCodeMapper> getFormulaOpCodeMapper() const override;
+ virtual css::table::CellAddress getReferencePosition() const override;
+
+ virtual ::std::unique_ptr<formula::FormulaTokenArray> convertToTokenArray(const css::uno::Sequence< css::sheet::FormulaToken >& _aTokenList) override;
+
+ // IControlReferenceHandler
+ virtual void ShowReference(const OUString& _sRef) override;
+ virtual void HideReference( bool bDoneRefMode = true ) override;
+ virtual void ReleaseFocus( formula::RefEdit* pEdit ) override;
+ virtual void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton ) override;
+};
+
+
+} // rptui
+
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMULA_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/FunctionHelper.hxx b/reportdesign/source/ui/inc/FunctionHelper.hxx
new file mode 100644
index 000000000..8eea9632b
--- /dev/null
+++ b/reportdesign/source/ui/inc/FunctionHelper.hxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FUNCTIONHELPER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FUNCTIONHELPER_HXX
+
+#include <formula/IFunctionDescription.hxx>
+#include <com/sun/star/report/meta/XFunctionManager.hpp>
+#include <com/sun/star/report/meta/XFunctionCategory.hpp>
+#include <com/sun/star/report/meta/XFunctionDescription.hpp>
+#include <map>
+#include <memory>
+#include <vector>
+
+namespace rptui
+{
+
+class FunctionCategory;
+class FunctionDescription;
+
+class FunctionManager : public formula::IFunctionManager
+{
+ typedef std::map< OUString, std::shared_ptr< FunctionDescription > > TFunctionsMap;
+ typedef std::map< OUString, std::shared_ptr< FunctionCategory > > TCategoriesMap;
+ css::uno::Reference< css::report::meta::XFunctionManager> m_xMgr;
+ mutable TCategoriesMap m_aCategories;
+ mutable ::std::vector< TCategoriesMap::iterator > m_aCategoryIndex;
+ mutable TFunctionsMap m_aFunctions;
+public:
+ FunctionManager(const css::uno::Reference< css::report::meta::XFunctionManager>& _xMgr);
+ virtual ~FunctionManager();
+ virtual sal_uInt32 getCount() const override;
+ virtual const formula::IFunctionCategory* getCategory(sal_uInt32 nPos) const override;
+ virtual void fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const override;
+ virtual sal_Unicode getSingleToken(const EToken _eToken) const override;
+
+ std::shared_ptr< FunctionDescription > get(const css::uno::Reference< css::report::meta::XFunctionDescription>& _xFunctionDescription) const;
+};
+
+class FunctionDescription : public formula::IFunctionDescription
+{
+ css::uno::Sequence< css::sheet::FunctionArgument > m_aParameter;
+ css::uno::Reference< css::report::meta::XFunctionDescription> m_xFunctionDescription;
+ const formula::IFunctionCategory* m_pFunctionCategory;
+public:
+ FunctionDescription(const formula::IFunctionCategory* _pFunctionCategory,const css::uno::Reference< css::report::meta::XFunctionDescription>& _xFunctionDescription);
+ virtual ~FunctionDescription(){}
+
+ virtual OUString getFunctionName() const override ;
+ virtual const formula::IFunctionCategory* getCategory() const override ;
+ virtual OUString getDescription() const override ;
+ virtual sal_Int32 getSuppressedArgumentCount() const override ;
+ virtual OUString getFormula(const ::std::vector< OUString >& _aArguments) const override ;
+ virtual void fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const override ;
+ virtual void initArgumentInfo() const override;
+ virtual OUString getSignature() const override ;
+ virtual OString getHelpId() const override ;
+ virtual bool isHidden() const override;
+ virtual sal_uInt32 getParameterCount() const override ;
+ virtual sal_uInt32 getVarArgsStart() const override;
+ virtual sal_uInt32 getVarArgsLimit() const override;
+ virtual OUString getParameterName(sal_uInt32 _nPos) const override ;
+ virtual OUString getParameterDescription(sal_uInt32 _nPos) const override ;
+ virtual bool isParameterOptional(sal_uInt32 _nPos) const override ;
+};
+
+class FunctionCategory : public formula::IFunctionCategory
+{
+ mutable ::std::vector< std::shared_ptr< FunctionDescription > > m_aFunctions;
+ css::uno::Reference< css::report::meta::XFunctionCategory> m_xCategory;
+ sal_uInt32 m_nFunctionCount;
+ sal_uInt32 m_nNumber;
+ const FunctionManager* m_pFunctionManager;
+public:
+ FunctionCategory(const FunctionManager* _pFMgr,sal_uInt32 _nPos,const css::uno::Reference< css::report::meta::XFunctionCategory>& _xCategory);
+ virtual ~FunctionCategory() {}
+
+ virtual sal_uInt32 getCount() const override;
+ virtual const formula::IFunctionDescription* getFunction(sal_uInt32 _nPos) const override;
+ virtual sal_uInt32 getNumber() const override;
+ virtual OUString getName() const override;
+};
+
+} // rptui
+
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FUNCTIONHELPER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/GeometryHandler.hxx b/reportdesign/source/ui/inc/GeometryHandler.hxx
new file mode 100644
index 000000000..13d08414c
--- /dev/null
+++ b/reportdesign/source/ui/inc/GeometryHandler.hxx
@@ -0,0 +1,307 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GEOMETRYHANDLER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GEOMETRYHANDLER_HXX
+
+#include <sal/config.h>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/inspection/XPropertyHandler.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/report/XFunctionsSupplier.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <unotools/resmgr.hxx>
+#include <map>
+#include <memory>
+#include <string_view>
+
+#include <comphelper/interfacecontainer3.hxx>
+#include <comphelper/stl_types.hxx>
+
+
+namespace rptui
+{
+
+
+ struct DefaultFunction
+ {
+ css::beans::Optional< OUString> m_sInitialFormula;
+ OUString m_sName;
+ OUString m_sSearchString;
+ OUString m_sFormula;
+ bool m_bPreEvaluated;
+
+ const OUString& getName() const { return m_sName; }
+ } ;
+
+ class OPropertyInfoService;
+ typedef ::std::pair< css::uno::Reference< css::report::XFunction>, css::uno::Reference< css::report::XFunctionsSupplier> > TFunctionPair;
+ typedef ::std::multimap< OUString,TFunctionPair, ::comphelper::UStringMixLess > TFunctions;
+ typedef ::comphelper::OInterfaceContainerHelper3< css::beans::XPropertyChangeListener > PropertyChangeListeners;
+ typedef ::cppu::WeakComponentImplHelper< css::inspection::XPropertyHandler
+ , css::beans::XPropertyChangeListener
+ , css::lang::XServiceInfo> GeometryHandler_Base;
+
+ class GeometryHandler:
+ private ::cppu::BaseMutex,
+ public GeometryHandler_Base
+ {
+ /** sets the counter function at the data field.
+ * If the counter function doesn't exist it will be created.
+ */
+ void impl_setCounterFunction_throw();
+
+ /** executes a dialog for choosing a filter criterion for a database report
+ @param _out_rSelectedClause
+ the filter or order clause as chosen by the user
+ @precond
+ we're really inspecting a database form (well, a RowSet at least)
+ @return
+ <TRUE/> if and only if the user successfully chose a clause
+ */
+ bool impl_dialogFilter_nothrow( OUString& _out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const;
+
+ /** returns the data field type depending on the data field of the report control
+ *
+ * \param _sDataField if the data field is not empty it will be used as data field, otherwise the data field will be used.
+ * \return the data field type
+ */
+ sal_uInt32 impl_getDataFieldType_throw(const OUString& _sDataField = OUString()) const;
+
+ css::uno::Any getConstantValue(bool bToControlValue,const TranslateId* pResId,const css::uno::Any& _aValue,const OUString& _sConstantName,const OUString & PropertyName );
+ css::beans::Property getProperty(const OUString & PropertyName);
+ static void implCreateListLikeControl(
+ const css::uno::Reference< css::inspection::XPropertyControlFactory >& _rxControlFactory
+ ,css::inspection::LineDescriptor & out_Descriptor
+ ,const TranslateId* pResId
+ ,bool _bReadOnlyControl
+ ,bool _bTrueIfListBoxFalseIfComboBox
+ );
+ static void implCreateListLikeControl(
+ const css::uno::Reference< css::inspection::XPropertyControlFactory >& _rxControlFactory
+ ,css::inspection::LineDescriptor & out_Descriptor
+ ,const ::std::vector< OUString>& _aEntries
+ ,bool _bReadOnlyControl
+ ,bool _bTrueIfListBoxFalseIfComboBox
+ );
+ void checkPosAndSize( const css::awt::Point& _aNewPos,
+ const css::awt::Size& _aSize);
+
+ OUString impl_convertToFormula( const css::uno::Any& _rControlValue );
+
+ void impl_initFieldList_nothrow( css::uno::Sequence< OUString >& _rFieldNames ) const;
+
+ /** Creates the function defined by the function template
+ *
+ * \param _sFunctionName the function name
+ * \param _sDataField the data field
+ * \param _aFunction the function template
+ */
+ void impl_createFunction(const OUString& _sFunctionName,std::u16string_view _sDataField,const DefaultFunction& _aFunction);
+
+ /** check whether the given function name is a counter function.
+ *
+ * \param _sQuotedFunctionName the quoted function name to check
+ * \param Out_sScope the scope of the function
+ * \return When true it is a counter functions otherwise false.
+ */
+ bool impl_isCounterFunction_throw(const OUString& _sQuotedFunctionName,OUString& Out_sScope) const;
+
+ /** clear the own properties like function and scope and send a notification
+ *
+ * \param _aGuard
+ * \param _sOldFunctionName
+ * \param _sOldScope
+ * \param _nOldDataFieldType
+ */
+ void resetOwnProperties(::osl::ResettableMutexGuard& _aGuard,const OUString& _sOldFunctionName,const OUString& _sOldScope,const sal_uInt32 _nOldDataFieldType);
+
+ /** checks whether the name is a field or a parameter
+ *
+ * \param _sName the name to check
+ * \return true when it is a field or parameter otherwise false
+ */
+ bool impl_isDataField(const OUString& _sName) const;
+
+ /**return all formula in a semicolon separated list
+ *
+ * \param _rList the localized function names
+ */
+ void impl_fillFormulaList_nothrow(::std::vector< OUString >& _out_rList) const;
+
+ /** return all group names in a semicolon separated list starting with the group where this control is contained in.
+ *
+ * \param _rList fills the list with all scope names.
+ */
+ void impl_fillScopeList_nothrow(::std::vector< OUString >& _out_rList) const;
+
+ /** return all supported output formats of the report definition
+ *
+ * \param _rList fills the list with all mime types
+ */
+ void impl_fillMimeTypes_nothrow(::std::vector< OUString >& _out_rList) const;
+
+ /** return the one supported output formats of the report definition
+ *
+ * \param _sMimetype the mimetype
+ */
+ OUString impl_ConvertMimeTypeToUI_nothrow(const OUString& _sMimetype) const;
+
+ /** return the MimeType for the given UI Name
+ *
+ * \param _sUIName the doc ui name
+ */
+ OUString impl_ConvertUIToMimeType_nothrow(const OUString& _sUIName) const;
+
+ /** get the functions supplier for the set scope, default is the surrounding group.
+ *
+ * \param _rsNamePostfix the name postfix which can be used when the scope as name part is needed
+ * \return the function supplier
+ */
+ css::uno::Reference< css::report::XFunctionsSupplier> fillScope_throw(OUString& _rsNamePostfix);
+
+ /** checks if the given function is a default function we know.
+ *
+ * \param _sQuotedFunction the quoted function name
+ * \param Out_rDataField the data field which is used in the function
+ * \param _xFunctionsSupplier the function supplier to search or empty if not used
+ * \param _bSet If set to sal_True than the m_sDefaultFunction and m_sScope vars will be set if successful.
+ * \return sal_True with known otherwise sal_False
+ */
+ bool isDefaultFunction(const OUString& _sQuotedFunction
+ ,OUString& Out_rDataField
+ ,const css::uno::Reference< css::report::XFunctionsSupplier>& _xFunctionsSupplier = css::uno::Reference< css::report::XFunctionsSupplier>()
+ ,bool _bSet = false) const;
+
+ /** checks if the given function is a default function we know.
+ *
+ * \param _xFunction
+ * \param _rDataField
+ * \param _rsDefaultFunctionName
+ * \return
+ */
+ bool impl_isDefaultFunction_nothrow( const css::uno::Reference< css::report::XFunction>& _xFunction
+ ,OUString& _rDataField
+ ,OUString& _rsDefaultFunctionName) const;
+
+ /** fills the member m_aDefaultFunctions
+ *
+ */
+ void loadDefaultFunctions();
+
+ /** creates a default function of the _sFunction for the data field _sDataField
+ * The new function will only be created if it didn't exist.
+ *
+ * \param _aGuard Will be cleared, when a new function was created.
+ * \param _sFunction The name of the function.
+ * \param _sDataField The name of the data field.
+ */
+ void createDefaultFunction(::osl::ResettableMutexGuard& _aGuard ,const OUString& _sFunction,std::u16string_view _sDataField);
+
+ void removeFunction();
+
+ class OBlocker
+ {
+ bool& m_bIn;
+ public:
+ OBlocker(bool& _bIn) : m_bIn(_bIn){ m_bIn = true; }
+ ~OBlocker() { m_bIn = false; }
+ };
+
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
+ // XPropertyChangeListener
+ virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent& evt) override;
+
+ public:
+ explicit GeometryHandler(css::uno::Reference< css::uno::XComponentContext > const & context);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName( ) override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ // css::lang::XComponent:
+ virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & xListener) override;
+ virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override;
+
+ // css::inspection::XPropertyHandler:
+ virtual void SAL_CALL inspect(const css::uno::Reference< css::uno::XInterface > & Component) override;
+ virtual css::uno::Any SAL_CALL getPropertyValue(const OUString & PropertyName) override;
+ virtual void SAL_CALL setPropertyValue(const OUString & PropertyName, const css::uno::Any & Value) override;
+ virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString & PropertyName) override;
+ virtual css::inspection::LineDescriptor SAL_CALL describePropertyLine(const OUString& PropertyName, const css::uno::Reference< css::inspection::XPropertyControlFactory >& ControlFactory ) override;
+ virtual css::uno::Any SAL_CALL convertToPropertyValue(const OUString & PropertyName, const css::uno::Any & ControlValue) override;
+ virtual css::uno::Any SAL_CALL convertToControlValue(const OUString & PropertyName, const css::uno::Any & PropertyValue, const css::uno::Type & ControlValueType) override;
+ virtual void SAL_CALL addPropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & Listener) override;
+ virtual void SAL_CALL removePropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & _rxListener) override;
+ virtual css::uno::Sequence< css::beans::Property > SAL_CALL getSupportedProperties() override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupersededProperties() override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getActuatingProperties() override;
+ virtual sal_Bool SAL_CALL isComposable(const OUString & PropertyName) override;
+ virtual css::inspection::InteractiveSelectionResult SAL_CALL onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, css::uno::Any & out_Data, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI) override;
+ virtual void SAL_CALL actuatingPropertyChanged(const OUString & ActuatingPropertyName, const css::uno::Any & NewValue, const css::uno::Any & OldValue, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit) override;
+ virtual sal_Bool SAL_CALL suspend(sal_Bool Suspend) override;
+
+ protected:
+ virtual ~GeometryHandler() override;
+ private:
+ GeometryHandler(GeometryHandler const &) = delete;
+ void operator =(GeometryHandler const &) = delete;
+
+ // override WeakComponentImplHelperBase::disposing()
+ // This function is called upon disposing the component,
+ // if your component needs special work when it becomes
+ // disposed, do it here.
+ virtual void SAL_CALL disposing() override;
+
+ PropertyChangeListeners m_aPropertyListeners;
+ css::uno::Sequence< OUString > m_aFieldNames;
+ css::uno::Sequence< OUString > m_aParamNames;
+ TFunctions m_aFunctionNames;
+ ::std::vector< DefaultFunction > m_aDefaultFunctions;
+ DefaultFunction m_aCounterFunction;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ mutable css::uno::Reference< css::report::XFunction> m_xFunction;
+ css::uno::Reference< css::inspection::XPropertyHandler > m_xFormComponentHandler; /// delegatee
+ css::uno::Reference< css::beans::XPropertySet > m_xReportComponent; /// inspectee
+ mutable css::uno::Reference< css::sdbc::XRowSet > m_xRowSet;
+ /// type converter, needed on various occasions
+ css::uno::Reference< css::script::XTypeConverter > m_xTypeConverter;
+ mutable OUString m_sDefaultFunction;
+ mutable OUString m_sScope;
+ sal_uInt32 m_nDataFieldType;
+ mutable bool m_bNewFunction;
+ bool m_bIn;
+ };
+
+} // namespace rptui
+
+
+#endif // RPT_GeometryHandler_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/GroupsSorting.hxx b/reportdesign/source/ui/inc/GroupsSorting.hxx
new file mode 100644
index 000000000..0418ee1d9
--- /dev/null
+++ b/reportdesign/source/ui/inc/GroupsSorting.hxx
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GROUPSSORTING_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GROUPSSORTING_HXX
+
+#include <com/sun/star/report/XGroups.hpp>
+#include <com/sun/star/report/XGroup.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <comphelper/propmultiplex.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <rtl/ref.hxx>
+#include <vcl/weld.hxx>
+#include <osl/diagnose.h>
+
+namespace comphelper
+{
+ class OPropertyChangeMultiplexer;
+}
+namespace rptui
+{
+class OFieldExpressionControl;
+class OReportController;
+/*************************************************************************
+|*
+|* Groups and Sorting dialog
+|*
+\************************************************************************/
+
+class OGroupsSortingDialog : public weld::GenericDialogController
+ , public ::cppu::BaseMutex
+ , public ::comphelper::OPropertyChangeListener
+{
+ friend class OFieldExpressionControl;
+
+ ::rptui::OReportController* m_pController;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pCurrentGroupListener;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener;
+ css::uno::Reference< css::report::XGroups> m_xGroups;
+ css::uno::Reference< css::container::XNameAccess > m_xColumns;
+ bool m_bReadOnly;
+
+ std::unique_ptr<weld::Toolbar> m_xToolBox;
+ std::unique_ptr<weld::Widget> m_xProperties;
+ std::unique_ptr<weld::ComboBox> m_xOrderLst;
+ std::unique_ptr<weld::ComboBox> m_xHeaderLst;
+ std::unique_ptr<weld::ComboBox> m_xFooterLst;
+ std::unique_ptr<weld::ComboBox> m_xGroupOnLst;
+ std::unique_ptr<weld::SpinButton> m_xGroupIntervalEd;
+ std::unique_ptr<weld::ComboBox> m_xKeepTogetherLst;
+ std::unique_ptr<weld::Label> m_xHelpWindow;
+ std::unique_ptr<weld::Container> m_xBox;
+ css::uno::Reference<css::awt::XWindow> m_xTableCtrlParent;
+ VclPtr<OFieldExpressionControl> m_xFieldExpression;
+
+private:
+ DECL_LINK( OnWidgetFocusLost, weld::Widget&, void );
+ DECL_LINK( OnWidgetFocusGot, weld::Widget&, void );
+
+ DECL_LINK( OnControlFocusGot, LinkParamNone*, void );
+
+ DECL_LINK( LBChangeHdl, weld::ComboBox&, void );
+ DECL_LINK( OnFormatAction, const OString&, void );
+
+ /** returns the groups
+ @return the groups which now have to check which one changes
+ */
+ css::uno::Reference< css::report::XGroups>& getGroups() { return m_xGroups; }
+
+ css::uno::Reference< css::report::XGroup> getGroup(sal_Int32 _nPos)
+ {
+ OSL_ENSURE(_nPos >= 0 && _nPos < m_xGroups->getCount(),"Invalid count!");
+ return css::uno::Reference< css::report::XGroup>(m_xGroups->getByIndex(_nPos),css::uno::UNO_QUERY);
+ }
+
+ /** updates the listboxes with the new group properties
+ @param _nRow the new group pos
+ */
+ void DisplayData( sal_Int32 _nRow );
+
+ /** saves the values from the listboxes into the group at position _nRow
+ @param _nRow the group pos to store in
+ */
+ void SaveData( sal_Int32 _nRow );
+
+ /** returns <TRUE/> when the dialog should be read only
+ */
+ bool isReadOnly( ) const { return m_bReadOnly;}
+
+ /** returns the data type for the given column name
+ @param _sColumnName
+ */
+ sal_Int32 getColumnDataType(const OUString& _sColumnName);
+
+ /** display the group props
+ @param _xGroup the group to display
+ */
+ void displayGroup(const css::uno::Reference< css::report::XGroup>& _xGroup);
+
+ /** enables or disables the up and down button
+ @param _nRow the row which will be active
+ */
+ void checkButtons(sal_Int32 _nRow);
+
+ /** clears the m_xColumns member and reset the fields
+ *
+ */
+ void fillColumns();
+ OGroupsSortingDialog(OGroupsSortingDialog const &) = delete;
+ void operator =(OGroupsSortingDialog const &) = delete;
+protected:
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override;
+public:
+ OGroupsSortingDialog(weld::Window* pParent,
+ bool _bReadOnly,
+ ::rptui::OReportController* _pController);
+ virtual ~OGroupsSortingDialog() override;
+
+ /* updates the current view
+ */
+ void UpdateData( );
+};
+
+} // namespace rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GROUPSSORTING_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/IReportControllerObserver.hxx b/reportdesign/source/ui/inc/IReportControllerObserver.hxx
new file mode 100644
index 000000000..3d9f7e75c
--- /dev/null
+++ b/reportdesign/source/ui/inc/IReportControllerObserver.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_IREPORTCONTROLLEROBSERVER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_IREPORTCONTROLLEROBSERVER_HXX
+
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+
+namespace rptui
+{
+ /* abstract */ class IReportControllerObserver
+ {
+ protected:
+ // IReportControllerObserver(){}
+ virtual ~IReportControllerObserver() {}
+
+ public:
+
+ virtual void notifyPropertyChange( const css::beans::PropertyChangeEvent& _rEvent ) = 0;
+ virtual void notifyElementInserted( const css::uno::Reference< css::uno::XInterface >& _rxElement ) = 0;
+ virtual void handle( const css::uno::Reference< css::uno::XInterface >& _rxElement ) = 0;
+ };
+
+} // namespace rptui
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/MarkedSection.hxx b/reportdesign/source/ui/inc/MarkedSection.hxx
new file mode 100644
index 000000000..2d97645c4
--- /dev/null
+++ b/reportdesign/source/ui/inc/MarkedSection.hxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_MARKEDSECTION_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_MARKEDSECTION_HXX
+
+#include <sal/types.h>
+
+namespace rptui
+{
+ class OSectionWindow;
+
+ enum NearSectionAccess
+ {
+ CURRENT = 0,
+ PREVIOUS = -1,
+ POST = 1
+ };
+
+ class IMarkedSection
+ {
+ public:
+ /** returns the section which is currently marked.
+ */
+ virtual OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const =0;
+
+ /** mark the section on the given position .
+ *
+ * \param _nPos the position is zero based.
+ */
+ virtual void markSection(const sal_uInt16 _nPos) = 0;
+
+ protected:
+ ~IMarkedSection() {}
+ };
+
+} // rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_MARKEDSECTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/Navigator.hxx b/reportdesign/source/ui/inc/Navigator.hxx
new file mode 100644
index 000000000..eed3e529c
--- /dev/null
+++ b/reportdesign/source/ui/inc/Navigator.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_NAVIGATOR_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_NAVIGATOR_HXX
+
+#include <vcl/weld.hxx>
+#include <memory>
+namespace rptui
+{
+ class OReportController;
+ class ONavigatorImpl;
+ class ONavigator : public weld::GenericDialogController
+ {
+ ::std::unique_ptr<ONavigatorImpl> m_pImpl;
+ ONavigator(const ONavigator&) = delete;
+ void operator =(const ONavigator&) = delete;
+
+ DECL_LINK(FocusChangeHdl, weld::Container&, void);
+
+ public:
+ ONavigator(weld::Window* pParent, OReportController& rController);
+ ~ONavigator();
+ };
+
+} // namespace rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_NAVIGATOR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/PageNumber.hxx b/reportdesign/source/ui/inc/PageNumber.hxx
new file mode 100644
index 000000000..eefa10c8b
--- /dev/null
+++ b/reportdesign/source/ui/inc/PageNumber.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PAGENUMBER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PAGENUMBER_HXX
+
+#include <vcl/weld.hxx>
+#include <com/sun/star/report/XReportDefinition.hpp>
+
+namespace rptui
+{
+class OReportController;
+/*************************************************************************
+|*
+|* Groups and Sorting dialog
+|*
+\************************************************************************/
+class OPageNumberDialog : public weld::GenericDialogController
+{
+ ::rptui::OReportController* m_pController;
+ css::uno::Reference< css::report::XReportDefinition>
+ m_xHoldAlive;
+ std::unique_ptr<weld::RadioButton> m_xPageN;
+ std::unique_ptr<weld::RadioButton> m_xPageNofM;
+ std::unique_ptr<weld::RadioButton> m_xTopPage;
+ std::unique_ptr<weld::RadioButton> m_xBottomPage;
+ std::unique_ptr<weld::ComboBox> m_xAlignmentLst;
+ std::unique_ptr<weld::CheckButton> m_xShowNumberOnFirstPage;
+
+ OPageNumberDialog(const OPageNumberDialog&) = delete;
+ void operator =(const OPageNumberDialog&) = delete;
+public:
+ OPageNumberDialog(weld::Window* pParent,
+ const css::uno::Reference< css::report::XReportDefinition>& _xHoldAlive,
+ ::rptui::OReportController* _pController);
+ virtual ~OPageNumberDialog() override;
+ virtual short run() override;
+};
+
+} // namespace rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PAGENUMBER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ReportComponentHandler.hxx b/reportdesign/source/ui/inc/ReportComponentHandler.hxx
new file mode 100644
index 000000000..fdf4ad0e6
--- /dev/null
+++ b/reportdesign/source/ui/inc/ReportComponentHandler.hxx
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCOMPONENTHANDLER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCOMPONENTHANDLER_HXX
+
+#include <sal/config.h>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <com/sun/star/inspection/XPropertyHandler.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+
+namespace rptui
+{
+
+
+ class OPropertyInfoService;
+
+ typedef ::cppu::WeakComponentImplHelper< css::inspection::XPropertyHandler
+ , css::lang::XServiceInfo> ReportComponentHandler_Base;
+
+ class ReportComponentHandler:
+ private ::cppu::BaseMutex,
+ public ReportComponentHandler_Base
+ {
+ public:
+ explicit ReportComponentHandler(css::uno::Reference< css::uno::XComponentContext > const & context);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName( ) override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ // css::lang::XComponent:
+ virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & xListener) override;
+ virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override;
+
+ // css::inspection::XPropertyHandler:
+ virtual void SAL_CALL inspect(const css::uno::Reference< css::uno::XInterface > & Component) override;
+ virtual css::uno::Any SAL_CALL getPropertyValue(const OUString & PropertyName) override;
+ virtual void SAL_CALL setPropertyValue(const OUString & PropertyName, const css::uno::Any & Value) override;
+ virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString & PropertyName) override;
+ virtual css::inspection::LineDescriptor SAL_CALL describePropertyLine(const OUString& PropertyName, const css::uno::Reference< css::inspection::XPropertyControlFactory >& ControlFactory ) override;
+ virtual css::uno::Any SAL_CALL convertToPropertyValue(const OUString & PropertyName, const css::uno::Any & ControlValue) override;
+ virtual css::uno::Any SAL_CALL convertToControlValue(const OUString & PropertyName, const css::uno::Any & PropertyValue, const css::uno::Type & ControlValueType) override;
+ virtual void SAL_CALL addPropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & Listener) override;
+ virtual void SAL_CALL removePropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & _rxListener) override;
+ virtual css::uno::Sequence< css::beans::Property > SAL_CALL getSupportedProperties() override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupersededProperties() override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getActuatingProperties() override;
+ virtual sal_Bool SAL_CALL isComposable(const OUString & PropertyName) override;
+ virtual css::inspection::InteractiveSelectionResult SAL_CALL onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, css::uno::Any & out_Data, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI) override;
+ virtual void SAL_CALL actuatingPropertyChanged(const OUString & ActuatingPropertyName, const css::uno::Any & NewValue, const css::uno::Any & OldValue, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit) override;
+ virtual sal_Bool SAL_CALL suspend(sal_Bool Suspend) override;
+
+ protected:
+ virtual ~ReportComponentHandler() override {}
+ private:
+ ReportComponentHandler(ReportComponentHandler const &) = delete;
+ void operator =(ReportComponentHandler const &) = delete;
+
+
+ // override WeakComponentImplHelperBase::disposing()
+ // This function is called upon disposing the component,
+ // if your component needs special work when it becomes
+ // disposed, do it here.
+ virtual void SAL_CALL disposing() override;
+
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::inspection::XPropertyHandler > m_xFormComponentHandler; /// delegatee
+ css::uno::Reference< css::uno::XInterface > m_xFormComponent; /// inspectee
+ };
+
+} // namespace rptui
+
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCOMPONENTHANDLER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ReportController.hxx b/reportdesign/source/ui/inc/ReportController.hxx
new file mode 100644
index 000000000..726ac8012
--- /dev/null
+++ b/reportdesign/source/ui/inc/ReportController.hxx
@@ -0,0 +1,450 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLER_HXX
+
+#include "DesignView.hxx"
+#include "ReportControllerObserver.hxx"
+#include <RptDef.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/embed/XVisualObject.hpp>
+#include <com/sun/star/frame/XDesktop2.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/report/XReportDefinition.hpp>
+#include <com/sun/star/report/XReportEngine.hpp>
+#include <com/sun/star/report/XSection.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/XModeSelector.hpp>
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/propertystatecontainer.hxx>
+#include <comphelper/uno3.hxx>
+#include <cppuhelper/implbase5.hxx>
+#include <comphelper/interfacecontainer3.hxx>
+#include <dbaccess/dbsubcomponentcontroller.hxx>
+#include <svl/lstner.hxx>
+#include <vcl/transfer.hxx>
+#include <sfx2/zoomitem.hxx>
+
+#include <functional>
+#include <memory>
+
+class TransferableClipboardListener;
+class VclWindowEvent;
+class SfxUndoManager;
+namespace rptui
+{
+ class OGroupsSortingDialog;
+ class OReportModel;
+ class OSectionView;
+ class OAddFieldWindow;
+ class OSectionWindow;
+
+ typedef ::dbaui::DBSubComponentController OReportController_BASE;
+ typedef ::cppu::ImplHelper5 < css::container::XContainerListener
+ , css::beans::XPropertyChangeListener
+ , css::view::XSelectionSupplier
+ , css::util::XModeSelector
+ , css::embed::XVisualObject
+ > OReportController_Listener;
+
+ class OReportController : public OReportController_BASE
+ ,public OReportController_Listener
+ ,public SfxListener
+ ,public ::comphelper::OPropertyStateContainer
+ ,public ::comphelper::OPropertyArrayUsageHelper < OReportController_BASE >
+ {
+ private:
+ ::comphelper::OInterfaceContainerHelper3<css::view::XSelectionChangeListener>
+ m_aSelectionListeners;
+ css::uno::Sequence< css::beans::PropertyValue>
+ m_aCollapsedSections;
+ TransferableDataHelper m_aSystemClipboard; // content of the clipboard
+ rtl::Reference<TransferableClipboardListener>
+ m_pClipboardNotifier; /// notifier for changes in the clipboard
+ std::shared_ptr<OGroupsSortingDialog> m_xGroupsFloater;
+
+ rtl::Reference<OXReportControllerObserver> m_pReportControllerObserver;
+
+ ODesignView* getDesignView() const { return static_cast< ODesignView* >( getView() ); }
+
+ css::uno::Reference< css::report::XReportDefinition > m_xReportDefinition;
+ css::uno::Reference< css::report::XReportEngine > m_xReportEngine;
+ css::uno::Reference< css::frame::XDesktop2 > m_xFrameLoader;
+ css::uno::Reference< css::sdbc::XRowSet > m_xRowSet;
+ css::uno::Reference< css::beans::XPropertyChangeListener > m_xRowSetMediator;
+ css::uno::Reference< css::util::XNumberFormatter > m_xFormatter; // a number formatter working with the report's NumberFormatsSupplier
+ mutable css::uno::Reference< css::lang::XComponent > m_xHoldAlive;
+ mutable css::uno::Reference< css::container::XNameAccess > m_xColumns;
+ css::awt::Size m_aVisualAreaSize;
+
+ std::shared_ptr<rptui::OReportModel>
+ m_aReportModel;
+ OUString m_sName; /// name for the report definition
+ OUString m_sLastActivePage; /// last active property browser page
+ OUString m_sMode; /// the current mode of the controller
+ sal_Int32 m_nSplitPos; /// the position of the splitter
+ sal_Int32 m_nPageNum; /// the page number from the restoreView call
+ sal_Int32 m_nSelectionCount;
+ ::sal_Int64 m_nAspect;
+ sal_Int16 m_nZoomValue;
+ SvxZoomType m_eZoomType;
+ bool m_bShowRuler;
+ bool m_bGridVisible;
+ bool m_bGridUse;
+ bool m_bShowProperties;
+ bool m_bHelplinesMove;
+ bool m_bChartEnabled;
+ bool m_bChartEnabledAsked;
+ bool m_bInGeneratePreview;
+
+ /** creates a formatted field in the given section with the given formula as data field
+ *
+ * \param _aArgs
+ * \param _xSection the section where to create the formatted field
+ * \param _sFunction the function which will be set at the data field.
+ */
+ void createControl(const css::uno::Sequence< css::beans::PropertyValue >& _aArgs,const css::uno::Reference< css::report::XSection>& _xSection,const OUString& _sFunction ,SdrObjKind _nObjectId = SdrObjKind::ReportDesignFormattedField);
+ /** switch the report header/footer sectionon off with undo or without depending on the given id.
+ *
+ * \param _nId Can either be SID_REPORTHEADER_WITHOUT_UNDO or SID_REPORTFOOTER_WITHOUT_UNDO or SID_REPORTHEADERFOOTER.
+ */
+ void switchReportSection(const sal_Int16 _nId);
+
+ /** switch the report header/footer sectionon off with undo or without depending on the given id.
+ *
+ * \param _nId Can either be SID_PAGEHEADER_WITHOUT_UNDO or SID_PAGEFOOTER_WITHOUT_UNDO or SID_PAGEHEADERFOOTER.
+ */
+ void switchPageSection(const sal_Int16 _nId);
+
+ /** append a new group or remove it with undo.
+ *
+ * \param _bAppend
+ * \param _aArgs The args which contains an element named PROPERTY_GROUP of type report::XGroup.
+ */
+ void modifyGroup(const bool _bAppend, const css::uno::Sequence< css::beans::PropertyValue >& _aArgs);
+
+ /** creates a group section.
+ *
+ * \param _bUndo true when undo action should be created
+ * \param _bHeader true when it is a header otherwise it is a footer
+ * \param _aArgs The args which contains an element named PROPERTY_GROUP of type report::XGroup.
+ */
+ void createGroupSection(const bool _bUndo,const bool _bHeader,const css::uno::Sequence< css::beans::PropertyValue >&_aArgs);
+
+ /** add or remove me as listener at the report definition
+ *
+ * \param _bAdd
+ */
+ void listen(const bool _bAdd);
+
+ /** opens the common page dialog
+ */
+ void openPageDialog(const css::uno::Reference< css::report::XSection>& _xSection);
+
+ /** opens or hides the sorting and grouping dialog
+ */
+ void openSortingAndGroupingDialog();
+
+ /** opens the zoom dialog
+ */
+ void openZoomDialog();
+
+ /** returns the position of the group inside the groups collection
+ */
+ sal_Int32 getGroupPosition(const css::uno::Reference< css::report::XGroup >& _xGroup);
+
+ /** calls propertyChanged when the header or footer is really turned on.
+ @param _rEvent the group
+ @param _bShow when <TRUE/> the header and footer will be shown otherwise not
+ */
+ void notifyGroupSections(const css::container::ContainerEvent& _rEvent
+ ,bool _bShow);
+
+ /** change the sections for a group
+ @param _sPropName the header or footer
+ @param _xGroup the group
+ @param _nGroupPos the position of the group inside the groups collection or the previous index when it was removed
+ @param _bShow when <TRUE/> the header and footer will be shown otherwise not
+ */
+ void groupChange( const css::uno::Reference< css::report::XGroup>& _xGroup
+ ,std::u16string_view _sPropName
+ ,sal_Int32 _nGroupPos
+ ,bool _bShow);
+
+ void executeMethodWithUndo(TranslateId pUndoStrId,const ::std::function<void(ODesignView *)>& _pMemfun);
+ void alignControlsWithUndo(TranslateId pUndoStrId, ControlModification _nControlModification, bool _bAlignAtSection = false);
+
+ css::uno::Reference< css::frame::XFrame > getXFrame();
+
+ /** shrink a section
+ @param pUndoStrId the string id of the string which is shown in undo menu
+ @param _nShrinkId ID of what you would like to shrink.
+ */
+ static void shrinkSectionBottom(const css::uno::Reference< css::report::XSection >& _xSection);
+ static void shrinkSectionTop(const css::uno::Reference< css::report::XSection >& _xSection);
+
+ public:
+ void shrinkSection(TranslateId pUndoStrId, const css::uno::Reference< css::report::XSection >& _xSection, sal_Int32 _nShrinkId);
+
+ /** opens the file open dialog to allow the user to select an image which will be
+ * bound to a newly created image button.
+ */
+ void insertGraphic();
+
+ /** creates a new function in the given value context
+ *
+ * \param _aValue contains a XNameContainer
+ */
+ void createNewFunction(const css::uno::Any& _aValue);
+
+ /** inserts a label - field pair into the current selected section
+ *
+ * \param aArgs
+ */
+ void addPairControls(const css::uno::Sequence< css::beans::PropertyValue >& aArgs);
+
+ /** inserts a label - field combination to show the page number and/or page count
+ *
+ * \param _aArgs
+ */
+ void createPageNumber(const css::uno::Sequence< css::beans::PropertyValue >& _aArgs);
+
+ /** creates a formatted field with TODAY() function and if set also a NOW() function
+ *
+ * \param _aArgs
+ */
+ void createDateTime(const css::uno::Sequence< css::beans::PropertyValue >& _aArgs);
+
+ /** gets the current section (SdrView)
+ *
+ * \return the currently selected section or <NULL/> if no one is selected
+ */
+ OSectionView* getCurrentSectionView() const;
+
+ /**change the ZOrder of a current select object.
+ *
+ * \param _nId The command ID about what to do.
+ */
+ void changeZOrder(sal_Int32 _nId);
+
+ /** marks the next or previous section, when the first/last section was already selected then the report will be selected.
+ *
+ * \param _bNext
+ */
+ void markSection(const bool _bNext);
+
+ /** collapse or expand the currently selected section.
+ *
+ * \param _bCollapse collapse if sal_True otherwise expand
+ */
+ void collapseSection(const bool _bCollapse);
+
+ /** fills the member that chart is enabled or not
+ *
+ */
+ void checkChartEnabled();
+
+ /** set the zoom factor at the design view
+ */
+ void impl_zoom_nothrow();
+
+ virtual void impl_onModifyChanged() override;
+
+ virtual void onLoadedMenu( const css::uno::Reference< css::frame::XLayoutManager >& _xLayoutManager ) override;
+ virtual void impl_initialize( ) override;
+ bool isUiVisible() const;
+
+ /** creates a new default control for the currently set type when the modifier KEY_MOD1 was pressed
+ * \param _aArgs must contain a propertyvalue with name "KeyModifier" and value KEY_MOD1 when control should be created.
+ */
+ void createDefaultControl(const css::uno::Sequence< css::beans::PropertyValue>& _aArgs);
+
+ /** fills the state for the feature request.
+ @param _sProperty the property which should be filled in the value
+ @param _rState the state to fill
+ */
+ void impl_fillState_nothrow(const OUString& _sProperty,dbaui::FeatureState& _rState) const;
+ void impl_fillCustomShapeState_nothrow(const char* _pCustomShapeType,dbaui::FeatureState& _rState) const;
+
+ /** set the property at all selected controls.
+ @return <TRUE/> when the selection is not empty
+ */
+ bool impl_setPropertyAtControls_throw(TranslateId pUndoResId
+ ,const OUString& _sProperty
+ ,const css::uno::Any& _aValue
+ ,const css::uno::Sequence< css::beans::PropertyValue >& _aArgs);
+
+ void OnInvalidateClipboard();
+ DECL_LINK( OnClipboardChanged, TransferableDataHelper*, void );
+ DECL_LINK( OnExecuteReport, void*, void );
+ // all the features which should be handled by this class
+ virtual void describeSupportedFeatures() override;
+ // state of a feature. 'feature' may be the handle of a css::util::URL somebody requested a dispatch interface for OR a toolbar slot.
+ virtual dbaui::FeatureState GetState(sal_uInt16 nId) const override;
+ // execute a feature
+ virtual void Execute(sal_uInt16 nId, const css::uno::Sequence< css::beans::PropertyValue>& aArgs) override;
+
+ virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, css::uno::Any& _rDefault ) const override;
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const css::uno::Any& rValue) override;
+
+ private:
+ virtual ~OReportController() override;
+
+ public:
+ explicit OReportController(css::uno::Reference< css::uno::XComponentContext > const & the_context);
+ OReportController(const OReportController&) = delete;
+ OReportController& operator=(const OReportController&) = delete;
+
+ DECL_LINK( OnCreateHdl, OAddFieldWindow&, void);
+
+ DECLARE_XINTERFACE( )
+ DECLARE_XTYPEPROVIDER( )
+
+ // SfxListener
+ virtual void Notify(SfxBroadcaster & rBc, SfxHint const & rHint) override;
+
+ /** returns <TRUE/> when the command is enabled
+ @param _nCommand the command id
+ @param _xControlFormat the report control format
+ */
+ static bool isFormatCommandEnabled(sal_uInt16 _nCommand
+ ,const css::uno::Reference< css::report::XReportControlFormat>& _xControlFormat);
+
+ virtual bool Construct(vcl::Window* pParent) override;
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
+
+ // css::frame::XController
+ virtual sal_Bool SAL_CALL suspend(sal_Bool bSuspend) override;
+
+ // css::lang::XComponent
+ virtual void SAL_CALL disposing() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual css::uno::Sequence< OUString> SAL_CALL getSupportedServiceNames() override;
+
+ // css::container::XContainerListener
+ virtual void SAL_CALL elementInserted(const css::container::ContainerEvent& Event) override;
+ virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent& Event) override;
+ virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent& Event) override;
+
+ // XPropertyChangeListener
+ virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override;
+
+ // XSelectionSupplier
+ virtual sal_Bool SAL_CALL select( const css::uno::Any& xSelection ) override;
+ virtual css::uno::Any SAL_CALL getSelection( ) override;
+ virtual void SAL_CALL addSelectionChangeListener( const css::uno::Reference< css::view::XSelectionChangeListener >& xListener ) override;
+ virtual void SAL_CALL removeSelectionChangeListener( const css::uno::Reference< css::view::XSelectionChangeListener >& xListener ) override;
+
+ // css::frame::XController
+ virtual sal_Bool SAL_CALL attachModel(const css::uno::Reference< css::frame::XModel > & xModel) override;
+ virtual css::uno::Any SAL_CALL getViewData() override;
+ virtual void SAL_CALL restoreViewData(const css::uno::Any& Data) override;
+
+ /** gives access to the report definition
+ * \return the report definition object, may be <NULL/>
+ */
+ const css::uno::Reference< css::report::XReportDefinition>& getReportDefinition() const { return m_xReportDefinition; }
+
+ // css::frame::XController
+ virtual css::uno::Reference< css::frame::XModel > SAL_CALL getModel() override;
+
+ // XTitle
+ virtual OUString SAL_CALL getTitle( ) override;
+
+ // XModeSelector
+ virtual void SAL_CALL setMode( const OUString& aMode ) override ;
+ virtual OUString SAL_CALL getMode( ) override ;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedModes( ) override ;
+ virtual sal_Bool SAL_CALL supportsMode( const OUString& aMode ) override ;
+
+ // XVisualObject
+ virtual void SAL_CALL setVisualAreaSize( ::sal_Int64 nAspect, const css::awt::Size& aSize ) override;
+ virtual css::awt::Size SAL_CALL getVisualAreaSize( ::sal_Int64 nAspect ) override;
+ virtual css::embed::VisualRepresentation SAL_CALL getPreferredVisualRepresentation( ::sal_Int64 nAspect ) override;
+ virtual ::sal_Int32 SAL_CALL getMapUnit( ::sal_Int64 nAspect ) override;
+
+
+ /** returns the current position of the splitter
+ *
+ * \return
+ */
+ sal_Int32 getSplitPos() const { return m_nSplitPos;}
+ void setSplitPos(sal_Int32 _nSplitPos) { m_nSplitPos = _nSplitPos;}
+
+ /** creates a new report from the report definition.
+ *
+ * \return The model or <NULL/> if the model could not be created.
+ */
+ css::uno::Reference< css::frame::XModel> executeReport();
+
+ /** returns the RowSet which reflects the current settings of the report definition
+
+ The caller is allowed to hold a reference to the RowSet - it is kept alive as long
+ as the controller lives, and it's settings will follow the report definition's settings.
+ */
+ css::uno::Reference< css::sdbc::XRowSet > const & getRowSet();
+
+ /** returns the number formatter
+ */
+ const css::uno::Reference< css::util::XNumberFormatter >& getReportNumberFormatter() const { return m_xFormatter;}
+
+ /** return the SdrModel of the real model
+ *
+ * \return
+ */
+ const std::shared_ptr<rptui::OReportModel>& getSdrModel() const { return m_aReportModel;}
+
+ const css::uno::Reference< css::uno::XComponentContext >& getContext() const { return m_xContext; }
+ sal_Int16 getZoomValue() const { return m_nZoomValue; }
+ void resetZoomType() { m_eZoomType = SvxZoomType::PERCENT; }
+
+ // css::beans::XPropertySet
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override
+ {
+ return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
+ }
+ // comphelper::OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override;
+
+ // cppu::OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
+
+ OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const;
+
+ css::uno::Reference< css::container::XNameAccess > const & getColumns() const;
+ OUString getColumnLabel_throw(const OUString& i_sColumnName) const;
+
+ SfxUndoManager& getUndoManager() const;
+ void clearUndoManager() const;
+ void addUndoAction( std::unique_ptr<SfxUndoAction> i_pAction );
+ };
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ReportControllerObserver.hxx b/reportdesign/source/ui/inc/ReportControllerObserver.hxx
new file mode 100644
index 000000000..d77fb3f2e
--- /dev/null
+++ b/reportdesign/source/ui/inc/ReportControllerObserver.hxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLEROBSERVER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLEROBSERVER_HXX
+
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <cppuhelper/implbase.hxx>
+
+#include <memory>
+
+#include <tools/link.hxx>
+
+#include "FormattedFieldBeautifier.hxx"
+#include "FixedTextColor.hxx"
+
+class VclSimpleEvent;
+
+namespace rptui
+{
+ class OReportController;
+ class OXReportControllerObserverImpl;
+
+
+ class OXReportControllerObserver
+ : public ::cppu::WeakImplHelper< css::beans::XPropertyChangeListener
+ , css::container::XContainerListener
+ , css::util::XModifyListener
+ >
+ {
+
+ const ::std::unique_ptr<OXReportControllerObserverImpl> m_pImpl;
+
+ FormattedFieldBeautifier m_aFormattedFieldBeautifier;
+ FixedTextColor m_aFixedTextColor;
+
+ // do not allow copy
+ OXReportControllerObserver(const OXReportControllerObserver&) = delete;
+ OXReportControllerObserver& operator=(const OXReportControllerObserver&) = delete;
+ virtual ~OXReportControllerObserver() override; // UNO Object must have private destructor!
+ public:
+ OXReportControllerObserver(const OReportController& _rController);
+
+ // XPropertyChangeListener
+ virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent& evt) override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
+
+ // XContainerListener
+ virtual void SAL_CALL elementInserted(const css::container::ContainerEvent& rEvent) override;
+ virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent& rEvent) override;
+ virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent& rEvent) override;
+
+ // XModifyListener
+ virtual void SAL_CALL modified( const css::lang::EventObject& aEvent ) override;
+
+
+ void AddElement(const css::uno::Reference< css::uno::XInterface>& Element);
+ void RemoveElement(const css::uno::Reference< css::uno::XInterface>& Element);
+
+ void AddSection( const css::uno::Reference< css::report::XSection>& _xSection);
+ void RemoveSection( const css::uno::Reference< css::report::XSection>& _xSection );
+
+ /**
+ Create an object ob OUndoEnvLock locks the undo possibility
+ As long as in the OUndoEnvLock scope, no undo is possible for manipulated object.
+ */
+ class OEnvLock
+ {
+ OXReportControllerObserver& m_rObserver;
+ public:
+ OEnvLock(OXReportControllerObserver& _rObserver): m_rObserver(_rObserver){m_rObserver.Lock();}
+ ~OEnvLock(){ m_rObserver.UnLock(); }
+ };
+
+ void Lock();
+ void UnLock();
+
+ void Clear();
+ private:
+
+ void switchListening( const css::uno::Reference< css::container::XIndexAccess >& _rxContainer, bool _bStartListening );
+ void switchListening( const css::uno::Reference< css::uno::XInterface >& _rxObject, bool _bStartListening );
+
+ DECL_LINK(SettingsChanged, VclSimpleEvent&, void );
+ };
+
+} // namespace rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLEROBSERVER_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ReportDefines.hxx b/reportdesign/source/ui/inc/ReportDefines.hxx
new file mode 100644
index 000000000..c56e20841
--- /dev/null
+++ b/reportdesign/source/ui/inc/ReportDefines.hxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTDEFINES_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTDEFINES_HXX
+
+namespace rptui
+{
+ enum class DlgEdMode { Insert, Select };
+
+#define REPORT_STARTMARKER_WIDTH 120
+#define REPORT_ENDMARKER_WIDTH 10
+#define REPORT_EXTRA_SPACE 10
+
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTDEFINES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ReportSection.hxx b/reportdesign/source/ui/inc/ReportSection.hxx
new file mode 100644
index 000000000..03bb57199
--- /dev/null
+++ b/reportdesign/source/ui/inc/ReportSection.hxx
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTSECTION_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTSECTION_HXX
+
+#include <vcl/window.hxx>
+#include <RptPage.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <comphelper/propmultiplex.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include "ReportDefines.hxx"
+#include "dlgedfunc.hxx"
+#include <vcl/transfer.hxx>
+#include <rtl/ref.hxx>
+#include <memory>
+
+namespace rptui
+{
+ class OReportModel;
+ class OReportPage;
+ class OSectionView;
+ class OSectionWindow;
+
+ class OReportSection : public vcl::Window
+ , public ::cppu::BaseMutex
+ , public ::comphelper::OPropertyChangeListener
+ , public DropTargetHelper
+ {
+ OReportPage* m_pPage;
+ OSectionView* m_pView;
+ VclPtr<OSectionWindow> m_pParent;
+ ::std::unique_ptr<DlgEdFunc> m_pFunc;
+ std::shared_ptr<OReportModel> m_pModel;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pMulti;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener;
+ css::uno::Reference< css::report::XSection > m_xSection;
+ sal_Int32 m_nPaintEntranceCount;
+
+ DlgEdMode m_eMode;
+
+ /** fills the section with all control from the report section
+ */
+ void fill();
+ /** checks all objects if they fit in the new paper width.
+ */
+ void impl_adjustObjectSizePosition(sal_Int32 i_nPaperWidth,sal_Int32 i_nLeftMargin,sal_Int32 i_nRightMargin);
+
+ OReportSection(OReportSection const &) = delete;
+ void operator =(OReportSection const &) = delete;
+ protected:
+ // DropTargetHelper overridables
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& _rEvt ) override;
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& _rEvt ) override;
+
+ // window overrides
+ virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
+ virtual void MouseMove( const MouseEvent& rMEvt ) override;
+ virtual void Command( const CommandEvent& rCEvt ) override;
+
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override;
+ public:
+ OReportSection(OSectionWindow* _pParent,const css::uno::Reference< css::report::XSection >& _xSection);
+ virtual ~OReportSection() override;
+ virtual void dispose() override;
+
+ // window overrides
+ virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
+ virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
+
+ /** copies the current selection in this section
+ @param _rAllreadyCopiedObjects This is an out/in put param which contains all already copied objects.
+ */
+ void Copy(css::uno::Sequence< css::beans::NamedValue >& _rAllreadyCopiedObjects);
+
+ void Copy(css::uno::Sequence< css::beans::NamedValue >& _rAllreadyCopiedObjects,bool _bEraseAnddNoClone);
+
+ /** paste a new control in this section
+ @param _aAllreadyCopiedObjects objects to paste into the section. Only objects are pasted where the name is equal to the section name.
+ @param _bForce If set to <TRUE/> than the objects will be copied into this section. The name is not compared in this case.
+ */
+ void Paste(const css::uno::Sequence< css::beans::NamedValue >& _aAllreadyCopiedObjects,bool _bForce = false);
+
+ /** Deletes the current selection in this section
+ *
+ */
+ void Delete();
+
+ /** All objects will be marked.
+ */
+ void SelectAll(const SdrObjKind _nObjectType);
+
+ /** makes the grid visible
+ *
+ * \param _bVisible when <TRUE/> the grid is made visible
+ */
+ void SetGridVisible(bool _bVisible);
+
+ OSectionWindow* getSectionWindow() const { return m_pParent; }
+ OSectionView& getSectionView() const { return *m_pView; }
+ OReportPage* getPage() const { return m_pPage; }
+ const css::uno::Reference< css::report::XSection >& getSection() const { return m_xSection; }
+
+ void SetMode( DlgEdMode m_eMode );
+
+ /** checks if the keycode is known by the child windows
+ @param _rCode the keycode
+ @return <TRUE/> if the keycode is handled otherwise <FALSE/>
+ */
+ bool handleKeyEvent(const KeyEvent& _rEvent);
+
+ /** returns the current control report model or <NULL/>
+ */
+ css::uno::Reference< css::report::XReportComponent > getCurrentControlModel() const;
+
+ /** fills the vector with all selected control models
+ /param _rSelection The vector will be filled and will not be cleared before.
+ */
+ void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const;
+
+ /** creates a default object (custom shape)
+ *
+ * @param _sType
+ */
+ void createDefault(const OUString& _sType);
+
+ /** creates a new default custom shape
+ *
+ * \param _sType
+ * \param _pObj
+ */
+ static void createDefault(const OUString& _sType,SdrObject* _pObj);
+ void stopScrollTimer();
+
+ /** deactivate the current active ole object if any
+ */
+ void deactivateOle();
+
+ /** returns true when an ole object is currently active
+ */
+ bool isUiActive() const;
+ };
+
+} //rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTSECTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ReportWindow.hxx b/reportdesign/source/ui/inc/ReportWindow.hxx
new file mode 100644
index 000000000..7e1716384
--- /dev/null
+++ b/reportdesign/source/ui/inc/ReportWindow.hxx
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTWINDOW_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTWINDOW_HXX
+
+#include <com/sun/star/report/XSection.hpp>
+#include "ReportDefines.hxx"
+#include <o3tl/deleter.hxx>
+#include <svtools/ruler.hxx>
+#include <sfx2/zoomitem.hxx>
+
+#include <memory>
+#include <vector>
+#include <comphelper/propmultiplex.hxx>
+
+#include "MarkedSection.hxx"
+#include "ViewsWindow.hxx"
+
+namespace rptui
+{
+ class ODesignView;
+ class OScrollWindowHelper;
+ class OSectionView;
+ class DlgEdFactory;
+
+ class OReportWindow : public vcl::Window
+ , public IMarkedSection
+ , public ::cppu::BaseMutex
+ , public ::comphelper::OPropertyChangeListener
+ {
+ VclPtr<Ruler> m_aHRuler;
+ VclPtr<ODesignView> m_pView;
+ VclPtr<OScrollWindowHelper> m_pParent;
+ VclPtr<OViewsWindow> m_aViewsWindow;
+ rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener;
+ std::unique_ptr<DlgEdFactory, o3tl::default_delete<DlgEdFactory>> m_pObjFac;
+
+ void ImplInitSettings();
+
+ sal_Int32 GetTotalHeight() const;
+ sal_Int32 impl_getRealPixelWidth() const;
+
+ OReportWindow(OReportWindow const &) = delete;
+ void operator =(OReportWindow const &) = delete;
+ protected:
+ virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override;
+ public:
+ OReportWindow(OScrollWindowHelper* _pParent,ODesignView* _pView);
+ virtual ~OReportWindow() override;
+ virtual void dispose() override;
+
+ // Window overrides
+ virtual void Resize() override;
+
+ ODesignView* getReportView() const { return m_pView; }
+ OScrollWindowHelper* getScrollWindow() const { return m_pParent; }
+
+ void SetMode( DlgEdMode m_eMode );
+ void SetInsertObj(SdrObjKind eObj, const OUString& _sShapeType);
+ OUString const & GetInsertObjString() const;
+ void setGridSnap(bool bOn);
+ void setDragStripes(bool bOn);
+
+ /** copies the current selection in this section
+ */
+ void Copy();
+
+ /** returns if paste is allowed
+ *
+ * \return <TRUE/> if paste is allowed
+ */
+ bool IsPasteAllowed() const;
+
+ /** paste a new control in this section
+ */
+ void Paste();
+
+ /** Deletes the current selection in this section
+ *
+ */
+ void Delete();
+
+ /** All objects will be marked.
+ */
+ void SelectAll(const SdrObjKind _nObjectType);
+
+ /** returns <TRUE/> when an object is marked
+ */
+ bool HasSelection() const;
+
+ Point getThumbPos() const;
+
+ /** removes the section at the given position.
+ *
+ * \param _nPosition Zero based.
+ */
+ void removeSection(sal_uInt16 _nPosition);
+
+ /** adds a new section at position _nPosition.
+ If the section is <NULL/> nothing happens.
+ If the position is grater than the current elements, the section will be appended.
+ */
+ void addSection(const css::uno::Reference< css::report::XSection >& _xSection
+ ,const OUString& _sColorEntry
+ ,sal_uInt16 _nPosition);
+
+ sal_uInt16 getSectionCount() const;
+
+ /** turns the grid on or off
+ *
+ * \param _bVisible
+ */
+ void toggleGrid(bool _bVisible);
+
+
+ /** shows the ruler
+ */
+ void showRuler(bool _bShow);
+
+ sal_Int32 getRulerHeight() const { return m_aHRuler->GetSizePixel().Height(); }
+
+ /** returns the total width of the first section
+ */
+ sal_Int32 GetTotalWidth() const;
+
+ /** calculate the max width of the markers
+ * The end marker will not be used for calculation.
+ *
+ * \return the max width
+ */
+ sal_Int32 getMaxMarkerWidth() const;
+
+ void ScrollChildren(const Point& _aThumbPos);
+
+ void notifySizeChanged();
+
+ /** unmark all objects on the views without the given one.
+ */
+ void unmarkAllObjects();
+
+ /** triggers the property browser with the report component or section
+ @param _xReportComponent
+ */
+ void showProperties( const css::uno::Reference< css::report::XSection>& _xReportComponent);
+
+ /** checks if the keycode is known by the child windows
+ @param _rCode the keycode
+ @return <TRUE/> if the keycode is handled otherwise <FALSE/>
+ */
+ bool handleKeyEvent(const KeyEvent& _rEvent);
+
+ /** the section as marked or not marked
+ @param _pSectionView the section where to set the marked flag
+ @param _bMark the marked flag
+ */
+ void setMarked(OSectionView const * _pSectionView, bool _bMark);
+ void setMarked(const css::uno::Reference< css::report::XSection>& _xSection, bool _bMark);
+ void setMarked(const css::uno::Sequence< css::uno::Reference< css::report::XReportComponent> >& _xShape, bool _bMark);
+
+ // IMarkedSection
+ OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const override;
+ OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const;
+ virtual void markSection(const sal_uInt16 _nPos) override;
+
+
+ /** fills the positions of all collapsed sections.
+ *
+ * \param _rCollapsedPositions Out parameter which holds afterwards all positions of the collapsed sections.
+ */
+ void fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const;
+
+ /** collapse all sections given by their position
+ *
+ * \param _aCollapsedSections The position of the sections which should be collapsed.
+ */
+ void collapseSections(const css::uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections);
+
+ /** align all marked objects in all sections
+ */
+ void alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection);
+
+ sal_uInt32 getMarkedObjectCount() const;
+
+ /** zoom the ruler and view windows
+ */
+ void zoom(const Fraction& _aZoom);
+
+ /** fills the vector with all selected control models
+ /param _rSelection The vector will be filled and will not be cleared before.
+ */
+ void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const;
+
+ /** calculates the zoom factor.
+ @param _eType which kind of zoom is needed
+ */
+ sal_uInt16 getZoomFactor(SvxZoomType _eType) const;
+ };
+
+} //rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTWINDOW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/RptUndo.hxx b/reportdesign/source/ui/inc/RptUndo.hxx
new file mode 100644
index 000000000..cef45a59d
--- /dev/null
+++ b/reportdesign/source/ui/inc/RptUndo.hxx
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_RPTUNDO_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_RPTUNDO_HXX
+
+#include <RptModel.hxx>
+#include <UndoActions.hxx>
+#include <functional>
+
+namespace com::sun::star {
+ namespace drawing {
+ class XShape;
+ }
+}
+
+namespace rptui
+{
+ /** \class OSectionUndo
+ * Undo class for section add and remove.
+ */
+ class OSectionUndo : public OCommentUndoAction
+ {
+ OSectionUndo(const OSectionUndo&) = delete;
+ void operator =(const OSectionUndo&) = delete;
+ protected:
+ ::std::vector< css::uno::Reference< css::drawing::XShape> >
+ m_aControls;
+ ::std::vector< ::std::pair< OUString ,css::uno::Any> >
+ m_aValues;
+ Action m_eAction;
+ sal_uInt16 m_nSlot;
+ bool m_bInserted;
+
+ virtual void implReInsert( ) = 0;
+ virtual void implReRemove( ) = 0;
+
+ void collectControls(const css::uno::Reference< css::report::XSection >& _xSection);
+ public:
+ OSectionUndo( OReportModel& rMod
+ ,sal_uInt16 _nSlot
+ ,Action _eAction
+ ,TranslateId pCommentID);
+ virtual ~OSectionUndo() override;
+
+ virtual void Undo() override;
+ virtual void Redo() override;
+ };
+
+ /** Undo action for the group header, footer, page header, footer
+ */
+ class OReportSectionUndo : public OSectionUndo
+ {
+ OReportHelper m_aReportHelper;
+ ::std::function<css::uno::Reference< css::report::XSection >(OReportHelper *)> m_pMemberFunction;
+
+ void implReInsert( ) override;
+ void implReRemove( ) override;
+ OReportSectionUndo(const OReportSectionUndo&) = delete;
+ void operator =(const OReportSectionUndo&) = delete;
+ public:
+ //OReportSectionUndo( const css::uno::Reference< css::report::XSection >& _xSection
+ OReportSectionUndo( OReportModel& rMod
+ ,sal_uInt16 _nSlot
+ ,::std::function<css::uno::Reference< css::report::XSection >(OReportHelper *)> _pMemberFunction
+ ,const css::uno::Reference< css::report::XReportDefinition >& _xReport
+ ,Action _eAction);
+ virtual ~OReportSectionUndo() override;
+ };
+
+ /** Undo action for the group header, footer
+ */
+ class OGroupSectionUndo : public OSectionUndo
+ {
+ OGroupHelper m_aGroupHelper;
+ ::std::function<css::uno::Reference< css::report::XSection >(OGroupHelper *)> m_pMemberFunction;
+
+ mutable OUString m_sName;
+
+ void implReInsert( ) override;
+ void implReRemove( ) override;
+ OGroupSectionUndo(const OGroupSectionUndo&) = delete;
+ void operator =(const OGroupSectionUndo&) = delete;
+ public:
+ //OGroupSectionUndo( const css::uno::Reference< css::report::XSection >& _xSection
+ OGroupSectionUndo( OReportModel& rMod
+ ,sal_uInt16 _nSlot
+ ,::std::function<css::uno::Reference< css::report::XSection >(OGroupHelper *)> _pMemberFunction
+ ,const css::uno::Reference< css::report::XGroup >& _xGroup
+ ,Action _eAction
+ ,TranslateId pCommentID);
+
+ virtual OUString GetComment() const override;
+ };
+
+ /** /class OGroupUndo
+ * \brief Undo action for removing a group object.
+ */
+ class OGroupUndo : public OCommentUndoAction
+ {
+ css::uno::Reference< css::report::XGroup> m_xGroup; ///<! the group for the undo redo action
+ css::uno::Reference< css::report::XReportDefinition > m_xReportDefinition; ///<! the parent report definition
+ Action m_eAction; ///<! the current action
+ sal_Int32 m_nLastPosition; ///<! the last position of the group
+
+ void implReInsert( );
+ void implReRemove( );
+ public:
+ OGroupUndo(OReportModel& rMod
+ ,TranslateId pCommentID
+ ,Action _eAction
+ ,const css::uno::Reference< css::report::XGroup>& _xGroup
+ ,const css::uno::Reference< css::report::XReportDefinition >& _xReportDefinition);
+ virtual void Undo() override;
+ virtual void Redo() override;
+ };
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_RPTUNDO_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ScrollHelper.hxx b/reportdesign/source/ui/inc/ScrollHelper.hxx
new file mode 100644
index 000000000..076943ff7
--- /dev/null
+++ b/reportdesign/source/ui/inc/ScrollHelper.hxx
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SCROLLHELPER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SCROLLHELPER_HXX
+
+#include <vcl/scrbar.hxx>
+#include <com/sun/star/report/XSection.hpp>
+#include <comphelper/propmultiplex.hxx>
+#include "ReportDefines.hxx"
+#include <cppuhelper/basemutex.hxx>
+#include <rtl/ref.hxx>
+#include "MarkedSection.hxx"
+#include "ReportWindow.hxx"
+
+namespace rptui
+{
+ class ODesignView;
+ class OReportWindow;
+ class OSectionView;
+
+ /** This class defines the scrollable area of the report design. It includes
+ the h-ruler and the sections, and end marker. Not the start marker.
+ */
+ typedef vcl::Window OScrollWindowHelper_BASE;
+ class OScrollWindowHelper : public ::cppu::BaseMutex
+ , public OScrollWindowHelper_BASE/*TabPage*/
+ , public ::comphelper::OPropertyChangeListener
+ , public IMarkedSection
+ {
+ private:
+ VclPtr<ScrollBar> m_aHScroll;
+ VclPtr<ScrollBar> m_aVScroll;
+ VclPtr<ScrollBarBox> m_aCornerWin; // window in the bottom right corner
+ Size m_aTotalPixelSize;
+ VclPtr<ODesignView> m_pParent;
+ VclPtr<OReportWindow> m_aReportWindow;
+ ::rtl::Reference<comphelper::OPropertyChangeMultiplexer >
+ m_pReportDefinitionMultiPlexer; // listener for property changes
+
+ DECL_LINK( ScrollHdl, ScrollBar*, void);
+ Size ResizeScrollBars();
+ void ImplInitSettings();
+ void impl_initScrollBar( ScrollBar& _rScrollBar ) const;
+
+ OScrollWindowHelper(OScrollWindowHelper const &) = delete;
+ void operator =(OScrollWindowHelper const &) = delete;
+ protected:
+ virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
+ // window
+ virtual void Resize() override;
+ virtual bool EventNotify( NotifyEvent& rNEvt ) override;
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override;
+ public:
+ OScrollWindowHelper( ODesignView* _pReportDesignView);
+ virtual ~OScrollWindowHelper() override;
+ virtual void dispose() override;
+
+ /** late ctor
+ */
+ void initialize();
+
+ Point getThumbPos() const { return Point(m_aHScroll->GetThumbPos(),m_aVScroll->GetThumbPos())/*m_aScrollOffset*/; }
+ void setTotalSize(sal_Int32 _nWidth, sal_Int32 _nHeight);
+ const Size& getTotalSize() const { return m_aTotalPixelSize; }
+ ScrollBar& GetHScroll() { return *m_aHScroll; }
+ ScrollBar& GetVScroll() { return *m_aVScroll; }
+
+ // forwards
+ void SetMode( DlgEdMode _eMode );
+ void SetInsertObj(SdrObjKind eObj, const OUString& _sShapeType);
+ OUString const & GetInsertObjString() const;
+ void setGridSnap(bool bOn);
+ void setDragStripes(bool bOn);
+ /** copies the current selection in this section
+ */
+ void Copy();
+
+ /** returns if paste is allowed
+ *
+ * \return <TRUE/> if paste is allowed
+ */
+ bool IsPasteAllowed() const;
+
+ /** paste a new control in this section
+ */
+ void Paste();
+
+ /** Deletes the current selection in this section
+ *
+ */
+ void Delete();
+
+ /** All objects will be marked.
+ */
+ void SelectAll(const SdrObjKind _nObjectType);
+
+ /** returns <TRUE/> when an object is marked
+ */
+ bool HasSelection() const;
+
+ /** removes the section at the given position.
+ *
+ * \param _nPosition Zero based.
+ */
+ void removeSection(sal_uInt16 _nPosition);
+
+ /** adds a new section at position _nPosition.
+ If the section is <NULL/> nothing happens.
+ If the position is grater than the current elements, the section will be appended.
+ */
+ void addSection(const css::uno::Reference< css::report::XSection >& _xSection
+ ,const OUString& _sColorEntry
+ ,sal_uInt16 _nPosition);
+
+ sal_uInt16 getSectionCount() const;
+
+ /** turns the grid on or off
+ *
+ * \param _bVisible
+ */
+ void toggleGrid(bool _bVisible);
+
+ /** unmark all objects on the views.
+ */
+ void unmarkAllObjects();
+
+ /** shows or hides the ruler.
+ */
+ void showRuler(bool _bShow);
+
+ /** calculate the max width of the markers
+ *
+ * The end marker will not be used for calculation.
+ * \return the max width
+ */
+ sal_Int32 getMaxMarkerWidth() const;
+
+ /** checks if the keycode is known by the child windows
+ @param _rCode the keycode
+ @return <TRUE/> if the keycode is handled otherwise <FALSE/>
+ */
+ bool handleKeyEvent(const KeyEvent& _rEvent);
+
+ /** the section as marked or not marked
+ @param _pSectionView the section where to set the marked flag
+ @param _bMark the marked flag
+ */
+ void setMarked(OSectionView const * _pSectionView, bool _bMark);
+ void setMarked(const css::uno::Reference< css::report::XSection>& _xSection, bool _bMark);
+ void setMarked(const css::uno::Sequence< css::uno::Reference< css::report::XReportComponent> >& _xShape, bool _bMark);
+
+ // IMarkedSection
+ OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const override;
+ OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const;
+ virtual void markSection(const sal_uInt16 _nPos) override;
+
+
+ /** fills the positions of all collapsed sections.
+ *
+ * \param _rCollapsedPositions Out parameter which holds afterwards all positions of the collapsed sections.
+ */
+ void fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const;
+
+ /** collapse all sections given by their position
+ *
+ * \param _aCollapsedSections The position of the sections which should be collapsed.
+ */
+ void collapseSections(const css::uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections);
+
+ /** align all marked objects in all sections
+ */
+ void alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection);
+
+ sal_uInt32 getMarkedObjectCount() const;
+
+ /** zoom the ruler and view windows
+ */
+ void zoom(const Fraction& _aZoom);
+
+ /** fills the vector with all selected control models
+ /param _rSelection The vector will be filled and will not be cleared before.
+ */
+ void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const;
+
+ /** calculates the zoom factor.
+ @param _eType which kind of zoom is needed
+ */
+ sal_uInt16 getZoomFactor(SvxZoomType _eType) const;
+ };
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SCROLLHELPER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/SectionView.hxx b/reportdesign/source/ui/inc/SectionView.hxx
new file mode 100644
index 000000000..df3cbc7b0
--- /dev/null
+++ b/reportdesign/source/ui/inc/SectionView.hxx
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONVIEW_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONVIEW_HXX
+
+
+#include <svx/svdview.hxx>
+namespace rptui
+{
+class OReportWindow;
+class OReportSection;
+
+
+// OSectionView
+
+
+class OSectionView : public SdrView
+{
+private:
+ VclPtr<OReportWindow> m_pReportWindow;
+ VclPtr<OReportSection> m_pSectionWindow;
+
+ void ObjectRemovedInAliveMode( const SdrObject* pObject );
+ OSectionView(const OSectionView&) = delete;
+ void operator =(const OSectionView&) = delete;
+public:
+
+ OSectionView(
+ SdrModel& rSdrModel,
+ OReportSection* _pSectionWindow,
+ OReportWindow* pEditor);
+
+ virtual ~OSectionView() override;
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
+ virtual void MarkListHasChanged() override;
+ virtual void MakeVisible( const tools::Rectangle& rRect, vcl::Window& rWin ) override;
+
+ OReportSection* getReportSection() const { return m_pSectionWindow; }
+
+ // switch the marked objects to the given layer.
+ void SetMarkedToLayer( SdrLayerID nLayerNo );
+
+ // return true when only shapes are marked, otherwise false.
+ bool OnlyShapesMarked() const;
+
+ /* returns the common layer id of the marked objects, otherwise -1 will be returned.
+ */
+ SdrLayerID GetLayerIdOfMarkedObjects() const;
+
+ // returns true if objects at Drag & Drop is resize not move
+ bool IsDragResize() const;
+};
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONVIEW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/SectionWindow.hxx b/reportdesign/source/ui/inc/SectionWindow.hxx
new file mode 100644
index 000000000..1e727c2e5
--- /dev/null
+++ b/reportdesign/source/ui/inc/SectionWindow.hxx
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONWINDOW_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONWINDOW_HXX
+
+#include <com/sun/star/report/XSection.hpp>
+#include <vcl/window.hxx>
+#include <vcl/split.hxx>
+#include <comphelper/propmultiplex.hxx>
+#include <cppuhelper/basemutex.hxx>
+
+#include <UndoActions.hxx>
+#include "StartMarker.hxx"
+#include "EndMarker.hxx"
+#include "ReportSection.hxx"
+
+namespace comphelper
+{
+ class OPropertyChangeMultiplexer;
+}
+namespace rptui
+{
+ class OViewsWindow;
+ class OSectionWindow : public vcl::Window
+ , public ::cppu::BaseMutex
+ , public ::comphelper::OPropertyChangeListener
+ {
+ VclPtr<OViewsWindow> m_pParent;
+ VclPtr<OStartMarker> m_aStartMarker;
+ VclPtr<OReportSection> m_aReportSection;
+ VclPtr<Splitter> m_aSplitter;
+ VclPtr<OEndMarker> m_aEndMarker;
+
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pSectionMulti;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pGroupMulti;
+
+ OSectionWindow(OSectionWindow const &) = delete;
+ void operator =(OSectionWindow const &) = delete;
+
+ /** set the title of the group header or footer
+ *
+ * \param _xGroup
+ * \param _nResId
+ * \param _pGetSection
+ * \param _pIsSectionOn
+ * @return sal_True when title was set otherwise FALSE
+ */
+ bool setGroupSectionTitle(
+ const css::uno::Reference<css::report::XGroup>& _xGroup, TranslateId pResId,
+ const ::std::function<css::uno::Reference<css::report::XSection>(OGroupHelper*)>&
+ _pGetSection,
+ const ::std::function<bool(OGroupHelper*)>& _pIsSectionOn);
+
+ /** set the title of the (report/page) header or footer
+ *
+ * \param _xGroup
+ * \param _nResId
+ * \param _pGetSection
+ * \param _pIsSectionOn
+ * @return sal_True when title was set otherwise FALSE
+ */
+ bool setReportSectionTitle(
+ const css::uno::Reference<css::report::XReportDefinition>& _xReport, TranslateId pResId,
+ const ::std::function<css::uno::Reference<css::report::XSection>(OReportHelper*)>&
+ _pGetSection,
+ const ::std::function<bool(OReportHelper*)>& _pIsSectionOn);
+ void ImplInitSettings();
+
+ DECL_LINK(Collapsed, OColorListener&, void);
+ DECL_LINK(StartSplitHdl, Splitter*, void);
+ DECL_LINK(SplitHdl, Splitter*, void);
+ DECL_LINK(EndSplitHdl, Splitter*, void);
+
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
+ // Window overrides
+ virtual void Resize() override;
+
+ protected:
+ virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override;
+ public:
+ OSectionWindow( OViewsWindow* _pParent
+ ,const css::uno::Reference< css::report::XSection >& _xSection
+ ,const OUString& _sColorEntry);
+ virtual ~OSectionWindow() override;
+ virtual void dispose() override;
+
+ OStartMarker& getStartMarker() { return *m_aStartMarker; }
+ OReportSection& getReportSection() { return *m_aReportSection; }
+ OEndMarker& getEndMarker() { return *m_aEndMarker; }
+ OViewsWindow* getViewsWindow() { return m_pParent; }
+
+ void setCollapsed(bool _bCollapsed);
+
+ /** triggers the property browser with the section
+ @param _pStartMarker
+ */
+ void showProperties();
+
+ /** set the marker as marked or not marked
+ @param _bMark set the new state of the marker
+ */
+ void setMarked(bool _bMark);
+
+ /** zoom the ruler and view windows
+ */
+ void zoom(const Fraction& _aZoom);
+
+ void scrollChildren(tools::Long _nThumbPosX);
+ };
+
+} // rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONWINDOW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/StartMarker.hxx b/reportdesign/source/ui/inc/StartMarker.hxx
new file mode 100644
index 000000000..630630faa
--- /dev/null
+++ b/reportdesign/source/ui/inc/StartMarker.hxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STARTMARKER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STARTMARKER_HXX
+
+#include <osl/interlck.h>
+#include <svtools/ruler.hxx>
+#include "ColorListener.hxx"
+#include <vcl/image.hxx>
+
+namespace rptui
+{
+ class OSectionWindow;
+ class OStartMarker : public OColorListener
+ {
+
+ VclPtr<Ruler> m_aVRuler;
+ OUString m_aText;
+ tools::Rectangle m_aTextRect;
+ Image m_aImage;
+ tools::Rectangle m_aImageRect;
+ VclPtr<OSectionWindow> m_pParent;
+ static Image* s_pDefCollapsed;
+ static Image* s_pDefExpanded;
+ static oslInterlockedCount s_nImageRefCount; /// When 0 all static images will be destroyed
+
+ bool m_bShowRuler;
+
+ void changeImage();
+ void initDefaultNodeImages();
+
+ virtual void ImplInitSettings() override;
+ virtual void ApplySettings(vcl::RenderContext& rRenderContext) override;
+
+ OStartMarker(OStartMarker const &) = delete;
+ void operator =(OStartMarker const &) = delete;
+ public:
+ OStartMarker(OSectionWindow* _pParent,const OUString& _sColorEntry);
+ virtual ~OStartMarker() override;
+ virtual void dispose() override;
+
+ // SfxListener
+ virtual void Notify(SfxBroadcaster & rBc, SfxHint const & rHint) override;
+ // Window overrides
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
+ virtual void MouseButtonUp(const MouseEvent& rMEvt) override;
+ virtual void Resize() override;
+ virtual void RequestHelp(const HelpEvent& rHEvt) override;
+
+ void setTitle(const OUString& _sTitle);
+ sal_Int32 getMinHeight() const;
+
+ /** shows or hides the ruler.
+ */
+ void showRuler(bool _bShow);
+
+ virtual void setCollapsed(bool _bCollapsed) override;
+
+ /** zoom the ruler and view windows
+ */
+ void zoom(const Fraction& _aZoom);
+ };
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STARTMARKER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/UITools.hxx b/reportdesign/source/ui/inc/UITools.hxx
new file mode 100644
index 000000000..13aafb14f
--- /dev/null
+++ b/reportdesign/source/ui/inc/UITools.hxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_UITOOLS_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_UITOOLS_HXX
+
+#include <com/sun/star/report/XGroup.hpp>
+#include <com/sun/star/report/XReportControlFormat.hpp>
+#include <com/sun/star/report/XShape.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include "ReportSection.hxx"
+#include <rtl/ref.hxx>
+#include <vcl/taskpanelist.hxx>
+#include <comphelper/stl_types.hxx>
+
+class SdrPage;
+class SdrObject;
+class SdrUnoObj;
+class SdrView;
+namespace tools { class Rectangle; }
+namespace comphelper
+{
+ class OPropertyChangeMultiplexer;
+ class OPropertyChangeListener;
+}
+namespace rptui
+{
+ /** returns the position of the object inside the index container
+ @param _xReportDefinition the report definition to get the groups
+ @param _xGroup the group to search
+ @return returns the position of the group in the list, otherwise -1
+ */
+ template<typename T> sal_Int32 getPositionInIndexAccess(
+ const css::uno::Reference< css::container::XIndexAccess >& _xCollection
+ ,const css::uno::Reference< T >& _xSearch)
+ {
+ sal_Int32 nCount = _xCollection->getCount();
+ sal_Int32 i = (nCount == 0) ? -1 : 0;
+ for (;i<nCount ; ++i)
+ {
+ css::uno::Reference< T > xObject(_xCollection->getByIndex(i),css::uno::UNO_QUERY);
+ if ( xObject == _xSearch )
+ break;
+ }
+ return i;
+ }
+
+ /** set the name of the header and footer of the group by the expression appended by the localized name of the section
+ @param _xGroup the group where the header/footer name is set by the expression of the group
+ */
+ void adjustSectionName(const css::uno::Reference< css::report::XGroup >& _xGroup,sal_Int32 _nPos);
+
+ /** add a listener for the properties size, left margin, right margin to the page style
+ *
+ * \param _xReportDefinition
+ * \param _pListener
+ * \return
+ */
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> addStyleListener( const css::uno::Reference< css::report::XReportDefinition >& _xReportDefinition
+ ,::comphelper::OPropertyChangeListener* _pListener);
+
+ /** opens the common character font dialog
+ */
+ bool openCharDialog(
+ const css::uno::Reference< css::report::XReportControlFormat>& _xReportControlFormat,
+ const css::uno::Reference< css::awt::XWindow>& _xWindow,
+ css::uno::Sequence< css::beans::NamedValue >& _out_rNewValues
+ );
+
+ /** opens the area dialog for shapes
+ */
+ bool openAreaDialog(
+ const css::uno::Reference< css::report::XShape >& _xShape
+ ,const css::uno::Reference< css::awt::XWindow>& _xWindow
+ );
+
+ /** opens the formula dialog
+ @param _out_rFormula
+ the formula chosen by the user
+ @precond
+ we're really inspecting a database report (well, a RowSet at least)
+ @return
+ <TRUE/> if and only if the user successfully chose a clause
+ */
+ bool openDialogFormula_nothrow( OUString& _in_out_rFormula
+ , const css::uno::Reference< css::uno::XComponentContext >& _xContext
+ , const css::uno::Reference< css::awt::XWindow>& _xWindow
+ , const css::uno::Reference < css::beans::XPropertySet >& _xRowSet
+ );
+
+ /** applies the character settings previously obtained via openCharDialog
+ */
+ void applyCharacterSettings(
+ const css::uno::Reference< css::report::XReportControlFormat >& _rxReportControlFormat,
+ const css::uno::Sequence< css::beans::NamedValue >& _rSettings
+ );
+
+ /** notifySystemWindow adds or remove the given window _pToRegister at the Systemwindow found when search _pWindow.
+ @param pWindow
+ The window which is used to search for the SystemWindow.
+ @param pToRegister
+ The window which should be added or removed on the TaskPaneList.
+ @param rMemFunc
+ The member function which should be called at the SystemWindow when found.
+ Possible values are:
+ ::comphelper::mem_fun(&TaskPaneList::AddWindow)
+ ::comphelper::mem_fun(&TaskPaneList::RemoveWindow)
+ */
+ void notifySystemWindow(vcl::Window const * pWindow, vcl::Window* pToRegister, const ::comphelper::mem_fun1_t<TaskPaneList, vcl::Window*>& rMemFunc);
+
+
+ const sal_Int16 ISOVER_IGNORE_CUSTOMSHAPES = 1;
+
+ /** checks whether the given rectangle overlapps another OUnoObject object in that view.
+ *
+ * \param _rRect
+ * \param _rPage
+ * \param _bAllObjects if <TRUE/> all objects are taken into account, otherwise only not marked ones
+ * \return the object which is overlapped, otherwise <NULL/>
+ */
+ SdrObject* isOver(const tools::Rectangle& _rRect,SdrPage const & _rPage,SdrView const & _rView,bool _bAllObjects = false,SdrObject const * _pIgnore = nullptr, sal_Int16 _nIgnoreType=0);
+
+ SdrObject* isOver(const tools::Rectangle& _rRect,SdrPage const & _rPage,SdrView const & _rView,bool _bAllObjects, std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> _pIgnoreList[], int _nIgnoreListLength);
+
+ /** checks whether the given OUnoObject object rectangle overlapps another object in that view.
+ *
+ * \param _pObj
+ * \param _rPage
+ * \param _rView
+ * \return the object which is overlapped, otherwise <NULL/>. If the given object is not of type OUnoObject <NULL/> will be returned.
+ */
+ SdrObject* isOver(SdrObject const * _pObj,SdrPage const & _rPage,SdrView const & _rView);
+
+ /** retrieves the names of the parameters of the command which the given RowSet is bound to
+ */
+ css::uno::Sequence< OUString >
+ getParameterNames( const css::uno::Reference< css::sdbc::XRowSet >& _rxRowSet );
+
+ /** ensures that no control overlaps the given one.
+ *
+ * \param pControl the control which should place in the section without overlapping
+ * \param _pReportSection the section
+ * \param _bInsert sal_True when the control should be inserted, otherwise not.
+ */
+ void correctOverlapping(SdrObject* pControl,OReportSection const & _aReportSection,bool _bInsert = true);
+
+ /** returns a Rectangle of a given SdrObject
+ *
+ * \param pControl the SdrObject
+ */
+
+ tools::Rectangle getRectangleFromControl(SdrObject* pControl);
+
+ /** sets the map mode at the window
+ @param _aZoom the zoom scale
+ @param _rWindow where to set the map mode
+ */
+ void setZoomFactor(const Fraction& _aZoom, vcl::Window& _rWindow);
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_UITOOLS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/ViewsWindow.hxx b/reportdesign/source/ui/inc/ViewsWindow.hxx
new file mode 100644
index 000000000..f83e28ca8
--- /dev/null
+++ b/reportdesign/source/ui/inc/ViewsWindow.hxx
@@ -0,0 +1,294 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_VIEWSWINDOW_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_VIEWSWINDOW_HXX
+
+#include <com/sun/star/report/XSection.hpp>
+#include <vcl/window.hxx>
+#include <svtools/colorcfg.hxx>
+#include "ReportDefines.hxx"
+#include "SectionView.hxx"
+#include <unotools/options.hxx>
+#include <vector>
+
+#include "MarkedSection.hxx"
+#include "SectionWindow.hxx"
+
+class SdrHdl;
+
+namespace rptui
+{
+ class OReportWindow;
+ class OReportSection;
+ class OSectionView;
+ enum class ControlModification;
+
+ struct RectangleLess
+ {
+ enum CompareMode { POS_LEFT,POS_RIGHT,POS_UPPER,POS_DOWN,POS_CENTER_HORIZONTAL,POS_CENTER_VERTICAL };
+ CompareMode m_eCompareMode;
+ Point m_aRefPoint;
+ RectangleLess(CompareMode _eCompareMode,const Point& _rRefPoint ) : m_eCompareMode(_eCompareMode),m_aRefPoint(_rRefPoint){}
+ bool operator() (const tools::Rectangle& lhs, const tools::Rectangle& rhs) const
+ {
+ switch(m_eCompareMode)
+ {
+ case POS_LEFT:
+ return lhs.Left() < rhs.Left();
+ case POS_RIGHT:
+ return lhs.Right() >= rhs.Right();
+ case POS_UPPER:
+ return lhs.Top() < rhs.Top();
+ case POS_DOWN:
+ return lhs.Bottom() >= rhs.Bottom();
+ case POS_CENTER_HORIZONTAL:
+ return std::abs(m_aRefPoint.X() - lhs.Center().X()) < std::abs(m_aRefPoint.X() - rhs.Center().X());
+ case POS_CENTER_VERTICAL:
+ return std::abs(lhs.Center().Y() - m_aRefPoint.Y()) < std::abs(rhs.Center().Y() - m_aRefPoint.Y());
+ }
+ return false;
+ }
+ };
+
+ class OViewsWindow : public vcl::Window
+ , public utl::ConfigurationListener
+ , public IMarkedSection
+ {
+ typedef ::std::multimap<tools::Rectangle,::std::pair<SdrObject*,OSectionView*>,RectangleLess> TRectangleMap;
+ public:
+ typedef ::std::vector< VclPtr<OSectionWindow> > TSectionsMap;
+
+ private:
+ TSectionsMap m_aSections;
+ svtools::ColorConfig m_aColorConfig;
+ VclPtr<OReportWindow> m_pParent;
+ OUString m_sShapeType;
+ bool m_bInUnmark;
+
+ void ImplInitSettings();
+ /** returns the iterator at pos _nPos or the end()
+ */
+ TSectionsMap::iterator getIteratorAtPos(sal_uInt16 _nPos);
+ void collectRectangles(TRectangleMap& _rMap);
+ static void collectBoundResizeRect(const TRectangleMap& _rSortRectangles, ControlModification _nControlModification,bool _bAlignAtSection,tools::Rectangle& _rBound,tools::Rectangle& _rResize);
+ void impl_resizeSectionWindow(OSectionWindow& _rSectionWindow,Point& _rStartPoint,bool _bSet);
+
+ OViewsWindow(OViewsWindow const &) = delete;
+ void operator =(OViewsWindow const &) = delete;
+ protected:
+ virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
+ // Window overrides
+ virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
+ virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
+
+ virtual void Paint( vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle& rRect ) override;
+ virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints ) override;
+ public:
+ OViewsWindow(
+ OReportWindow* _pReportWindow);
+ virtual ~OViewsWindow() override;
+ virtual void dispose() override;
+
+ // Window overrides
+ virtual void Resize() override;
+
+ void resize(const OSectionWindow& _rSectionWindow);
+
+ OReportWindow* getView() const { return m_pParent; }
+
+ /** removes the section at the given position.
+ *
+ * \param _nPosition Zero based.
+ */
+ void removeSection(sal_uInt16 _nPosition);
+
+ /** adds a new section at position _nPosition.
+ If the section is <NULL/> nothing happens.
+ If the position is grater than the current elements, the section will be appended.
+ */
+ void addSection(const css::uno::Reference< css::report::XSection >& _xSection
+ ,const OUString& _sColorEntry
+ ,sal_uInt16 _nPosition);
+
+ sal_uInt16 getSectionCount() const;
+ /** return the section at the given position
+ *
+ * \param _nPos
+ * \return the section at this pos or an empty section
+ */
+ OSectionWindow* getSectionWindow(const sal_uInt16 _nPos) const;
+
+ /** turns the grid on or off
+ *
+ * \param _bVisible
+ */
+ void toggleGrid(bool _bVisible);
+ void setGridSnap(bool bOn);
+ void setDragStripes(bool bOn);
+
+ /** returns the total accumulated height of all sections until _pSection is reached
+ */
+ sal_Int32 getTotalHeight() const;
+
+ bool empty() const { return m_aSections.empty(); }
+ void SetMode( DlgEdMode m_eMode );
+ void SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType);
+ const OUString& GetInsertObjString() const { return m_sShapeType;}
+ /** copies the current selection in this section
+ */
+ void Copy();
+
+ /** returns if paste is allowed
+ *
+ * \return <TRUE/> if paste is allowed
+ */
+ bool IsPasteAllowed() const;
+
+ /** paste a new control in this section
+ */
+ void Paste();
+
+ /** Deletes the current selection in this section
+ *
+ */
+ void Delete();
+
+ /** All objects will be marked.
+ */
+ void SelectAll(const SdrObjKind _nObjectType);
+
+ /** returns <TRUE/> when an object is marked
+ */
+ bool HasSelection() const;
+
+ /** unmark all objects on the views without the given one.
+ *
+ * @param _pSectionView The view where the objects should not be unmarked.
+ */
+ void unmarkAllObjects(OSectionView const * _pSectionView);
+
+ /** returns the report section window for the given xsection
+ @param _xSection the section
+ */
+ OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const;
+
+ /** checks if the keycode is known by the child windows
+ @param _rCode the keycode
+ @return <TRUE/> if the keycode is handled otherwise <FALSE/>
+ */
+ bool handleKeyEvent(const KeyEvent& _rEvent);
+
+ /** the section as marked or not marked
+ @param _pSectionView the section where to set the marked flag
+ @param _bMark the marked flag
+ */
+ void setMarked(OSectionView const * _pSectionView, bool _bMark);
+ void setMarked(const css::uno::Reference< css::report::XSection>& _xSection, bool _bMark);
+ void setMarked(const css::uno::Sequence< css::uno::Reference< css::report::XReportComponent> >& _xShape, bool _bMark);
+
+ // IMarkedSection
+ OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const override;
+ virtual void markSection(const sal_uInt16 _nPos) override;
+
+ /** align all marked objects in all sections
+ */
+ void alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection);
+
+ /** creates a default object
+ *
+ */
+ void createDefault();
+
+ /** shows or hides the ruler.
+ */
+ void showRuler(bool _bShow);
+
+ /** returns the currently set shape type.
+ *
+ * \return \member m_sShapeType
+ */
+ const OUString& getShapeType() const { return m_sShapeType; }
+
+ /** returns the current position in the list
+ */
+ sal_uInt16 getPosition(const OSectionWindow* _pSectionWindow) const;
+
+ /** calls on every section BrkAction
+ *
+ */
+ void BrkAction();
+ void BegMarkObj(const Point& _aPnt,const OSectionView* _pSection);
+
+ private:
+ void BegDragObj_createInvisibleObjectAtPosition(const tools::Rectangle& _aRect, const OSectionView& _rSection);
+ void EndDragObj_removeInvisibleObjects();
+ Point m_aDragDelta;
+ ::std::vector<SdrObject*> m_aBegDragTempList;
+ public:
+ void BegDragObj(const Point& _aPnt, SdrHdl* _pHdl,const OSectionView* _pSection);
+ void EndDragObj(bool _bDragIntoNewSection,const OSectionView* _pSection,const Point& _aPnt);
+
+ void EndAction();
+ void ForceMarkedToAnotherPage();
+ bool IsAction() const;
+ bool IsDragObj() const;
+ void handleKey(const vcl::KeyCode& _rCode);
+ void stopScrollTimer();
+
+ /** return the section at the given point which is relative to the given section
+ *
+ * \param _pSection the section which is used as reference point
+ * \param _rPnt the point, it will be changed that it is inside the section which will be returned
+ * \return the section
+ */
+ OSectionView* getSectionRelativeToPosition(const OSectionView* _pSection,Point& _rPnt);
+
+ void MovAction(const Point& rPnt,const OSectionView* _pSection, bool _bControlKeySet);
+
+ sal_uInt32 getMarkedObjectCount() const;
+
+ /** fills the positions of all collapsed sections.
+ *
+ * \param _rCollapsedPositions Out parameter which holds afterwards all positions of the collapsed sections.
+ */
+ void fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const;
+
+ /** collapse all sections given by their position
+ *
+ * \param _aCollapsedSections The position of the sections which should be collapsed.
+ */
+ void collapseSections(const css::uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections);
+
+ /** zoom the ruler and view windows
+ */
+ void zoom(const Fraction& _aZoom);
+
+ void scrollChildren(const Point& _aThumbPos);
+
+ /** fills the vector with all selected control models
+ /param _rSelection The vector will be filled and will not be cleared before.
+ */
+ void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const;
+ };
+
+} // rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_VIEWSWINDOW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/dlgedclip.hxx b/reportdesign/source/ui/inc/dlgedclip.hxx
new file mode 100644
index 000000000..0290a0293
--- /dev/null
+++ b/reportdesign/source/ui/inc/dlgedclip.hxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDCLIP_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDCLIP_HXX
+
+#include <vcl/transfer.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+namespace rptui
+{
+// OReportExchange
+
+/** \class OReportExchange
+ * \brief defines a clipboard format for copying selection elements.
+ * \ingroup reportdesign_source_ui_report
+ *
+ *
+ */
+class OReportExchange : public TransferableHelper
+{
+public:
+ typedef css::uno::Sequence<css::beans::NamedValue> TSectionElements;
+
+ /** Constructs a new exchange object with section elements
+ *
+ * \param _rCopyElements the elements to copy. Each section is one entry. The value must be a sequence of elements.
+ * \return
+ */
+ OReportExchange(const TSectionElements& _rCopyElements);
+
+ /** checks whether or not a descriptor can be extracted from the data flavor vector given
+ *
+ * \param _rFlavors
+ available flavors
+ * \return
+ */
+ static bool canExtract(const DataFlavorExVector& _rFlavors);
+
+ /** extract the section elements
+ *
+ * \param _rData the clipboard data
+ * \return the copied elements
+ */
+ static TSectionElements extractCopies(const TransferableDataHelper& _rData);
+
+ /** returns the format id.
+ *
+ * \return the registered format id
+ */
+ static SotClipboardFormatId getDescriptorFormatId();
+
+protected:
+ // TransferableHelper overridables
+ virtual void AddSupportedFormats() override;
+ virtual bool GetData(const css::datatransfer::DataFlavor& rFlavor,
+ const OUString& rDestDoc) override;
+
+private:
+ TSectionElements m_aCopyElements;
+};
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDCLIP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/dlgedfac.hxx b/reportdesign/source/ui/inc/dlgedfac.hxx
new file mode 100644
index 000000000..6a79ef780
--- /dev/null
+++ b/reportdesign/source/ui/inc/dlgedfac.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFAC_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFAC_HXX
+
+#include <svx/svdobj.hxx>
+#include <tools/link.hxx>
+
+namespace rptui
+{
+// DlgEdFactory
+
+class DlgEdFactory
+{
+public:
+ DlgEdFactory();
+ ~DlgEdFactory() COVERITY_NOEXCEPT_FALSE;
+
+ DECL_STATIC_LINK(DlgEdFactory, MakeObject, SdrObjCreatorParams, SdrObject*);
+};
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFAC_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/dlgedfunc.hxx b/reportdesign/source/ui/inc/dlgedfunc.hxx
new file mode 100644
index 000000000..403f548e0
--- /dev/null
+++ b/reportdesign/source/ui/inc/dlgedfunc.hxx
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFUNC_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFUNC_HXX
+
+#include <tools/gen.hxx>
+#include <vcl/event.hxx>
+#include <vcl/timer.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+
+class Timer;
+class MouseEvent;
+class Point;
+class SdrTextObj;
+class SdrObject;
+namespace rptui
+{
+
+class OReportSection;
+class OSectionView;
+
+
+// DlgEdFunc
+
+
+class DlgEdFunc /* : public LinkHdl */
+{
+ DlgEdFunc(const DlgEdFunc&) = delete;
+ void operator =(const DlgEdFunc&) = delete;
+protected:
+ VclPtr<OReportSection> m_pParent;
+ OSectionView& m_rView;
+ Timer aScrollTimer;
+ Point m_aMDPos;
+ css::uno::Reference<css::uno::XInterface> m_xOverlappingObj;
+ SdrObject * m_pOverlappingObj;
+ Color m_nOverlappedControlColor;
+ Color m_nOldColor;
+ bool m_bSelectionMode;
+ bool m_bUiActive;
+ bool m_bShowPropertyBrowser;
+
+ DECL_LINK( ScrollTimeout, Timer *, void );
+ void ForceScroll( const Point& rPos );
+ /** checks that no other object is overlapped.
+ *
+ * \param rMEvt
+ */
+ void checkMovementAllowed(const MouseEvent& rMEvt);
+
+ /** sets the correct mouse pointer when moving an object
+ *
+ * \param rMEvt
+ * \return <TRUE/> when the pointer was already set.
+ */
+ bool setMovementPointer(const MouseEvent& rMEvt);
+
+ bool isRectangleHit(const MouseEvent& rMEvt);
+ /**
+ returns true, as long as only customshapes in the marked list,
+ custom shapes can drop every where
+ */
+ bool isOnlyCustomShapeMarked() const;
+
+ /** activate object if it is of type OBJ_OLE2
+ */
+ void activateOle(SdrObject* _pObj);
+
+ void checkTwoClicks(const MouseEvent& rMEvt);
+
+public:
+ DlgEdFunc( OReportSection* pParent );
+ virtual ~DlgEdFunc();
+
+ virtual bool MouseButtonDown( const MouseEvent& rMEvt );
+ virtual bool MouseButtonUp( const MouseEvent& rMEvt );
+ virtual bool MouseMove( const MouseEvent& rMEvt );
+
+ /** checks if the keycode is known by the child windows
+ @param _rCode the keycode
+ @return <TRUE/> if the keycode is handled otherwise <FALSE/>
+ */
+ bool handleKeyEvent(const KeyEvent& _rEvent);
+
+ /** returns <TRUE/> if the mouse event is over an existing object
+ *
+ * \param rMEvt
+ * \return <TRUE/> if overlapping, otherwise <FALSE/>
+ */
+ bool isOverlapping(const MouseEvent& rMEvt);
+ void setOverlappedControlColor(Color _nColor);
+ void stopScrollTimer();
+
+ /** deactivate all ole object
+ */
+ void deactivateOle(bool _bSelect = false);
+
+ bool isUiActive() const { return m_bUiActive; }
+protected:
+ void colorizeOverlappedObject(SdrObject* _pOverlappedObj);
+ void unColorizeOverlappedObj();
+
+
+};
+
+
+// DlgEdFuncInsert
+
+
+class DlgEdFuncInsert : public DlgEdFunc
+{
+public:
+ DlgEdFuncInsert( OReportSection* pParent );
+ virtual ~DlgEdFuncInsert() override;
+
+ virtual bool MouseButtonDown( const MouseEvent& rMEvt ) override;
+ virtual bool MouseButtonUp( const MouseEvent& rMEvt ) override;
+ virtual bool MouseMove( const MouseEvent& rMEvt ) override;
+};
+
+
+// DlgEdFuncSelect
+
+
+class DlgEdFuncSelect : public DlgEdFunc
+{
+public:
+ DlgEdFuncSelect( OReportSection* pParent );
+ virtual ~DlgEdFuncSelect() override;
+
+ virtual bool MouseButtonDown( const MouseEvent& rMEvt ) override;
+ virtual bool MouseButtonUp( const MouseEvent& rMEvt ) override;
+ virtual bool MouseMove( const MouseEvent& rMEvt ) override;
+};
+
+}
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFUNC_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/dlgpage.hxx b/reportdesign/source/ui/inc/dlgpage.hxx
new file mode 100644
index 000000000..0e40bd0c6
--- /dev/null
+++ b/reportdesign/source/ui/inc/dlgpage.hxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGPAGE_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGPAGE_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+namespace rptui
+{
+/*************************************************************************
+|*
+|* Page setup tab dialog
+|*
+\************************************************************************/
+class ORptPageDialog : public SfxTabDialogController
+{
+private:
+ ORptPageDialog(const ORptPageDialog&) = delete;
+ void operator=(const ORptPageDialog&) = delete;
+
+public:
+ ORptPageDialog(weld::Window* pParent, const SfxItemSet* pAttr, const OUString& rDialog);
+ virtual void PageCreated(const OString& rId, SfxTabPage& rPage) override;
+};
+
+} // namespace rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGPAGE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/metadata.hxx b/reportdesign/source/ui/inc/metadata.hxx
new file mode 100644
index 000000000..c5ea24a82
--- /dev/null
+++ b/reportdesign/source/ui/inc/metadata.hxx
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_METADATA_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_METADATA_HXX
+
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/inspection/XPropertyHandler.hpp>
+#include <o3tl/typed_flags_set.hxx>
+
+#include <string_view>
+#include <vector>
+
+ //= UI flags (for all browsable properties)
+enum class PropUIFlags {
+ NONE = 0x0001, // no special flag
+ Composeable = 0x0002, // the property is "composeable", i.e. an intersection of property
+ // sets should expose it, if all elements do
+ DataProperty = 0x0004 // the property is to appear on the "Data" page
+};
+namespace o3tl {
+ template<> struct typed_flags<PropUIFlags> : is_typed_flags<PropUIFlags, 0x0007> {};
+}
+
+
+namespace rptui
+{
+
+
+ struct OPropertyInfoImpl;
+
+
+ //= OPropertyInfoService
+
+ class OPropertyInfoService final
+ {
+ public:
+ // IPropertyInfoService
+ static sal_Int32 getPropertyId(const OUString& _rName);
+ static OUString getPropertyTranslation(sal_Int32 _nId);
+ static OString getPropertyHelpId(sal_Int32 _nId);
+ static PropUIFlags getPropertyUIFlags(sal_Int32 _nId);
+ static void getExcludeProperties(::std::vector< css::beans::Property >& _rExcludeProperties,const css::uno::Reference< css::inspection::XPropertyHandler >& _xFormComponentHandler);
+
+ static bool isComposable(
+ const OUString& _rPropertyName,
+ const css::uno::Reference< css::inspection::XPropertyHandler >& _xFormComponentHandler
+ );
+
+ private:
+ static const OPropertyInfoImpl* getPropertyInfo();
+
+ static const OPropertyInfoImpl* getPropertyInfo(const OUString& _rName);
+ static const OPropertyInfoImpl* getPropertyInfo(sal_Int32 _nId);
+
+ OPropertyInfoService(const OPropertyInfoService&) = delete;
+ void operator =(const OPropertyInfoService&) = delete;
+ OPropertyInfoService() = delete;
+
+ static sal_uInt16 s_nCount;
+ static OPropertyInfoImpl* s_pPropertyInfos;
+ // TODO: a real structure which allows quick access by name as well as by id
+ };
+
+
+ //= HelpIdUrl
+
+ /// small helper to translate help ids into help urls
+ class HelpIdUrl
+ {
+ public:
+ static OUString getHelpURL( std::string_view _sHelpId );
+ };
+
+
+ //= property ids (for all browsable properties)
+ //= The ID is used for the view order in the property browser.
+
+
+ #define PROPERTY_ID_FORCENEWPAGE 1
+ #define PROPERTY_ID_NEWROWORCOL 2
+ #define PROPERTY_ID_KEEPTOGETHER 3
+ #define PROPERTY_ID_CANGROW 4
+ #define PROPERTY_ID_CANSHRINK 5
+ #define PROPERTY_ID_REPEATSECTION 6
+ #define PROPERTY_ID_PRESERVEIRI 7
+ #define PROPERTY_ID_VISIBLE 8
+ #define PROPERTY_ID_GROUPKEEPTOGETHER 9
+ #define PROPERTY_ID_PAGEHEADEROPTION 10
+ #define PROPERTY_ID_PAGEFOOTEROPTION 11
+ #define PROPERTY_ID_POSITIONX 12
+ #define PROPERTY_ID_POSITIONY 13
+ #define PROPERTY_ID_WIDTH 14
+ #define PROPERTY_ID_HEIGHT 15
+ #define PROPERTY_ID_AUTOGROW 16
+ #define PROPERTY_ID_FORMULA 17
+ #define PROPERTY_ID_CONDITIONALPRINTEXPRESSION 18
+ #define PROPERTY_ID_PRINTREPEATEDVALUES 19
+ #define PROPERTY_ID_PRINTWHENGROUPCHANGE 20
+ #define PROPERTY_ID_INITIALFORMULA 21
+ #define PROPERTY_ID_STARTNEWCOLUMN 22
+ #define PROPERTY_ID_TYPE 23
+ #define PROPERTY_ID_DATAFIELD 24
+ #define PROPERTY_ID_CHARFONTNAME 25
+ #define PROPERTY_ID_DEEPTRAVERSING 26
+ #define PROPERTY_ID_PREEVALUATED 27
+
+ #define PROPERTY_ID_BACKTRANSPARENT 28
+ #define PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT 29
+ #define PROPERTY_ID_BACKCOLOR 30
+ #define PROPERTY_ID_CONTROLBACKGROUND 31
+
+ #define PROPERTY_ID_FORMULALIST 32
+ #define PROPERTY_ID_SCOPE 33
+ #define PROPERTY_ID_RESETPAGENUMBER 34
+ #define PROPERTY_ID_CHARTTYPE 35
+ #define PROPERTY_ID_MASTERFIELDS 36
+ #define PROPERTY_ID_DETAILFIELDS 37
+ #define PROPERTY_ID_PREVIEW_COUNT 38
+ #define PROPERTY_ID_AREA 39
+ #define PROPERTY_ID_MIMETYPE 40
+
+ #define PROPERTY_ID_FONT 41
+ #define PROPERTY_ID_PARAADJUST 42
+ #define PROPERTY_ID_VERTICALALIGN 43
+
+
+} // namespace rptui
+
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_METADATA_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/propbrw.hxx b/reportdesign/source/ui/inc/propbrw.hxx
new file mode 100644
index 000000000..5b697df05
--- /dev/null
+++ b/reportdesign/source/ui/inc/propbrw.hxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PROPBRW_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PROPBRW_HXX
+
+#include <com/sun/star/frame/XFrame2.hpp>
+#include <com/sun/star/inspection/XObjectInspector.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <svl/SfxBroadcaster.hxx>
+#include <svl/lstner.hxx>
+#include <vcl/dockwin.hxx>
+#include <vcl/layout.hxx>
+#include <svx/svdmark.hxx>
+
+namespace rptui
+{
+
+class OSectionView;
+class ODesignView;
+class OObjectBase;
+
+// PropBrw
+
+
+class PropBrw final : public DockingWindow , public SfxListener, public SfxBroadcaster
+{
+ VclPtr<VclVBox> m_xContentArea;
+
+ css::uno::Reference< css::uno::XComponentContext >
+ m_xInspectorContext;
+ css::uno::Reference< css::uno::XComponentContext >
+ m_xORB;
+ css::uno::Reference< css::frame::XFrame2 >
+ m_xMeAsFrame;
+ css::uno::Reference< css::inspection::XObjectInspector >
+ m_xBrowserController;
+ css::uno::Reference< css::uno::XInterface>
+ m_xLastSection; /// is the previously displayed section
+ OUString m_sLastActivePage;
+ VclPtr<ODesignView> m_pDesignView;
+ OSectionView* m_pView;
+ bool m_bInitialStateChange;
+
+ PropBrw(PropBrw const &) = delete;
+ void operator =(PropBrw const &) = delete;
+
+ virtual bool Close() override;
+
+ css::uno::Sequence< css::uno::Reference< css::uno::XInterface> >
+ CreateCompPropSet(const SdrMarkList& rMarkList);
+
+ void implSetNewObject(
+ const css::uno::Sequence< css::uno::Reference< css::uno::XInterface> >& _aObjects = css::uno::Sequence< css::uno::Reference< css::uno::XInterface> >());
+
+ static OUString GetHeadlineName(
+ const css::uno::Sequence< css::uno::Reference< css::uno::XInterface> >& _aObjects);
+
+ void implDetachController();
+ css::uno::Reference< css::uno::XInterface> CreateComponentPair(OObjectBase* _pObj);
+ css::uno::Reference< css::uno::XInterface> CreateComponentPair(
+ const css::uno::Reference< css::uno::XInterface>& _xFormComponent
+ ,const css::uno::Reference< css::uno::XInterface>& _xReportComponent);
+ DECL_LINK( OnAsyncGetFocus, void*, void );
+
+public:
+ PropBrw(const css::uno::Reference< css::uno::XComponentContext >& _xORB
+ ,Window* pParent
+ ,ODesignView* _pDesignView);
+ virtual ~PropBrw() override;
+ virtual void dispose() override;
+
+ virtual void LoseFocus() override;
+
+ void Update( OSectionView* m_pView );
+ void Update( const css::uno::Reference< css::uno::XInterface>& _xReportComponent);
+ OUString getCurrentPage() const;
+ void setCurrentPage(const OUString& _sLastActivePage);
+
+ ::Size getMinimumSize() const;
+};
+
+} // rptui
+
+#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PROPBRW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inc/statusbarcontroller.hxx b/reportdesign/source/ui/inc/statusbarcontroller.hxx
new file mode 100644
index 000000000..13bfb7706
--- /dev/null
+++ b/reportdesign/source/ui/inc/statusbarcontroller.hxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STATUSBARCONTROLLER_HXX
+#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STATUSBARCONTROLLER_HXX
+
+#include <svtools/statusbarcontroller.hxx>
+#include <comphelper/uno3.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+class SfxStatusBarControl;
+namespace rptui
+{
+ typedef ::cppu::ImplHelper1 < css::lang::XServiceInfo> OStatusbarController_BASE;
+ class OStatusbarController : public ::svt::StatusbarController,
+ public OStatusbarController_BASE
+ {
+ css::uno::Reference< css::frame::XStatusbarController > m_rController;
+ sal_uInt16 m_nSlotId;
+ sal_uInt16 m_nId;
+ public:
+ OStatusbarController(const css::uno::Reference< css::uno::XComponentContext >& _rxORB);
+
+ private:
+ void SAL_CALL dispose() override;
+ // XInterface
+ DECLARE_XINTERFACE( )
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual css::uno::Sequence< OUString> SAL_CALL getSupportedServiceNames() override;
+ // need by registration
+
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
+
+ // XUpdatable
+ virtual void SAL_CALL update() override;
+
+ // XStatusListener
+ virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& Event ) override;
+
+ // XStatusbarController
+ virtual sal_Bool SAL_CALL mouseButtonDown( const css::awt::MouseEvent& aMouseEvent ) override;
+ virtual sal_Bool SAL_CALL mouseMove( const css::awt::MouseEvent& aMouseEvent ) override;
+ virtual sal_Bool SAL_CALL mouseButtonUp( const css::awt::MouseEvent& aMouseEvent ) override;
+ virtual void SAL_CALL command( const css::awt::Point& aPos,
+ ::sal_Int32 nCommand,
+ sal_Bool bMouseEvent,
+ const css::uno::Any& aData ) override;
+ virtual void SAL_CALL paint( const css::uno::Reference< css::awt::XGraphics >& xGraphics,
+ const css::awt::Rectangle& rOutputRectangle,
+ ::sal_Int32 nStyle ) override;
+ virtual void SAL_CALL click( const css::awt::Point& aPos ) override;
+ virtual void SAL_CALL doubleClick( const css::awt::Point& aPos ) override;
+ };
+}
+#endif // DBAUI_STATUSBARCONTROLLER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inspection/DataProviderHandler.cxx b/reportdesign/source/ui/inspection/DataProviderHandler.cxx
new file mode 100644
index 000000000..9e789db4c
--- /dev/null
+++ b/reportdesign/source/ui/inspection/DataProviderHandler.cxx
@@ -0,0 +1,513 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <DataProviderHandler.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/types.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <strings.hxx>
+#include <com/sun/star/form/inspection/FormComponentPropertyHandler.hpp>
+#include <com/sun/star/inspection/PropertyControlType.hpp>
+#include <com/sun/star/inspection/PropertyLineElement.hpp>
+#include <com/sun/star/lang/NullPointerException.hpp>
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <com/sun/star/chart2/FormattedString.hpp>
+#include <com/sun/star/chart2/XTitled.hpp>
+#include <com/sun/star/chart2/XTitle.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/report/XReportDefinition.hpp>
+#include <com/sun/star/script/Converter.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <metadata.hxx>
+#include <osl/mutex.hxx>
+#include <tools/diagnose_ex.h>
+#include <core_resource.hxx>
+#include <helpids.h>
+#include <strings.hrc>
+#include <PropertyForward.hxx>
+
+namespace rptui
+{
+
+using namespace ::com::sun::star;
+
+DataProviderHandler::DataProviderHandler(uno::Reference< uno::XComponentContext > const & context)
+ :DataProviderHandler_Base(m_aMutex)
+ ,m_xContext(context)
+{
+ try
+ {
+ m_xFormComponentHandler = form::inspection::FormComponentPropertyHandler::create(m_xContext);
+ m_xTypeConverter = script::Converter::create(m_xContext);
+
+ }catch(const uno::Exception &)
+ {
+ }
+}
+
+OUString SAL_CALL DataProviderHandler::getImplementationName( )
+{
+ return "com.sun.star.comp.report.DataProviderHandler";
+}
+
+sal_Bool SAL_CALL DataProviderHandler::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL DataProviderHandler::getSupportedServiceNames( )
+{
+ return { "com.sun.star.report.inspection.DataProviderHandler" };
+}
+
+// override WeakComponentImplHelperBase::disposing()
+// This function is called upon disposing the component,
+// if your component needs special work when it becomes
+// disposed, do it here.
+void SAL_CALL DataProviderHandler::disposing()
+{
+ ::comphelper::disposeComponent(m_xFormComponentHandler);
+ ::comphelper::disposeComponent( m_xMasterDetails );
+ ::comphelper::disposeComponent(m_xTypeConverter);
+}
+void SAL_CALL DataProviderHandler::addEventListener(const uno::Reference< lang::XEventListener > & xListener)
+{
+ m_xFormComponentHandler->addEventListener(xListener);
+}
+
+void SAL_CALL DataProviderHandler::removeEventListener(const uno::Reference< lang::XEventListener > & aListener)
+{
+ m_xFormComponentHandler->removeEventListener(aListener);
+}
+
+// inspection::XPropertyHandler:
+
+/********************************************************************************/
+void SAL_CALL DataProviderHandler::inspect(const uno::Reference< uno::XInterface > & Component)
+{
+ try
+ {
+ uno::Reference< container::XNameContainer > xNameCont(Component,uno::UNO_QUERY);
+ static const OUStringLiteral sFormComponent(u"FormComponent");
+ if ( xNameCont->hasByName(sFormComponent) )
+ {
+ uno::Reference<beans::XPropertySet> xProp(xNameCont->getByName(sFormComponent),uno::UNO_QUERY);
+ static const OUStringLiteral sModel(u"Model");
+ if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName(sModel) )
+ {
+ m_xChartModel.set(xProp->getPropertyValue(sModel),uno::UNO_QUERY);
+ if ( m_xChartModel.is() )
+ m_xFormComponent = m_xChartModel->getDataProvider();
+ }
+ }
+ m_xDataProvider.set(m_xFormComponent,uno::UNO_QUERY);
+ m_xReportComponent.set( xNameCont->getByName("ReportComponent"), uno::UNO_QUERY );
+ if ( m_xDataProvider.is() )
+ {
+ auto aNoConverter = std::make_shared<AnyConverter>();
+ TPropertyNamePair aPropertyMediation;
+ aPropertyMediation.emplace( PROPERTY_MASTERFIELDS, TPropertyConverter(PROPERTY_MASTERFIELDS,aNoConverter) );
+ aPropertyMediation.emplace( PROPERTY_DETAILFIELDS, TPropertyConverter(PROPERTY_DETAILFIELDS,aNoConverter) );
+
+ m_xMasterDetails = new OPropertyMediator( m_xDataProvider, m_xReportComponent, std::move(aPropertyMediation), true );
+ }
+ }
+ catch(const uno::Exception &)
+ {
+ throw lang::NullPointerException();
+ }
+ if ( m_xFormComponent.is() )
+ {
+ m_xFormComponentHandler->inspect(m_xFormComponent);
+ }
+}
+
+uno::Any SAL_CALL DataProviderHandler::getPropertyValue(const OUString & PropertyName)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ uno::Any aPropertyValue;
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_CHARTTYPE:
+ // TODO: We need a possibility to get the UI of the selected chart type
+ // LEM: this business of ignoring ChartType seems very fishy!
+ //if( m_xChartModel.is() )
+ //{
+ // uno::Reference< chart2::XDiagram > xDiagram( m_xChartModel->getFirstDiagram() );
+ // if( xDiagram.is() )
+ // {
+ // OUString sChartTypes;
+ // uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
+ // const uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
+ // const uno::Reference< chart2::XCoordinateSystem >* pIter = aCooSysSeq.getConstArray();
+ // const uno::Reference< chart2::XCoordinateSystem >* pEnd = pIter + aCooSysSeq.getLength();
+ // for(;pIter != pEnd;++pIter)
+ // {
+ // const uno::Reference< chart2::XChartTypeContainer > xCTCnt( *pIter, uno::UNO_QUERY_THROW );
+ // const uno::Sequence< uno::Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
+ // const uno::Reference< chart2::XChartType >* pChartTypeIter = aCTSeq.getConstArray();
+ // const uno::Reference< chart2::XChartType >* pChartTypeEnd = pChartTypeIter + aCTSeq.getLength();
+ // for(;pChartTypeIter != pChartTypeEnd;++pChartTypeIter)
+ // {
+ // sChartTypes += (*pChartTypeIter)->getChartType();
+ // sChartTypes += ";";
+ // }
+ // }
+ // aPropertyValue;// <<= sChartTypes;
+ // }
+ //}
+ break;
+ case PROPERTY_ID_PREVIEW_COUNT:
+ if (m_xDataProvider) // tdf#117159 crash with chart in database report otherwise
+ aPropertyValue <<= m_xDataProvider->getRowLimit();
+ break;
+ default:
+ aPropertyValue = m_xFormComponentHandler->getPropertyValue( PropertyName );
+ break;
+ }
+ return aPropertyValue;
+}
+
+void SAL_CALL DataProviderHandler::setPropertyValue(const OUString & PropertyName, const uno::Any & Value)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_CHARTTYPE:
+ break;
+ case PROPERTY_ID_PREVIEW_COUNT:
+ m_xDataProvider->setPropertyValue(PropertyName,Value);
+ break;
+ default:
+ m_xFormComponentHandler->setPropertyValue(PropertyName, Value);
+ break;
+ }
+}
+
+void DataProviderHandler::impl_updateChartTitle_throw(const uno::Any& _aValue)
+{
+ uno::Reference<chart2::XTitled> xTitled(m_xChartModel,uno::UNO_QUERY);
+ if ( !xTitled.is() )
+ return;
+
+ uno::Reference<chart2::XTitle> xTitle = xTitled->getTitleObject();
+ if ( !xTitle.is() )
+ {
+ xTitle.set(m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.chart2.Title",m_xContext),uno::UNO_QUERY);
+ xTitled->setTitleObject(xTitle);
+ }
+ if ( xTitle.is() )
+ {
+ uno::Reference< chart2::XFormattedString2> xFormatted = chart2::FormattedString::create(m_xContext);
+ OUString sStr;
+ _aValue >>= sStr;
+ xFormatted->setString(sStr);
+ xTitle->setText({ xFormatted });
+ }
+}
+
+beans::PropertyState SAL_CALL DataProviderHandler::getPropertyState(const OUString & PropertyName)
+{
+ return m_xFormComponentHandler->getPropertyState(PropertyName);
+}
+
+inspection::LineDescriptor SAL_CALL DataProviderHandler::describePropertyLine(const OUString & PropertyName, const uno::Reference< inspection::XPropertyControlFactory > & _xControlFactory)
+{
+ inspection::LineDescriptor aOut;
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_CHARTTYPE:
+ aOut.PrimaryButtonId = UID_RPT_PROP_CHARTTYPE_DLG;
+ aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::TextField , true);
+ aOut.HasPrimaryButton = true;
+ break;
+ case PROPERTY_ID_PREVIEW_COUNT:
+ aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::NumericField , false);
+ break;
+ case PROPERTY_ID_MASTERFIELDS:
+ case PROPERTY_ID_DETAILFIELDS:
+ aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::StringListField , false);
+ aOut.PrimaryButtonId = UID_RPT_PROP_DLG_LINKFIELDS;
+ aOut.HasPrimaryButton = true;
+ break;
+ default:
+ aOut = m_xFormComponentHandler->describePropertyLine(PropertyName, _xControlFactory);
+ }
+ if ( nId != -1 )
+ {
+ aOut.Category = (OPropertyInfoService::getPropertyUIFlags(nId ) & PropUIFlags::DataProperty) ?
+ std::u16string_view(u"Data")
+ :
+ std::u16string_view(u"General");
+ aOut.HelpURL = HelpIdUrl::getHelpURL( OPropertyInfoService::getPropertyHelpId( nId ) );
+ aOut.DisplayName = OPropertyInfoService::getPropertyTranslation(nId);
+ }
+ return aOut;
+}
+
+uno::Any SAL_CALL DataProviderHandler::convertToPropertyValue(const OUString & _rPropertyValue, const uno::Any & _rControlValue)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ uno::Any aPropertyValue( _rControlValue );
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(_rPropertyValue);
+ switch(nId)
+ {
+ case PROPERTY_ID_CHARTTYPE:
+ break;
+ case PROPERTY_ID_PREVIEW_COUNT:
+ try
+ {
+ aPropertyValue = m_xTypeConverter->convertTo( _rControlValue, ::cppu::UnoType<sal_Int32>::get());
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "DataProviderHandler::convertToPropertyValue: caught an exception while converting via TypeConverter!" );
+ }
+ break;
+ case PROPERTY_ID_MASTERFIELDS:
+ case PROPERTY_ID_DETAILFIELDS:
+ break;
+ default:
+ aPropertyValue = m_xFormComponentHandler->convertToPropertyValue(_rPropertyValue, _rControlValue);
+ }
+ return aPropertyValue;
+}
+
+uno::Any SAL_CALL DataProviderHandler::convertToControlValue(const OUString & _rPropertyName, const uno::Any & _rPropertyValue, const uno::Type & ControlValueType)
+{
+ uno::Any aControlValue( _rPropertyValue );
+ if ( !aControlValue.hasValue() )
+ // NULL is converted to NULL
+ return aControlValue;
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(_rPropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_CHARTTYPE:
+ break;
+ case PROPERTY_ID_MASTERFIELDS:
+ case PROPERTY_ID_DETAILFIELDS:
+ case PROPERTY_ID_PREVIEW_COUNT:
+ try
+ {
+ aControlValue = m_xTypeConverter->convertTo( _rPropertyValue, ControlValueType);
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::convertToPropertyValue: caught an exception while converting via TypeConverter!" );
+ }
+ break;
+ default:
+ aControlValue = m_xFormComponentHandler->convertToControlValue(_rPropertyName, _rPropertyValue, ControlValueType);
+ }
+ return aControlValue;
+}
+
+void SAL_CALL DataProviderHandler::addPropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & Listener)
+{
+ m_xFormComponentHandler->addPropertyChangeListener(Listener);
+}
+
+void SAL_CALL DataProviderHandler::removePropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & _rxListener)
+{
+ m_xFormComponentHandler->removePropertyChangeListener(_rxListener);
+}
+
+uno::Sequence< beans::Property > SAL_CALL DataProviderHandler::getSupportedProperties()
+{
+ ::std::vector< beans::Property > aNewProps;
+ if( m_xChartModel.is() )
+ {
+ rptui::OPropertyInfoService::getExcludeProperties( aNewProps, m_xFormComponentHandler );
+ beans::Property aValue;
+ static const std::u16string_view s_pProperties[] =
+ {
+ u"" PROPERTY_CHARTTYPE
+ ,u"" PROPERTY_MASTERFIELDS
+ ,u"" PROPERTY_DETAILFIELDS
+ ,u"" PROPERTY_PREVIEW_COUNT
+ };
+
+ for (const auto & rName : s_pProperties)
+ {
+ aValue.Name = rName;
+ aNewProps.push_back(aValue);
+ }
+ }
+ return uno::Sequence< beans::Property >(aNewProps.data(), aNewProps.size());
+}
+
+uno::Sequence< OUString > SAL_CALL DataProviderHandler::getSupersededProperties()
+{
+ uno::Sequence< OUString > aRet { PROPERTY_TITLE }; // have a look at OPropertyInfoService::getExcludeProperties
+ return aRet;
+}
+
+uno::Sequence< OUString > SAL_CALL DataProviderHandler::getActuatingProperties()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ uno::Sequence< OUString > aSeq { PROPERTY_TITLE };
+ return ::comphelper::concatSequences(m_xFormComponentHandler->getActuatingProperties(),aSeq);
+}
+
+sal_Bool SAL_CALL DataProviderHandler::isComposable( const OUString& _rPropertyName )
+{
+ return OPropertyInfoService::isComposable( _rPropertyName, m_xFormComponentHandler );
+}
+
+inspection::InteractiveSelectionResult SAL_CALL DataProviderHandler::onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, uno::Any & out_Data, const uno::Reference< inspection::XObjectInspectorUI > & _rxInspectorUI)
+{
+ if ( !_rxInspectorUI.is() )
+ throw lang::NullPointerException();
+
+ inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled;
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_CHARTTYPE:
+ if ( impl_dialogChartType_nothrow(aGuard) )
+ eResult = inspection::InteractiveSelectionResult_ObtainedValue;
+ break;
+ case PROPERTY_ID_MASTERFIELDS:
+ case PROPERTY_ID_DETAILFIELDS:
+ if ( impl_dialogLinkedFields_nothrow( aGuard ) )
+ eResult = inspection::InteractiveSelectionResult_Success;
+ break;
+ default:
+ eResult = m_xFormComponentHandler->onInteractivePropertySelection(PropertyName, Primary, out_Data, _rxInspectorUI);
+ }
+
+ return eResult;
+}
+
+void SAL_CALL DataProviderHandler::actuatingPropertyChanged(const OUString & ActuatingPropertyName, const uno::Any & NewValue, const uno::Any & OldValue, const uno::Reference< inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit)
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( ActuatingPropertyName == PROPERTY_COMMAND )
+ {
+ if ( NewValue != OldValue )
+ {
+ uno::Reference< report::XReportDefinition> xReport = m_xReportComponent->getSection()->getReportDefinition();
+ bool bDoEnableMasterDetailFields = xReport.is() && !xReport->getCommand().isEmpty() && !m_xDataProvider->getCommand().isEmpty();
+ InspectorUI->enablePropertyUIElements( PROPERTY_DETAILFIELDS, inspection::PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
+ InspectorUI->enablePropertyUIElements( PROPERTY_MASTERFIELDS, inspection::PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
+
+ bool bModified = xReport->isModified();
+ // this fills the chart again
+ ::comphelper::NamedValueCollection aArgs;
+ aArgs.put( "CellRangeRepresentation", uno::Any( OUString( "all" ) ) );
+ aArgs.put( "HasCategories", uno::Any( true ) );
+ aArgs.put( "FirstCellAsLabel", uno::Any( true ) );
+ aArgs.put( "DataRowSource", uno::Any( chart::ChartDataRowSource_COLUMNS ) );
+ uno::Reference< chart2::data::XDataReceiver > xReceiver(m_xChartModel,uno::UNO_QUERY_THROW);
+ xReceiver->setArguments( aArgs.getPropertyValues() );
+ if ( !bModified )
+ xReport->setModified(false);
+ }
+ m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, InspectorUI, FirstTimeInit);
+ }
+ else if ( ActuatingPropertyName == PROPERTY_TITLE )
+ {
+ if ( NewValue != OldValue )
+ impl_updateChartTitle_throw(NewValue);
+ }
+ else
+ {
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(ActuatingPropertyName);
+ switch(nId)
+ {
+
+ case PROPERTY_ID_MASTERFIELDS:
+ break;
+ case PROPERTY_ID_DETAILFIELDS:
+ break;
+ default:
+ m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, InspectorUI, FirstTimeInit);
+ }
+ }
+}
+
+sal_Bool SAL_CALL DataProviderHandler::suspend(sal_Bool Suspend)
+{
+ return m_xFormComponentHandler->suspend(Suspend);
+}
+bool DataProviderHandler::impl_dialogLinkedFields_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
+{
+ uno::Sequence<uno::Any> aSeq(comphelper::InitAnyPropertySequence(
+ {
+ {"ParentWindow", m_xContext->getValueByName("DialogParentWindow")},
+ {"Detail", uno::Any(m_xDataProvider)},
+ {"Master", uno::Any(m_xReportComponent->getSection()->getReportDefinition())},
+ {"Explanation", uno::Any(RptResId(TranslateId(nullptr, RID_STR_EXPLANATION)))},
+ {"DetailLabel", uno::Any(RptResId(RID_STR_DETAILLABEL))},
+ {"MasterLabel", uno::Any(RptResId(RID_STR_MASTERLABEL))},
+ }));
+
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
+ m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "org.openoffice.comp.form.ui.MasterDetailLinkDialog", aSeq, m_xContext),
+ uno::UNO_QUERY);
+
+ _rClearBeforeDialog.clear();
+ return ( xDialog->execute() != 0 );
+}
+
+bool DataProviderHandler::impl_dialogChartType_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
+{
+ uno::Sequence<uno::Any> aSeq(comphelper::InitAnyPropertySequence(
+ {
+ {"ParentWindow", m_xContext->getValueByName("DialogParentWindow")},
+ {"ChartModel", uno::Any(m_xChartModel)}
+ }));
+
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
+ m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.chart2.ChartTypeDialog", aSeq, m_xContext),
+ uno::UNO_QUERY);
+
+ _rClearBeforeDialog.clear();
+ return ( xDialog->execute() != 0 );
+}
+
+} // namespace rptui
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+reportdesign_DataProviderHandler_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new rptui::DataProviderHandler(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inspection/DefaultInspection.cxx b/reportdesign/source/ui/inspection/DefaultInspection.cxx
new file mode 100644
index 000000000..80269f433
--- /dev/null
+++ b/reportdesign/source/ui/inspection/DefaultInspection.cxx
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <DefaultInspection.hxx>
+#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <strings.hrc>
+#include <core_resource.hxx>
+#include <helpids.h>
+#include <cppuhelper/supportsservice.hxx>
+#include <tools/debug.hxx>
+#include <metadata.hxx>
+#include <tools/urlobj.hxx>
+
+
+namespace rptui
+{
+ OUString HelpIdUrl::getHelpURL( std::string_view sHelpId )
+ {
+ OUString aTmp( OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8) );
+ DBG_ASSERT( INetURLObject( aTmp ).GetProtocol() == INetProtocol::NotValid, "Wrong HelpId!" );
+ return INET_HID_SCHEME + aTmp;
+ }
+
+ using namespace com::sun::star::uno;
+ using namespace com::sun::star;
+ using com::sun::star::inspection::PropertyCategoryDescriptor;
+
+
+ //= DefaultComponentInspectorModel
+
+
+ DefaultComponentInspectorModel::DefaultComponentInspectorModel( const Reference< XComponentContext >& _rxContext)
+ :m_xContext( _rxContext )
+ ,m_bConstructed( false )
+ ,m_bHasHelpSection( false )
+ ,m_bIsReadOnly(false)
+ ,m_nMinHelpTextLines( 3 )
+ ,m_nMaxHelpTextLines( 8 )
+ {
+ }
+
+ DefaultComponentInspectorModel::~DefaultComponentInspectorModel()
+ {
+ }
+
+ OUString SAL_CALL DefaultComponentInspectorModel::getImplementationName( )
+ {
+ return "com.sun.star.comp.report.DefaultComponentInspectorModel";
+ }
+
+ sal_Bool SAL_CALL DefaultComponentInspectorModel::supportsService( const OUString& ServiceName )
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ Sequence< OUString > SAL_CALL DefaultComponentInspectorModel::getSupportedServiceNames( )
+ {
+ return { "com.sun.star.report.inspection.DefaultComponentInspectorModel" };
+ }
+
+ Sequence< Any > SAL_CALL DefaultComponentInspectorModel::getHandlerFactories()
+ {
+ // service names for all our handlers
+ return Sequence<Any> {
+ Any(OUString( "com.sun.star.report.inspection.ReportComponentHandler")),
+ Any(OUString( "com.sun.star.form.inspection.EditPropertyHandler")),
+ Any(OUString( "com.sun.star.report.inspection.DataProviderHandler")),
+ Any(OUString( "com.sun.star.report.inspection.GeometryHandler"))
+ };
+ }
+
+ sal_Bool SAL_CALL DefaultComponentInspectorModel::getHasHelpSection()
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ return m_bHasHelpSection;
+ }
+
+
+ ::sal_Int32 SAL_CALL DefaultComponentInspectorModel::getMinHelpTextLines()
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ return m_nMinHelpTextLines;
+ }
+
+ sal_Bool SAL_CALL DefaultComponentInspectorModel::getIsReadOnly()
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ return m_bIsReadOnly;
+ }
+
+ void SAL_CALL DefaultComponentInspectorModel::setIsReadOnly( sal_Bool _isreadonly )
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ m_bIsReadOnly = _isreadonly;
+ }
+
+
+ ::sal_Int32 SAL_CALL DefaultComponentInspectorModel::getMaxHelpTextLines()
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ return m_nMaxHelpTextLines;
+ }
+
+ void SAL_CALL DefaultComponentInspectorModel::initialize( const Sequence< Any >& _arguments )
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ if ( m_bConstructed )
+ throw ucb::AlreadyInitializedException();
+
+ if ( !_arguments.hasElements() )
+ { // constructor: "createDefault()"
+ m_bConstructed = true;
+ return;
+ }
+
+ if ( _arguments.getLength() == 2 )
+ { // constructor: "createWithHelpSection( long, long )"
+ sal_Int32 nMinHelpTextLines( 0 ), nMaxHelpTextLines( 0 );
+ if ( !( _arguments[0] >>= nMinHelpTextLines ) || !( _arguments[1] >>= nMaxHelpTextLines ) )
+ throw lang::IllegalArgumentException( OUString(), *this, 0 );
+ createWithHelpSection( nMinHelpTextLines, nMaxHelpTextLines );
+ return;
+ }
+
+ throw lang::IllegalArgumentException( OUString(), *this, 0 );
+ }
+
+
+ void DefaultComponentInspectorModel::createWithHelpSection( sal_Int32 _nMinHelpTextLines, sal_Int32 _nMaxHelpTextLines )
+ {
+ if ( ( _nMinHelpTextLines <= 0 ) || ( _nMaxHelpTextLines <= 0 ) || ( _nMinHelpTextLines > _nMaxHelpTextLines ) )
+ throw lang::IllegalArgumentException( OUString(), *this, 0 );
+
+ m_bHasHelpSection = true;
+ m_nMinHelpTextLines = _nMinHelpTextLines;
+ m_nMaxHelpTextLines = _nMaxHelpTextLines;
+ m_bConstructed = true;
+ }
+
+ Sequence< PropertyCategoryDescriptor > SAL_CALL DefaultComponentInspectorModel::describeCategories( )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ const struct
+ {
+ const char* programmaticName;
+ TranslateId uiNameResId;
+ OString helpId;
+ } aCategories[] = {
+ { "General", RID_STR_PROPPAGE_DEFAULT, HID_RPT_PROPDLG_TAB_GENERAL },
+ { "Data", RID_STR_PROPPAGE_DATA, HID_RPT_PROPDLG_TAB_DATA },
+ };
+
+ const size_t nCategories = SAL_N_ELEMENTS( aCategories );
+ Sequence< PropertyCategoryDescriptor > aReturn( nCategories );
+ PropertyCategoryDescriptor* pReturn = aReturn.getArray();
+ for ( size_t i=0; i<nCategories; ++i, ++pReturn )
+ {
+ pReturn->ProgrammaticName = OUString::createFromAscii( aCategories[i].programmaticName );
+ pReturn->UIName = RptResId( aCategories[i].uiNameResId );
+ pReturn->HelpURL = HelpIdUrl::getHelpURL( aCategories[i].helpId );
+ }
+
+ return aReturn;
+ }
+
+
+ ::sal_Int32 SAL_CALL DefaultComponentInspectorModel::getPropertyOrderIndex( const OUString& _rPropertyName )
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ const sal_Int32 nPropertyId( OPropertyInfoService::getPropertyId( _rPropertyName ) );
+ if ( nPropertyId != -1 )
+ return nPropertyId;
+
+ if ( !m_xComponent.is() )
+ try
+ {
+ m_xComponent.set(m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.form.inspection.DefaultFormComponentInspectorModel",m_xContext),UNO_QUERY_THROW);
+ }
+ catch(const Exception &)
+ {
+ return 0;
+ }
+
+ return m_xComponent->getPropertyOrderIndex(_rPropertyName);
+ }
+
+
+} // namespace rptui
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+reportdesign_DefaultComponentInspectorModel_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new rptui::DefaultComponentInspectorModel(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inspection/GeometryHandler.cxx b/reportdesign/source/ui/inspection/GeometryHandler.cxx
new file mode 100644
index 000000000..66852237b
--- /dev/null
+++ b/reportdesign/source/ui/inspection/GeometryHandler.cxx
@@ -0,0 +1,2215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <iterator>
+#include <map>
+#include <string_view>
+
+#include <GeometryHandler.hxx>
+
+#include <comphelper/sequence.hxx>
+#include <comphelper/types.hxx>
+#include <comphelper/property.hxx>
+#include <comphelper/mimeconfighelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+#include <strings.hxx>
+#include <reportformula.hxx>
+
+#include <i18nutil/searchopt.hxx>
+#include <unotools/textsearch.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <unotools/syslocale.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/resary.hxx>
+#include <com/sun/star/lang/NullPointerException.hpp>
+#include <com/sun/star/form/inspection/FormComponentPropertyHandler.hpp>
+#include <com/sun/star/inspection/StringRepresentation.hpp>
+#include <com/sun/star/inspection/PropertyControlType.hpp>
+#include <com/sun/star/inspection/XStringListControl.hpp>
+#include <com/sun/star/report/Function.hpp>
+#include <com/sun/star/report/XReportDefinition.hpp>
+#include <com/sun/star/report/XShape.hpp>
+#include <com/sun/star/report/XSection.hpp>
+#include <com/sun/star/report/XFixedLine.hpp>
+#include <com/sun/star/script/Converter.hpp>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/FilterDialog.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <com/sun/star/util/MeasureUnit.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/inspection/XNumericControl.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+
+#include <tools/fldunit.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <core_resource.hxx>
+#include <stringarray.hrc>
+#include <strings.hrc>
+#include <RptDef.hxx>
+#include <UITools.hxx>
+
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+
+#include <metadata.hxx>
+#include <sfx2/docfilt.hxx>
+
+#include <helpids.h>
+#include <toolkit/helper/convert.hxx>
+#include <o3tl/functional.hxx>
+#include <o3tl/safeint.hxx>
+
+#define DATA_OR_FORMULA 0
+#define FUNCTION 1
+#define COUNTER 2
+#define USER_DEF_FUNCTION 3
+#define UNDEF_DATA 4
+
+
+namespace rptui
+{
+
+using namespace ::com::sun::star;
+
+namespace{
+
+OUString lcl_getQuotedFunctionName(std::u16string_view _sFunction)
+{
+ return OUString::Concat("[") + _sFunction + "]";
+}
+
+OUString lcl_getQuotedFunctionName(const uno::Reference< report::XFunction>& _xFunction)
+{
+ return lcl_getQuotedFunctionName(_xFunction->getName());
+}
+
+void lcl_collectFunctionNames(const uno::Reference< report::XFunctions>& _xFunctions,TFunctions& _rFunctionNames)
+{
+ uno::Reference< report::XFunctionsSupplier> xParent(_xFunctions->getParent(),uno::UNO_QUERY_THROW);
+ const sal_Int32 nCount = _xFunctions->getCount();
+ for (sal_Int32 i = 0; i < nCount ; ++i)
+ {
+ uno::Reference< report::XFunction > xFunction(_xFunctions->getByIndex(i),uno::UNO_QUERY_THROW);
+ _rFunctionNames.emplace( lcl_getQuotedFunctionName(xFunction),TFunctionPair(xFunction,xParent) );
+ }
+}
+
+void lcl_collectFunctionNames(const uno::Reference< report::XSection>& _xSection,TFunctions& _rFunctionNames)
+{
+ const uno::Reference< report::XReportDefinition> xReportDefinition = _xSection->getReportDefinition();
+ const uno::Reference< report::XGroups> xGroups = xReportDefinition->getGroups();
+ sal_Int32 nPos = -1;
+ uno::Reference< report::XGroup> xGroup = _xSection->getGroup();
+ if ( xGroup.is() )
+ nPos = getPositionInIndexAccess(xGroups,xGroup);
+ else if ( _xSection == xReportDefinition->getDetail() )
+ nPos = xGroups->getCount()-1;
+
+ for (sal_Int32 i = 0 ; i <= nPos ; ++i)
+ {
+ xGroup.set(xGroups->getByIndex(i),uno::UNO_QUERY_THROW);
+ lcl_collectFunctionNames(xGroup->getFunctions(),_rFunctionNames);
+ }
+ lcl_collectFunctionNames(xReportDefinition->getFunctions(),_rFunctionNames);
+}
+
+void lcl_convertFormulaTo(const uno::Any& _aPropertyValue,uno::Any& _rControlValue)
+{
+ OUString sName;
+ _aPropertyValue >>= sName;
+ const sal_Int32 nLen = sName.getLength();
+ if ( nLen )
+ {
+ ReportFormula aFormula( sName );
+ _rControlValue <<= aFormula.getUndecoratedContent();
+ }
+}
+
+// return value rounded to the nearest multiple of base
+// if equidistant of two multiples, round up (for positive numbers)
+// T is assumed to be an integer type
+template <typename T, T base> T lcl_round(T value)
+{
+ OSL_ENSURE(value >= 0, "lcl_round: positive numbers only please");
+ const T threshold = (base % 2 == 0) ? (base/2) : (base/2 + 1);
+ const T rest = value % base;
+ if ( rest >= threshold )
+ return value + (base - rest);
+ else
+ return value - rest;
+}
+
+} // anonymous namespace
+
+bool GeometryHandler::impl_isDataField(const OUString& _sName) const
+{
+ bool bIsField = ( ::std::find( m_aFieldNames.begin(), m_aFieldNames.end(), _sName ) != m_aFieldNames.end() );
+
+ if ( !bIsField )
+ {
+ bIsField = ( ::std::find( m_aParamNames.begin(), m_aParamNames.end(), _sName ) != m_aParamNames.end() );
+ }
+ return bIsField;
+}
+
+OUString GeometryHandler::impl_convertToFormula( const uno::Any& _rControlValue )
+{
+ OUString sName;
+ _rControlValue >>= sName;
+
+ if ( sName.isEmpty() )
+ return sName;
+
+ ReportFormula aParser( sName );
+ if ( aParser.isValid() )
+ return sName;
+
+ return ReportFormula(impl_isDataField(sName) ? ReportFormula::Field : ReportFormula::Expression, sName).getCompleteFormula();
+}
+
+GeometryHandler::GeometryHandler(uno::Reference< uno::XComponentContext > const & context)
+ : GeometryHandler_Base(m_aMutex)
+ , m_aPropertyListeners(m_aMutex)
+ , m_xContext(context)
+ , m_nDataFieldType(0)
+ , m_bNewFunction(false)
+ , m_bIn(false)
+{
+ try
+ {
+ m_xFormComponentHandler = form::inspection::FormComponentPropertyHandler::create(m_xContext);
+ m_xTypeConverter = script::Converter::create(context);
+ loadDefaultFunctions();
+ }
+ catch(const uno::Exception&)
+ {
+ }
+}
+
+GeometryHandler::~GeometryHandler()
+{
+}
+
+OUString SAL_CALL GeometryHandler::getImplementationName( )
+{
+ return "com.sun.star.comp.report.GeometryHandler";
+}
+
+sal_Bool SAL_CALL GeometryHandler::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL GeometryHandler::getSupportedServiceNames( )
+{
+ return { "com.sun.star.report.inspection.GeometryHandler" };
+}
+
+// override WeakComponentImplHelperBase::disposing()
+// This function is called upon disposing the component,
+// if your component needs special work when it becomes
+// disposed, do it here.
+void SAL_CALL GeometryHandler::disposing()
+{
+ try
+ {
+ ::comphelper::disposeComponent(m_xFormComponentHandler);
+ ::comphelper::disposeComponent(m_xTypeConverter);
+ if ( m_xReportComponent.is() && m_xReportComponent->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) )
+ m_xReportComponent->removePropertyChangeListener(PROPERTY_DATAFIELD,static_cast< beans::XPropertyChangeListener* >( this ));
+
+ m_xReportComponent.clear();
+ m_xRowSet.clear();
+ m_aPropertyListeners.clear();
+ }
+ catch(uno::Exception&)
+ {}
+}
+void SAL_CALL GeometryHandler::addEventListener(const uno::Reference< lang::XEventListener > & xListener)
+{
+ m_xFormComponentHandler->addEventListener(xListener);
+}
+
+void SAL_CALL GeometryHandler::removeEventListener(const uno::Reference< lang::XEventListener > & aListener)
+{
+ m_xFormComponentHandler->removeEventListener(aListener);
+}
+
+// inspection::XPropertyHandler:
+
+/********************************************************************************/
+void SAL_CALL GeometryHandler::inspect( const uno::Reference< uno::XInterface > & _rxInspectee )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_sScope.clear();
+ m_sDefaultFunction.clear();
+ m_bNewFunction = false;
+ m_nDataFieldType = 0;
+ m_xFunction.clear();
+ m_aFunctionNames.clear();
+ try
+ {
+ if ( m_xReportComponent.is() && m_xReportComponent->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) )
+ m_xReportComponent->removePropertyChangeListener(PROPERTY_DATAFIELD,static_cast< beans::XPropertyChangeListener* >( this ));
+
+ const uno::Reference< container::XNameContainer > xObjectAsContainer( _rxInspectee, uno::UNO_QUERY );
+ m_xReportComponent.set( xObjectAsContainer->getByName("ReportComponent"), uno::UNO_QUERY );
+
+ static const OUStringLiteral sRowSet(u"RowSet");
+ if ( xObjectAsContainer->hasByName( sRowSet ) )
+ {
+ const uno::Any aRowSet( xObjectAsContainer->getByName(sRowSet) );
+ aRowSet >>= m_xRowSet;
+ // forward the rowset to our delegator handler
+ uno::Reference< beans::XPropertySet > xProp( m_xFormComponentHandler,uno::UNO_QUERY );
+ xProp->setPropertyValue( sRowSet, aRowSet );
+
+ m_aParamNames = getParameterNames( m_xRowSet );
+ impl_initFieldList_nothrow(m_aFieldNames);
+ if ( m_xReportComponent->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) )
+ m_xReportComponent->addPropertyChangeListener(PROPERTY_DATAFIELD,static_cast< beans::XPropertyChangeListener* >( this ));
+ }
+
+ const uno::Reference< report::XReportComponent> xReportComponent( m_xReportComponent, uno::UNO_QUERY);
+ uno::Reference< report::XSection> xSection( m_xReportComponent, uno::UNO_QUERY );
+ if ( !xSection.is() && xReportComponent.is() )
+ xSection = xReportComponent->getSection();
+ if ( xSection.is() )
+ lcl_collectFunctionNames( xSection, m_aFunctionNames );
+ }
+ catch(const uno::Exception &)
+ {
+ throw lang::NullPointerException();
+ }
+ m_xFormComponentHandler->inspect(m_xReportComponent);
+}
+
+uno::Any SAL_CALL GeometryHandler::getPropertyValue(const OUString & PropertyName)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ uno::Any aPropertyValue;
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_CONDITIONALPRINTEXPRESSION:
+ case PROPERTY_ID_INITIALFORMULA:
+ case PROPERTY_ID_FORMULA:
+ case PROPERTY_ID_DATAFIELD:
+ aPropertyValue = m_xReportComponent->getPropertyValue( PropertyName );
+ lcl_convertFormulaTo(aPropertyValue,aPropertyValue);
+ if ( PROPERTY_ID_DATAFIELD == nId )
+ {
+ OUString sDataField;
+ aPropertyValue >>= sDataField;
+ switch(m_nDataFieldType)
+ {
+ case DATA_OR_FORMULA:
+ break;
+ case FUNCTION:
+ if ( isDefaultFunction(sDataField,sDataField) )
+ aPropertyValue <<= sDataField;
+ else if ( sDataField.isEmpty() )
+ aPropertyValue = uno::Any();
+ break;
+ case COUNTER:
+ case USER_DEF_FUNCTION:
+ aPropertyValue = uno::Any();
+ break;
+ }
+
+ }
+ break;
+ case PROPERTY_ID_TYPE:
+ {
+ const sal_uInt32 nOldDataFieldType = m_nDataFieldType;
+ m_nDataFieldType = impl_getDataFieldType_throw();
+ if ( UNDEF_DATA == m_nDataFieldType )
+ m_nDataFieldType = nOldDataFieldType;
+ aPropertyValue <<= m_nDataFieldType;
+ }
+ break;
+ case PROPERTY_ID_FORMULALIST:
+ case PROPERTY_ID_SCOPE:
+ {
+ uno::Any aDataField = m_xReportComponent->getPropertyValue( PROPERTY_DATAFIELD );
+ lcl_convertFormulaTo(aDataField,aDataField);
+ OUString sDataField;
+ aDataField >>= sDataField;
+ switch(m_nDataFieldType)
+ {
+ case DATA_OR_FORMULA:
+ break;
+ case FUNCTION:
+ if ( isDefaultFunction(sDataField,sDataField,uno::Reference< report::XFunctionsSupplier>(),true) )
+ aPropertyValue <<= (PROPERTY_ID_FORMULALIST == nId ? m_sDefaultFunction : m_sScope);
+ break;
+ case USER_DEF_FUNCTION:
+ if ( !sDataField.isEmpty() && PROPERTY_ID_FORMULALIST == nId )
+ aPropertyValue = aDataField;
+ break;
+ case COUNTER:
+ if ( PROPERTY_ID_SCOPE == nId && impl_isCounterFunction_throw(sDataField,m_sScope) )
+ aPropertyValue <<= m_sScope;
+ break;
+ }
+
+ }
+ break;
+ case PROPERTY_ID_BACKCOLOR:
+ case PROPERTY_ID_CONTROLBACKGROUND:
+ {
+ aPropertyValue = m_xReportComponent->getPropertyValue( PropertyName );
+ Color nColor = COL_TRANSPARENT;
+ if ( (aPropertyValue >>= nColor) && COL_TRANSPARENT == nColor )
+ aPropertyValue.clear();
+ }
+ break;
+ case PROPERTY_ID_MIMETYPE:
+ {
+ OUString sValue;
+ m_xReportComponent->getPropertyValue( PropertyName ) >>= sValue;
+ aPropertyValue <<= impl_ConvertMimeTypeToUI_nothrow(sValue);
+ }
+ break;
+ default:
+ aPropertyValue = m_xReportComponent->getPropertyValue( PropertyName );
+ break;
+ }
+ return aPropertyValue;
+}
+
+void SAL_CALL GeometryHandler::setPropertyValue(const OUString & PropertyName, const uno::Any & Value)
+{
+ ::osl::ResettableMutexGuard aGuard( m_aMutex );
+ uno::Any aNewValue = Value;
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName);
+ bool bHandled = false;
+ switch(nId)
+ {
+ case PROPERTY_ID_INITIALFORMULA:
+ case PROPERTY_ID_FORMULA:
+ break;
+ case PROPERTY_ID_DATAFIELD:
+ {
+ OBlocker aBlocker(m_bIn);
+ m_xReportComponent->setPropertyValue(PropertyName, aNewValue);
+ bHandled = true;
+ const OUString sOldFunctionName = m_sDefaultFunction;
+ const OUString sOldScope = m_sScope;
+
+ uno::Any aPropertyValue;
+ lcl_convertFormulaTo(Value,aPropertyValue);
+ OUString sDataField;
+ aPropertyValue >>= sDataField;
+
+ m_sScope.clear();
+ m_sDefaultFunction.clear();
+ m_xFunction.clear();
+ const sal_uInt32 nOldDataFieldType = m_nDataFieldType;
+ if ( !sDataField.isEmpty() )
+ {
+ if ( isDefaultFunction(sDataField,sDataField,uno::Reference< report::XFunctionsSupplier>(),true) )
+ m_nDataFieldType = FUNCTION;
+ else if ( m_aFunctionNames.find(sDataField) != m_aFunctionNames.end() )
+ m_nDataFieldType = USER_DEF_FUNCTION;
+ }
+
+ resetOwnProperties(aGuard,sOldFunctionName,sOldScope,nOldDataFieldType);
+ }
+ break;
+ case PROPERTY_ID_TYPE:
+ {
+ bHandled = true;
+ Value >>= m_nDataFieldType;
+
+ const OUString sOldFunctionName = m_sDefaultFunction;
+ const OUString sOldScope = m_sScope;
+ m_sDefaultFunction.clear();
+ m_sScope.clear();
+
+ if ( m_nDataFieldType == COUNTER )
+ {
+ impl_setCounterFunction_throw();
+ }
+ else
+ {
+ if ( m_bNewFunction )
+ removeFunction();
+ m_xFunction.clear();
+ OBlocker aBlocker(m_bIn);
+ m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(OUString()));
+ }
+ resetOwnProperties(aGuard,sOldFunctionName,sOldScope,m_nDataFieldType);
+ }
+ break;
+ case PROPERTY_ID_FORMULALIST:
+ {
+ bHandled = true;
+ OUString sFunction;
+ if ( !(Value >>= sFunction) || sFunction.isEmpty() )
+ {
+ if ( m_nDataFieldType == FUNCTION )
+ {
+ m_sDefaultFunction.clear();
+ if ( m_bNewFunction )
+ removeFunction();
+ m_xFunction.clear();
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.PropertyName = PROPERTY_SCOPE;
+ aEvent.OldValue <<= m_sScope;
+ m_sScope.clear();
+ aEvent.NewValue <<= m_sScope;
+ aGuard.clear();
+ m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aEvent );
+ }
+ else if ( m_nDataFieldType == USER_DEF_FUNCTION )
+ {
+ OBlocker aBlocker(m_bIn);
+ m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(OUString()));
+ }
+ }
+ else if ( m_nDataFieldType == USER_DEF_FUNCTION )
+ {
+ OBlocker aBlocker(m_bIn);
+ const sal_uInt32 nNewDataType = impl_getDataFieldType_throw(sFunction);
+ if ( nNewDataType != UNDEF_DATA && nNewDataType != m_nDataFieldType )
+ {
+ const OUString sOldFunctionName = m_sDefaultFunction;
+ const OUString sOldScope = m_sScope;
+ m_sScope.clear();
+ m_sDefaultFunction.clear();
+ m_xFunction.clear();
+ if ( nNewDataType == COUNTER )
+ impl_isCounterFunction_throw(sFunction,m_sScope);
+ else
+ {
+ OUString sNamePostfix;
+ OUString sDataField;
+ const uno::Reference< report::XFunctionsSupplier> xFunctionsSupplier = fillScope_throw(sNamePostfix);
+ isDefaultFunction(sFunction,sDataField,xFunctionsSupplier,true);
+ }
+ const sal_uInt32 nOldDataFieldType = m_nDataFieldType;
+ m_nDataFieldType = nNewDataType;
+ m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(impl_convertToFormula( uno::Any(sFunction))));
+ resetOwnProperties(aGuard,sOldFunctionName,sOldScope,nOldDataFieldType);
+ }
+ else
+ m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(impl_convertToFormula( uno::Any(sFunction))));
+ }
+ else if ( m_nDataFieldType == FUNCTION )
+ {
+ uno::Any aPropertyValue = m_xReportComponent->getPropertyValue(PROPERTY_DATAFIELD);
+ lcl_convertFormulaTo(aPropertyValue,aPropertyValue);
+ OUString sDataField;
+ aPropertyValue >>= sDataField;
+ if ( m_nDataFieldType == FUNCTION && (!isDefaultFunction(sDataField,sDataField) || m_sDefaultFunction != sFunction) )
+ {
+ if ( m_bNewFunction )
+ removeFunction();
+ // function currently does not exist
+ createDefaultFunction(aGuard,sFunction,sDataField);
+ m_sDefaultFunction = sFunction;
+ }
+ }
+ }
+
+ break;
+ case PROPERTY_ID_SCOPE:
+ if ( !(Value >>= m_sScope) )
+ m_sScope.clear();
+ else
+ {
+ if ( m_bNewFunction )
+ removeFunction();
+ if ( m_nDataFieldType == COUNTER )
+ impl_setCounterFunction_throw();
+ else
+ {
+ OSL_ENSURE(m_xFunction.is(),"Where is my function gone!");
+
+ OUString sNamePostfix;
+ const uno::Reference< report::XFunctionsSupplier> xFunctionsSupplier = fillScope_throw(sNamePostfix);
+
+ OUString sQuotedFunctionName(lcl_getQuotedFunctionName(m_xFunction));
+ if ( isDefaultFunction(sQuotedFunctionName,sQuotedFunctionName,xFunctionsSupplier,true) )
+ m_bNewFunction = false;
+ else
+ {
+ OUString sDefaultFunctionName;
+ OUString sDataField;
+ OSL_VERIFY( impl_isDefaultFunction_nothrow(m_xFunction,sDataField,sDefaultFunctionName) );
+ m_sDefaultFunction = sDefaultFunctionName;
+ createDefaultFunction(aGuard,m_sDefaultFunction,sDataField);
+ }
+ }
+ }
+ bHandled = true;
+ break;
+ case PROPERTY_ID_POSITIONX:
+ case PROPERTY_ID_POSITIONY:
+ case PROPERTY_ID_HEIGHT:
+ case PROPERTY_ID_WIDTH:
+ {
+ const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY);
+ if ( xSourceReportComponent.is() ) // check only report components
+ {
+ sal_Int32 nNewValue = 0;
+ Value >>= nNewValue;
+ OSL_ENSURE(nNewValue >= 0, "A position/dimension should not be negative!");
+ nNewValue = lcl_round<sal_Int32, 10>(nNewValue);
+ awt::Point aAwtPoint = xSourceReportComponent->getPosition();
+ awt::Size aAwtSize = xSourceReportComponent->getSize();
+ if ( nId == PROPERTY_ID_POSITIONX )
+ aAwtPoint.X = nNewValue;
+ else if ( nId == PROPERTY_ID_POSITIONY )
+ aAwtPoint.Y = nNewValue;
+ else if ( nId == PROPERTY_ID_HEIGHT )
+ aAwtSize.Height = nNewValue;
+ else if ( nId == PROPERTY_ID_WIDTH )
+ aAwtSize.Width = nNewValue;
+
+ checkPosAndSize(aAwtPoint,aAwtSize);
+ }
+ }
+ break;
+ case PROPERTY_ID_FONT:
+ {
+ const uno::Reference< report::XReportControlFormat > xReportControlFormat( m_xReportComponent,uno::UNO_QUERY_THROW );
+ uno::Sequence< beans::NamedValue > aFontSettings;
+ OSL_VERIFY( Value >>= aFontSettings );
+ applyCharacterSettings( xReportControlFormat, aFontSettings );
+ bHandled = true;
+ }
+ break;
+ case PROPERTY_ID_MIMETYPE:
+ {
+ OUString sValue;
+ Value >>= sValue;
+ aNewValue <<= impl_ConvertUIToMimeType_nothrow(sValue);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if ( !bHandled )
+ m_xReportComponent->setPropertyValue(PropertyName, aNewValue);
+}
+
+
+beans::PropertyState SAL_CALL GeometryHandler::getPropertyState(const OUString & PropertyName)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return m_xFormComponentHandler->getPropertyState(PropertyName);
+}
+
+void GeometryHandler::implCreateListLikeControl(
+ const uno::Reference< inspection::XPropertyControlFactory >& _rxControlFactory
+ ,inspection::LineDescriptor & out_Descriptor
+ ,const TranslateId* pResId
+ ,bool _bReadOnlyControl
+ ,bool _bTrueIfListBoxFalseIfComboBox
+ )
+{
+ std::vector<OUString> aList;
+ for (const TranslateId* pItem = pResId; *pItem; ++pItem)
+ aList.push_back(RptResId(*pItem));
+ implCreateListLikeControl(_rxControlFactory, out_Descriptor, aList, _bReadOnlyControl, _bTrueIfListBoxFalseIfComboBox);
+}
+
+void GeometryHandler::implCreateListLikeControl(
+ const uno::Reference< inspection::XPropertyControlFactory >& _rxControlFactory
+ ,inspection::LineDescriptor & out_Descriptor
+ ,const ::std::vector< OUString>& _aEntries
+ ,bool _bReadOnlyControl
+ ,bool _bTrueIfListBoxFalseIfComboBox
+ )
+{
+ const uno::Reference< inspection::XStringListControl > xListControl(
+ _rxControlFactory->createPropertyControl(
+ _bTrueIfListBoxFalseIfComboBox ? inspection::PropertyControlType::ListBox : inspection::PropertyControlType::ComboBox, _bReadOnlyControl
+ ),
+ uno::UNO_QUERY_THROW
+ );
+
+ out_Descriptor.Control = xListControl.get();
+ for (auto const& it : _aEntries)
+ {
+ xListControl->appendListEntry(it);
+ }
+}
+
+
+inspection::LineDescriptor SAL_CALL GeometryHandler::describePropertyLine(const OUString & PropertyName, const uno::Reference< inspection::XPropertyControlFactory > & _xControlFactory)
+{
+ inspection::LineDescriptor aOut;
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_FORCENEWPAGE:
+ case PROPERTY_ID_NEWROWORCOL:
+ implCreateListLikeControl(_xControlFactory,aOut,RID_STR_FORCENEWPAGE_CONST,false,true);
+ break;
+ case PROPERTY_ID_GROUPKEEPTOGETHER:
+ implCreateListLikeControl(_xControlFactory,aOut,RID_STR_GROUPKEEPTOGETHER_CONST,false,true);
+ break;
+ case PROPERTY_ID_PAGEHEADEROPTION:
+ case PROPERTY_ID_PAGEFOOTEROPTION:
+ implCreateListLikeControl(_xControlFactory,aOut,RID_STR_REPORTPRINTOPTION_CONST,false,true);
+ break;
+ case PROPERTY_ID_FORMULALIST:
+ {
+ ::std::vector< OUString > aList;
+ impl_fillFormulaList_nothrow(aList);
+ implCreateListLikeControl(_xControlFactory,aOut,aList,false,true);
+ }
+ break;
+ case PROPERTY_ID_SCOPE:
+ {
+ ::std::vector< OUString > aList;
+ impl_fillScopeList_nothrow(aList);
+ implCreateListLikeControl(_xControlFactory,aOut,aList,false,true);
+ }
+ break;
+ case PROPERTY_ID_MIMETYPE:
+ {
+ ::std::vector< OUString > aList;
+ impl_fillMimeTypes_nothrow(aList);
+ implCreateListLikeControl(_xControlFactory,aOut,aList,false,true);
+ }
+ break;
+ case PROPERTY_ID_TYPE:
+ implCreateListLikeControl(_xControlFactory,aOut,RID_STR_TYPE_CONST,false,true);
+ break;
+ case PROPERTY_ID_VISIBLE:
+ case PROPERTY_ID_CANGROW:
+ case PROPERTY_ID_CANSHRINK:
+ case PROPERTY_ID_REPEATSECTION:
+ case PROPERTY_ID_PRINTREPEATEDVALUES:
+ case PROPERTY_ID_STARTNEWCOLUMN:
+ case PROPERTY_ID_RESETPAGENUMBER:
+ case PROPERTY_ID_PRINTWHENGROUPCHANGE:
+ case PROPERTY_ID_KEEPTOGETHER:
+ case PROPERTY_ID_DEEPTRAVERSING:
+ case PROPERTY_ID_PREEVALUATED:
+ case PROPERTY_ID_PRESERVEIRI:
+ case PROPERTY_ID_BACKTRANSPARENT:
+ case PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT:
+ {
+ const TranslateId* pResId = RID_STR_BOOL;
+ if ( PROPERTY_ID_KEEPTOGETHER == nId && uno::Reference< report::XGroup>(m_xReportComponent,uno::UNO_QUERY).is())
+ pResId = RID_STR_KEEPTOGETHER_CONST;
+ implCreateListLikeControl(_xControlFactory,aOut,pResId,false,true);
+ }
+ break;
+ case PROPERTY_ID_INITIALFORMULA:
+ case PROPERTY_ID_FORMULA:
+ aOut.PrimaryButtonId = UID_RPT_PROP_FORMULA;
+ aOut.HasPrimaryButton = true;
+ aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::MultiLineTextField , false);
+ break;
+ case PROPERTY_ID_CONDITIONALPRINTEXPRESSION:
+ aOut.PrimaryButtonId = UID_RPT_PROP_FORMULA;
+ aOut.HasPrimaryButton = true;
+ aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::MultiLineTextField , false);
+ break;
+ case PROPERTY_ID_DATAFIELD:
+ {
+ uno::Reference< inspection::XStringListControl > xListControl(
+ _xControlFactory->createPropertyControl(
+ m_nDataFieldType == DATA_OR_FORMULA ? inspection::PropertyControlType::ComboBox : inspection::PropertyControlType::ListBox, false
+ ),
+ uno::UNO_QUERY_THROW
+ );
+
+ if ( m_nDataFieldType == DATA_OR_FORMULA )
+ {
+ aOut.PrimaryButtonId = UID_RPT_PROP_FORMULA;
+ aOut.HasPrimaryButton = true;
+ }
+
+ aOut.Control = xListControl.get();
+ if ( m_nDataFieldType == USER_DEF_FUNCTION )
+ {
+ // add function names
+ ::std::for_each(m_aFunctionNames.begin(), m_aFunctionNames.end(),
+ [&xListControl] (const TFunctions::value_type& func) {
+ xListControl->appendListEntry(func.first);
+ });
+ }
+ else
+ {
+ for (auto const& it : std::as_const(m_aFieldNames))
+ {
+ xListControl->appendListEntry(it);
+ }
+ for (auto const& it : std::as_const(m_aParamNames))
+ {
+ xListControl->appendListEntry(it);
+ }
+ }
+ }
+ break;
+ case PROPERTY_ID_BACKCOLOR:
+ case PROPERTY_ID_CONTROLBACKGROUND:
+ aOut.Control = _xControlFactory->createPropertyControl( inspection::PropertyControlType::ColorListBox, false );
+ break;
+ case PROPERTY_ID_FONT:
+ aOut.PrimaryButtonId = UID_RPT_RPT_PROP_DLG_FONT_TYPE;
+ aOut.Control = _xControlFactory->createPropertyControl( inspection::PropertyControlType::TextField, true );
+ aOut.HasPrimaryButton = true;
+ break;
+ case PROPERTY_ID_AREA:
+ aOut.PrimaryButtonId = UID_RPT_RPT_PROP_DLG_AREA;
+ aOut.Control = _xControlFactory->createPropertyControl( inspection::PropertyControlType::TextField, true );
+ aOut.HasPrimaryButton = true;
+ break;
+ case PROPERTY_ID_VERTICALALIGN:
+ implCreateListLikeControl(_xControlFactory,aOut,RID_STR_VERTICAL_ALIGN_CONST,false,true);
+ break;
+ case PROPERTY_ID_PARAADJUST:
+ implCreateListLikeControl(_xControlFactory,aOut,RID_STR_PARAADJUST_CONST,false,true);
+ break;
+ default:
+ {
+ aOut = m_xFormComponentHandler->describePropertyLine(PropertyName, _xControlFactory);
+ }
+ }
+
+ if ( nId != -1 )
+ {
+ aOut.Category = (OPropertyInfoService::getPropertyUIFlags(nId ) & PropUIFlags::DataProperty) ?
+ std::u16string_view(u"Data")
+ :
+ std::u16string_view(u"General");
+ aOut.HelpURL = HelpIdUrl::getHelpURL( OPropertyInfoService::getPropertyHelpId( nId ) );
+ aOut.DisplayName = OPropertyInfoService::getPropertyTranslation(nId);
+ }
+
+ if ( ( nId == PROPERTY_ID_POSITIONX )
+ || ( nId == PROPERTY_ID_POSITIONY )
+ || ( nId == PROPERTY_ID_WIDTH )
+ || ( nId == PROPERTY_ID_HEIGHT )
+ )
+ {
+ const MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
+ const sal_Int16 nDisplayUnit = VCLUnoHelper::ConvertToMeasurementUnit( MeasurementSystem::Metric == eSystem ? FieldUnit::CM : FieldUnit::INCH, 1 );
+ uno::Reference< inspection::XNumericControl > xNumericControl(aOut.Control,uno::UNO_QUERY);
+ xNumericControl->setDecimalDigits( 2 );
+ xNumericControl->setValueUnit( util::MeasureUnit::MM_100TH );
+ uno::Reference< drawing::XShapeDescriptor> xShapeDesc(m_xReportComponent,uno::UNO_QUERY);
+ bool bSetMin = !xShapeDesc.is() || xShapeDesc->getShapeType() != "com.sun.star.drawing.CustomShape";
+ if ( bSetMin )
+ xNumericControl->setMinValue(beans::Optional<double>(true,0.0));
+ if ( nDisplayUnit != -1 )
+ xNumericControl->setDisplayUnit( nDisplayUnit );
+ uno::Reference< report::XReportComponent> xComp(m_xReportComponent,uno::UNO_QUERY);
+ if ( xComp.is() && xComp->getSection().is() )
+ {
+ uno::Reference< report::XReportDefinition > xReport = xComp->getSection()->getReportDefinition();
+ OSL_ENSURE(xReport.is(),"Why is the report definition NULL!");
+ if ( xReport.is() )
+ {
+ const awt::Size aSize = getStyleProperty<awt::Size>(xReport,PROPERTY_PAPERSIZE);
+ const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReport,PROPERTY_LEFTMARGIN);
+ const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReport,PROPERTY_RIGHTMARGIN);
+ switch(nId)
+ {
+ case PROPERTY_ID_POSITIONX:
+ case PROPERTY_ID_WIDTH:
+ if ( bSetMin )
+ xNumericControl->setMinValue(beans::Optional<double>(true,0.0));
+ xNumericControl->setMaxValue(beans::Optional<double>(true,double(aSize.Width - nLeftMargin - nRightMargin)));
+ if ( PROPERTY_ID_WIDTH == nId )
+ {
+ uno::Reference<report::XFixedLine> xFixedLine(m_xReportComponent,uno::UNO_QUERY);
+ if ( xFixedLine.is() && xFixedLine->getOrientation() == 1 ) // vertical
+ xNumericControl->setMinValue(beans::Optional<double>(true,0.08 ));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else if ( PROPERTY_ID_HEIGHT == nId )
+ {
+ const uno::Reference< report::XSection> xSection(m_xReportComponent,uno::UNO_QUERY);
+ if ( xSection.is() )
+ {
+ sal_Int32 nHeight = 0;
+ const sal_Int32 nCount = xSection->getCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference<drawing::XShape> xShape(xSection->getByIndex(i),uno::UNO_QUERY);
+ nHeight = ::std::max<sal_Int32>(nHeight,xShape->getPosition().Y + xShape->getSize().Height);
+ }
+ xNumericControl->setMinValue(beans::Optional<double>(true,nHeight ));
+ }
+ }
+ }
+ return aOut;
+}
+
+beans::Property GeometryHandler::getProperty(const OUString & PropertyName)
+{
+ uno::Sequence< beans::Property > aProps = getSupportedProperties();
+ const beans::Property* pIter = aProps.getConstArray();
+ const beans::Property* pEnd = pIter + aProps.getLength();
+ const beans::Property* pFind = ::std::find_if(pIter, pEnd,
+ [&PropertyName] (const beans::Property& x) -> bool {
+ return x.Name == PropertyName;
+ });
+ if ( pFind == pEnd )
+ return beans::Property();
+ return *pFind;
+}
+uno::Any GeometryHandler::getConstantValue(bool _bToControlValue,const TranslateId* pResId,const uno::Any& _aValue,const OUString& _sConstantName,const OUString & PropertyName )
+{
+ std::vector<OUString> aList;
+ for (const TranslateId* pItem = pResId; *pItem; ++pItem)
+ aList.push_back(RptResId(*pItem));
+ uno::Sequence< OUString > aSeq(aList.size());
+ auto aSeqRange = asNonConstRange(aSeq);
+ for (size_t i = 0; i < aList.size(); ++i)
+ aSeqRange[i] = aList[i];
+
+ uno::Reference< inspection::XStringRepresentation > xConversionHelper = inspection::StringRepresentation::createConstant( m_xContext,m_xTypeConverter,_sConstantName,aSeq);
+ if ( _bToControlValue )
+ {
+ return uno::Any( xConversionHelper->convertToControlValue( _aValue ) );
+ }
+ else
+ {
+ OUString sControlValue;
+ _aValue >>= sControlValue;
+ const beans::Property aProp = getProperty(PropertyName);
+ return xConversionHelper->convertToPropertyValue( sControlValue, aProp.Type );
+ }
+}
+
+uno::Any SAL_CALL GeometryHandler::convertToPropertyValue(const OUString & PropertyName, const uno::Any & _rControlValue)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ uno::Any aPropertyValue( _rControlValue );
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_FORCENEWPAGE:
+ case PROPERTY_ID_NEWROWORCOL:
+ aPropertyValue = getConstantValue(false,RID_STR_FORCENEWPAGE_CONST,_rControlValue,"com.sun.star.report.ForceNewPage",PropertyName);
+ break;
+ case PROPERTY_ID_GROUPKEEPTOGETHER:
+ aPropertyValue = getConstantValue(false,RID_STR_GROUPKEEPTOGETHER_CONST,_rControlValue,"com.sun.star.report.GroupKeepTogether",PropertyName);
+ break;
+ case PROPERTY_ID_PAGEHEADEROPTION:
+ case PROPERTY_ID_PAGEFOOTEROPTION:
+ aPropertyValue = getConstantValue(false,RID_STR_REPORTPRINTOPTION_CONST,_rControlValue,"com.sun.star.report.ReportPrintOption",PropertyName);
+ break;
+ case PROPERTY_ID_BACKCOLOR:
+ case PROPERTY_ID_CONTROLBACKGROUND:
+ if ( !_rControlValue.hasValue() )
+ {
+ aPropertyValue <<= COL_TRANSPARENT;
+ break;
+ }
+ [[fallthrough]];
+
+ case PROPERTY_ID_KEEPTOGETHER:
+ if ( uno::Reference< report::XGroup>(m_xReportComponent,uno::UNO_QUERY).is())
+ {
+ aPropertyValue = getConstantValue(false,RID_STR_KEEPTOGETHER_CONST,_rControlValue,"com.sun.star.report.KeepTogether",PropertyName);
+ break;
+ }
+ [[fallthrough]];
+
+ case PROPERTY_ID_VISIBLE:
+ case PROPERTY_ID_CANGROW:
+ case PROPERTY_ID_CANSHRINK:
+ case PROPERTY_ID_REPEATSECTION:
+ case PROPERTY_ID_PRINTREPEATEDVALUES:
+ case PROPERTY_ID_STARTNEWCOLUMN:
+ case PROPERTY_ID_RESETPAGENUMBER:
+ case PROPERTY_ID_PRINTWHENGROUPCHANGE:
+ case PROPERTY_ID_DEEPTRAVERSING:
+ case PROPERTY_ID_PREEVALUATED:
+ case PROPERTY_ID_PRESERVEIRI:
+ case PROPERTY_ID_BACKTRANSPARENT:
+ case PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT:
+ {
+ if ( aPropertyValue.hasValue() )
+ {
+ const beans::Property aProp = getProperty(PropertyName);
+ if ( aPropertyValue.getValueType().equals( aProp.Type ) )
+ // nothing to do, type is already as desired
+ return aPropertyValue;
+
+ if ( _rControlValue.getValueType().getTypeClass() == uno::TypeClass_STRING )
+ {
+ OUString sControlValue;
+ _rControlValue >>= sControlValue;
+
+ const uno::Reference< inspection::XStringRepresentation > xConversionHelper = inspection::StringRepresentation::create( m_xContext,m_xTypeConverter );
+ aPropertyValue = xConversionHelper->convertToPropertyValue( sControlValue, aProp.Type );
+ }
+ else
+ {
+ try
+ {
+ aPropertyValue = m_xTypeConverter->convertTo( _rControlValue, aProp.Type );
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::convertToPropertyValue: caught an exception while converting via TypeConverter!" );
+ }
+ }
+ }
+
+ break;
+ }
+ case PROPERTY_ID_CONDITIONALPRINTEXPRESSION:
+ case PROPERTY_ID_INITIALFORMULA:
+ case PROPERTY_ID_FORMULA:
+ return uno::Any( impl_convertToFormula( _rControlValue ) );
+ case PROPERTY_ID_DATAFIELD:
+ {
+ OUString sDataField;
+ _rControlValue >>= sDataField;
+ if ( isDefaultFunction(sDataField,sDataField) )
+ {
+ OSL_ENSURE(m_xFunction.is(),"No function set!");
+ aPropertyValue <<= impl_convertToFormula( uno::Any(lcl_getQuotedFunctionName(m_xFunction)) );
+ }
+ else
+ aPropertyValue <<= impl_convertToFormula( _rControlValue );
+ }
+ break;
+ case PROPERTY_ID_POSITIONX:
+ {
+ aPropertyValue = m_xFormComponentHandler->convertToPropertyValue(PropertyName, _rControlValue);
+ sal_Int32 nPosX = 0;
+ aPropertyValue >>= nPosX;
+ const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY);
+ if ( xSourceReportComponent->getSection().is() )
+ nPosX += getStyleProperty<sal_Int32>(xSourceReportComponent->getSection()->getReportDefinition(),PROPERTY_LEFTMARGIN);
+ aPropertyValue <<= nPosX;
+ }
+ break;
+ case PROPERTY_ID_FONT:
+ aPropertyValue = m_xFormComponentHandler->convertToPropertyValue(PROPERTY_FONT, _rControlValue);
+ break;
+ case PROPERTY_ID_SCOPE:
+ case PROPERTY_ID_FORMULALIST:
+ case PROPERTY_ID_AREA:
+ aPropertyValue = _rControlValue;
+ break;
+ case PROPERTY_ID_TYPE:
+ {
+ OUString sValue;
+ _rControlValue >>= sValue;
+
+ sal_uInt32 nFound(RESARRAY_INDEX_NOTFOUND);
+ sal_uInt32 i = 0;
+ for (const TranslateId* pItem = RID_STR_TYPE_CONST; *pItem; ++pItem)
+ {
+ if (sValue == RptResId(*pItem))
+ {
+ nFound = i;
+ break;
+ }
+ ++i;
+ }
+ if (nFound != RESARRAY_INDEX_NOTFOUND)
+ aPropertyValue <<= nFound;
+ }
+ break;
+ case PROPERTY_ID_MIMETYPE:
+ aPropertyValue = _rControlValue;
+ break;
+ case PROPERTY_ID_VERTICALALIGN:
+ {
+ OUString sValue;
+ _rControlValue >>= sValue;
+
+ sal_uInt32 nFound(RESARRAY_INDEX_NOTFOUND);
+ sal_uInt32 i = 0;
+ for (const TranslateId* pItem = RID_STR_VERTICAL_ALIGN_CONST; *pItem; ++pItem)
+ {
+ if (sValue == RptResId(*pItem))
+ {
+ nFound = i;
+ break;
+ }
+ ++i;
+ }
+ if (nFound != RESARRAY_INDEX_NOTFOUND)
+ aPropertyValue <<= static_cast<style::VerticalAlignment>(nFound);
+ }
+ break;
+ case PROPERTY_ID_PARAADJUST:
+ {
+ OUString sValue;
+ _rControlValue >>= sValue;
+
+ sal_uInt32 nFound(RESARRAY_INDEX_NOTFOUND);
+ sal_uInt32 i = 0;
+ for (const TranslateId* pItem = RID_STR_PARAADJUST_CONST; *pItem; ++pItem)
+ {
+ if (sValue == RptResId(*pItem))
+ {
+ nFound = i;
+ break;
+ }
+ ++i;
+ }
+
+ if (nFound != RESARRAY_INDEX_NOTFOUND)
+ aPropertyValue <<= static_cast<sal_Int16>(nFound);
+ }
+ break;
+ default:
+ return m_xFormComponentHandler->convertToPropertyValue(PropertyName, _rControlValue);
+ }
+ return aPropertyValue;
+}
+
+uno::Any SAL_CALL GeometryHandler::convertToControlValue(const OUString & PropertyName, const uno::Any & _rPropertyValue, const uno::Type & _rControlValueType)
+{
+ uno::Any aControlValue( _rPropertyValue );
+ if ( !aControlValue.hasValue() )
+ // NULL is converted to NULL
+ return aControlValue;
+
+ uno::Any aPropertyValue(_rPropertyValue);
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_AREA:
+ break;
+ case PROPERTY_ID_FORCENEWPAGE:
+ case PROPERTY_ID_NEWROWORCOL:
+ aControlValue = getConstantValue(true,RID_STR_FORCENEWPAGE_CONST,aPropertyValue,"com.sun.star.report.ForceNewPage",PropertyName);
+ break;
+ case PROPERTY_ID_GROUPKEEPTOGETHER:
+ aControlValue = getConstantValue(true,RID_STR_GROUPKEEPTOGETHER_CONST,aPropertyValue,"com.sun.star.report.GroupKeepTogether",PropertyName);
+ break;
+ case PROPERTY_ID_PAGEHEADEROPTION:
+ case PROPERTY_ID_PAGEFOOTEROPTION:
+ aControlValue = getConstantValue(true,RID_STR_REPORTPRINTOPTION_CONST,aPropertyValue,"com.sun.star.report.ReportPrintOption",PropertyName);
+ break;
+ case PROPERTY_ID_KEEPTOGETHER:
+ if ( uno::Reference< report::XGroup>(m_xReportComponent,uno::UNO_QUERY).is())
+ {
+ aControlValue = getConstantValue(true,RID_STR_KEEPTOGETHER_CONST,aPropertyValue,"com.sun.star.report.KeepTogether",PropertyName);
+ break;
+ }
+ [[fallthrough]];
+ case PROPERTY_ID_VISIBLE:
+ case PROPERTY_ID_CANGROW:
+ case PROPERTY_ID_CANSHRINK:
+ case PROPERTY_ID_REPEATSECTION:
+ case PROPERTY_ID_PRINTREPEATEDVALUES:
+ case PROPERTY_ID_STARTNEWCOLUMN:
+ case PROPERTY_ID_RESETPAGENUMBER:
+ case PROPERTY_ID_PRINTWHENGROUPCHANGE:
+ case PROPERTY_ID_DEEPTRAVERSING:
+ case PROPERTY_ID_PREEVALUATED:
+ case PROPERTY_ID_PRESERVEIRI:
+ case PROPERTY_ID_BACKTRANSPARENT:
+ case PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT:
+ {
+ if ( _rControlValueType.getTypeClass() == uno::TypeClass_STRING )
+ {
+ const uno::Reference< inspection::XStringRepresentation > xConversionHelper = inspection::StringRepresentation::create( m_xContext,m_xTypeConverter );
+ aControlValue <<= xConversionHelper->convertToControlValue( aPropertyValue );
+ }
+ else
+ {
+ try
+ {
+ aControlValue = m_xTypeConverter->convertTo( aPropertyValue, _rControlValueType );
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::convertToControlValue: caught an exception while converting via TypeConverter!" );
+ }
+ }
+ break;
+ }
+ case PROPERTY_ID_CONDITIONALPRINTEXPRESSION:
+ case PROPERTY_ID_INITIALFORMULA:
+ case PROPERTY_ID_FORMULA:
+ lcl_convertFormulaTo(aPropertyValue,aControlValue);
+ break;
+ case PROPERTY_ID_DATAFIELD:
+ {
+ OUString sValue;
+ aControlValue >>= sValue;
+ if ( isDefaultFunction(sValue,sValue) )
+ aControlValue <<= sValue;
+ else
+ lcl_convertFormulaTo(aPropertyValue,aControlValue);
+ }
+ break;
+ case PROPERTY_ID_FONT:
+ aControlValue = m_xFormComponentHandler->convertToControlValue(PROPERTY_FONT, aPropertyValue, _rControlValueType);
+ break;
+ case PROPERTY_ID_POSITIONX:
+ {
+ sal_Int32 nPosX = 0;
+ aPropertyValue >>= nPosX;
+ const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY);
+ if ( xSourceReportComponent->getSection().is() )
+ nPosX -= getStyleProperty<sal_Int32>(xSourceReportComponent->getSection()->getReportDefinition(),PROPERTY_LEFTMARGIN);
+ aPropertyValue <<= nPosX;
+ aControlValue = m_xFormComponentHandler->convertToControlValue(PropertyName, aPropertyValue, _rControlValueType);
+ }
+ break;
+ case PROPERTY_ID_FORMULALIST:
+ aControlValue <<= m_sDefaultFunction;
+ break;
+ case PROPERTY_ID_SCOPE:
+ aControlValue <<= m_sScope;
+ break;
+ case PROPERTY_ID_MIMETYPE:
+ aControlValue = aPropertyValue;
+ break;
+ case PROPERTY_ID_TYPE:
+ {
+ if (m_nDataFieldType < SAL_N_ELEMENTS(RID_STR_TYPE_CONST) - 1)
+ aControlValue <<= RptResId(RID_STR_TYPE_CONST[m_nDataFieldType]);
+ }
+ break;
+ case PROPERTY_ID_VERTICALALIGN:
+ {
+ style::VerticalAlignment nParagraphVertAlign = style::VerticalAlignment_TOP;
+ aPropertyValue >>= nParagraphVertAlign;
+ if (sal_uInt32(nParagraphVertAlign) < SAL_N_ELEMENTS(RID_STR_VERTICAL_ALIGN_CONST) - 1)
+ aControlValue <<= RptResId(RID_STR_VERTICAL_ALIGN_CONST[static_cast<sal_uInt32>(nParagraphVertAlign)]);
+ }
+ break;
+ case PROPERTY_ID_PARAADJUST:
+ {
+ sal_Int16 nParagraphAdjust = sal_Int16(style::ParagraphAdjust_LEFT);
+ aPropertyValue >>= nParagraphAdjust;
+ if (o3tl::make_unsigned(nParagraphAdjust) < SAL_N_ELEMENTS(RID_STR_PARAADJUST_CONST) - 1)
+ aControlValue <<= RptResId(RID_STR_PARAADJUST_CONST[nParagraphAdjust]);
+ }
+ break;
+ case PROPERTY_ID_BACKCOLOR:
+ case PROPERTY_ID_CONTROLBACKGROUND:
+ {
+ Color nColor = COL_TRANSPARENT;
+ if ( (aPropertyValue >>= nColor) && COL_TRANSPARENT == nColor )
+ aPropertyValue.clear();
+ }
+ [[fallthrough]];
+ default:
+ aControlValue = m_xFormComponentHandler->convertToControlValue(PropertyName, aPropertyValue, _rControlValueType);
+ }
+ return aControlValue;
+}
+void SAL_CALL GeometryHandler::addPropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & _rxListener)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aPropertyListeners.addInterface( _rxListener );
+ m_xFormComponentHandler->addPropertyChangeListener(_rxListener);
+}
+
+void SAL_CALL GeometryHandler::removePropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & _rxListener)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aPropertyListeners.removeInterface( _rxListener );
+ m_xFormComponentHandler->removePropertyChangeListener(_rxListener);
+}
+
+
+uno::Sequence< beans::Property > SAL_CALL GeometryHandler::getSupportedProperties()
+{
+ ::std::vector< beans::Property > aNewProps;
+ aNewProps.reserve(20); // only a guess
+ rptui::OPropertyInfoService::getExcludeProperties( aNewProps, m_xFormComponentHandler );
+
+ const OUString pIncludeProperties[] =
+ {
+ OUString(PROPERTY_FORCENEWPAGE)
+ ,OUString(PROPERTY_KEEPTOGETHER)
+ ,OUString(PROPERTY_CANGROW)
+ ,OUString(PROPERTY_CANSHRINK)
+ ,OUString(PROPERTY_REPEATSECTION)
+ ,OUString(PROPERTY_PRINTREPEATEDVALUES)
+ ,OUString(PROPERTY_CONDITIONALPRINTEXPRESSION)
+ ,OUString(PROPERTY_STARTNEWCOLUMN)
+ ,OUString(PROPERTY_RESETPAGENUMBER)
+ ,OUString(PROPERTY_PRINTWHENGROUPCHANGE)
+ ,OUString(PROPERTY_VISIBLE)
+ ,OUString(PROPERTY_PAGEHEADEROPTION)
+ ,OUString(PROPERTY_PAGEFOOTEROPTION)
+ ,OUString("ControlLabel")
+ ,OUString(PROPERTY_POSITIONX)
+ ,OUString(PROPERTY_POSITIONY)
+ ,OUString(PROPERTY_WIDTH)
+ ,OUString(PROPERTY_HEIGHT)
+ ,OUString(PROPERTY_AUTOGROW)
+ ,OUString(PROPERTY_PREEVALUATED)
+ ,OUString(PROPERTY_DEEPTRAVERSING)
+ ,OUString(PROPERTY_FORMULA)
+ ,OUString(PROPERTY_INITIALFORMULA)
+ ,OUString(PROPERTY_PRESERVEIRI)
+ ,OUString(PROPERTY_DATAFIELD)
+ ,OUString(PROPERTY_FONT)
+ ,OUString(PROPERTY_BACKCOLOR)
+ ,OUString(PROPERTY_BACKTRANSPARENT)
+ ,OUString(PROPERTY_CONTROLBACKGROUND)
+ ,OUString(PROPERTY_CONTROLBACKGROUNDTRANSPARENT)
+ ,OUString(PROPERTY_LABEL)
+ ,OUString(PROPERTY_MIMETYPE)
+ ,OUString(PROPERTY_VERTICALALIGN)
+ ,OUString(PROPERTY_PARAADJUST)
+ };
+ const uno::Reference < beans::XPropertySetInfo > xInfo = m_xReportComponent->getPropertySetInfo();
+ const uno::Sequence< beans::Property> aSeq = xInfo->getProperties();
+ for (const auto & rIncludeProp : pIncludeProperties)
+ {
+ const beans::Property* pFind = ::std::find_if(aSeq.begin(), aSeq.end(),
+ [&rIncludeProp] (const beans::Property& x) -> bool {
+ return x.Name == rIncludeProp;
+ });
+ if ( pFind != aSeq.end() )
+ {
+ // special case for controls which contain a data field
+ if ( PROPERTY_DATAFIELD == rIncludeProp )
+ {
+ beans::Property aValue;
+ aValue.Name = PROPERTY_FORMULALIST;
+ aNewProps.push_back(aValue);
+ aValue.Name = PROPERTY_SCOPE;
+ aNewProps.push_back(aValue);
+ aValue.Name = PROPERTY_TYPE;
+ aNewProps.push_back(aValue);
+ }
+ aNewProps.push_back(*pFind);
+ }
+ }
+
+ // special property for shapes
+// if ( uno::Reference< report::XShape>(m_xReportComponent,uno::UNO_QUERY).is() )
+// {
+// beans::Property aValue;
+// aValue.Name = PROPERTY_AREA;
+// aNewProps.push_back(aValue);
+// }
+ // re-enable when the remaining issues of #i88727# are fixed
+
+ return uno::Sequence< beans::Property > (&(*aNewProps.begin()),aNewProps.size());
+}
+
+uno::Sequence< OUString > SAL_CALL GeometryHandler::getSupersededProperties()
+{
+ uno::Sequence< OUString > aRet;
+ const uno::Reference<report::XReportDefinition> xReport(m_xReportComponent,uno::UNO_QUERY);
+ if ( xReport.is() && !uno::Reference< report::XSection>(xReport->getParent(),uno::UNO_QUERY).is() )
+ {
+ aRet.realloc(5);
+ OUString* pIter = aRet.getArray();
+ *pIter++ = PROPERTY_POSITIONX;
+ *pIter++ = PROPERTY_POSITIONY;
+ *pIter++ = PROPERTY_WIDTH;
+ *pIter++ = PROPERTY_HEIGHT;
+ *pIter++ = PROPERTY_DATAFIELD;
+ }
+ return aRet;
+}
+
+uno::Sequence< OUString > SAL_CALL GeometryHandler::getActuatingProperties()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ uno::Sequence< OUString > aSeq
+ {
+ PROPERTY_BACKTRANSPARENT,
+ PROPERTY_CONTROLBACKGROUNDTRANSPARENT,
+ PROPERTY_FORMULALIST,
+ PROPERTY_TYPE,
+ PROPERTY_DATAFIELD
+ };
+
+ return ::comphelper::concatSequences(m_xFormComponentHandler->getActuatingProperties(),aSeq);
+}
+
+sal_Bool SAL_CALL GeometryHandler::isComposable(const OUString & _rPropertyName)
+{
+ return OPropertyInfoService::isComposable( _rPropertyName, m_xFormComponentHandler );
+}
+
+inspection::InteractiveSelectionResult SAL_CALL GeometryHandler::onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, uno::Any & _rData, const uno::Reference< inspection::XObjectInspectorUI > & _rxInspectorUI)
+{
+ if ( !_rxInspectorUI.is() )
+ throw lang::NullPointerException();
+ if (PropertyName == PROPERTY_FILTER)
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled;
+ OUString sClause;
+ if ( impl_dialogFilter_nothrow( sClause, aGuard ) )
+ {
+ _rData <<= sClause;
+ eResult = inspection::InteractiveSelectionResult_ObtainedValue;
+ }
+ return eResult;
+ }
+ else if (PropertyName == PROPERTY_FONT)
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled;
+ const uno::Reference< awt::XWindow> xInspectorWindow(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY);
+ const uno::Reference< report::XReportControlFormat> xReportControlFormat(m_xReportComponent,uno::UNO_QUERY);
+ aGuard.clear();
+
+ uno::Sequence< beans::NamedValue > aFontSettings;
+ if ( rptui::openCharDialog( xReportControlFormat, xInspectorWindow, aFontSettings ) )
+ {
+ _rData <<= aFontSettings;
+ eResult = inspection::InteractiveSelectionResult_ObtainedValue;
+ }
+ return eResult;
+ }
+ else if ( PropertyName == PROPERTY_FORMULA
+ || PropertyName == PROPERTY_INITIALFORMULA
+ || PropertyName == PROPERTY_DATAFIELD
+ || PropertyName == PROPERTY_CONDITIONALPRINTEXPRESSION)
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+
+ OUString sFormula;
+ m_xReportComponent->getPropertyValue(PropertyName) >>= sFormula;
+ const uno::Reference< awt::XWindow> xInspectorWindow(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY);
+ uno::Reference< uno::XComponentContext > xContext = m_xContext;
+ uno::Reference< beans::XPropertySet > xRowSet( m_xRowSet,uno::UNO_QUERY);
+ aGuard.clear();
+
+ inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled;
+ if ( rptui::openDialogFormula_nothrow( sFormula, xContext,xInspectorWindow,xRowSet ) )
+ {
+ _rData <<= sFormula;
+ eResult = inspection::InteractiveSelectionResult_ObtainedValue;
+ }
+ return eResult;
+ }
+ else if (PropertyName == PROPERTY_AREA)
+ {
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled;
+ const uno::Reference< awt::XWindow> xInspectorWindow(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY);
+ const uno::Reference< report::XShape> xShape(m_xReportComponent,uno::UNO_QUERY);
+ aGuard.clear();
+
+ if ( rptui::openAreaDialog( xShape, xInspectorWindow) )
+ {
+ eResult = inspection::InteractiveSelectionResult_ObtainedValue;
+ beans::PropertyChangeEvent aScopeEvent;
+ aScopeEvent.PropertyName = PROPERTY_FILLCOLOR;
+ aScopeEvent.NewValue = xShape->getPropertyValue(PROPERTY_FILLCOLOR);
+ m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aScopeEvent );
+ }
+ return eResult;
+ }
+
+
+ return m_xFormComponentHandler->onInteractivePropertySelection(PropertyName, Primary, _rData, _rxInspectorUI);
+}
+
+void SAL_CALL GeometryHandler::actuatingPropertyChanged(const OUString & ActuatingPropertyName, const uno::Any & NewValue, const uno::Any & OldValue, const uno::Reference< inspection::XObjectInspectorUI > & _rxInspectorUI, sal_Bool _bFirstTimeInit)
+{
+ if ( !_rxInspectorUI.is() )
+ throw lang::NullPointerException();
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ const sal_Int32 nId = OPropertyInfoService::getPropertyId(ActuatingPropertyName);
+ switch(nId)
+ {
+ case PROPERTY_ID_TYPE:
+ {
+ sal_uInt32 nNewVal = 0;
+ NewValue >>= nNewVal;
+ switch(nNewVal)
+ {
+ case DATA_OR_FORMULA:
+ _rxInspectorUI->rebuildPropertyUI(PROPERTY_DATAFIELD);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_DATAFIELD,true);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,false);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,false);
+ OSL_ENSURE(m_sDefaultFunction.isEmpty(),"Why is the m_sDefaultFunction set?");
+ OSL_ENSURE(m_sScope.isEmpty(),"Why is the m_sScope set?");
+ break;
+ case FUNCTION:
+ _rxInspectorUI->rebuildPropertyUI(PROPERTY_DATAFIELD);
+ _rxInspectorUI->rebuildPropertyUI(PROPERTY_FORMULALIST);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_DATAFIELD,true);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,!m_sDefaultFunction.isEmpty());
+ _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,!m_sScope.isEmpty());
+ break;
+ case USER_DEF_FUNCTION:
+ _rxInspectorUI->enablePropertyUI(PROPERTY_DATAFIELD,false);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,true);
+ _rxInspectorUI->rebuildPropertyUI(PROPERTY_FORMULALIST);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,false);
+ break;
+ case COUNTER:
+ _rxInspectorUI->enablePropertyUI(PROPERTY_DATAFIELD,false);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,false);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,true);
+ break;
+ }
+ }
+ break;
+ case PROPERTY_ID_DATAFIELD:
+ {
+ bool bEnable = (m_nDataFieldType != DATA_OR_FORMULA && m_nDataFieldType != COUNTER );
+ if ( bEnable )
+ {
+ OUString sValue;
+ m_xReportComponent->getPropertyValue( PROPERTY_DATAFIELD ) >>= sValue;
+ bEnable = !sValue.isEmpty();
+ }
+ _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,bEnable);
+ if ( bEnable )
+ {
+ _rxInspectorUI->rebuildPropertyUI(PROPERTY_DATAFIELD);
+ _rxInspectorUI->rebuildPropertyUI(PROPERTY_FORMULALIST);
+ }
+ m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, _rxInspectorUI, _bFirstTimeInit);
+ }
+ break;
+ case PROPERTY_ID_FORMULALIST:
+ {
+ _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,m_nDataFieldType == FUNCTION || m_nDataFieldType == COUNTER);
+ }
+ break;
+ case PROPERTY_ID_BACKTRANSPARENT:
+ case PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT:
+ {
+ bool bValue = false;
+ NewValue >>= bValue;
+ bValue = !bValue;
+ _rxInspectorUI->enablePropertyUI(PROPERTY_BACKCOLOR,bValue);
+ _rxInspectorUI->enablePropertyUI(PROPERTY_CONTROLBACKGROUND,bValue);
+ }
+ break;
+ default:
+ m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, _rxInspectorUI, _bFirstTimeInit);
+ break;
+ }
+}
+
+sal_Bool SAL_CALL GeometryHandler::suspend(sal_Bool Suspend)
+{
+ return m_xFormComponentHandler->suspend(Suspend);
+}
+
+bool GeometryHandler::impl_dialogFilter_nothrow( OUString& _out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
+{
+ _out_rSelectedClause.clear();
+ bool bSuccess = false;
+ ::dbtools::SQLExceptionInfo aErrorInfo;
+ uno::Reference< awt::XWindow > xInspectorWindow;
+ uno::Reference< lang::XMultiComponentFactory > xFactory;
+ try
+ {
+ xFactory = m_xContext->getServiceManager();
+ xInspectorWindow.set(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY);
+ uno::Reference<sdbc::XConnection> xCon(m_xContext->getValueByName("ActiveConnection") ,uno::UNO_QUERY);
+ if ( !xCon.is() )
+ return false;
+
+ uno::Reference< beans::XPropertySet> xRowSetProp(m_xRowSet,uno::UNO_QUERY);
+ if ( !m_xRowSet.is() )
+ {
+ m_xRowSet.set(xFactory->createInstanceWithContext("com.sun.star.sdb.RowSet",m_xContext),uno::UNO_QUERY);
+ xRowSetProp.set(m_xRowSet,uno::UNO_QUERY);
+ xRowSetProp->setPropertyValue(PROPERTY_ACTIVECONNECTION,uno::Any(xCon));
+ ::comphelper::copyProperties(m_xReportComponent,xRowSetProp);
+ }
+
+ // get a composer for the statement which the form is currently based on
+ uno::Reference< sdb::XSingleSelectQueryComposer > xComposer( ::dbtools::getCurrentSettingsComposer( xRowSetProp, m_xContext, nullptr ) );
+ OSL_ENSURE( xComposer.is(), "GeometryHandler::impl_dialogFilter_nothrow: could not obtain a composer!" );
+ if ( !xComposer.is() )
+ return false;
+
+ // create the dialog
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog = sdb::FilterDialog::createWithQuery(m_xContext, xComposer, m_xRowSet, xInspectorWindow);
+
+ const OUString sPropertyUIName(RptResId(RID_STR_FILTER));
+ // initialize the dialog
+ xDialog->setTitle( sPropertyUIName );
+
+ _rClearBeforeDialog.clear();
+ bSuccess = ( xDialog->execute() != 0 );
+ if ( bSuccess )
+ _out_rSelectedClause = xComposer->getFilter();
+ }
+ catch (const sdb::SQLContext& e) { aErrorInfo = e; }
+ catch (const sdbc::SQLWarning& e) { aErrorInfo = e; }
+ catch (const sdbc::SQLException& e) { aErrorInfo = e; }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::impl_dialogFilter_nothrow" );
+ }
+
+ if ( aErrorInfo.isValid() )
+ ::dbtools::showError( aErrorInfo, xInspectorWindow, m_xContext );
+
+ return bSuccess;
+}
+
+void GeometryHandler::checkPosAndSize( const awt::Point& _aNewPos,
+ const awt::Size& _aSize)
+{
+ const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY);
+ const uno::Reference< report::XSection> xSection(xSourceReportComponent->getParent(),uno::UNO_QUERY);
+ if ( !xSection.is() || uno::Reference< report::XShape>(xSourceReportComponent,uno::UNO_QUERY).is() ) // shapes can overlap.
+ return;
+
+ ::Point aPos(VCLPoint(_aNewPos));
+ if ( aPos.X() < 0 || aPos.Y() < 0 ) // TODO: have to check size with pos aka || (aPos.X() + aAwtSize.Width) > m_xSection->getReportDefinition()->
+ throw beans::PropertyVetoException(RptResId(RID_STR_ILLEGAL_POSITION),xSourceReportComponent);
+
+ ::tools::Rectangle aSourceRect(aPos,VCLSize(_aSize));
+
+ const sal_Int32 nCount = xSection->getCount();
+ for (sal_Int32 i = 0; i < nCount ; ++i)
+ {
+ const uno::Reference< report::XReportComponent> xReportComponent(xSection->getByIndex(i),uno::UNO_QUERY);
+ if ( xReportComponent.is() && xReportComponent != xSourceReportComponent )
+ {
+ const ::tools::Rectangle aBoundRect(VCLPoint(xReportComponent->getPosition()),VCLSize(xReportComponent->getSize()));
+ const ::tools::Rectangle aRect = aSourceRect.GetIntersection(aBoundRect);
+ if ( !aRect.IsEmpty() && (aRect.Left() != aRect.Right() && aRect.Top() != aRect.Bottom() ) )
+ throw beans::PropertyVetoException(RptResId( RID_STR_OVERLAP_OTHER_CONTROL),xSourceReportComponent);
+ }
+ }
+}
+
+void GeometryHandler::impl_fillFormulaList_nothrow(::std::vector< OUString >& out_rList) const
+{
+ if ( m_nDataFieldType == FUNCTION )
+ {
+ for (auto const& it : m_aDefaultFunctions)
+ {
+ out_rList.push_back(it.getName());
+ }
+ }
+ else if ( m_nDataFieldType == USER_DEF_FUNCTION )
+ ::std::transform( m_aFunctionNames.begin(),
+ m_aFunctionNames.end(),
+ ::std::back_inserter(out_rList),
+ ::o3tl::select1st< TFunctions::value_type >() );
+}
+
+OUString GeometryHandler::impl_ConvertUIToMimeType_nothrow(const OUString& _sUIName) const
+{
+ ::std::vector< OUString > aList;
+ impl_fillMimeTypes_nothrow(aList);
+ OUString sRet;
+ ::std::vector< OUString >::const_iterator aFind = ::std::find(aList.begin(),aList.end(),_sUIName);
+ if ( aFind != aList.end() )
+ {
+ const std::size_t nPos = aFind - aList.begin();
+ const uno::Reference< report::XReportDefinition> xReportDefinition(m_xReportComponent,uno::UNO_QUERY);
+ if ( xReportDefinition.is() )
+ {
+ const uno::Sequence< OUString > aMimeTypes( xReportDefinition->getAvailableMimeTypes() );
+ sRet = aMimeTypes[nPos];
+ }
+ }
+ return sRet;
+}
+
+OUString GeometryHandler::impl_ConvertMimeTypeToUI_nothrow(const OUString& _sMimetype) const
+{
+ ::comphelper::MimeConfigurationHelper aMimeHelper(m_xContext);
+ OUString sRet;
+ std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetDefaultFilter( aMimeHelper.GetDocServiceNameFromMediaType(_sMimetype) );
+ if ( pFilter )
+ sRet = pFilter->GetUIName();
+ if ( sRet.isEmpty() )
+ sRet = _sMimetype;
+ return sRet;
+}
+
+void GeometryHandler::impl_fillMimeTypes_nothrow(::std::vector< OUString >& _out_rList) const
+{
+ try
+ {
+ const uno::Reference< report::XReportDefinition> xReportDefinition(m_xReportComponent,uno::UNO_QUERY);
+ if ( xReportDefinition.is() )
+ {
+ const uno::Sequence< OUString > aMimeTypes( xReportDefinition->getAvailableMimeTypes() );
+ for(const OUString& rMimeType : aMimeTypes)
+ {
+ const OUString sDocName( impl_ConvertMimeTypeToUI_nothrow(rMimeType) );
+ if ( !sDocName.isEmpty() )
+ _out_rList.push_back(sDocName);
+ }
+ }
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "");
+ }
+}
+
+void GeometryHandler::impl_fillScopeList_nothrow(::std::vector< OUString >& _out_rList) const
+{
+ try
+ {
+ const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY_THROW);
+ const uno::Reference< report::XSection> xSection(xSourceReportComponent->getParent(),uno::UNO_QUERY_THROW);
+
+ const uno::Reference< report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
+ const uno::Reference< report::XGroups> xGroups = xReportDefinition->getGroups();
+ sal_Int32 nPos = -1;
+ uno::Reference< report::XGroup> xGroup = xSection->getGroup();
+ if ( xGroup.is() )
+ nPos = getPositionInIndexAccess(xGroups,xGroup);
+ else if ( xSection == xReportDefinition->getDetail() )
+ nPos = xGroups->getCount()-1;
+
+ const OUString sGroup = RptResId(RID_STR_SCOPE_GROUP);
+ for (sal_Int32 i = 0 ; i <= nPos ; ++i)
+ {
+ xGroup.set(xGroups->getByIndex(i),uno::UNO_QUERY_THROW);
+ OUString sGroupName = sGroup.replaceFirst("%1",xGroup->getExpression());
+ _out_rList.push_back(sGroupName);
+ }
+ _out_rList.push_back(xReportDefinition->getName());
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "");
+ }
+}
+
+uno::Reference< report::XFunctionsSupplier> GeometryHandler::fillScope_throw(OUString& _rsNamePostfix)
+{
+ uno::Reference< report::XFunctionsSupplier> xReturn;
+
+ const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY_THROW);
+ const uno::Reference< report::XSection> xSection(xSourceReportComponent->getParent(),uno::UNO_QUERY_THROW);
+ const uno::Reference< report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
+ if ( m_sScope.isEmpty() )
+ {
+ const uno::Reference< report::XGroup> xGroup = xSection->getGroup();
+ if ( xGroup.is() )
+ {
+ OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP);
+ _rsNamePostfix = xGroup->getExpression();
+ m_sScope = sGroupName.replaceFirst("%1",_rsNamePostfix);
+ xReturn = xGroup.get();
+ }
+ else if ( xSection == xReportDefinition->getDetail() )
+ {
+ const uno::Reference< report::XGroups> xGroups = xReportDefinition->getGroups();
+ const sal_Int32 nCount = xGroups->getCount();
+ if ( nCount )
+ {
+ const uno::Reference< report::XGroup> xGroup2(xGroups->getByIndex(nCount - 1),uno::UNO_QUERY_THROW);
+ OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP);
+ _rsNamePostfix = xGroup2->getExpression();
+ m_sScope = sGroupName.replaceFirst("%1",_rsNamePostfix);
+ xReturn = xGroup2.get();
+ }
+ }
+ if ( m_sScope.isEmpty() )
+ {
+ xReturn = xReportDefinition.get();
+ _rsNamePostfix = m_sScope = xReportDefinition->getName();
+ }
+ }
+ else if ( m_sScope == xReportDefinition->getName() )
+ {
+ xReturn = xReportDefinition.get();
+ _rsNamePostfix = m_sScope;
+ }
+ else
+ {
+ uno::Reference< report::XGroups> xGroups = xReportDefinition->getGroups();
+ const sal_Int32 nCount = xGroups->getCount();
+
+ for (sal_Int32 i = 0 ; i < nCount; ++i)
+ {
+ const uno::Reference< report::XGroup> xGroup(xGroups->getByIndex(i),uno::UNO_QUERY_THROW);
+ OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP);
+ if ( m_sScope == sGroupName.replaceFirst("%1",xGroup->getExpression()) )
+ {
+ _rsNamePostfix = xGroup->getExpression();
+ xReturn = xGroup.get();
+ break;
+ }
+ }
+
+ }
+ OSL_ENSURE(xReturn.is(),"Why don't we have a functionssupplier here!");
+
+ return xReturn;
+}
+
+bool GeometryHandler::isDefaultFunction( const OUString& _sQuotedFunction
+ ,OUString& _rDataField
+ ,const uno::Reference< report::XFunctionsSupplier>& _xFunctionsSupplier
+ ,bool _bSet) const
+{
+ bool bDefaultFunction = false;
+ try
+ {
+ const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY_THROW);
+ const uno::Reference< report::XSection> xSection(xSourceReportComponent->getParent(),uno::UNO_QUERY_THROW);
+ const uno::Reference< report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
+
+ ::std::pair<TFunctions::const_iterator,TFunctions::const_iterator> aFind = m_aFunctionNames.equal_range(_sQuotedFunction);
+ while ( aFind.first != aFind.second )
+ {
+ if ( !_xFunctionsSupplier.is() || _xFunctionsSupplier == aFind.first->second.second )
+ {
+ const beans::Optional< OUString> aInitialFormula = aFind.first->second.first->getInitialFormula();
+ if ( aInitialFormula.IsPresent )
+ {
+ OUString sDefaultFunctionName;
+ bDefaultFunction = impl_isDefaultFunction_nothrow(aFind.first->second.first,_rDataField,sDefaultFunctionName);
+ if ( bDefaultFunction )
+ {
+ m_xFunction = aFind.first->second.first;
+ if ( _bSet )
+ {
+ m_sDefaultFunction = sDefaultFunctionName;
+ uno::Reference< report::XGroup> xGroup(aFind.first->second.second,uno::UNO_QUERY);
+ if ( xGroup.is() )
+ {
+ OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP);
+ m_sScope = sGroupName.replaceFirst("%1",xGroup->getExpression());
+ }
+ else
+ m_sScope = xReportDefinition->getName();
+ }
+ }
+ break;
+ }
+ }
+ ++(aFind.first);
+ }
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "");
+ }
+ return bDefaultFunction;
+}
+
+bool GeometryHandler::impl_isDefaultFunction_nothrow( const uno::Reference< report::XFunction>& _xFunction
+ ,OUString& _rDataField
+ ,OUString& _rsDefaultFunctionName) const
+{
+ bool bDefaultFunction = false;
+ try
+ {
+ const OUString sFormula( _xFunction->getFormula() );
+ i18nutil::SearchOptions2 aSearchOptions;
+ aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::REGEXP;
+ aSearchOptions.searchFlag = 0x00000100;
+ auto aIter = std::find_if(m_aDefaultFunctions.begin(), m_aDefaultFunctions.end(),
+ [&aSearchOptions, &sFormula](const DefaultFunction& rDefaultFunction) {
+ aSearchOptions.searchString = rDefaultFunction.m_sSearchString;
+ utl::TextSearch aTextSearch( aSearchOptions);
+ sal_Int32 start = 0;
+ sal_Int32 end = sFormula.getLength();
+ return aTextSearch.SearchForward(sFormula, &start, &end) && start == 0 && end == sFormula.getLength();
+ });
+ if (aIter != m_aDefaultFunctions.end()) // default function found
+ {
+ sal_Int32 start = 0;
+ sal_Int32 end = sFormula.getLength();
+ aSearchOptions.searchString = "\\[[:alpha:]+([:space:]*[:alnum:]*)*\\]";
+ utl::TextSearch aDataSearch( aSearchOptions);
+ (void)aDataSearch.SearchForward(sFormula, &start, &end);
+ ++start;
+ _rDataField = sFormula.copy(start,end-start-1);
+ _rsDefaultFunctionName = aIter->m_sName;
+ bDefaultFunction = true;
+ }
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "");
+ }
+ return bDefaultFunction;
+}
+
+void GeometryHandler::loadDefaultFunctions()
+{
+ if ( !m_aDefaultFunctions.empty() )
+ return;
+
+ m_aCounterFunction.m_bPreEvaluated = false;
+ m_aCounterFunction.m_sName = RptResId(RID_STR_F_COUNTER);
+ m_aCounterFunction.m_sFormula = "rpt:[%FunctionName] + 1";
+ m_aCounterFunction.m_sSearchString = "rpt:\\[[:alpha:]+([:space:]*[:alnum:]*)*\\][:space:]*\\+[:space:]*[:digit:]*";
+ m_aCounterFunction.m_sInitialFormula.IsPresent = true;
+ m_aCounterFunction.m_sInitialFormula.Value = "rpt:1";
+
+ DefaultFunction aDefault;
+
+ aDefault.m_bPreEvaluated = true;
+
+ aDefault.m_sName = RptResId(RID_STR_F_ACCUMULATION);
+ aDefault.m_sFormula = "rpt:[%Column] + [%FunctionName]";
+ aDefault.m_sSearchString = "rpt:\\[[:alpha:]+([:space:]*[:alnum:]*)*\\][:space:]*\\+[:space:]*\\[[:alpha:]+([:space:]*[:alnum:]*)*\\]";
+ aDefault.m_sInitialFormula.IsPresent = true;
+ aDefault.m_sInitialFormula.Value = "rpt:[%Column]";
+ m_aDefaultFunctions.push_back(aDefault);
+
+ aDefault.m_sName = RptResId(RID_STR_F_MINIMUM);
+ aDefault.m_sFormula = "rpt:IF([%Column] < [%FunctionName];[%Column];[%FunctionName])";
+ aDefault.m_sSearchString = "rpt:IF\\((\\[[:alpha:]+([:space:]*[:alnum:]*)*\\])[:space:]*<[:space:]*(\\[[:alpha:]+([:space:]*[:alnum:]*)*\\]);[:space:]*\\1[:space:]*;[:space:]*\\3[:space:]*\\)";
+ aDefault.m_sInitialFormula.IsPresent = true;
+ aDefault.m_sInitialFormula.Value = "rpt:[%Column]";
+ m_aDefaultFunctions.push_back(aDefault);
+
+ aDefault.m_sName = RptResId(RID_STR_F_MAXIMUM);
+ aDefault.m_sFormula = "rpt:IF([%Column] > [%FunctionName];[%Column];[%FunctionName])";
+ aDefault.m_sSearchString = "rpt:IF\\((\\[[:alpha:]+([:space:]*[:alnum:]*)*\\])[:space:]*>[:space:]*(\\[[:alpha:]+([:space:]*[:alnum:]*)*\\]);[:space:]*\\1[:space:]*;[:space:]*\\3[:space:]*\\)";
+ aDefault.m_sInitialFormula.IsPresent = true;
+ aDefault.m_sInitialFormula.Value = "rpt:[%Column]";
+ m_aDefaultFunctions.push_back(aDefault);
+}
+
+void GeometryHandler::createDefaultFunction(::osl::ResettableMutexGuard& _aGuard ,const OUString& _sFunction,std::u16string_view _sDataField)
+{
+ try
+ {
+ OUString sNamePostfix;
+ const uno::Reference< report::XFunctionsSupplier> xFunctionsSupplier = fillScope_throw(sNamePostfix);
+
+ auto aIter = std::find_if(m_aDefaultFunctions.begin(), m_aDefaultFunctions.end(),
+ [&_sFunction](const DefaultFunction& rDefaultFunction) { return rDefaultFunction.m_sName == _sFunction; });
+ if (aIter != m_aDefaultFunctions.end())
+ {
+ const OUString sFunctionName( _sFunction + _sDataField + sNamePostfix);
+ const OUString sQuotedFunctionName(lcl_getQuotedFunctionName(sFunctionName));
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.PropertyName = PROPERTY_SCOPE;
+ aEvent.OldValue <<= m_sScope;
+
+ ::std::pair<TFunctions::const_iterator,TFunctions::const_iterator> aFind = m_aFunctionNames.equal_range(sQuotedFunctionName);
+ while ( aFind.first != aFind.second )
+ {
+ if ( xFunctionsSupplier == aFind.first->second.second )
+ {
+ m_xFunction = aFind.first->second.first;
+ OUString sTemp;
+ isDefaultFunction(sQuotedFunctionName,sTemp,uno::Reference< report::XFunctionsSupplier>(),true); // implicitly sets the m_sScope
+ break;
+ }
+ ++(aFind.first);
+ }
+ if ( aFind.first == aFind.second )
+ impl_createFunction(sFunctionName,_sDataField,*aIter);
+
+ OBlocker aBlocker(m_bIn);
+ m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any( impl_convertToFormula( uno::Any(sQuotedFunctionName) )));
+ aEvent.NewValue <<= m_sScope;
+ _aGuard.clear();
+ m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aEvent );
+ }
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "");
+ }
+}
+
+void GeometryHandler::removeFunction()
+{
+ if ( !m_xFunction.is() )
+ return;
+
+ const OUString sQuotedFunctionName(lcl_getQuotedFunctionName(m_xFunction));
+ ::std::pair<TFunctions::iterator,TFunctions::iterator> aFind = m_aFunctionNames.equal_range(sQuotedFunctionName);
+ while ( aFind.first != aFind.second )
+ {
+ if ( aFind.first->second.first == m_xFunction )
+ {
+ uno::Reference< report::XFunctions> xFunctions = aFind.first->second.second->getFunctions();
+ xFunctions->removeByIndex(xFunctions->getCount() - 1 ); /// TODO: insert new method in XFunctions: removeFunction(xfunction)
+ m_aFunctionNames.erase(aFind.first);
+ m_bNewFunction = false;
+ break;
+ }
+ ++(aFind.first);
+ }
+}
+
+void GeometryHandler::resetOwnProperties(::osl::ResettableMutexGuard& _aGuard,const OUString& _sOldFunctionName,const OUString& _sOldScope,const sal_uInt32 _nOldDataFieldType)
+{
+ const OUString sNewFunction = m_sDefaultFunction;
+ const OUString sNewScope = m_sScope;
+ const sal_uInt32 nNewDataFieldType = m_nDataFieldType;
+ _aGuard.clear();
+ if ( _nOldDataFieldType != nNewDataFieldType )
+ {
+ beans::PropertyChangeEvent aScopeEvent;
+ aScopeEvent.PropertyName = PROPERTY_TYPE;
+ aScopeEvent.OldValue <<= _nOldDataFieldType;
+ aScopeEvent.NewValue <<= nNewDataFieldType;
+ m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aScopeEvent );
+ }
+ if ( _sOldFunctionName != sNewFunction )
+ {
+ beans::PropertyChangeEvent aFormulaEvent;
+ aFormulaEvent.PropertyName = PROPERTY_FORMULALIST;
+ aFormulaEvent.OldValue <<= _sOldFunctionName;
+ aFormulaEvent.NewValue <<= sNewFunction;
+
+ m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aFormulaEvent );
+ }
+ if ( _sOldScope != sNewScope )
+ {
+ beans::PropertyChangeEvent aScopeEvent;
+ aScopeEvent.PropertyName = PROPERTY_SCOPE;
+ aScopeEvent.OldValue <<= _sOldScope;
+ aScopeEvent.NewValue <<= sNewScope;
+ m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aScopeEvent );
+ }
+
+ _aGuard.reset();
+}
+
+void GeometryHandler::impl_initFieldList_nothrow( uno::Sequence< OUString >& _rFieldNames ) const
+{
+ _rFieldNames.realloc(0);
+ try
+ {
+ uno::Reference< awt::XWindow> xInspectorWindow(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY);
+ weld::WaitObject aWaitCursor(Application::GetFrameWeld(xInspectorWindow));
+
+ // get the form of the control we're inspecting
+ uno::Reference< beans::XPropertySet > xFormSet( m_xRowSet, uno::UNO_QUERY );
+ if ( !xFormSet.is() )
+ return;
+
+ OUString sObjectName;
+ OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMAND ) >>= sObjectName );
+ // when there is no command we don't need to ask for columns
+ uno::Reference<sdbc::XConnection> xCon(m_xContext->getValueByName("ActiveConnection") ,uno::UNO_QUERY);
+ if ( !sObjectName.isEmpty() && xCon.is() )
+ {
+ sal_Int32 nObjectType = sdb::CommandType::COMMAND;
+ OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nObjectType );
+
+ _rFieldNames = ::dbtools::getFieldNamesByCommandDescriptor( xCon, nObjectType, sObjectName );
+ }
+ }
+ catch (uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::impl_initFieldList_nothrow" );
+ }
+}
+
+bool GeometryHandler::impl_isCounterFunction_throw(const OUString& _sQuotedFunctionName,OUString& Out_sScope) const
+{
+ ::std::pair<TFunctions::const_iterator,TFunctions::const_iterator> aFind = m_aFunctionNames.equal_range(_sQuotedFunctionName);
+ while ( aFind.first != aFind.second )
+ {
+ const beans::Optional< OUString> aInitialFormula = aFind.first->second.first->getInitialFormula();
+ if ( aInitialFormula.IsPresent )
+ {
+ const OUString sFormula( aFind.first->second.first->getFormula() );
+ i18nutil::SearchOptions2 aSearchOptions;
+ aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::REGEXP;
+ aSearchOptions.searchFlag = 0x00000100;
+ aSearchOptions.searchString = m_aCounterFunction.m_sSearchString;
+ utl::TextSearch aTextSearch( aSearchOptions);
+ sal_Int32 start = 0;
+ sal_Int32 end = sFormula.getLength();
+ if ( aTextSearch.SearchForward(sFormula,&start,&end) && start == 0 && end == sFormula.getLength()) // counter function found
+ {
+ const uno::Reference< report::XGroup > xGroup(aFind.first->second.second,uno::UNO_QUERY);
+ if ( xGroup.is() )
+ {
+ OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP);
+ Out_sScope = sGroupName.replaceFirst("%1",xGroup->getExpression());
+ }
+ else
+ Out_sScope = uno::Reference< report::XReportDefinition >(aFind.first->second.second,uno::UNO_QUERY_THROW)->getName();
+ break;
+ }
+ }
+ ++(aFind.first);
+ }
+ return aFind.first != aFind.second;
+}
+
+void GeometryHandler::impl_createFunction(const OUString& _sFunctionName,std::u16string_view _sDataField,const DefaultFunction& _aFunction)
+{
+ if ( m_bNewFunction )
+ removeFunction();
+
+ const OUString sQuotedFunctionName(lcl_getQuotedFunctionName(_sFunctionName));
+ m_xFunction.set(report::Function::create(m_xContext));
+ m_xFunction->setName( _sFunctionName );
+
+ static const OUStringLiteral sPlaceHolder1(u"%Column");
+ static const OUStringLiteral sPlaceHolder2(u"%FunctionName");
+ OUString sFormula(_aFunction.m_sFormula);
+ sFormula = sFormula.replaceAll(sPlaceHolder1,_sDataField);
+ sFormula = sFormula.replaceAll(sPlaceHolder2,_sFunctionName);
+
+ m_xFunction->setFormula(sFormula);
+ m_xFunction->setPreEvaluated(_aFunction.m_bPreEvaluated);
+ m_xFunction->setDeepTraversing(false);
+ if ( _aFunction.m_sInitialFormula.IsPresent )
+ {
+ beans::Optional< OUString> aInitialFormula = _aFunction.m_sInitialFormula;
+ OUString sInitialFormula = aInitialFormula.Value;
+ sInitialFormula = sInitialFormula.replaceAll(sPlaceHolder1,_sDataField);
+ sInitialFormula = sInitialFormula.replaceAll(sPlaceHolder2,_sFunctionName);
+ aInitialFormula.Value = sInitialFormula;
+ m_xFunction->setInitialFormula( aInitialFormula );
+ }
+ OUString sNamePostfix;
+ const uno::Reference< report::XFunctionsSupplier> xFunctionsSupplier = fillScope_throw(sNamePostfix);
+ const uno::Reference< container::XIndexContainer> xFunctions(xFunctionsSupplier->getFunctions(),uno::UNO_QUERY_THROW);
+ xFunctions->insertByIndex(xFunctions->getCount(),uno::Any(m_xFunction));
+ m_aFunctionNames.emplace(sQuotedFunctionName,TFunctionPair(m_xFunction,xFunctionsSupplier));
+ m_bNewFunction = true;
+}
+
+void GeometryHandler::impl_setCounterFunction_throw()
+{
+ OUString sNamePostfix;
+ fillScope_throw(sNamePostfix);
+ OUString sFunctionName = m_aCounterFunction.m_sName + sNamePostfix;
+ const OUString sQuotedFunctionName = lcl_getQuotedFunctionName(sFunctionName);
+ OUString sScope;
+ if ( !(!sFunctionName.isEmpty() && m_aFunctionNames.find(sQuotedFunctionName) != m_aFunctionNames.end() && impl_isCounterFunction_throw(sQuotedFunctionName,sScope)) )
+ impl_createFunction(sFunctionName,{},m_aCounterFunction);
+
+ OBlocker aBlocker(m_bIn);
+ m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(impl_convertToFormula( uno::Any(sQuotedFunctionName))));
+}
+
+sal_uInt32 GeometryHandler::impl_getDataFieldType_throw(const OUString& _sDataField) const
+{
+ sal_uInt32 nDataFieldType = UNDEF_DATA;
+ OUString sDataField;
+ if ( !_sDataField.isEmpty() )
+ sDataField = _sDataField;
+ else
+ {
+ uno::Any aDataField( m_xReportComponent->getPropertyValue( PROPERTY_DATAFIELD ) );
+ lcl_convertFormulaTo(aDataField,aDataField);
+ aDataField >>= sDataField;
+ }
+
+ if ( !sDataField.isEmpty() )
+ {
+ if ( impl_isDataField(sDataField) )
+ nDataFieldType = DATA_OR_FORMULA;
+ else if ( isDefaultFunction(sDataField,sDataField) )
+ nDataFieldType = FUNCTION;
+ else if ( m_aFunctionNames.find(sDataField) != m_aFunctionNames.end() )
+ {
+ nDataFieldType = USER_DEF_FUNCTION;
+ OUString sScope;
+ if ( impl_isCounterFunction_throw(sDataField,sScope) )
+ nDataFieldType = COUNTER;
+ }
+ else
+ nDataFieldType = DATA_OR_FORMULA;
+ }
+ return nDataFieldType;
+}
+
+// XEventListener
+void SAL_CALL GeometryHandler::disposing(const lang::EventObject& )
+{
+}
+// XPropertyChangeListener
+void SAL_CALL GeometryHandler::propertyChange(const beans::PropertyChangeEvent& /*evt*/)
+{
+ ::osl::ResettableMutexGuard aGuard( m_aMutex );
+ if ( m_bIn )
+ return;
+
+ const sal_uInt32 nOldDataFieldType = m_nDataFieldType;
+ const OUString sOldFunctionName = m_sDefaultFunction;
+ const OUString sOldScope = m_sScope;
+ m_sDefaultFunction.clear();
+ m_sScope.clear();
+ m_nDataFieldType = impl_getDataFieldType_throw();
+ if ( UNDEF_DATA == m_nDataFieldType )
+ m_nDataFieldType = nOldDataFieldType;
+ uno::Any aDataField = m_xReportComponent->getPropertyValue( PROPERTY_DATAFIELD );
+ lcl_convertFormulaTo(aDataField,aDataField);
+ OUString sDataField;
+ aDataField >>= sDataField;
+ switch(m_nDataFieldType)
+ {
+ case FUNCTION:
+ isDefaultFunction(sDataField,sDataField,uno::Reference< report::XFunctionsSupplier>(),true);
+ break;
+ case COUNTER:
+ impl_isCounterFunction_throw(sDataField,m_sScope);
+ break;
+ default:
+ ;
+ }
+
+ resetOwnProperties(aGuard,sOldFunctionName,sOldScope,nOldDataFieldType);
+}
+
+} // namespace rptui
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+reportdesign_GeometryHandler_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new rptui::GeometryHandler(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inspection/ReportComponentHandler.cxx b/reportdesign/source/ui/inspection/ReportComponentHandler.cxx
new file mode 100644
index 000000000..28b33acc4
--- /dev/null
+++ b/reportdesign/source/ui/inspection/ReportComponentHandler.cxx
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <ReportComponentHandler.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/NullPointerException.hpp>
+#include <comphelper/types.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/form/inspection/FormComponentPropertyHandler.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <metadata.hxx>
+
+
+namespace rptui
+{
+
+using namespace ::com::sun::star;
+
+ReportComponentHandler::ReportComponentHandler(uno::Reference< uno::XComponentContext > const & context)
+ :ReportComponentHandler_Base(m_aMutex)
+ ,m_xContext(context)
+{
+ try
+ {
+ m_xFormComponentHandler = form::inspection::FormComponentPropertyHandler::create(m_xContext);
+
+ }catch(const uno::Exception &)
+ {
+ }
+}
+
+OUString SAL_CALL ReportComponentHandler::getImplementationName( )
+{
+ return "com.sun.star.comp.report.ReportComponentHandler";
+}
+
+sal_Bool SAL_CALL ReportComponentHandler::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL ReportComponentHandler::getSupportedServiceNames( )
+{
+ return { "com.sun.star.report.inspection.ReportComponentHandler" };
+}
+
+// override WeakComponentImplHelperBase::disposing()
+// This function is called upon disposing the component,
+// if your component needs special work when it becomes
+// disposed, do it here.
+void SAL_CALL ReportComponentHandler::disposing()
+{
+ ::comphelper::disposeComponent(m_xFormComponentHandler);
+}
+void SAL_CALL ReportComponentHandler::addEventListener(const uno::Reference< lang::XEventListener > & xListener)
+{
+ m_xFormComponentHandler->addEventListener(xListener);
+}
+
+void SAL_CALL ReportComponentHandler::removeEventListener(const uno::Reference< lang::XEventListener > & aListener)
+{
+ m_xFormComponentHandler->removeEventListener(aListener);
+}
+
+// inspection::XPropertyHandler:
+
+/********************************************************************************/
+void SAL_CALL ReportComponentHandler::inspect(const uno::Reference< uno::XInterface > & Component)
+{
+ try
+ {
+ uno::Reference< container::XNameContainer > xNameCont(Component,uno::UNO_QUERY);
+ static const OUStringLiteral sFormComponent(u"FormComponent");
+ if ( xNameCont->hasByName(sFormComponent) )
+ xNameCont->getByName(sFormComponent) >>= m_xFormComponent;
+ static const OUStringLiteral sRowSet(u"RowSet");
+ if ( xNameCont->hasByName(sRowSet) )
+ {
+ uno::Reference<beans::XPropertySet> xProp(m_xFormComponentHandler,uno::UNO_QUERY);
+ xProp->setPropertyValue(sRowSet,xNameCont->getByName(sRowSet));
+ }
+ }
+ catch(const uno::Exception &)
+ {
+ throw lang::NullPointerException();
+ }
+ if ( m_xFormComponent.is() )
+ {
+ m_xFormComponentHandler->inspect(m_xFormComponent);
+ }
+}
+
+uno::Any SAL_CALL ReportComponentHandler::getPropertyValue(const OUString & PropertyName)
+{
+ return m_xFormComponentHandler->getPropertyValue(PropertyName);
+}
+
+void SAL_CALL ReportComponentHandler::setPropertyValue(const OUString & PropertyName, const uno::Any & Value)
+{
+ m_xFormComponentHandler->setPropertyValue(PropertyName, Value);
+}
+
+beans::PropertyState SAL_CALL ReportComponentHandler::getPropertyState(const OUString & PropertyName)
+{
+ return m_xFormComponentHandler->getPropertyState(PropertyName);
+}
+
+inspection::LineDescriptor SAL_CALL ReportComponentHandler::describePropertyLine(const OUString & PropertyName, const uno::Reference< inspection::XPropertyControlFactory > & ControlFactory)
+{
+ return m_xFormComponentHandler->describePropertyLine(PropertyName, ControlFactory);
+}
+
+uno::Any SAL_CALL ReportComponentHandler::convertToPropertyValue(const OUString & PropertyName, const uno::Any & ControlValue)
+{
+ return m_xFormComponentHandler->convertToPropertyValue(PropertyName, ControlValue);
+}
+
+uno::Any SAL_CALL ReportComponentHandler::convertToControlValue(const OUString & PropertyName, const uno::Any & PropertyValue, const uno::Type & ControlValueType)
+{
+ return m_xFormComponentHandler->convertToControlValue(PropertyName, PropertyValue, ControlValueType);
+}
+
+void SAL_CALL ReportComponentHandler::addPropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & Listener)
+{
+ m_xFormComponentHandler->addPropertyChangeListener(Listener);
+}
+
+void SAL_CALL ReportComponentHandler::removePropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & _rxListener)
+{
+ m_xFormComponentHandler->removePropertyChangeListener(_rxListener);
+}
+
+uno::Sequence< beans::Property > SAL_CALL ReportComponentHandler::getSupportedProperties()
+{
+ ::std::vector< beans::Property > aNewProps;
+ rptui::OPropertyInfoService::getExcludeProperties( aNewProps, m_xFormComponentHandler );
+
+ return uno::Sequence< beans::Property >(aNewProps.data(), aNewProps.size());
+}
+
+uno::Sequence< OUString > SAL_CALL ReportComponentHandler::getSupersededProperties()
+{
+ uno::Sequence< OUString > aRet;
+ return aRet;
+}
+
+uno::Sequence< OUString > SAL_CALL ReportComponentHandler::getActuatingProperties()
+{
+ return m_xFormComponentHandler->getActuatingProperties();
+}
+
+sal_Bool SAL_CALL ReportComponentHandler::isComposable( const OUString& _rPropertyName )
+{
+ return OPropertyInfoService::isComposable( _rPropertyName, m_xFormComponentHandler );
+}
+
+inspection::InteractiveSelectionResult SAL_CALL ReportComponentHandler::onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, uno::Any & out_Data, const uno::Reference< inspection::XObjectInspectorUI > & InspectorUI)
+{
+ return m_xFormComponentHandler->onInteractivePropertySelection(PropertyName, Primary, out_Data, InspectorUI);
+}
+
+void SAL_CALL ReportComponentHandler::actuatingPropertyChanged(const OUString & ActuatingPropertyName, const uno::Any & NewValue, const uno::Any & OldValue, const uno::Reference< inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit)
+{
+ m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, InspectorUI, FirstTimeInit);
+}
+
+sal_Bool SAL_CALL ReportComponentHandler::suspend(sal_Bool Suspend)
+{
+ return m_xFormComponentHandler->suspend(Suspend);
+}
+
+
+} // namespace rptui
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+reportdesign_ReportComponentHandler_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new rptui::ReportComponentHandler(context));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/inspection/metadata.cxx b/reportdesign/source/ui/inspection/metadata.cxx
new file mode 100644
index 000000000..59bbdb21d
--- /dev/null
+++ b/reportdesign/source/ui/inspection/metadata.cxx
@@ -0,0 +1,293 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <metadata.hxx>
+#include <com/sun/star/inspection/XPropertyHandler.hpp>
+#include <core_resource.hxx>
+#include <helpids.h>
+#include <strings.hrc>
+#include <strings.hxx>
+
+#include <algorithm>
+#include <string_view>
+
+namespace rptui
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star;
+
+
+ //= OPropertyInfoImpl
+
+ struct OPropertyInfoImpl
+ {
+ OUString sName;
+ OUString sTranslation;
+ OString sHelpId;
+ sal_Int32 nId;
+ PropUIFlags nUIFlags;
+
+ OPropertyInfoImpl(
+ const OUString& rName,
+ sal_Int32 _nId,
+ const OUString& aTranslation,
+ const OString& _sHelpId,
+ PropUIFlags _nUIFlags);
+ };
+
+
+ OPropertyInfoImpl::OPropertyInfoImpl(const OUString& _rName, sal_Int32 _nId,
+ const OUString& aString, const OString& sHid, PropUIFlags _nUIFlags)
+ :sName(_rName)
+ ,sTranslation(aString)
+ ,sHelpId(sHid)
+ ,nId(_nId)
+ ,nUIFlags(_nUIFlags)
+ {
+ }
+
+ namespace {
+
+ // compare PropertyInfo
+ struct PropertyInfoLessByName
+ {
+ bool operator()( const OPropertyInfoImpl& _lhs, const OPropertyInfoImpl& _rhs )
+ {
+ return _lhs.sName < _rhs.sName;
+ }
+ };
+
+ }
+
+ //= OPropertyInfoService
+
+ sal_uInt16 OPropertyInfoService::s_nCount = 0;
+ OPropertyInfoImpl* OPropertyInfoService::s_pPropertyInfos = nullptr;
+
+ const OPropertyInfoImpl* OPropertyInfoService::getPropertyInfo()
+ {
+ if ( s_pPropertyInfos )
+ return s_pPropertyInfos;
+
+ static OPropertyInfoImpl aPropertyInfos[] =
+ {
+ OPropertyInfoImpl(PROPERTY_FORCENEWPAGE, PROPERTY_ID_FORCENEWPAGE, RptResId(RID_STR_FORCENEWPAGE), HID_RPT_PROP_FORCENEWPAGE, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_NEWROWORCOL, PROPERTY_ID_NEWROWORCOL, RptResId(RID_STR_NEWROWORCOL), HID_RPT_PROP_NEWROWORCOL, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_KEEPTOGETHER, PROPERTY_ID_KEEPTOGETHER, RptResId(RID_STR_KEEPTOGETHER), HID_RPT_PROP_KEEPTOGETHER, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_CANGROW, PROPERTY_ID_CANGROW, RptResId(RID_STR_CANGROW), HID_RPT_PROP_CANGROW, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_CANSHRINK, PROPERTY_ID_CANSHRINK, RptResId(RID_STR_CANSHRINK), HID_RPT_PROP_CANSHRINK, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_REPEATSECTION, PROPERTY_ID_REPEATSECTION, RptResId(RID_STR_REPEATSECTION), HID_RPT_PROP_REPEATSECTION, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_PRINTREPEATEDVALUES, PROPERTY_ID_PRINTREPEATEDVALUES, RptResId(RID_STR_PRINTREPEATEDVALUES), HID_RPT_PROP_PRINTREPEATEDVALUES, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_CONDITIONALPRINTEXPRESSION, PROPERTY_ID_CONDITIONALPRINTEXPRESSION, RptResId(RID_STR_CONDITIONALPRINTEXPRESSION), HID_RPT_PROP_CONDITIONALPRINTEXPRESSION,
+ PropUIFlags::Composeable ),
+ OPropertyInfoImpl(PROPERTY_STARTNEWCOLUMN, PROPERTY_ID_STARTNEWCOLUMN, RptResId(RID_STR_STARTNEWCOLUMN), HID_RPT_PROP_STARTNEWCOLUMN, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_RESETPAGENUMBER, PROPERTY_ID_RESETPAGENUMBER, RptResId(RID_STR_RESETPAGENUMBER), HID_RPT_PROP_RESETPAGENUMBER, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_PRINTWHENGROUPCHANGE, PROPERTY_ID_PRINTWHENGROUPCHANGE, RptResId(RID_STR_PRINTWHENGROUPCHANGE), HID_RPT_PROP_PRINTWHENGROUPCHANGE, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_VISIBLE, PROPERTY_ID_VISIBLE, RptResId(RID_STR_VISIBLE), HID_RPT_PROP_VISIBLE, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_GROUPKEEPTOGETHER, PROPERTY_ID_GROUPKEEPTOGETHER, RptResId(RID_STR_GROUPKEEPTOGETHER), HID_RPT_PROP_GROUPKEEPTOGETHER, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_PAGEHEADEROPTION, PROPERTY_ID_PAGEHEADEROPTION, RptResId(RID_STR_PAGEHEADEROPTION), HID_RPT_PROP_PAGEHEADEROPTION, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_PAGEFOOTEROPTION, PROPERTY_ID_PAGEFOOTEROPTION, RptResId(RID_STR_PAGEFOOTEROPTION), HID_RPT_PROP_PAGEFOOTEROPTION, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_POSITIONX, PROPERTY_ID_POSITIONX, RptResId(RID_STR_POSITIONX), HID_RPT_PROP_RPT_POSITIONX, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_POSITIONY, PROPERTY_ID_POSITIONY, RptResId(RID_STR_POSITIONY), HID_RPT_PROP_RPT_POSITIONY, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_WIDTH, PROPERTY_ID_WIDTH, RptResId(RID_STR_WIDTH), HID_RPT_PROP_RPT_WIDTH, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_HEIGHT, PROPERTY_ID_HEIGHT, RptResId(RID_STR_HEIGHT), HID_RPT_PROP_RPT_HEIGHT, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_AUTOGROW, PROPERTY_ID_AUTOGROW, RptResId(RID_STR_AUTOGROW), HID_RPT_PROP_RPT_AUTOGROW, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_FONT, PROPERTY_ID_FONT, RptResId(RID_STR_FONT), HID_RPT_PROP_RPT_FONT, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_PREEVALUATED, PROPERTY_ID_PREEVALUATED, RptResId(RID_STR_PREEVALUATED), HID_RPT_PROP_PREEVALUATED, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_DEEPTRAVERSING, PROPERTY_ID_DEEPTRAVERSING, RptResId(RID_STR_DEEPTRAVERSING), HID_RPT_PROP_DEEPTRAVERSING, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_FORMULA, PROPERTY_ID_FORMULA, RptResId(RID_STR_FORMULA), HID_RPT_PROP_FORMULA, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_INITIALFORMULA, PROPERTY_ID_INITIALFORMULA, RptResId(RID_STR_INITIALFORMULA), HID_RPT_PROP_INITIALFORMULA, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_TYPE, PROPERTY_ID_TYPE, RptResId(RID_STR_TYPE), HID_RPT_PROP_TYPE, PropUIFlags::Composeable | PropUIFlags::DataProperty),
+ OPropertyInfoImpl(PROPERTY_DATAFIELD,PROPERTY_ID_DATAFIELD, RptResId(RID_STR_DATAFIELD), HID_RPT_PROP_DATAFIELD, PropUIFlags::Composeable | PropUIFlags::DataProperty),
+ OPropertyInfoImpl(PROPERTY_FORMULALIST, PROPERTY_ID_FORMULALIST, RptResId(RID_STR_FORMULALIST), HID_RPT_PROP_FORMULALIST, PropUIFlags::Composeable | PropUIFlags::DataProperty),
+ OPropertyInfoImpl(PROPERTY_SCOPE, PROPERTY_ID_SCOPE, RptResId(RID_STR_SCOPE), HID_RPT_PROP_SCOPE, PropUIFlags::Composeable | PropUIFlags::DataProperty),
+ OPropertyInfoImpl(PROPERTY_PRESERVEIRI, PROPERTY_ID_PRESERVEIRI, RptResId(RID_STR_PRESERVEIRI), HID_RPT_PROP_PRESERVEIRI, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_BACKCOLOR, PROPERTY_ID_BACKCOLOR, RptResId(RID_STR_BACKCOLOR), HID_RPT_PROP_BACKCOLOR, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_CONTROLBACKGROUND, PROPERTY_ID_CONTROLBACKGROUND, RptResId(RID_STR_BACKCOLOR), HID_RPT_PROP_BACKCOLOR, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_BACKTRANSPARENT, PROPERTY_ID_BACKTRANSPARENT, RptResId(RID_STR_BACKTRANSPARENT), HID_RPT_PROP_BACKTRANSPARENT, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_CONTROLBACKGROUNDTRANSPARENT, PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT, RptResId(RID_STR_CONTROLBACKGROUNDTRANSPARENT), HID_RPT_PROP_CONTROLBACKGROUNDTRANSPARENT,
+ PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_CHARTTYPE, PROPERTY_ID_CHARTTYPE, RptResId(RID_STR_CHARTTYPE), HID_RPT_PROP_CHARTTYPE, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_PREVIEW_COUNT, PROPERTY_ID_PREVIEW_COUNT, RptResId(RID_STR_PREVIEW_COUNT), HID_RPT_PROP_PREVIEW_COUNT, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_MASTERFIELDS, PROPERTY_ID_MASTERFIELDS, RptResId(RID_STR_MASTERFIELDS), HID_RPT_PROP_MASTERFIELDS, PropUIFlags::Composeable | PropUIFlags::DataProperty),
+ OPropertyInfoImpl(PROPERTY_DETAILFIELDS, PROPERTY_ID_DETAILFIELDS, RptResId(RID_STR_DETAILFIELDS), HID_RPT_PROP_DETAILFIELDS, PropUIFlags::Composeable | PropUIFlags::DataProperty),
+ OPropertyInfoImpl(PROPERTY_AREA, PROPERTY_ID_AREA, RptResId(RID_STR_AREA), HID_RPT_PROP_AREA, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_MIMETYPE, PROPERTY_ID_MIMETYPE, RptResId(RID_STR_MIMETYPE), HID_RPT_PROP_MIMETYPE, PropUIFlags::Composeable | PropUIFlags::DataProperty),
+ OPropertyInfoImpl(PROPERTY_PARAADJUST, PROPERTY_ID_PARAADJUST, RptResId(RID_STR_PARAADJUST), HID_RPT_PROP_PARAADJUST, PropUIFlags::Composeable),
+ OPropertyInfoImpl(PROPERTY_VERTICALALIGN, PROPERTY_ID_VERTICALALIGN, RptResId(RID_STR_VERTICALALIGN), HID_RPT_PROP_VERTICALALIGN, PropUIFlags::Composeable)
+ };
+
+ s_pPropertyInfos = aPropertyInfos;
+ s_nCount = SAL_N_ELEMENTS(aPropertyInfos);
+ ::std::sort( aPropertyInfos, aPropertyInfos + SAL_N_ELEMENTS(aPropertyInfos), PropertyInfoLessByName() );
+
+ return s_pPropertyInfos;
+ }
+
+
+ sal_Int32 OPropertyInfoService::getPropertyId(const OUString& _rName)
+ {
+ const OPropertyInfoImpl* pInfo = getPropertyInfo(_rName);
+ return pInfo ? pInfo->nId : -1;
+ }
+
+
+ OUString OPropertyInfoService::getPropertyTranslation(sal_Int32 _nId)
+ {
+ const OPropertyInfoImpl* pInfo = getPropertyInfo(_nId);
+ return pInfo ? pInfo->sTranslation : OUString();
+ }
+
+
+ OString OPropertyInfoService::getPropertyHelpId(sal_Int32 _nId)
+ {
+ const OPropertyInfoImpl* pInfo = getPropertyInfo(_nId);
+ return pInfo ? pInfo->sHelpId : OString();
+ }
+
+
+ PropUIFlags OPropertyInfoService::getPropertyUIFlags(sal_Int32 _nId)
+ {
+ const OPropertyInfoImpl* pInfo = getPropertyInfo(_nId);
+ return pInfo ? pInfo->nUIFlags : PropUIFlags::NONE;
+ }
+
+
+ const OPropertyInfoImpl* OPropertyInfoService::getPropertyInfo(const OUString& _rName)
+ {
+ // initialization
+ if(!s_pPropertyInfos)
+ getPropertyInfo();
+ OPropertyInfoImpl aSearch(_rName, 0, OUString(), "", PropUIFlags::NONE);
+
+ const OPropertyInfoImpl* pPropInfo = ::std::lower_bound(
+ s_pPropertyInfos, s_pPropertyInfos + s_nCount, aSearch, PropertyInfoLessByName() );
+
+ if ( ( pPropInfo < s_pPropertyInfos + s_nCount ) && pPropInfo->sName == _rName )
+ return pPropInfo;
+
+ return nullptr;
+ }
+
+
+ const OPropertyInfoImpl* OPropertyInfoService::getPropertyInfo(sal_Int32 _nId)
+ {
+ // initialization
+ if(!s_pPropertyInfos)
+ getPropertyInfo();
+
+ // TODO: a real structure which allows quick access by name as well as by id
+ for (sal_uInt16 i = 0; i < s_nCount; i++)
+ if (s_pPropertyInfos[i].nId == _nId)
+ return &s_pPropertyInfos[i];
+
+ return nullptr;
+ }
+
+
+ bool OPropertyInfoService::isComposable( const OUString& _rPropertyName, const css::uno::Reference< css::inspection::XPropertyHandler >& _rxFormComponentHandler )
+ {
+ sal_Int32 nId = getPropertyId( _rPropertyName );
+ if ( nId != -1 )
+ {
+ PropUIFlags nFlags = getPropertyUIFlags( nId );
+ return bool( nFlags & PropUIFlags::Composeable );
+ }
+
+ return _rxFormComponentHandler->isComposable( _rPropertyName );
+ }
+
+
+ void OPropertyInfoService::getExcludeProperties(::std::vector< beans::Property >& _rExcludeProperties,const css::uno::Reference< css::inspection::XPropertyHandler >& _xFormComponentHandler)
+ {
+ const uno::Sequence< beans::Property > aProps = _xFormComponentHandler->getSupportedProperties();
+ static const std::u16string_view pExcludeProperties[] =
+ {
+ u"Enabled",
+ u"Printable",
+ u"WordBreak",
+ u"MultiLine",
+ u"Tag",
+ u"HelpText",
+ u"HelpURL",
+ u"MaxTextLen",
+ u"ReadOnly",
+ u"Tabstop",
+ u"TabIndex",
+ u"ValueMin",
+ u"ValueMax",
+ u"Spin",
+ u"SpinValue",
+ u"SpinValueMin",
+ u"SpinValueMax",
+ u"DefaultSpinValue",
+ u"SpinIncrement",
+ u"Repeat",
+ u"RepeatDelay",
+ u"ControlLabel", /// TODO: has to be checked
+ u"LabelControl",
+ u"Title", // comment this out if you want to have title feature for charts
+ u"" PROPERTY_MAXTEXTLEN,
+ u"" PROPERTY_EFFECTIVEDEFAULT,
+ u"" PROPERTY_EFFECTIVEMAX,
+ u"" PROPERTY_EFFECTIVEMIN,
+ u"HideInactiveSelection",
+ u"SubmitAction",
+ u"InputRequired",
+ u"VerticalAlign",
+ u"" PROPERTY_ALIGN,
+ u"" PROPERTY_EMPTY_IS_NULL,
+ u"" PROPERTY_FILTERPROPOSAL
+ ,u"" PROPERTY_POSITIONX
+ ,u"" PROPERTY_POSITIONY
+ ,u"" PROPERTY_WIDTH
+ ,u"" PROPERTY_HEIGHT
+ ,u"" PROPERTY_AUTOGROW
+ ,u"" PROPERTY_FONT
+ ,u"" PROPERTY_LABEL
+ ,u"" PROPERTY_LINECOLOR
+ ,u"" PROPERTY_BORDER
+ ,u"" PROPERTY_BORDERCOLOR
+ ,u"" PROPERTY_BACKTRANSPARENT
+ ,u"" PROPERTY_CONTROLBACKGROUND
+ ,u"" PROPERTY_BACKGROUNDCOLOR
+ ,u"" PROPERTY_CONTROLBACKGROUNDTRANSPARENT
+ ,u"" PROPERTY_FORMULALIST
+ ,u"" PROPERTY_SCOPE
+ ,u"" PROPERTY_TYPE
+ ,u"" PROPERTY_DATASOURCENAME
+ ,u"" PROPERTY_VERTICALALIGN
+ };
+
+ for (beans::Property const & prop : aProps)
+ {
+ size_t nPos = 0;
+ for (; nPos < SAL_N_ELEMENTS(pExcludeProperties) && pExcludeProperties[nPos] != prop.Name; ++nPos )
+ ;
+ if ( nPos == SAL_N_ELEMENTS(pExcludeProperties) )
+ _rExcludeProperties.push_back(prop);
+ }
+ }
+
+
+} // namespace pcr
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/misc/ColorListener.cxx b/reportdesign/source/ui/misc/ColorListener.cxx
new file mode 100644
index 000000000..48fa67902
--- /dev/null
+++ b/reportdesign/source/ui/misc/ColorListener.cxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <ColorListener.hxx>
+#include <svl/hint.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/event.hxx>
+
+#include <strings.hxx>
+
+
+namespace rptui
+{
+
+OColorListener::OColorListener(vcl::Window* _pParent ,const OUString& _sColorEntry)
+: Window(_pParent)
+,m_sColorEntry(_sColorEntry)
+,m_nColor(COL_LIGHTBLUE)
+,m_bCollapsed(false)
+,m_bMarked(false)
+{
+ StartListening(m_aExtendedColorConfig);
+ m_nColor = m_aExtendedColorConfig.GetColorValue(CFG_REPORTDESIGNER,m_sColorEntry).getColor();
+ m_nTextBoundaries = m_aColorConfig.GetColorValue(::svtools::DOCBOUNDARIES).nColor;
+}
+
+OColorListener::~OColorListener()
+{
+ disposeOnce();
+}
+
+void OColorListener::dispose()
+{
+ EndListening(m_aExtendedColorConfig);
+ vcl::Window::dispose();
+}
+
+void OColorListener::Notify(SfxBroadcaster & /*rBc*/, SfxHint const & rHint)
+{
+ if (rHint.GetId() == SfxHintId::ColorsChanged)
+ {
+ m_nColor = m_aExtendedColorConfig.GetColorValue(CFG_REPORTDESIGNER,m_sColorEntry).getColor();
+ m_nTextBoundaries = m_aColorConfig.GetColorValue(::svtools::DOCBOUNDARIES).nColor;
+ Invalidate(InvalidateFlags::NoChildren|InvalidateFlags::NoErase);
+ }
+}
+
+void OColorListener::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+void OColorListener::setCollapsed(bool _bCollapsed)
+{
+ if ( m_bCollapsed != _bCollapsed )
+ {
+ m_bCollapsed = _bCollapsed;
+ m_aCollapsedLink.Call(*this);
+ }
+}
+
+void OColorListener::setMarked(bool _bMark)
+{
+ if ( m_bMarked != _bMark)
+ {
+ m_bMarked = _bMark;
+ Invalidate(InvalidateFlags::NoChildren|InvalidateFlags::NoErase);
+ }
+}
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/misc/FunctionHelper.cxx b/reportdesign/source/ui/misc/FunctionHelper.cxx
new file mode 100644
index 000000000..547567178
--- /dev/null
+++ b/reportdesign/source/ui/misc/FunctionHelper.cxx
@@ -0,0 +1,268 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <FunctionHelper.hxx>
+
+#include <o3tl/safeint.hxx>
+#include <tools/diagnose_ex.h>
+#include <formula/funcvarargs.h>
+
+
+namespace rptui
+{
+
+ using namespace ::com::sun::star;
+
+FunctionManager::FunctionManager(const uno::Reference< report::meta::XFunctionManager>& _xMgr)
+: m_xMgr(_xMgr)
+{
+}
+FunctionManager::~FunctionManager()
+{
+}
+sal_Unicode FunctionManager::getSingleToken(const formula::IFunctionManager::EToken _eToken) const
+{
+ switch(_eToken)
+ {
+ case eOk:
+ return '(';
+ case eClose:
+ return ')';
+ case eSep:
+ return ';';
+ case eArrayOpen:
+ return '{';
+ case eArrayClose:
+ return '}';
+ }
+ return 0;
+}
+
+sal_uInt32 FunctionManager::getCount() const
+{
+ return m_xMgr->getCount();
+}
+
+const formula::IFunctionCategory* FunctionManager::getCategory(sal_uInt32 _nPos) const
+{
+ if ( _nPos >= m_aCategoryIndex.size() )
+ {
+ uno::Reference< report::meta::XFunctionCategory> xCategory = m_xMgr->getCategory(_nPos);
+ auto pCategory = std::make_shared<FunctionCategory>(this,_nPos + 1,xCategory);
+ m_aCategoryIndex.push_back( m_aCategories.emplace(xCategory->getName(),pCategory).first );
+ }
+ return m_aCategoryIndex[_nPos]->second.get();
+}
+
+void FunctionManager::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& /*_rLastRUFunctions*/) const
+{
+}
+
+std::shared_ptr< FunctionDescription > FunctionManager::get(const uno::Reference< report::meta::XFunctionDescription>& _xFunctionDescription) const
+{
+ std::shared_ptr< FunctionDescription > pDesc;
+ if ( _xFunctionDescription.is() )
+ {
+ const OUString sFunctionName = _xFunctionDescription->getName();
+ TFunctionsMap::const_iterator aFunctionFind = m_aFunctions.find(sFunctionName);
+ if ( aFunctionFind == m_aFunctions.end() )
+ {
+ const uno::Reference< report::meta::XFunctionCategory> xCategory = _xFunctionDescription->getCategory();
+ const OUString sCategoryName = xCategory->getName();
+ TCategoriesMap::iterator aCategoryFind = m_aCategories.find(sCategoryName);
+ if ( aCategoryFind == m_aCategories.end() )
+ {
+ aCategoryFind = m_aCategories.emplace(sCategoryName,std::make_shared< FunctionCategory > (this,xCategory->getNumber() + 1,xCategory)).first;
+ m_aCategoryIndex.push_back( aCategoryFind );
+ }
+ aFunctionFind = m_aFunctions.emplace(sFunctionName,std::make_shared<FunctionDescription>(aCategoryFind->second.get(),_xFunctionDescription)).first;
+ }
+ pDesc = aFunctionFind->second;
+ }
+ return pDesc;
+}
+
+FunctionCategory::FunctionCategory(const FunctionManager* _pFMgr,sal_uInt32 _nPos,const uno::Reference< report::meta::XFunctionCategory>& _xCategory)
+: m_xCategory(_xCategory)
+,m_nFunctionCount(_xCategory->getCount())
+, m_nNumber(_nPos)
+,m_pFunctionManager(_pFMgr)
+{
+}
+
+sal_uInt32 FunctionCategory::getCount() const
+{
+ return m_nFunctionCount;
+}
+
+const formula::IFunctionDescription* FunctionCategory::getFunction(sal_uInt32 _nPos) const
+{
+ if ( _nPos >= m_aFunctions.size() && _nPos < m_nFunctionCount )
+ {
+ uno::Reference< report::meta::XFunctionDescription> xFunctionDescription = m_xCategory->getFunction(_nPos);
+ std::shared_ptr< FunctionDescription > pFunction = m_pFunctionManager->get(xFunctionDescription);
+ m_aFunctions.push_back( pFunction );
+ }
+ return m_aFunctions[_nPos].get();
+}
+
+sal_uInt32 FunctionCategory::getNumber() const
+{
+ return m_nNumber;
+}
+
+OUString FunctionCategory::getName() const
+{
+ return m_xCategory->getName();
+}
+
+FunctionDescription::FunctionDescription(const formula::IFunctionCategory* _pFunctionCategory,const uno::Reference< report::meta::XFunctionDescription>& _xFunctionDescription)
+: m_xFunctionDescription(_xFunctionDescription)
+, m_pFunctionCategory(_pFunctionCategory)
+{
+ m_aParameter = m_xFunctionDescription->getArguments();
+}
+OUString FunctionDescription::getFunctionName() const
+{
+ return m_xFunctionDescription->getName();
+}
+
+const formula::IFunctionCategory* FunctionDescription::getCategory() const
+{
+ return m_pFunctionCategory;
+}
+
+OUString FunctionDescription::getDescription() const
+{
+ return m_xFunctionDescription->getDescription();
+}
+
+sal_Int32 FunctionDescription::getSuppressedArgumentCount() const
+{
+ return m_aParameter.getLength();
+}
+
+OUString FunctionDescription::getFormula(const ::std::vector< OUString >& _aArguments) const
+{
+ OUString sFormula;
+ try
+ {
+ sFormula = m_xFunctionDescription->createFormula(uno::Sequence< OUString >(_aArguments.data(), _aArguments.size()));
+ }
+ catch(const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "");
+ }
+ return sFormula;
+}
+
+void FunctionDescription::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const
+{
+ const sal_Int32 nCount = m_aParameter.getLength();
+ for(sal_Int32 i = 0;i < nCount; ++i)
+ {
+ _rArguments.push_back(i);
+ }
+}
+
+void FunctionDescription::initArgumentInfo() const
+{
+}
+
+OUString FunctionDescription::getSignature() const
+{
+ return m_xFunctionDescription->getSignature();
+}
+
+OString FunctionDescription::getHelpId() const
+{
+ return OString();
+}
+
+bool FunctionDescription::isHidden() const
+{
+ return false;
+}
+
+sal_uInt32 FunctionDescription::getParameterCount() const
+{
+ return m_aParameter.getLength();
+}
+
+sal_uInt32 FunctionDescription::getVarArgsStart() const
+{
+ /* XXX there are no variable number of arguments, are there? Nevertheless
+ * consider the varargs handling of the Function Wizard and return a value
+ * within the bounds of parameters. */
+ // Don't use defines/constants that could change in future, parameter count
+ // could be part of an implicit stable API.
+ // offapi/com/sun/star/report/meta/XFunctionDescription.idl doesn't tell.
+ const sal_uInt32 nVarArgs30 = 30; // ugly hard coded old VAR_ARGS of formula::ParaWin
+ const sal_uInt32 nPairedVarArgs60 = 60; // ugly hard coded old PAIRED_VAR_ARGS of formula::ParaWin
+ const sal_uInt32 nVarArgs255 = 255; // ugly hard coded new VAR_ARGS of formula::ParaWin
+ const sal_uInt32 nPairedVarArgs510 = 510; // ugly hard coded new PAIRED_VAR_ARGS of formula::ParaWin
+ sal_uInt32 nLen = m_aParameter.getLength();
+ // If the value of VAR_ARGS changes then adapt *and* maintain implicit API
+ // stability, ie. old code using the old VAR_ARGS and PAIRED_VAR_ARGS
+ // values must still be handled. It is *not* sufficient to simply change
+ // the values here.
+ static_assert(nVarArgs255 == VAR_ARGS && nPairedVarArgs510 == PAIRED_VAR_ARGS,
+ "VAR_ARGS or PAIRED_VAR_ARGS has unexpected value");
+ if (nLen >= nPairedVarArgs510)
+ nLen -= nPairedVarArgs510;
+ else if (nLen >= nVarArgs255)
+ nLen -= nVarArgs255;
+ else if (nLen >= nPairedVarArgs60)
+ nLen -= nPairedVarArgs60;
+ else if (nLen >= nVarArgs30)
+ nLen -= nVarArgs30;
+ return nLen ? nLen - 1 : 0;
+}
+
+sal_uInt32 FunctionDescription::getVarArgsLimit() const
+{
+ return 0;
+}
+
+OUString FunctionDescription::getParameterName(sal_uInt32 _nPos) const
+{
+ if ( _nPos < o3tl::make_unsigned(m_aParameter.getLength()) )
+ return m_aParameter[_nPos].Name;
+ return OUString();
+}
+
+OUString FunctionDescription::getParameterDescription(sal_uInt32 _nPos) const
+{
+ if ( _nPos < o3tl::make_unsigned(m_aParameter.getLength()) )
+ return m_aParameter[_nPos].Description;
+ return OUString();
+}
+
+bool FunctionDescription::isParameterOptional(sal_uInt32 _nPos) const
+{
+ if ( _nPos < o3tl::make_unsigned(m_aParameter.getLength()) )
+ return m_aParameter[_nPos].IsOptional;
+ return false;
+}
+
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/misc/RptUndo.cxx b/reportdesign/source/ui/misc/RptUndo.cxx
new file mode 100644
index 000000000..60d0927d6
--- /dev/null
+++ b/reportdesign/source/ui/misc/RptUndo.cxx
@@ -0,0 +1,385 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <RptUndo.hxx>
+#include <strings.hxx>
+#include <rptui_slotid.hrc>
+#include <UITools.hxx>
+#include <UndoEnv.hxx>
+
+#include <dbaccess/IController.hxx>
+#include <com/sun/star/report/XSection.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/types.hxx>
+#include <svx/unoshape.hxx>
+#include <utility>
+#include <tools/diagnose_ex.h>
+
+#include <functional>
+
+namespace rptui
+{
+ using namespace ::com::sun::star;
+ using namespace uno;
+ using namespace lang;
+ using namespace beans;
+ using namespace awt;
+ using namespace util;
+ using namespace container;
+ using namespace report;
+
+
+namespace
+{
+ void lcl_collectElements(const uno::Reference< report::XSection >& _xSection,::std::vector< uno::Reference< drawing::XShape> >& _rControls)
+ {
+ if ( _xSection.is() )
+ {
+ sal_Int32 nCount = _xSection->getCount();
+ _rControls.reserve(nCount);
+ while ( nCount )
+ {
+ uno::Reference< drawing::XShape> xShape(_xSection->getByIndex(nCount-1),uno::UNO_QUERY);
+ _rControls.push_back(xShape);
+ _xSection->remove(xShape);
+ --nCount;
+ }
+ }
+ }
+
+ void lcl_insertElements(const uno::Reference< report::XSection >& _xSection,const ::std::vector< uno::Reference< drawing::XShape> >& _aControls)
+ {
+ if ( !_xSection.is() )
+ return;
+
+ ::std::vector< uno::Reference< drawing::XShape> >::const_reverse_iterator aIter = _aControls.rbegin();
+ ::std::vector< uno::Reference< drawing::XShape> >::const_reverse_iterator aEnd = _aControls.rend();
+ for (; aIter != aEnd; ++aIter)
+ {
+ try
+ {
+ const awt::Point aPos = (*aIter)->getPosition();
+ const awt::Size aSize = (*aIter)->getSize();
+ _xSection->add(*aIter);
+ (*aIter)->setPosition( aPos );
+ (*aIter)->setSize( aSize );
+ }
+ catch(const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "lcl_insertElements");
+ }
+ }
+ }
+
+ void lcl_setValues(const uno::Reference< report::XSection >& _xSection,const ::std::vector< ::std::pair< OUString ,uno::Any> >& _aValues)
+ {
+ if ( !_xSection.is() )
+ return;
+
+ for (const auto& [rPropName, rValue] : _aValues)
+ {
+ try
+ {
+ _xSection->setPropertyValue(rPropName, rValue);
+ }
+ catch(const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "lcl_setValues");
+ }
+ }
+ }
+}
+
+
+OSectionUndo::OSectionUndo(OReportModel& _rMod
+ ,sal_uInt16 _nSlot
+ ,Action _eAction
+ ,TranslateId pCommentID)
+: OCommentUndoAction(_rMod,pCommentID)
+,m_eAction(_eAction)
+,m_nSlot(_nSlot)
+,m_bInserted(false)
+{
+}
+
+OSectionUndo::~OSectionUndo()
+{
+ if ( m_bInserted )
+ return;
+
+ OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv();
+ for (uno::Reference<drawing::XShape>& xShape : m_aControls)
+ {
+ rEnv.RemoveElement(xShape);
+
+#if OSL_DEBUG_LEVEL > 0
+ SvxShape* pShape = comphelper::getFromUnoTunnel<SvxShape>( xShape );
+ SdrObject* pObject = pShape ? pShape->GetSdrObject() : nullptr;
+ OSL_ENSURE( pShape && pShape->HasSdrObjectOwnership() && pObject && !pObject->IsInserted(),
+ "OSectionUndo::~OSectionUndo: inconsistency in the shape/object ownership!" );
+#endif
+ try
+ {
+ comphelper::disposeComponent(xShape);
+ }
+ catch(const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "");
+ }
+ }
+}
+
+void OSectionUndo::collectControls(const uno::Reference< report::XSection >& _xSection)
+{
+ m_aControls.clear();
+ try
+ {
+ // copy all properties for restoring
+ uno::Reference< beans::XPropertySetInfo> xInfo = _xSection->getPropertySetInfo();
+ const uno::Sequence< beans::Property> aSeq = xInfo->getProperties();
+ for(const beans::Property& rProp : aSeq)
+ {
+ if ( 0 == (rProp.Attributes & beans::PropertyAttribute::READONLY) )
+ m_aValues.emplace_back(rProp.Name,_xSection->getPropertyValue(rProp.Name));
+ }
+ lcl_collectElements(_xSection,m_aControls);
+ }
+ catch(uno::Exception&)
+ {
+ }
+}
+
+void OSectionUndo::Undo()
+{
+ try
+ {
+ switch ( m_eAction )
+ {
+ case Inserted:
+ implReRemove();
+ break;
+
+ case Removed:
+ implReInsert();
+ break;
+ }
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "OSectionUndo::Undo" );
+ }
+}
+
+void OSectionUndo::Redo()
+{
+ try
+ {
+ switch ( m_eAction )
+ {
+ case Inserted:
+ implReInsert();
+ break;
+
+ case Removed:
+ implReRemove();
+ break;
+ }
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "OSectionUndo::Redo" );
+ }
+}
+
+OReportSectionUndo::OReportSectionUndo(
+ OReportModel& _rMod, sal_uInt16 _nSlot,
+ ::std::function<uno::Reference<report::XSection>(OReportHelper*)> _pMemberFunction,
+ const uno::Reference<report::XReportDefinition>& _xReport, Action _eAction)
+ : OSectionUndo(_rMod, _nSlot, _eAction, {})
+ , m_aReportHelper(_xReport)
+ , m_pMemberFunction(std::move(_pMemberFunction))
+{
+ if( m_eAction == Removed )
+ collectControls(m_pMemberFunction(&m_aReportHelper));
+}
+
+OReportSectionUndo::~OReportSectionUndo()
+{
+}
+
+void OReportSectionUndo::implReInsert( )
+{
+ const uno::Sequence< beans::PropertyValue > aArgs;
+ m_pController->executeChecked(m_nSlot,aArgs);
+ uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aReportHelper);
+ lcl_insertElements(xSection,m_aControls);
+ lcl_setValues(xSection,m_aValues);
+ m_bInserted = true;
+}
+
+void OReportSectionUndo::implReRemove( )
+{
+ if( m_eAction == Removed )
+ collectControls(m_pMemberFunction(&m_aReportHelper));
+ const uno::Sequence< beans::PropertyValue > aArgs;
+ m_pController->executeChecked(m_nSlot,aArgs);
+ m_bInserted = false;
+}
+
+OGroupSectionUndo::OGroupSectionUndo(
+ OReportModel& _rMod, sal_uInt16 _nSlot,
+ ::std::function<uno::Reference<report::XSection>(OGroupHelper*)> _pMemberFunction,
+ const uno::Reference<report::XGroup>& _xGroup, Action _eAction, TranslateId pCommentID)
+ : OSectionUndo(_rMod, _nSlot, _eAction, pCommentID)
+ , m_aGroupHelper(_xGroup)
+ , m_pMemberFunction(std::move(_pMemberFunction))
+{
+ if( m_eAction == Removed )
+ {
+ uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aGroupHelper);
+ if ( xSection.is() )
+ m_sName = xSection->getName();
+ collectControls(xSection);
+ }
+}
+
+OUString OGroupSectionUndo::GetComment() const
+{
+ if ( m_sName.isEmpty() )
+ {
+ try
+ {
+ uno::Reference< report::XSection > xSection = const_cast<OGroupSectionUndo*>(this)->m_pMemberFunction(&const_cast<OGroupSectionUndo*>(this)->m_aGroupHelper);
+
+ if ( xSection.is() )
+ m_sName = xSection->getName();
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+ return m_strComment + m_sName;
+}
+
+void OGroupSectionUndo::implReInsert( )
+{
+ const OUString aHeaderFooterOnName(SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? OUString(PROPERTY_HEADERON) : OUString(PROPERTY_FOOTERON));
+ uno::Sequence< beans::PropertyValue > aArgs{
+ comphelper::makePropertyValue(aHeaderFooterOnName, true),
+ comphelper::makePropertyValue(PROPERTY_GROUP, m_aGroupHelper.getGroup())
+ };
+ m_pController->executeChecked(m_nSlot,aArgs);
+
+ uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aGroupHelper);
+ lcl_insertElements(xSection,m_aControls);
+ lcl_setValues(xSection,m_aValues);
+ m_bInserted = true;
+}
+
+void OGroupSectionUndo::implReRemove( )
+{
+ if( m_eAction == Removed )
+ collectControls(m_pMemberFunction(&m_aGroupHelper));
+
+ const OUString aHeaderFooterOnName(SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? OUString(PROPERTY_HEADERON) : OUString(PROPERTY_FOOTERON));
+ uno::Sequence< beans::PropertyValue > aArgs{
+ comphelper::makePropertyValue(aHeaderFooterOnName, false),
+ comphelper::makePropertyValue(PROPERTY_GROUP, m_aGroupHelper.getGroup())
+ };
+
+ m_pController->executeChecked(m_nSlot,aArgs);
+ m_bInserted = false;
+}
+
+
+OGroupUndo::OGroupUndo(OReportModel& _rMod
+ ,TranslateId pCommentID
+ ,Action _eAction
+ ,const uno::Reference< report::XGroup>& _xGroup
+ ,const uno::Reference< report::XReportDefinition >& _xReportDefinition)
+: OCommentUndoAction(_rMod,pCommentID)
+,m_xGroup(_xGroup)
+,m_xReportDefinition(_xReportDefinition)
+,m_eAction(_eAction)
+{
+ m_nLastPosition = getPositionInIndexAccess(m_xReportDefinition->getGroups(),m_xGroup);
+}
+
+void OGroupUndo::implReInsert( )
+{
+ try
+ {
+ m_xReportDefinition->getGroups()->insertByIndex(m_nLastPosition,uno::Any(m_xGroup));
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while undoing remove group");
+ }
+}
+
+void OGroupUndo::implReRemove( )
+{
+ try
+ {
+ m_xReportDefinition->getGroups()->removeByIndex(m_nLastPosition);
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while redoing remove group");
+ }
+}
+
+void OGroupUndo::Undo()
+{
+ switch ( m_eAction )
+ {
+ case Inserted:
+ implReRemove();
+ break;
+
+ case Removed:
+ implReInsert();
+ break;
+ }
+
+}
+
+void OGroupUndo::Redo()
+{
+ switch ( m_eAction )
+ {
+ case Inserted:
+ implReInsert();
+ break;
+
+ case Removed:
+ implReRemove();
+ break;
+ }
+}
+
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/misc/UITools.cxx b/reportdesign/source/ui/misc/UITools.cxx
new file mode 100644
index 000000000..9e00b4ad5
--- /dev/null
+++ b/reportdesign/source/ui/misc/UITools.cxx
@@ -0,0 +1,1064 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <memory>
+#include <toolkit/helper/convert.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <SectionView.hxx>
+#include <UITools.hxx>
+#include <Formula.hxx>
+#include <FunctionHelper.hxx>
+#include <reportformula.hxx>
+
+#include <tools/diagnose_ex.h>
+
+#include <vcl/settings.hxx>
+#include <vcl/syswin.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/unohelp.hxx>
+#include <vcl/window.hxx>
+
+#include <com/sun/star/lang/NullPointerException.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <svx/svdpool.hxx>
+
+#include <editeng/charscaleitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/emphasismarkitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/blinkitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/autokernitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <svx/drawitem.hxx>
+#include <editeng/twolinesitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <editeng/charhiddenitem.hxx>
+#include <editeng/memberids.h>
+#include <svx/xgrscit.hxx>
+#include <svx/svditer.hxx>
+#include <svx/xtable.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/unoprov.hxx>
+#include <svx/svxids.hrc>
+
+#include <unotools/charclass.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/sharedstringpool.hxx>
+
+#include <comphelper/propmultiplex.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+
+#include <connectivity/dbexception.hxx>
+#include <connectivity/dbtools.hxx>
+
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/report/XShape.hpp>
+#include <com/sun/star/sdb/XParametersSupplier.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <i18nlangtag/languagetag.hxx>
+#include <dlgpage.hxx>
+#include <strings.hxx>
+#include <core_resource.hxx>
+#include <RptObject.hxx>
+#include <RptDef.hxx>
+#include <strings.hrc>
+#include <ReportDefinition.hxx>
+#include <RptModel.hxx>
+
+#include <svx/xflbckit.hxx>
+#include <svx/xflbmpit.hxx>
+#include <svx/xflbmsli.hxx>
+#include <svx/xflbmsxy.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xflboxy.hxx>
+#include <svx/xflbstit.hxx>
+#include <svx/xflbtoxy.hxx>
+
+#include <svx/xbtmpit.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xfltrit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xsflclit.hxx>
+
+/// Note that we deliberately overlap an existing item id, so that we can have contiguous item ids for
+/// the static defaults.
+#define ITEMID_FIRST XATTR_FILL_LAST
+
+#define ITEMID_FONT TypedWhichId<SvxFontItem>(ITEMID_FIRST)
+#define ITEMID_FONTHEIGHT TypedWhichId<SvxFontHeightItem>(ITEMID_FIRST + 1)
+#define ITEMID_LANGUAGE TypedWhichId<SvxLanguageItem>(ITEMID_FIRST + 2)
+
+#define ITEMID_POSTURE TypedWhichId<SvxPostureItem>(ITEMID_FIRST + 3)
+#define ITEMID_WEIGHT TypedWhichId<SvxWeightItem>(ITEMID_FIRST + 4)
+#define ITEMID_SHADOWED TypedWhichId<SvxShadowedItem>(ITEMID_FIRST + 5)
+#define ITEMID_WORDLINEMODE TypedWhichId<SvxWordLineModeItem>(ITEMID_FIRST + 6)
+#define ITEMID_CONTOUR TypedWhichId<SvxContourItem>(ITEMID_FIRST + 7)
+#define ITEMID_CROSSEDOUT TypedWhichId<SvxCrossedOutItem>(ITEMID_FIRST + 8)
+#define ITEMID_UNDERLINE TypedWhichId<SvxUnderlineItem>(ITEMID_FIRST + 9)
+
+#define ITEMID_COLOR TypedWhichId<SvxColorItem>(ITEMID_FIRST + 10)
+#define ITEMID_KERNING TypedWhichId<SvxKerningItem>(ITEMID_FIRST + 11)
+#define ITEMID_CASEMAP TypedWhichId<SvxCaseMapItem>(ITEMID_FIRST + 12)
+
+#define ITEMID_ESCAPEMENT TypedWhichId<SvxEscapementItem>(ITEMID_FIRST + 13)
+#define ITEMID_FONTLIST ITEMID_FIRST + 14
+#define ITEMID_AUTOKERN TypedWhichId<SvxAutoKernItem>(ITEMID_FIRST + 15)
+#define ITEMID_COLOR_TABLE TypedWhichId<SvxColorListItem>(ITEMID_FIRST + 16)
+#define ITEMID_BLINK TypedWhichId<SvxBlinkItem>(ITEMID_FIRST + 17)
+#define ITEMID_EMPHASISMARK TypedWhichId<SvxEmphasisMarkItem>(ITEMID_FIRST + 18)
+#define ITEMID_TWOLINES TypedWhichId<SvxTwoLinesItem>(ITEMID_FIRST + 19)
+#define ITEMID_CHARROTATE TypedWhichId<SvxCharRotateItem>(ITEMID_FIRST + 20)
+#define ITEMID_CHARSCALE_W TypedWhichId<SvxCharScaleWidthItem>(ITEMID_FIRST + 21)
+#define ITEMID_CHARRELIEF TypedWhichId<SvxCharReliefItem>(ITEMID_FIRST + 22)
+#define ITEMID_CHARHIDDEN TypedWhichId<SvxCharHiddenItem>(ITEMID_FIRST + 23)
+#define ITEMID_BRUSH TypedWhichId<SvxBrushItem>(ITEMID_FIRST + 24)
+#define ITEMID_HORJUSTIFY TypedWhichId<SvxHorJustifyItem>(ITEMID_FIRST + 25)
+#define ITEMID_VERJUSTIFY TypedWhichId<SvxVerJustifyItem>(ITEMID_FIRST + 26)
+#define ITEMID_FONT_ASIAN TypedWhichId<SvxFontItem>(ITEMID_FIRST + 27)
+#define ITEMID_FONTHEIGHT_ASIAN TypedWhichId<SvxFontHeightItem>(ITEMID_FIRST + 28)
+#define ITEMID_LANGUAGE_ASIAN TypedWhichId<SvxLanguageItem>(ITEMID_FIRST + 29)
+#define ITEMID_POSTURE_ASIAN TypedWhichId<SvxPostureItem>(ITEMID_FIRST + 30)
+#define ITEMID_WEIGHT_ASIAN TypedWhichId<SvxWeightItem>(ITEMID_FIRST + 31)
+#define ITEMID_FONT_COMPLEX TypedWhichId<SvxFontItem>(ITEMID_FIRST + 32)
+#define ITEMID_FONTHEIGHT_COMPLEX TypedWhichId<SvxFontHeightItem>(ITEMID_FIRST + 33)
+#define ITEMID_LANGUAGE_COMPLEX TypedWhichId<SvxLanguageItem>(ITEMID_FIRST + 34)
+#define ITEMID_POSTURE_COMPLEX TypedWhichId<SvxPostureItem>(ITEMID_FIRST + 35)
+#define ITEMID_WEIGHT_COMPLEX TypedWhichId<SvxWeightItem>(ITEMID_FIRST + 36)
+
+#define WESTERN 0
+#define ASIAN 1
+#define COMPLEX 2
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace formula;
+
+void adjustSectionName(const uno::Reference< report::XGroup >& _xGroup,sal_Int32 _nPos)
+{
+ OSL_ENSURE(_xGroup.is(),"Group is NULL -> GPF");
+ if ( _xGroup->getHeaderOn() && _xGroup->getHeader()->getName().isEmpty() )
+ {
+ OUString sName = RptResId(RID_STR_GROUPHEADER) + OUString::number(_nPos);
+ _xGroup->getHeader()->setName(sName);
+ }
+
+ if ( _xGroup->getFooterOn() && _xGroup->getFooter()->getName().isEmpty() )
+ {
+ OUString sName = RptResId(RID_STR_GROUPFOOTER) + OUString::number(_nPos);
+ _xGroup->getFooter()->setName(sName);
+ }
+}
+
+::rtl::Reference< comphelper::OPropertyChangeMultiplexer> addStyleListener(const uno::Reference< report::XReportDefinition >& _xReportDefinition,::comphelper::OPropertyChangeListener* _pListener)
+{
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> pRet;
+ if ( _xReportDefinition.is() )
+ {
+ uno::Reference<beans::XPropertySet> xPageStyle(getUsedStyle(_xReportDefinition),uno::UNO_QUERY);
+ if ( xPageStyle.is() )
+ {
+ pRet = new comphelper::OPropertyChangeMultiplexer(_pListener,xPageStyle);
+ pRet->addProperty(PROPERTY_LEFTMARGIN);
+ pRet->addProperty(PROPERTY_RIGHTMARGIN);
+ pRet->addProperty(PROPERTY_PAPERSIZE);
+ pRet->addProperty(PROPERTY_BACKCOLOR);
+ }
+ }
+ return pRet;
+}
+
+
+namespace
+{
+
+ vcl::Font lcl_getReportControlFont( const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat, awt::FontDescriptor& _out_rControlFont ,sal_uInt16 _nWichFont)
+ {
+ if ( !_rxReportControlFormat.is() )
+ throw uno::RuntimeException();
+
+ switch(_nWichFont)
+ {
+ case WESTERN:
+ _out_rControlFont = _rxReportControlFormat->getFontDescriptor();
+ break;
+ case ASIAN:
+ _out_rControlFont = _rxReportControlFormat->getFontDescriptorAsian();
+ break;
+ case COMPLEX:
+ _out_rControlFont = _rxReportControlFormat->getFontDescriptorComplex();
+ break;
+
+ }
+
+ vcl::Font aDefaultFont = Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetAppFont();
+ return VCLUnoHelper::CreateFont( _out_rControlFont, aDefaultFont );
+ }
+
+
+ vcl::Font lcl_getReportControlFont( const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat,sal_uInt16 _nWhich )
+ {
+ awt::FontDescriptor aAwtFont;
+ return lcl_getReportControlFont( _rxReportControlFormat, aAwtFont, _nWhich );
+ }
+
+ vcl::Font lcl_setFont(const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat,
+ SfxItemSet& _rItemSet,sal_uInt16 _nWhich,sal_uInt16 _nFont, sal_uInt16 _nFontHeight,sal_uInt16 _nLanguage,sal_uInt16 _nPosture, sal_uInt16 _nWeight)
+ {
+ // fill it
+ awt::FontDescriptor aControlFont;
+ const vcl::Font aFont( lcl_getReportControlFont( _rxReportControlFormat, aControlFont,_nWhich ) );
+
+ SvxFontItem aFontItem(_nFont);
+ aFontItem.PutValue( uno::Any( aControlFont ), 0 );
+ _rItemSet.Put(aFontItem);
+
+ _rItemSet.Put(SvxFontHeightItem(o3tl::convert(aFont.GetFontHeight(), o3tl::Length::pt, o3tl::Length::twip), 100, _nFontHeight));
+ lang::Locale aLocale;
+ switch(_nWhich)
+ {
+ default:
+ aLocale = _rxReportControlFormat->getCharLocale();
+ break;
+ case ASIAN:
+ aLocale = _rxReportControlFormat->getCharLocaleAsian();
+ break;
+ case COMPLEX:
+ aLocale = _rxReportControlFormat->getCharLocaleComplex();
+ break;
+ }
+
+ _rItemSet.Put(SvxLanguageItem(LanguageTag(aLocale).makeFallback().getLanguageType(),_nLanguage));
+
+ _rItemSet.Put(SvxPostureItem(aFont.GetItalic(),_nPosture));
+ _rItemSet.Put(SvxWeightItem(aFont.GetWeight(),_nWeight));
+ return aFont;
+ }
+
+ void lcl_fillShapeToItems( const uno::Reference<report::XShape >& _xShape,SfxItemSet& _rItemSet )
+ {
+ uno::Reference< beans::XPropertySetInfo> xInfo = _xShape->getPropertySetInfo();
+ SvxUnoPropertyMapProvider aMap;
+ const SfxItemPropertyMap& rPropertyMap = aMap.GetPropertySet(SVXMAP_CUSTOMSHAPE, SdrObject::GetGlobalDrawObjectItemPool())->getPropertyMap();
+ for (const auto pProp : rPropertyMap.getPropertyEntries())
+ {
+ if ( xInfo->hasPropertyByName(pProp->aName) )
+ {
+ const SfxPoolItem* pItem = _rItemSet.GetItem(pProp->nWID);
+ if ( pItem )
+ {
+ ::std::unique_ptr<SfxPoolItem> pClone(pItem->CloneSetWhich(pProp->nWID));
+ pClone->PutValue(_xShape->getPropertyValue(pProp->aName), pProp->nMemberId);
+ _rItemSet.Put(std::move(pClone));
+ }
+ }
+ }
+ }
+
+ void lcl_fillItemsToShape( const uno::Reference<report::XShape >& _xShape,const SfxItemSet& _rItemSet )
+ {
+ const uno::Reference< beans::XPropertySetInfo> xInfo = _xShape->getPropertySetInfo();
+ SvxUnoPropertyMapProvider aMap;
+ const SfxItemPropertyMap& rPropertyMap = aMap.GetPropertySet(SVXMAP_CUSTOMSHAPE, SdrObject::GetGlobalDrawObjectItemPool())->getPropertyMap();
+ for (const auto pProp : rPropertyMap.getPropertyEntries())
+ {
+ if ( SfxItemState::SET == _rItemSet.GetItemState(pProp->nWID) && xInfo->hasPropertyByName(pProp->aName) )
+ {
+ if ( ( pProp->nFlags & beans::PropertyAttribute::READONLY ) != beans::PropertyAttribute::READONLY )
+ {
+ const SfxPoolItem* pItem = _rItemSet.GetItem(pProp->nWID);
+ if ( pItem )
+ {
+ uno::Any aValue;
+ pItem->QueryValue(aValue, pProp->nMemberId);
+ try
+ {
+ _xShape->setPropertyValue(pProp->aName, aValue);
+ }
+ catch(uno::Exception&)
+ { // shapes have a bug so we ignore this one.
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void lcl_CharPropertiesToItems( const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat,
+ SfxItemSet& _rItemSet )
+ {
+ if ( !_rxReportControlFormat.is() )
+ throw lang::NullPointerException();
+
+ uno::Reference< beans::XPropertySet > xSet(_rxReportControlFormat,uno::UNO_QUERY_THROW);
+
+ // fill it
+ const vcl::Font aFont( lcl_setFont(_rxReportControlFormat, _rItemSet,WESTERN,ITEMID_FONT,ITEMID_FONTHEIGHT,ITEMID_LANGUAGE,ITEMID_POSTURE,ITEMID_WEIGHT ) );
+
+ _rItemSet.Put(SvxShadowedItem(_rxReportControlFormat->getCharShadowed(),ITEMID_SHADOWED));
+ _rItemSet.Put(SvxWordLineModeItem(aFont.IsWordLineMode(),ITEMID_WORDLINEMODE));
+ _rItemSet.Put(SvxContourItem(_rxReportControlFormat->getCharContoured(),ITEMID_CONTOUR));
+ _rItemSet.Put(SvxAutoKernItem(_rxReportControlFormat->getCharAutoKerning(),ITEMID_AUTOKERN));
+ _rItemSet.Put(SvxCrossedOutItem(aFont.GetStrikeout(),ITEMID_CROSSEDOUT));
+ _rItemSet.Put(SvxCaseMapItem(static_cast<SvxCaseMap>(_rxReportControlFormat->getCharCaseMap()),ITEMID_CASEMAP));
+
+ _rItemSet.Put(SvxEscapementItem(_rxReportControlFormat->getCharEscapement(),_rxReportControlFormat->getCharEscapementHeight(),ITEMID_ESCAPEMENT));
+ _rItemSet.Put(SvxBlinkItem(_rxReportControlFormat->getCharFlash(),ITEMID_BLINK));
+ _rItemSet.Put(SvxCharHiddenItem(_rxReportControlFormat->getCharHidden(),ITEMID_CHARHIDDEN));
+ _rItemSet.Put(SvxTwoLinesItem(_rxReportControlFormat->getCharCombineIsOn(),_rxReportControlFormat->getCharCombinePrefix().toChar(),_rxReportControlFormat->getCharCombineSuffix().toChar(),ITEMID_TWOLINES));
+ SvxUnderlineItem aUnderLineItem(aFont.GetUnderline(),ITEMID_UNDERLINE);
+ aUnderLineItem.SetColor(Color(ColorTransparency, _rxReportControlFormat->getCharUnderlineColor()));
+ _rItemSet.Put(aUnderLineItem);
+ _rItemSet.Put(SvxKerningItem(_rxReportControlFormat->getCharKerning(),ITEMID_KERNING));
+ _rItemSet.Put(SvxEmphasisMarkItem(static_cast<FontEmphasisMark>(_rxReportControlFormat->getCharEmphasis()),ITEMID_EMPHASISMARK));
+ _rItemSet.Put(SvxCharReliefItem(static_cast<FontRelief>(_rxReportControlFormat->getCharRelief()),ITEMID_CHARRELIEF));
+ _rItemSet.Put(SvxColorItem(::Color(ColorTransparency, _rxReportControlFormat->getCharColor()),ITEMID_COLOR));
+ _rItemSet.Put(SvxCharRotateItem(Degree10(_rxReportControlFormat->getCharRotation()),false,ITEMID_CHARROTATE));
+ _rItemSet.Put(SvxCharScaleWidthItem(_rxReportControlFormat->getCharScaleWidth(),ITEMID_CHARSCALE_W));
+
+ SvxHorJustifyItem aHorJustifyItem(ITEMID_HORJUSTIFY);
+ aHorJustifyItem.PutValue(xSet->getPropertyValue(PROPERTY_PARAADJUST),MID_HORJUST_ADJUST);
+ _rItemSet.Put(aHorJustifyItem);
+ SvxVerJustifyItem aVerJustifyItem(ITEMID_VERJUSTIFY);
+ aVerJustifyItem.PutValue(xSet->getPropertyValue(PROPERTY_VERTICALALIGN),MID_HORJUST_ADJUST);
+ _rItemSet.Put(aVerJustifyItem);
+
+ uno::Reference< report::XShape> xShape(_rxReportControlFormat,uno::UNO_QUERY);
+ if ( !xShape.is() )
+ _rItemSet.Put(SvxBrushItem(::Color(ColorTransparency, _rxReportControlFormat->getControlBackground()),ITEMID_BRUSH));
+
+ lcl_setFont(_rxReportControlFormat, _rItemSet,ASIAN,ITEMID_FONT_ASIAN,ITEMID_FONTHEIGHT_ASIAN,ITEMID_LANGUAGE_ASIAN,ITEMID_POSTURE_ASIAN,ITEMID_WEIGHT_ASIAN );
+ lcl_setFont(_rxReportControlFormat, _rItemSet,COMPLEX,ITEMID_FONT_COMPLEX,ITEMID_FONTHEIGHT_COMPLEX,ITEMID_LANGUAGE_COMPLEX,ITEMID_POSTURE_COMPLEX,ITEMID_WEIGHT_COMPLEX );
+ }
+
+
+ void lcl_pushBack( uno::Sequence< beans::NamedValue >& _out_rProperties, const OUString& _sName, const uno::Any& _rValue )
+ {
+ sal_Int32 nLen( _out_rProperties.getLength() );
+ _out_rProperties.realloc( nLen + 1 );
+ _out_rProperties.getArray()[ nLen ] = beans::NamedValue( _sName, _rValue );
+ }
+
+
+ void lcl_initAwtFont( const vcl::Font& _rOriginalFont, const SfxItemSet& _rItemSet, awt::FontDescriptor& _out_rAwtFont,
+ TypedWhichId<SvxFontItem> _nFont, TypedWhichId<SvxFontHeightItem> _nFontHeight,
+ TypedWhichId<SvxPostureItem> _nPosture, TypedWhichId<SvxWeightItem> _nWeight)
+ {
+ vcl::Font aNewFont( _rOriginalFont );
+ if ( const SvxFontItem* pFontItem = _rItemSet.GetItemIfSet( _nFont) )
+ {
+ aNewFont.SetFamilyName(pFontItem->GetFamilyName());
+ aNewFont.SetStyleName(pFontItem->GetStyleName());
+ aNewFont.SetFamily(pFontItem->GetFamily());
+ aNewFont.SetPitch(pFontItem->GetPitch());
+ aNewFont.SetCharSet(pFontItem->GetCharSet());
+ }
+ if ( const SvxFontHeightItem* pFontItem = _rItemSet.GetItemIfSet( _nFontHeight ) )
+ {
+ aNewFont.SetFontHeight(o3tl::convert(pFontItem->GetHeight(), o3tl::Length::twip, o3tl::Length::pt));
+ }
+ if ( const SvxPostureItem* pPostureItem = _rItemSet.GetItemIfSet( _nPosture) )
+ {
+ aNewFont.SetItalic(pPostureItem->GetPosture());
+ }
+ if ( const SvxWeightItem* pWeightItem = _rItemSet.GetItemIfSet( _nWeight ) )
+ {
+ aNewFont.SetWeight(pWeightItem->GetWeight());
+ }
+ if ( const SvxWordLineModeItem* pWordLineItem = _rItemSet.GetItemIfSet( ITEMID_WORDLINEMODE ) )
+ {
+ aNewFont.SetWordLineMode(pWordLineItem->GetValue());
+ }
+ if ( const SvxCrossedOutItem* pCrossedOutItem = _rItemSet.GetItemIfSet( ITEMID_CROSSEDOUT ) )
+ {
+ aNewFont.SetStrikeout(pCrossedOutItem->GetStrikeout());
+ }
+ if ( const SvxCharRotateItem* pRotateItem = _rItemSet.GetItemIfSet( ITEMID_CHARROTATE ) )
+ {
+ aNewFont.SetOrientation(pRotateItem->GetValue());
+ }
+ if ( const SvxCharScaleWidthItem* pCharItem = _rItemSet.GetItemIfSet( ITEMID_CHARSCALE_W ) )
+ {
+ aNewFont.SetWidthType(vcl::unohelper::ConvertFontWidth(pCharItem->GetValue()));
+ }
+ if ( const SvxUnderlineItem* pUnderlineItem = _rItemSet.GetItemIfSet( ITEMID_UNDERLINE ) )
+ {
+ aNewFont.SetUnderline(pUnderlineItem->GetLineStyle());
+ }
+ if ( const SvxColorItem* pColorItem = _rItemSet.GetItemIfSet( ITEMID_COLOR ) )
+ {
+ aNewFont.SetColor(pColorItem->GetValue());
+ }
+
+ _out_rAwtFont = VCLUnoHelper::CreateFontDescriptor( aNewFont );
+ }
+
+
+ void lcl_itemsToCharProperties( const vcl::Font& _rOriginalControlFont,const vcl::Font& _rOriginalControlFontAsian,const vcl::Font& _rOriginalControlFontComplex, const SfxItemSet& _rItemSet, uno::Sequence< beans::NamedValue >& _out_rProperties )
+ {
+ // create an AWT font
+ awt::FontDescriptor aAwtFont;
+ lcl_initAwtFont( _rOriginalControlFont, _rItemSet, aAwtFont,ITEMID_FONT,ITEMID_FONTHEIGHT,ITEMID_POSTURE, ITEMID_WEIGHT);
+ lcl_pushBack( _out_rProperties, "Font", uno::Any( aAwtFont ) );
+ lcl_initAwtFont( _rOriginalControlFontAsian, _rItemSet, aAwtFont,ITEMID_FONT_ASIAN,ITEMID_FONTHEIGHT_ASIAN,ITEMID_POSTURE_ASIAN, ITEMID_WEIGHT_ASIAN);
+ lcl_pushBack( _out_rProperties, "FontAsian", uno::Any( aAwtFont ) );
+ lcl_initAwtFont( _rOriginalControlFontComplex, _rItemSet, aAwtFont,ITEMID_FONT_COMPLEX,ITEMID_FONTHEIGHT_COMPLEX,ITEMID_POSTURE_COMPLEX, ITEMID_WEIGHT_COMPLEX);
+ lcl_pushBack( _out_rProperties, "FontComplex", uno::Any( aAwtFont ) );
+
+ // properties which cannot be represented in an AWT font need to be preserved directly
+ if ( const SvxShadowedItem* pShadowedItem = _rItemSet.GetItemIfSet( ITEMID_SHADOWED) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARSHADOWED, uno::Any( pShadowedItem->GetValue() ) );
+ if ( const SvxContourItem* pContourItem = _rItemSet.GetItemIfSet( ITEMID_CONTOUR ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARCONTOURED, uno::Any( pContourItem->GetValue() ) );
+ if ( const SvxUnderlineItem* pUnderlineItem = _rItemSet.GetItemIfSet( ITEMID_UNDERLINE ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARUNDERLINECOLOR, uno::Any( pUnderlineItem->GetColor() ) );
+ if ( const SvxHorJustifyItem* pJustifyItem = _rItemSet.GetItemIfSet( ITEMID_HORJUSTIFY ) )
+ {
+ uno::Any aValue;
+ pJustifyItem->QueryValue(aValue,MID_HORJUST_ADJUST);
+ lcl_pushBack( _out_rProperties, PROPERTY_PARAADJUST, aValue );
+ }
+ if ( const SvxVerJustifyItem* pJustifyItem = _rItemSet.GetItemIfSet( ITEMID_VERJUSTIFY ) )
+ {
+ uno::Any aValue;
+ pJustifyItem->QueryValue(aValue,MID_HORJUST_ADJUST);
+ lcl_pushBack( _out_rProperties, PROPERTY_VERTICALALIGN, aValue );
+ }
+ if ( const SvxCharReliefItem* pReliefItem = _rItemSet.GetItemIfSet( ITEMID_CHARRELIEF ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARRELIEF, uno::Any( static_cast< sal_Int16 >( pReliefItem->GetEnumValue() ) ) );
+ if ( const SvxCharHiddenItem* pHiddenItem = _rItemSet.GetItemIfSet( ITEMID_CHARHIDDEN ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARHIDDEN, uno::Any( pHiddenItem->GetValue() ) );
+ if ( const SvxAutoKernItem* pKernItem = _rItemSet.GetItemIfSet( ITEMID_AUTOKERN ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARAUTOKERNING, uno::Any( pKernItem->GetValue() ) );
+ if ( const SvxBrushItem* pBrushItem = _rItemSet.GetItemIfSet( ITEMID_BRUSH ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CONTROLBACKGROUND, uno::Any( pBrushItem->GetColor() ) );
+ if ( const SvxBlinkItem* pBlinkItem = _rItemSet.GetItemIfSet( ITEMID_BLINK ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARFLASH, uno::Any( pBlinkItem->GetValue() ) );
+ if ( const SvxEmphasisMarkItem* pMarkItem = _rItemSet.GetItemIfSet( ITEMID_EMPHASISMARK ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHAREMPHASIS, uno::Any( static_cast< sal_Int16 >( pMarkItem->GetEmphasisMark() ) ) );
+ if ( const SvxTwoLinesItem* pLinesItem = _rItemSet.GetItemIfSet( ITEMID_TWOLINES ) )
+ {
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARCOMBINEISON, uno::Any( pLinesItem->GetValue() ) );
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARCOMBINEPREFIX, uno::Any( OUString( pLinesItem->GetStartBracket() ) ) );
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARCOMBINESUFFIX, uno::Any( OUString( pLinesItem->GetEndBracket() ) ) );
+ }
+ if ( const SvxColorItem* pColorItem = _rItemSet.GetItemIfSet( ITEMID_COLOR ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARCOLOR, uno::Any( pColorItem->GetValue() ) );
+ if ( const SvxKerningItem* pKernItem = _rItemSet.GetItemIfSet( ITEMID_KERNING ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARKERNING, uno::Any( pKernItem->GetValue() ) );
+ if ( const SvxCaseMapItem* pCaseMapItem = _rItemSet.GetItemIfSet( ITEMID_CASEMAP ) )
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARCASEMAP, uno::Any( pCaseMapItem->GetEnumValue() ) );
+ struct Items {
+ TypedWhichId<SvxLanguageItem> nWhich;
+ OUString sPropertyName;
+ };
+ const Items pItems[] = { {ITEMID_LANGUAGE,OUString(PROPERTY_CHARLOCALE)}
+ ,{ITEMID_LANGUAGE_ASIAN,OUString(PROPERTY_CHARLOCALEASIAN)}
+ ,{ITEMID_LANGUAGE_COMPLEX,OUString(PROPERTY_CHARLOCALECOMPLEX)}
+ };
+ for(const auto & k : pItems)
+ {
+ if ( const SvxLanguageItem* pLanguageItem = _rItemSet.GetItemIfSet( k.nWhich ) )
+ {
+ lang::Locale aCharLocale( LanguageTag( pLanguageItem->GetLanguage()).getLocale());
+ lcl_pushBack( _out_rProperties, k.sPropertyName, uno::Any( aCharLocale ) );
+ }
+ }
+ if ( const SvxEscapementItem* pEscapementItem = _rItemSet.GetItemIfSet( ITEMID_ESCAPEMENT ) )
+ {
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARESCAPEMENT, uno::Any( pEscapementItem->GetEsc() ) );
+ lcl_pushBack( _out_rProperties, PROPERTY_CHARESCAPEMENTHEIGHT, uno::Any(static_cast<sal_Int8>(pEscapementItem->GetProportionalHeight())) );
+ }
+ }
+
+
+ template< class ATTRIBUTE_TYPE >
+ void lcl_applyFontAttribute( const ::comphelper::NamedValueCollection& _rAttrValues, const OUString& _pAttributeName,
+ const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat,
+ void (SAL_CALL report::XReportControlFormat::*pSetter)( ATTRIBUTE_TYPE ) )
+ {
+ ATTRIBUTE_TYPE aAttributeValue = ATTRIBUTE_TYPE();
+ if ( _rAttrValues.get_ensureType( _pAttributeName, aAttributeValue ) )
+ (_rxReportControlFormat.get()->*pSetter)( aAttributeValue );
+ }
+
+
+ void lcl_applyFontAttribute( const ::comphelper::NamedValueCollection& _rAttrValues, const OUString& _pAttributeName,
+ const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat,
+ void (SAL_CALL report::XReportControlFormat::*pSetter)( const OUString& ) )
+ {
+ OUString aAttributeValue;
+ if ( _rAttrValues.get_ensureType( _pAttributeName, aAttributeValue ) )
+ (_rxReportControlFormat.get()->*pSetter)( aAttributeValue );
+ }
+
+
+ void lcl_applyFontAttribute( const ::comphelper::NamedValueCollection& _rAttrValues, const OUString& _pAttributeName,
+ const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat,
+ void (SAL_CALL report::XReportControlFormat::*pSetter)( const lang::Locale& ) )
+ {
+ lang::Locale aAttributeValue;
+ if ( _rAttrValues.get_ensureType( _pAttributeName, aAttributeValue ) )
+ (_rxReportControlFormat.get()->*pSetter)( aAttributeValue );
+ }
+}
+
+
+bool openCharDialog( const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat,
+ const uno::Reference< awt::XWindow>& _rxParentWindow, uno::Sequence< beans::NamedValue >& _out_rNewValues )
+{
+ OSL_PRECOND( _rxReportControlFormat.is() && _rxParentWindow.is(), "openCharDialog: invalid parameters!" );
+ if ( !_rxReportControlFormat.is() || !_rxParentWindow.is() )
+ return false;
+
+ _out_rNewValues = uno::Sequence< beans::NamedValue >();
+
+
+ // UNO->ItemSet
+ static SfxItemInfo aItemInfos[] =
+ {
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+ { 0, true },
+
+ { SID_ATTR_CHAR_FONT, true },
+ { SID_ATTR_CHAR_FONTHEIGHT, true },
+ { SID_ATTR_CHAR_LANGUAGE, true },
+ { SID_ATTR_CHAR_POSTURE, true },
+ { SID_ATTR_CHAR_WEIGHT, true },
+ { SID_ATTR_CHAR_SHADOWED, true },
+ { SID_ATTR_CHAR_WORDLINEMODE, true },
+ { SID_ATTR_CHAR_CONTOUR, true },
+ { SID_ATTR_CHAR_STRIKEOUT, true },
+ { SID_ATTR_CHAR_UNDERLINE, true },
+ { SID_ATTR_CHAR_COLOR, true },
+ { SID_ATTR_CHAR_KERNING, true },
+ { SID_ATTR_CHAR_CASEMAP, true },
+ { SID_ATTR_CHAR_ESCAPEMENT, true },
+ { SID_ATTR_CHAR_FONTLIST, true },
+ { SID_ATTR_CHAR_AUTOKERN, true },
+ { SID_COLOR_TABLE, true },
+ { SID_ATTR_FLASH, true },
+ { SID_ATTR_CHAR_EMPHASISMARK, true },
+ { SID_ATTR_CHAR_TWO_LINES, true },
+ { SID_ATTR_CHAR_ROTATED, true },
+ { SID_ATTR_CHAR_SCALEWIDTH, true },
+ { SID_ATTR_CHAR_RELIEF, true },
+ { SID_ATTR_CHAR_HIDDEN, true },
+ { SID_ATTR_BRUSH, true },
+ { SID_ATTR_ALIGN_HOR_JUSTIFY, true },
+ { SID_ATTR_ALIGN_VER_JUSTIFY, true },
+
+ // Asian
+ { SID_ATTR_CHAR_CJK_FONT, true },
+ { SID_ATTR_CHAR_CJK_FONTHEIGHT, true },
+ { SID_ATTR_CHAR_CJK_LANGUAGE, true },
+ { SID_ATTR_CHAR_CJK_POSTURE, true },
+ { SID_ATTR_CHAR_CJK_WEIGHT, true },
+ // Complex
+ { SID_ATTR_CHAR_CTL_FONT, true },
+ { SID_ATTR_CHAR_CTL_FONTHEIGHT, true },
+ { SID_ATTR_CHAR_CTL_LANGUAGE, true },
+ { SID_ATTR_CHAR_CTL_POSTURE, true },
+ { SID_ATTR_CHAR_CTL_WEIGHT, true }
+ };
+ FontList aFontList(Application::GetDefaultDevice());
+ XColorListRef pColorList( XColorList::CreateStdColorList() );
+ const Graphic aNullGraphic;
+ const ::Color aNullLineCol(COL_DEFAULT_SHAPE_STROKE); // #i121448# Use defined default color
+ const ::Color aNullFillCol(COL_DEFAULT_SHAPE_FILLING); // #i121448# Use defined default color
+ const XGradient aNullGrad(COL_BLACK, COL_WHITE);
+ const XHatch aNullHatch(aNullLineCol);
+ std::vector<SfxPoolItem*> pDefaults
+ {
+ new XFillStyleItem,
+ new XFillColorItem("", aNullFillCol),
+ new XFillGradientItem(aNullGrad),
+ new XFillHatchItem(aNullHatch),
+ new XFillBitmapItem(aNullGraphic),
+ new XFillTransparenceItem,
+ new XGradientStepCountItem,
+ new XFillBmpTileItem,
+ new XFillBmpPosItem,
+ new XFillBmpSizeXItem,
+ new XFillBmpSizeYItem,
+ new XFillFloatTransparenceItem(aNullGrad, false),
+ new XSecondaryFillColorItem("", aNullFillCol),
+ new XFillBmpSizeLogItem,
+ new XFillBmpTileOffsetXItem,
+ new XFillBmpTileOffsetYItem,
+ new XFillBmpStretchItem,
+ new XFillBmpPosOffsetXItem,
+ new XFillBmpPosOffsetYItem,
+ new XFillBackgroundItem,
+
+ new SvxFontItem(ITEMID_FONT),
+ new SvxFontHeightItem(240,100,ITEMID_FONTHEIGHT),
+ new SvxLanguageItem(LANGUAGE_GERMAN,ITEMID_LANGUAGE),
+ new SvxPostureItem(ITALIC_NONE,ITEMID_POSTURE),
+ new SvxWeightItem(WEIGHT_NORMAL,ITEMID_WEIGHT),
+
+ new SvxShadowedItem(false,ITEMID_SHADOWED),
+ new SvxWordLineModeItem(false,ITEMID_WORDLINEMODE),
+ new SvxContourItem(false,ITEMID_CONTOUR),
+ new SvxCrossedOutItem(STRIKEOUT_NONE,ITEMID_CROSSEDOUT),
+ new SvxUnderlineItem(LINESTYLE_NONE,ITEMID_UNDERLINE),
+
+ new SvxColorItem(ITEMID_COLOR),
+ new SvxKerningItem(0,ITEMID_KERNING),
+ new SvxCaseMapItem(SvxCaseMap::NotMapped,ITEMID_CASEMAP),
+ new SvxEscapementItem(ITEMID_ESCAPEMENT),
+ new SvxFontListItem(&aFontList,ITEMID_FONTLIST),
+ new SvxAutoKernItem(false,ITEMID_AUTOKERN),
+ new SvxColorListItem(pColorList,ITEMID_COLOR_TABLE),
+ new SvxBlinkItem(false,ITEMID_BLINK),
+ new SvxEmphasisMarkItem(FontEmphasisMark::NONE,ITEMID_EMPHASISMARK),
+ new SvxTwoLinesItem(true,0,0,ITEMID_TWOLINES),
+ new SvxCharRotateItem(0_deg10,false,ITEMID_CHARROTATE),
+ new SvxCharScaleWidthItem(100,ITEMID_CHARSCALE_W),
+ new SvxCharReliefItem(FontRelief::NONE,ITEMID_CHARRELIEF),
+ new SvxCharHiddenItem(false,ITEMID_CHARHIDDEN),
+ new SvxBrushItem(ITEMID_BRUSH),
+ new SvxHorJustifyItem(ITEMID_HORJUSTIFY),
+ new SvxVerJustifyItem(ITEMID_VERJUSTIFY),
+// Asian
+ new SvxFontItem(ITEMID_FONT_ASIAN),
+ new SvxFontHeightItem(240,100,ITEMID_FONTHEIGHT_ASIAN),
+ new SvxLanguageItem(LANGUAGE_GERMAN,ITEMID_LANGUAGE_ASIAN),
+ new SvxPostureItem(ITALIC_NONE,ITEMID_POSTURE_ASIAN),
+ new SvxWeightItem(WEIGHT_NORMAL,ITEMID_WEIGHT_ASIAN),
+// Complex
+ new SvxFontItem(ITEMID_FONT_COMPLEX),
+ new SvxFontHeightItem(240,100,ITEMID_FONTHEIGHT_COMPLEX),
+ new SvxLanguageItem(LANGUAGE_GERMAN,ITEMID_LANGUAGE_COMPLEX),
+ new SvxPostureItem(ITALIC_NONE,ITEMID_POSTURE_COMPLEX),
+ new SvxWeightItem(WEIGHT_NORMAL,ITEMID_WEIGHT_COMPLEX)
+
+ };
+
+ OSL_ASSERT( pDefaults.size() == SAL_N_ELEMENTS(aItemInfos) );
+
+ static const WhichRangesContainer pRanges(svl::Items<
+ XATTR_FILLSTYLE, XATTR_FILLBACKGROUND,
+ ITEMID_FONT, ITEMID_WEIGHT_COMPLEX
+ >);
+
+ rtl::Reference<SfxItemPool> pPool(new SfxItemPool("ReportCharProperties", XATTR_FILL_FIRST,ITEMID_WEIGHT_COMPLEX, aItemInfos, &pDefaults));
+ // not needed for font height pPool->SetDefaultMetric( MapUnit::Map100thMM ); // ripped, don't understand why
+ pPool->FreezeIdRanges(); // the same
+ bool bSuccess = false;
+ try
+ {
+ SfxItemSet aDescriptor( *pPool, pRanges );
+ lcl_CharPropertiesToItems( _rxReportControlFormat, aDescriptor );
+
+ { // want the dialog to be destroyed before our set
+ ORptPageDialog aDlg(Application::GetFrameWeld(_rxParentWindow), &aDescriptor, "CharDialog");
+ uno::Reference< report::XShape > xShape( _rxReportControlFormat, uno::UNO_QUERY );
+ if ( xShape.is() )
+ aDlg.RemoveTabPage("background");
+ bSuccess = aDlg.run() == RET_OK;
+ if ( bSuccess )
+ {
+ lcl_itemsToCharProperties( lcl_getReportControlFont( _rxReportControlFormat,WESTERN ),
+ lcl_getReportControlFont( _rxReportControlFormat,ASIAN ),
+ lcl_getReportControlFont( _rxReportControlFormat,COMPLEX ), *aDlg.GetOutputItemSet(), _out_rNewValues );
+ }
+ }
+ }
+ catch(uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+
+ pPool.clear();
+ for (SfxPoolItem* pDefault : pDefaults)
+ delete pDefault;
+
+ return bSuccess;
+}
+
+bool openAreaDialog( const uno::Reference<report::XShape >& _xShape,const uno::Reference< awt::XWindow>& _rxParentWindow )
+{
+ OSL_PRECOND( _xShape.is() && _rxParentWindow.is(), "openAreaDialog: invalid parameters!" );
+ if ( !_xShape.is() || !_rxParentWindow.is() )
+ return false;
+
+ std::shared_ptr<rptui::OReportModel> pModel = ::reportdesign::OReportDefinition::getSdrModel(_xShape->getSection()->getReportDefinition());
+
+ weld::Window* pParent = Application::GetFrameWeld(_rxParentWindow);
+
+ bool bSuccess = false;
+ try
+ {
+ SfxItemPool& rItemPool = pModel->GetItemPool();
+ SfxItemSet aDescriptor( rItemPool, rItemPool.GetFirstWhich(), rItemPool.GetLastWhich() );
+ lcl_fillShapeToItems(_xShape, aDescriptor);
+
+ { // want the dialog to be destroyed before our set
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxAreaTabDialog> pDialog(
+ pFact->CreateSvxAreaTabDialog(pParent, &aDescriptor, pModel.get(), true, false));
+ if ( RET_OK == pDialog->Execute() )
+ {
+ bSuccess = true;
+ lcl_fillItemsToShape(_xShape,*pDialog->GetOutputItemSet());
+ }
+ }
+ }
+ catch(uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+
+ return bSuccess;
+}
+
+
+void applyCharacterSettings( const uno::Reference< report::XReportControlFormat >& _rxReportControlFormat, const uno::Sequence< beans::NamedValue >& _rSettings )
+{
+ ::comphelper::NamedValueCollection aSettings( _rSettings );
+
+ try
+ {
+ awt::FontDescriptor aAwtFont;
+ if ( aSettings.get( "Font" ) >>= aAwtFont )
+ {
+ OUString sTemp = aAwtFont.Name;
+ aAwtFont.Name.clear(); // hack to
+ _rxReportControlFormat->setFontDescriptor( aAwtFont );
+ _rxReportControlFormat->setCharFontName( sTemp );
+ }
+ if ( aSettings.get( "FontAsian" ) >>= aAwtFont )
+ {
+ OUString sTemp = aAwtFont.Name;
+ aAwtFont.Name.clear(); // hack to
+ _rxReportControlFormat->setFontDescriptorAsian( aAwtFont );
+ _rxReportControlFormat->setCharFontNameAsian( sTemp );
+ }
+ if ( aSettings.get( "FontComplex" ) >>= aAwtFont )
+ {
+ OUString sTemp = aAwtFont.Name;
+ aAwtFont.Name.clear(); // hack to
+ _rxReportControlFormat->setFontDescriptorComplex( aAwtFont );
+ _rxReportControlFormat->setCharFontNameComplex( sTemp );
+ }
+
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARSHADOWED, _rxReportControlFormat, &report::XReportControlFormat::setCharShadowed );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARCONTOURED, _rxReportControlFormat, &report::XReportControlFormat::setCharContoured );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARUNDERLINECOLOR, _rxReportControlFormat, &report::XReportControlFormat::setCharUnderlineColor );
+ lcl_applyFontAttribute( aSettings, PROPERTY_PARAADJUST, _rxReportControlFormat, &report::XReportControlFormat::setParaAdjust );
+ lcl_applyFontAttribute( aSettings, PROPERTY_VERTICALALIGN, _rxReportControlFormat, &report::XReportControlFormat::setVerticalAlign );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARRELIEF, _rxReportControlFormat, &report::XReportControlFormat::setCharRelief );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARHIDDEN, _rxReportControlFormat, &report::XReportControlFormat::setCharHidden );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARAUTOKERNING, _rxReportControlFormat, &report::XReportControlFormat::setCharAutoKerning );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CONTROLBACKGROUND, _rxReportControlFormat, &report::XReportControlFormat::setControlBackground );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARFLASH, _rxReportControlFormat, &report::XReportControlFormat::setCharFlash );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHAREMPHASIS, _rxReportControlFormat, &report::XReportControlFormat::setCharEmphasis );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARCOMBINEISON, _rxReportControlFormat, &report::XReportControlFormat::setCharCombineIsOn );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARCOMBINEPREFIX, _rxReportControlFormat, &report::XReportControlFormat::setCharCombinePrefix );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARCOMBINESUFFIX, _rxReportControlFormat, &report::XReportControlFormat::setCharCombineSuffix );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARCOLOR, _rxReportControlFormat, &report::XReportControlFormat::setCharColor );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARKERNING, _rxReportControlFormat, &report::XReportControlFormat::setCharKerning );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARCASEMAP, _rxReportControlFormat, &report::XReportControlFormat::setCharCaseMap );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARLOCALE, _rxReportControlFormat, &report::XReportControlFormat::setCharLocale );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARESCAPEMENT, _rxReportControlFormat, &report::XReportControlFormat::setCharEscapement );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARESCAPEMENTHEIGHT, _rxReportControlFormat, &report::XReportControlFormat::setCharEscapementHeight );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARLOCALEASIAN, _rxReportControlFormat, &report::XReportControlFormat::setCharLocaleAsian );
+ lcl_applyFontAttribute( aSettings, PROPERTY_CHARLOCALECOMPLEX, _rxReportControlFormat, &report::XReportControlFormat::setCharLocaleComplex );
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+void notifySystemWindow(vcl::Window const * _pWindow, vcl::Window* _pToRegister, const ::comphelper::mem_fun1_t<TaskPaneList,vcl::Window*>& rMemFunc)
+{
+ OSL_ENSURE(_pWindow,"Window can not be null!");
+ SystemWindow* pSystemWindow = _pWindow ? _pWindow->GetSystemWindow() : nullptr;
+ if ( pSystemWindow )
+ {
+ rMemFunc( pSystemWindow->GetTaskPaneList(), _pToRegister );
+ }
+}
+
+SdrObject* isOver(const tools::Rectangle& _rRect, SdrPage const & _rPage, SdrView const & _rView, bool _bAllObjects, SdrObject const * _pIgnore, sal_Int16 _nIgnoreType)
+{
+ SdrObject* pOverlappedObj = nullptr;
+ SdrObjListIter aIter(&_rPage,SdrIterMode::DeepNoGroups);
+
+ while( !pOverlappedObj )
+ {
+ SdrObject* pObjIter = aIter.Next();
+ if( !pObjIter )
+ break;
+ if ( _pIgnore != pObjIter
+ && (_bAllObjects || !_rView.IsObjMarked(pObjIter))
+ && (dynamic_cast<OUnoObject*>(pObjIter) != nullptr || dynamic_cast<OOle2Obj*>(pObjIter) != nullptr))
+ {
+ if (_nIgnoreType == ISOVER_IGNORE_CUSTOMSHAPES && pObjIter->GetObjIdentifier() == SdrObjKind::CustomShape)
+ {
+ continue;
+ }
+
+ if (dynamic_cast<OUnoObject*>(pObjIter) != nullptr || dynamic_cast<OOle2Obj*>(pObjIter) != nullptr)
+ {
+ tools::Rectangle aRect = _rRect.GetIntersection(pObjIter->GetLastBoundRect());
+ if ( !aRect.IsEmpty() && (aRect.Left() != aRect.Right() && aRect.Top() != aRect.Bottom() ) )
+ pOverlappedObj = pObjIter;
+ }
+ }
+ }
+ return pOverlappedObj;
+}
+
+static bool checkArrayForOccurrence(SdrObject const * _pObjToCheck, std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> _pIgnore[], int _nListLength)
+{
+ for(int i=0;i<_nListLength;i++)
+ {
+ SdrObject *pIgnore = _pIgnore[i].get();
+ if (pIgnore == _pObjToCheck)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+SdrObject* isOver(const tools::Rectangle& _rRect,SdrPage const & _rPage,SdrView const & _rView,bool _bAllObjects, std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> _pIgnoreList[], int _nIgnoreListLength)
+{
+ SdrObject* pOverlappedObj = nullptr;
+ SdrObjListIter aIter(&_rPage,SdrIterMode::DeepNoGroups);
+
+ while( !pOverlappedObj )
+ {
+ SdrObject* pObjIter = aIter.Next();
+ if( !pObjIter )
+ break;
+ if (checkArrayForOccurrence(pObjIter, _pIgnoreList, _nIgnoreListLength))
+ {
+ continue;
+ }
+
+ if ( (_bAllObjects || !_rView.IsObjMarked(pObjIter))
+ && (dynamic_cast<OUnoObject*>(pObjIter) != nullptr || dynamic_cast<OOle2Obj*>(pObjIter) != nullptr) )
+ {
+ tools::Rectangle aRect = _rRect.GetIntersection(pObjIter->GetLastBoundRect());
+ if ( !aRect.IsEmpty() && (aRect.Left() != aRect.Right() && aRect.Top() != aRect.Bottom() ) )
+ pOverlappedObj = pObjIter;
+ }
+ }
+ return pOverlappedObj;
+}
+
+
+SdrObject* isOver(SdrObject const * _pObj,SdrPage const & _rPage,SdrView const & _rView)
+{
+ SdrObject* pOverlappedObj = nullptr;
+ if (dynamic_cast<OUnoObject const *>(_pObj) != nullptr || dynamic_cast<OOle2Obj const *>(_pObj) != nullptr) // this doesn't need to be done for shapes
+ {
+ tools::Rectangle aRect = _pObj->GetCurrentBoundRect();
+ pOverlappedObj = isOver(aRect,_rPage,_rView,false/*_bUnMarkedObjects*/,_pObj);
+ }
+ return pOverlappedObj;
+}
+
+
+uno::Sequence< OUString > getParameterNames( const uno::Reference< sdbc::XRowSet >& _rxRowSet )
+{
+ uno::Sequence< OUString > aNames;
+
+ try
+ {
+ uno::Reference< sdb::XParametersSupplier > xSuppParams( _rxRowSet, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xParams( xSuppParams->getParameters() );
+ if ( xParams.is() )
+ {
+ sal_Int32 count( xParams->getCount() );
+ aNames.realloc( count );
+ auto pNames = aNames.getArray();
+
+ uno::Reference< beans::XPropertySet > xParam;
+ OUString sParamName;
+ for ( sal_Int32 i=0; i<count; ++i )
+ {
+ xParam.set( xParams->getByIndex(i), uno::UNO_QUERY_THROW );
+ OSL_VERIFY( xParam->getPropertyValue( PROPERTY_NAME ) >>= sParamName );
+ pNames[i] = sParamName;
+ }
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+
+ return aNames;
+}
+
+tools::Rectangle getRectangleFromControl(SdrObject* _pControl)
+{
+ if (_pControl)
+ {
+ uno::Reference< report::XReportComponent > xComponent( _pControl->getUnoShape(), uno::UNO_QUERY);
+ if (xComponent.is())
+ {
+ tools::Rectangle aRect(VCLPoint(xComponent->getPosition()),VCLSize(xComponent->getSize()));
+ aRect.setHeight(aRect.getHeight() + 1);
+ aRect.setWidth(aRect.getWidth() + 1);
+ return aRect;
+ }
+ }
+ return tools::Rectangle();
+}
+
+// check overlapping
+void correctOverlapping(SdrObject* _pControl,OReportSection const & _aReportSection,bool _bInsert)
+{
+ OSectionView& rSectionView = _aReportSection.getSectionView();
+ uno::Reference< report::XReportComponent> xComponent(_pControl->getUnoShape(),uno::UNO_QUERY);
+ tools::Rectangle aRect = getRectangleFromControl(_pControl);
+
+ bool bOverlapping = true;
+ while ( bOverlapping )
+ {
+ SdrObject* pOverlappedObj = isOver(aRect,*_aReportSection.getPage(),rSectionView,true, _pControl);
+ bOverlapping = pOverlappedObj != nullptr;
+ if ( bOverlapping )
+ {
+ const tools::Rectangle& aLogicRect = pOverlappedObj->GetLogicRect();
+ aRect.Move(0,aLogicRect.Top() + aLogicRect.getHeight() - aRect.Top());
+ xComponent->setPositionY(aRect.Top());
+ }
+ }
+ if (_bInsert) // now insert objects
+ rSectionView.InsertObjectAtView(_pControl,*rSectionView.GetSdrPageView(), SdrInsertFlags::ADDMARK);
+}
+
+void setZoomFactor(const Fraction& _aZoom, vcl::Window& _rWindow)
+{
+ MapMode aMapMode( _rWindow.GetMapMode() );
+ aMapMode.SetScaleX(_aZoom);
+ aMapMode.SetScaleY(_aZoom);
+ _rWindow.SetMapMode(aMapMode);
+}
+
+bool openDialogFormula_nothrow( OUString& _in_out_rFormula
+ , const css::uno::Reference< css::uno::XComponentContext >& _xContext
+ , const uno::Reference< awt::XWindow>& _xInspectorWindow
+ , const css::uno::Reference < css::beans::XPropertySet >& _xRowSet
+ )
+{
+ OSL_PRECOND( _xInspectorWindow.is(), "openDialogFormula_nothrow: invalid parameters!" );
+ if ( !_xInspectorWindow.is() )
+ return false;
+ bool bSuccess = false;
+ ::dbtools::SQLExceptionInfo aErrorInfo;
+ uno::Reference< awt::XWindow > xInspectorWindow;
+ uno::Reference< lang::XMultiComponentFactory > xFactory;
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory;
+ try
+ {
+ xFactory = _xContext->getServiceManager();
+ xServiceFactory.set(xFactory,uno::UNO_QUERY);
+
+ uno::Reference< report::meta::XFunctionManager> xMgr(xFactory->createInstanceWithContext("org.libreoffice.report.pentaho.SOFunctionManager",_xContext),uno::UNO_QUERY);
+ if ( xMgr.is() )
+ {
+ auto pFormulaManager = std::make_shared<FunctionManager>(xMgr);
+ ReportFormula aFormula( _in_out_rFormula );
+
+ CharClass aCC(_xContext, LanguageTag(LANGUAGE_SYSTEM));
+ svl::SharedStringPool aStringPool(aCC);
+
+ FormulaDialog aDlg(
+ Application::GetFrameWeld(_xInspectorWindow), xServiceFactory, pFormulaManager,
+ aFormula.getUndecoratedContent(), _xRowSet, aStringPool);
+
+ bSuccess = aDlg.run() == RET_OK;
+ if ( bSuccess )
+ {
+ OUString sFormula = aDlg.getCurrentFormula();
+ if ( sFormula[0] == '=' )
+ _in_out_rFormula = OUString::Concat("rpt:") + sFormula.subView(1);
+ else
+ _in_out_rFormula = "rpt:" + sFormula;
+ }
+ }
+ }
+ catch (const sdb::SQLContext& e) { aErrorInfo = e; }
+ catch (const sdbc::SQLWarning& e) { aErrorInfo = e; }
+ catch (const sdbc::SQLException& e) { aErrorInfo = e; }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::impl_dialogFilter_nothrow" );
+ }
+
+ if ( aErrorInfo.isValid() )
+ ::dbtools::showError( aErrorInfo, xInspectorWindow, _xContext );
+
+ return bSuccess;
+}
+
+} // namespace rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/misc/statusbarcontroller.cxx b/reportdesign/source/ui/misc/statusbarcontroller.cxx
new file mode 100644
index 000000000..22f2d7714
--- /dev/null
+++ b/reportdesign/source/ui/misc/statusbarcontroller.cxx
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <statusbarcontroller.hxx>
+
+#include <cppuhelper/supportsservice.hxx>
+#include <comphelper/types.hxx>
+#include <svx/zoomsliderctrl.hxx>
+#include <svx/zoomctrl.hxx>
+#include <svx/svxids.hrc>
+#include <sfx2/zoomitem.hxx>
+#include <svx/zoomslideritem.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/status.hxx>
+#include <osl/mutex.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+namespace rptui
+{
+ using namespace svt;
+ using namespace com::sun::star::uno;
+ using namespace com::sun::star::beans;
+ using namespace com::sun::star::lang;
+ using namespace ::com::sun::star::frame;
+ using namespace ::com::sun::star::util;
+
+OUString SAL_CALL OStatusbarController::getImplementationName()
+{
+ return "com.sun.star.report.comp.StatusbarController";
+}
+
+sal_Bool SAL_CALL OStatusbarController::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+Sequence< OUString> SAL_CALL OStatusbarController::getSupportedServiceNames()
+{
+ return { "com.sun.star.frame.StatusbarController" };
+}
+
+IMPLEMENT_FORWARD_XINTERFACE2(OStatusbarController, ::svt::StatusbarController,OStatusbarController_BASE)
+
+OStatusbarController::OStatusbarController(const Reference< XComponentContext >& rxContext)
+: ::svt::StatusbarController(rxContext, Reference< XFrame >(), OUString(), 0)
+,m_nSlotId(0)
+,m_nId(1)
+{
+}
+
+void SAL_CALL OStatusbarController::initialize( const Sequence< Any >& _rArguments )
+{
+ StatusbarController::initialize(_rArguments);
+ SolarMutexGuard aSolarMutexGuard;
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ VclPtr< StatusBar > pStatusBar = static_cast<StatusBar*>(VCLUnoHelper::GetWindow(m_xParentWindow));
+ if ( !pStatusBar )
+ return;
+
+ const sal_uInt16 nCount = pStatusBar->GetItemCount();
+ for (sal_uInt16 nPos = 0; nPos < nCount; ++nPos)
+ {
+ const sal_uInt16 nItemId = pStatusBar->GetItemId(nPos);
+ if ( pStatusBar->GetItemCommand(nItemId) == m_aCommandURL )
+ {
+ m_nId = nItemId;
+ break;
+ }
+ }
+
+ rtl::Reference<SfxStatusBarControl> pController;
+ if ( m_aCommandURL == ".uno:ZoomSlider" )
+ {
+ m_nSlotId = SID_ATTR_ZOOMSLIDER;
+ pController = new SvxZoomSliderControl(m_nSlotId,m_nId,*pStatusBar);
+ }
+ else if ( m_aCommandURL == ".uno:Zoom" )
+ {
+ m_nSlotId = SID_ATTR_ZOOM;
+ pController = new SvxZoomStatusBarControl(m_nSlotId,m_nId,*pStatusBar);
+ }
+
+ if ( pController )
+ {
+ m_rController.set( pController );
+ if ( m_rController.is() )
+ {
+ m_rController->initialize(_rArguments);
+ m_rController->update();
+ }
+ }
+
+ addStatusListener(m_aCommandURL);
+ update();
+}
+// XStatusListener
+void SAL_CALL OStatusbarController::statusChanged( const FeatureStateEvent& _aEvent)
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ if ( !m_rController.is() )
+ return;
+
+ if ( m_aCommandURL == ".uno:ZoomSlider" )
+ {
+ Sequence< PropertyValue > aSeq;
+ if ( (_aEvent.State >>= aSeq) && aSeq.getLength() == 2 )
+ {
+ SvxZoomSliderItem aZoomSlider(100,20,400);
+ aZoomSlider.PutValue(_aEvent.State, 0);
+ static_cast<SvxZoomSliderControl*>(m_rController.get())->StateChangedAtStatusBarControl(m_nSlotId,SfxItemState::DEFAULT,&aZoomSlider);
+ }
+ }
+ else if ( m_aCommandURL == ".uno:Zoom" )
+ {
+ Sequence< PropertyValue > aSeq;
+ if ( (_aEvent.State >>= aSeq) && aSeq.getLength() == 3 )
+ {
+ SvxZoomItem aZoom;
+ aZoom.PutValue(_aEvent.State, 0 );
+ static_cast<SvxZoomStatusBarControl*>(m_rController.get())->StateChangedAtStatusBarControl(m_nSlotId,SfxItemState::DEFAULT,&aZoom);
+ }
+ }
+}
+
+// XStatusbarController
+sal_Bool SAL_CALL OStatusbarController::mouseButtonDown(const css::awt::MouseEvent& _aEvent)
+{
+ return m_rController.is() && m_rController->mouseButtonDown(_aEvent);
+}
+
+sal_Bool SAL_CALL OStatusbarController::mouseMove( const css::awt::MouseEvent& _aEvent)
+{
+ return m_rController.is() && m_rController->mouseMove(_aEvent);
+}
+
+sal_Bool SAL_CALL OStatusbarController::mouseButtonUp( const css::awt::MouseEvent& _aEvent)
+{
+ return m_rController.is() && m_rController->mouseButtonUp(_aEvent);
+}
+
+void SAL_CALL OStatusbarController::command(
+ const css::awt::Point& aPos,
+ ::sal_Int32 nCommand,
+ sal_Bool bMouseEvent,
+ const css::uno::Any& aData )
+{
+ if ( m_rController.is() )
+ m_rController->command( aPos, nCommand, bMouseEvent, aData );
+}
+
+void SAL_CALL OStatusbarController::paint(
+ const css::uno::Reference< css::awt::XGraphics >& xGraphics,
+ const css::awt::Rectangle& rOutputRectangle,
+ ::sal_Int32 nStyle )
+{
+ if ( m_rController.is() )
+ m_rController->paint( xGraphics, rOutputRectangle, nStyle );
+}
+
+void SAL_CALL OStatusbarController::click(
+ const css::awt::Point& aPos )
+{
+ if ( m_rController.is() )
+ m_rController->click( aPos );
+}
+
+void SAL_CALL OStatusbarController::doubleClick(
+ const css::awt::Point& aPos )
+{
+ if ( m_rController.is() )
+ m_rController->doubleClick( aPos );
+}
+
+void SAL_CALL OStatusbarController::update()
+{
+ ::svt::StatusbarController::update();
+ if ( m_rController.is() )
+ m_rController->update();
+}
+
+// XComponent
+void SAL_CALL OStatusbarController::dispose()
+{
+ if ( m_rController.is() )
+ ::comphelper::disposeComponent( m_rController );
+
+ svt::StatusbarController::dispose();
+}
+
+} // rptui
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+reportdesign_OStatusbarController_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new rptui::OStatusbarController(context));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/DesignView.cxx b/reportdesign/source/ui/report/DesignView.cxx
new file mode 100644
index 000000000..ab213479b
--- /dev/null
+++ b/reportdesign/source/ui/report/DesignView.cxx
@@ -0,0 +1,686 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <DesignView.hxx>
+#include <ReportController.hxx>
+#include <svtools/acceleratorexecute.hxx>
+#include <unotools/viewoptions.hxx>
+#include <RptDef.hxx>
+#include <UITools.hxx>
+#include <RptObject.hxx>
+#include <propbrw.hxx>
+#include <helpids.h>
+#include <SectionView.hxx>
+#include <ReportSection.hxx>
+#include <rptui_slotid.hrc>
+#include <AddField.hxx>
+#include <ScrollHelper.hxx>
+#include <Navigator.hxx>
+#include <SectionWindow.hxx>
+
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+#include <algorithm>
+
+namespace rptui
+{
+using namespace ::dbaui;
+using namespace ::utl;
+using namespace ::com::sun::star;
+using namespace uno;
+using namespace lang;
+using namespace beans;
+using namespace container;
+
+#define START_SIZE_TASKPANE 30
+#define COLSET_ID 1
+#define REPORT_ID 2
+#define TASKPANE_ID 3
+
+namespace {
+
+class OTaskWindow : public vcl::Window
+{
+ VclPtr<PropBrw> m_pPropWin;
+public:
+ explicit OTaskWindow(vcl::Window* _pParent) : Window(_pParent),m_pPropWin(nullptr){}
+ virtual ~OTaskWindow() override { disposeOnce(); }
+ virtual void dispose() override { m_pPropWin.clear(); vcl::Window::dispose(); }
+
+ void setPropertyBrowser(PropBrw* _pPropWin)
+ {
+ m_pPropWin = _pPropWin;
+ }
+
+ virtual void Resize() override
+ {
+ const Size aSize = GetOutputSizePixel();
+ if ( m_pPropWin && aSize.Height() && aSize.Width() )
+ m_pPropWin->SetSizePixel(aSize);
+ }
+};
+
+}
+
+
+
+ODesignView::ODesignView( vcl::Window* pParent,
+ const Reference< XComponentContext >& _rxOrb,
+ OReportController& _rController) :
+ ODataView( pParent, _rController, _rxOrb, WB_DIALOGCONTROL )
+ ,m_aSplitWin(VclPtr<SplitWindow>::Create(this))
+ ,m_rReportController( _rController )
+ ,m_aScrollWindow(VclPtr<rptui::OScrollWindowHelper>::Create(this))
+ ,m_pPropWin(nullptr)
+ ,m_pCurrentView(nullptr)
+ ,m_aMarkIdle("reportdesign ODesignView Mark Idle")
+ ,m_eMode( DlgEdMode::Select )
+ ,m_eActObj( SdrObjKind::NONE )
+ ,m_aGridSizeCoarse( 1000, 1000 ) // #i93595# 100TH_MM changed to grid using coarse 1 cm grid
+ ,m_aGridSizeFine( 250, 250 ) // and a 0,25 cm subdivision for better visualisation
+ ,m_bDeleted( false )
+{
+ SetHelpId(UID_RPT_RPT_APP_VIEW);
+ ImplInitSettings();
+
+ SetMapMode( MapMode( MapUnit::Map100thMM ) );
+
+ // now create the task pane on the right side :-)
+ m_pTaskPane = VclPtr<OTaskWindow>::Create(this);
+
+ m_aSplitWin->InsertItem( COLSET_ID,100,SPLITWINDOW_APPEND, 0, SplitWindowItemFlags::PercentSize | SplitWindowItemFlags::ColSet );
+ m_aSplitWin->InsertItem( REPORT_ID, m_aScrollWindow.get(), 100, SPLITWINDOW_APPEND, COLSET_ID, SplitWindowItemFlags::PercentSize);
+
+ // set up splitter
+ m_aSplitWin->SetSplitHdl(LINK(this, ODesignView,SplitHdl));
+ m_aSplitWin->SetAlign(WindowAlign::Left);
+ m_aSplitWin->Show();
+
+ m_aMarkIdle.SetInvokeHandler( LINK( this, ODesignView, MarkTimeout ) );
+}
+
+
+ODesignView::~ODesignView()
+{
+ disposeOnce();
+}
+
+void ODesignView::dispose()
+{
+ m_bDeleted = true;
+ Hide();
+ m_aScrollWindow->Hide();
+ m_aMarkIdle.Stop();
+ if ( m_pPropWin )
+ {
+ notifySystemWindow(this,m_pPropWin,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
+ m_pPropWin.disposeAndClear();
+ }
+ if ( m_xAddField )
+ {
+ SvtViewOptions aDlgOpt( EViewType::Window, UID_RPT_RPT_APP_VIEW );
+ aDlgOpt.SetWindowState(OStringToOUString(m_xAddField->getDialog()->get_window_state(WindowStateMask::All), RTL_TEXTENCODING_ASCII_US));
+
+ if (m_xAddField->getDialog()->get_visible())
+ m_xAddField->response(RET_CANCEL);
+
+ m_xAddField.reset();
+ }
+ if ( m_xReportExplorer )
+ {
+ SvtViewOptions aDlgOpt(EViewType::Window, OStringToOUString(m_xReportExplorer->get_help_id(), RTL_TEXTENCODING_UTF8));
+ aDlgOpt.SetWindowState(OStringToOUString(m_xReportExplorer->getDialog()->get_window_state(WindowStateMask::All), RTL_TEXTENCODING_ASCII_US));
+
+ if (m_xReportExplorer->getDialog()->get_visible())
+ m_xReportExplorer->response(RET_CANCEL);
+
+ m_xReportExplorer.reset();
+ }
+
+ m_pTaskPane.disposeAndClear();
+ m_aScrollWindow.disposeAndClear();
+ m_aSplitWin.disposeAndClear();
+ dbaui::ODataView::dispose();
+}
+
+void ODesignView::initialize()
+{
+ SetMapMode( MapMode( MapUnit::Map100thMM ) );
+ m_aScrollWindow->initialize();
+ m_aScrollWindow->Show();
+}
+
+void ODesignView::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ODataView::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+bool ODesignView::PreNotify( NotifyEvent& rNEvt )
+{
+ bool bRet = ODataView::PreNotify(rNEvt); // 1 := has to be handled here
+ switch(rNEvt.GetType())
+ {
+ case MouseNotifyEvent::KEYINPUT:
+ {
+ if ( m_pPropWin && m_pPropWin->HasChildPathFocus() )
+ return false;
+ if (m_xAddField && m_xAddField->getDialog()->has_toplevel_focus())
+ return false;
+ if ( m_xReportExplorer && m_xReportExplorer->getDialog()->has_toplevel_focus())
+ return false;
+ const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ if ( handleKeyEvent(*pKeyEvent) )
+ bRet = true;
+ else if ( bRet && m_pAccel )
+ {
+ const vcl::KeyCode& rCode = pKeyEvent->GetKeyCode();
+ util::URL aUrl;
+ aUrl.Complete = m_pAccel->findCommand(svt::AcceleratorExecute::st_VCLKey2AWTKey(rCode));
+ if ( aUrl.Complete.isEmpty() || !m_xController->isCommandEnabled( aUrl.Complete ) )
+ bRet = false;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return bRet;
+}
+
+void ODesignView::resizeDocumentView(tools::Rectangle& _rPlayground)
+{
+ if ( !_rPlayground.IsEmpty() )
+ {
+ const Size aPlaygroundSize( _rPlayground.GetSize() );
+
+ // calc the split pos, and forward it to the controller
+ sal_Int32 nSplitPos = getController().getSplitPos();
+ if ( 0 != aPlaygroundSize.Width() )
+ {
+ if ( ( -1 == nSplitPos )
+ || ( nSplitPos >= aPlaygroundSize.Width() )
+ )
+ {
+ tools::Long nMinWidth = static_cast<tools::Long>(0.1*aPlaygroundSize.Width());
+ if ( m_pPropWin && m_pPropWin->IsVisible() )
+ nMinWidth = m_pPropWin->GetMinOutputSizePixel().Width();
+ nSplitPos = static_cast<sal_Int32>(_rPlayground.Right() - nMinWidth);
+ getController().setSplitPos(nSplitPos);
+ }
+ }
+
+ if ( m_aSplitWin->IsItemValid(TASKPANE_ID) )
+ {
+ // normalize the split pos
+ const tools::Long nSplitterWidth = StyleSettings::GetSplitSize();
+ Point aTaskPanePos(nSplitPos + nSplitterWidth, _rPlayground.Top());
+ if (m_pTaskPane && m_pTaskPane->IsVisible() && m_pPropWin)
+ {
+ aTaskPanePos.setX( aPlaygroundSize.Width() - m_pTaskPane->GetSizePixel().Width() );
+ sal_Int32 nMinWidth = m_pPropWin->getMinimumSize().Width();
+ if ( nMinWidth > (aPlaygroundSize.Width() - aTaskPanePos.X()) )
+ {
+ aTaskPanePos.setX( aPlaygroundSize.Width() - nMinWidth );
+ }
+ nSplitPos = aTaskPanePos.X() - nSplitterWidth;
+ getController().setSplitPos(nSplitPos);
+
+ const tools::Long nTaskPaneSize = static_cast<tools::Long>((aPlaygroundSize.Width() - aTaskPanePos.X())*100/aPlaygroundSize.Width());
+ if ( m_aSplitWin->GetItemSize( TASKPANE_ID ) != nTaskPaneSize )
+ {
+ m_aSplitWin->SetItemSize( REPORT_ID, 99 - nTaskPaneSize );
+ m_aSplitWin->SetItemSize( TASKPANE_ID, nTaskPaneSize );
+ }
+ }
+ }
+ // set the size of the report window
+ m_aSplitWin->SetPosSizePixel( _rPlayground.TopLeft(),aPlaygroundSize );
+ }
+ // just for completeness: there is no space left, we occupied it all ...
+ _rPlayground.SetPos( _rPlayground.BottomRight() );
+ _rPlayground.SetSize( Size( 0, 0 ) );
+
+}
+
+IMPL_LINK_NOARG(ODesignView, MarkTimeout, Timer *, void)
+{
+ if ( m_pPropWin && m_pPropWin->IsVisible() )
+ {
+ m_pPropWin->Update(m_pCurrentView);
+ uno::Reference<beans::XPropertySet> xProp(m_xReportComponent,uno::UNO_QUERY);
+ if ( xProp.is() )
+ {
+ m_pPropWin->Update(xProp);
+ static_cast<OTaskWindow*>(m_pTaskPane.get())->Resize();
+ }
+ Resize();
+ }
+}
+
+
+void ODesignView::SetMode( DlgEdMode _eNewMode )
+{
+ m_eMode = _eNewMode;
+ if ( m_eMode == DlgEdMode::Select )
+ m_eActObj = SdrObjKind::NONE;
+
+ m_aScrollWindow->SetMode(_eNewMode);
+}
+
+void ODesignView::SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType )
+{
+ m_eActObj = eObj;
+ m_aScrollWindow->SetInsertObj( eObj,_sShapeType );
+}
+
+OUString const & ODesignView::GetInsertObjString() const
+{
+ return m_aScrollWindow->GetInsertObjString();
+}
+
+
+void ODesignView::Cut()
+{
+ Copy();
+ Delete();
+}
+
+
+void ODesignView::Copy()
+{
+ m_aScrollWindow->Copy();
+}
+
+
+void ODesignView::Paste()
+{
+ m_aScrollWindow->Paste();
+}
+
+void ODesignView::Delete()
+{
+ m_aScrollWindow->Delete();
+}
+
+bool ODesignView::HasSelection() const
+{
+ return m_aScrollWindow->HasSelection();
+}
+
+
+bool ODesignView::IsPasteAllowed() const
+{
+ return m_aScrollWindow->IsPasteAllowed();
+}
+
+
+void ODesignView::UpdatePropertyBrowserDelayed(OSectionView& _rView)
+{
+ if ( m_pCurrentView != &_rView )
+ {
+ if ( m_pCurrentView )
+ m_aScrollWindow->setMarked(m_pCurrentView,false);
+ m_pCurrentView = &_rView;
+ m_aScrollWindow->setMarked(m_pCurrentView, true);
+ m_xReportComponent.clear();
+ DlgEdHint aHint( RPTUI_HINT_SELECTIONCHANGED );
+ Broadcast( aHint );
+ }
+ m_aMarkIdle.Start();
+}
+
+
+void ODesignView::toggleGrid(bool _bGridVisible)
+{
+ m_aScrollWindow->toggleGrid(_bGridVisible);
+}
+
+sal_uInt16 ODesignView::getSectionCount() const
+{
+ return m_aScrollWindow->getSectionCount();
+}
+
+void ODesignView::showRuler(bool _bShow)
+{
+ m_aScrollWindow->showRuler(_bShow);
+}
+
+void ODesignView::removeSection(sal_uInt16 _nPosition)
+{
+ m_aScrollWindow->removeSection(_nPosition);
+}
+
+void ODesignView::addSection(const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry,sal_uInt16 _nPosition)
+{
+ m_aScrollWindow->addSection(_xSection,_sColorEntry,_nPosition);
+}
+
+void ODesignView::GetFocus()
+{
+ Window::GetFocus();
+
+ if ( !m_bDeleted )
+ {
+ OSectionWindow* pSectionWindow = m_aScrollWindow->getMarkedSection();
+ if ( pSectionWindow )
+ pSectionWindow->GrabFocus();
+ }
+}
+
+void ODesignView::ImplInitSettings()
+{
+ SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor() ));
+ GetOutDev()->SetFillColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
+ SetTextFillColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
+}
+
+IMPL_LINK_NOARG( ODesignView, SplitHdl, SplitWindow*, void )
+{
+ const Size aOutputSize = GetOutputSizePixel();
+ const tools::Long nTest = aOutputSize.Width() * m_aSplitWin->GetItemSize(TASKPANE_ID) / 100;
+ tools::Long nMinWidth = static_cast<tools::Long>(0.1*aOutputSize.Width());
+ if ( m_pPropWin && m_pPropWin->IsVisible() )
+ nMinWidth = m_pPropWin->GetMinOutputSizePixel().Width();
+
+ if ( (aOutputSize.Width() - nTest) >= nMinWidth && nTest > m_aScrollWindow->getMaxMarkerWidth() )
+ {
+ getController().setSplitPos(nTest);
+ }
+}
+
+void ODesignView::SelectAll(const SdrObjKind _nObjectType)
+{
+ m_aScrollWindow->SelectAll(_nObjectType);
+}
+
+void ODesignView::unmarkAllObjects()
+{
+ m_aScrollWindow->unmarkAllObjects();
+}
+
+void ODesignView::togglePropertyBrowser(bool _bToggleOn)
+{
+ if ( !m_pPropWin && _bToggleOn )
+ {
+ m_pPropWin = VclPtr<PropBrw>::Create(getController().getORB(), m_pTaskPane,this);
+ m_pPropWin->Invalidate();
+ static_cast<OTaskWindow*>(m_pTaskPane.get())->setPropertyBrowser(m_pPropWin);
+ notifySystemWindow(this,m_pPropWin,::comphelper::mem_fun(&TaskPaneList::AddWindow));
+ }
+ if ( !(m_pPropWin && _bToggleOn != m_pPropWin->IsVisible()) )
+ return;
+
+ if ( !m_pCurrentView && !m_xReportComponent.is() )
+ m_xReportComponent = getController().getReportDefinition();
+
+ const bool bWillBeVisible = _bToggleOn;
+ m_pPropWin->Show(bWillBeVisible);
+ m_pTaskPane->Show(bWillBeVisible);
+ m_pTaskPane->Invalidate();
+
+ if ( bWillBeVisible )
+ m_aSplitWin->InsertItem( TASKPANE_ID, m_pTaskPane,START_SIZE_TASKPANE, SPLITWINDOW_APPEND, COLSET_ID, SplitWindowItemFlags::PercentSize);
+ else
+ m_aSplitWin->RemoveItem(TASKPANE_ID);
+
+ if ( bWillBeVisible )
+ m_aMarkIdle.Start();
+}
+
+void ODesignView::showProperties(const uno::Reference< uno::XInterface>& _xReportComponent)
+{
+ if ( m_xReportComponent != _xReportComponent )
+ {
+ m_xReportComponent = _xReportComponent;
+ if ( m_pCurrentView )
+ m_aScrollWindow->setMarked(m_pCurrentView,false);
+ m_pCurrentView = nullptr;
+ m_aMarkIdle.Start();
+ }
+}
+
+bool ODesignView::isReportExplorerVisible() const
+{
+ return m_xReportExplorer && m_xReportExplorer->getDialog()->get_visible();
+}
+
+void ODesignView::toggleReportExplorer()
+{
+ if ( !m_xReportExplorer )
+ {
+ OReportController& rReportController = getController();
+ m_xReportExplorer = std::make_shared<ONavigator>(GetFrameWeld(), rReportController);
+ SvtViewOptions aDlgOpt(EViewType::Window, OStringToOUString(m_xReportExplorer->get_help_id(), RTL_TEXTENCODING_UTF8));
+ if ( aDlgOpt.Exists() )
+ m_xReportExplorer->getDialog()->set_window_state(OUStringToOString(aDlgOpt.GetWindowState(), RTL_TEXTENCODING_ASCII_US));
+ }
+
+ if (!m_xReportExplorer->getDialog()->get_visible())
+ weld::DialogController::runAsync(m_xReportExplorer, [this](sal_Int32 /*nResult*/) { m_xReportExplorer.reset(); });
+ else
+ m_xReportExplorer->response(RET_CANCEL);
+}
+
+bool ODesignView::isAddFieldVisible() const
+{
+ return m_xAddField && m_xAddField->getDialog()->get_visible();
+}
+
+void ODesignView::toggleAddField()
+{
+ if (!m_xAddField)
+ {
+ uno::Reference< report::XReportDefinition > xReport(m_xReportComponent,uno::UNO_QUERY);
+ uno::Reference< report::XReportComponent > xReportComponent(m_xReportComponent,uno::UNO_QUERY);
+ OReportController& rReportController = getController();
+ if ( !m_pCurrentView && !xReport.is() )
+ {
+ if ( xReportComponent.is() )
+ xReport = xReportComponent->getSection()->getReportDefinition();
+ else
+ xReport = rReportController.getReportDefinition().get();
+ }
+ else if ( m_pCurrentView )
+ {
+ uno::Reference< report::XSection > xSection = m_pCurrentView->getReportSection()->getSection();
+ xReport = xSection->getReportDefinition();
+ }
+ uno::Reference < beans::XPropertySet > xSet(rReportController.getRowSet(),uno::UNO_QUERY);
+ m_xAddField = std::make_shared<OAddFieldWindow>(GetFrameWeld(), xSet);
+ m_xAddField->SetCreateHdl(LINK( &rReportController, OReportController, OnCreateHdl ) );
+ SvtViewOptions aDlgOpt( EViewType::Window, UID_RPT_RPT_APP_VIEW );
+ if ( aDlgOpt.Exists() )
+ m_xAddField->getDialog()->set_window_state(OUStringToOString(aDlgOpt.GetWindowState(), RTL_TEXTENCODING_ASCII_US));
+ m_xAddField->Update();
+ }
+ if (!m_xAddField->getDialog()->get_visible())
+ weld::DialogController::runAsync(m_xAddField, [this](sal_Int32 /*nResult*/) { m_xAddField.reset(); });
+ else
+ m_xAddField->response(RET_CANCEL);
+}
+
+uno::Reference< report::XSection > ODesignView::getCurrentSection() const
+{
+ uno::Reference< report::XSection > xSection;
+ if ( m_pCurrentView )
+ xSection = m_pCurrentView->getReportSection()->getSection();
+
+ return xSection;
+}
+
+uno::Reference< report::XReportComponent > ODesignView::getCurrentControlModel() const
+{
+ uno::Reference< report::XReportComponent > xModel;
+ if ( m_pCurrentView )
+ {
+ xModel = m_pCurrentView->getReportSection()->getCurrentControlModel();
+ }
+ return xModel;
+}
+
+OSectionWindow* ODesignView::getMarkedSection(NearSectionAccess nsa) const
+{
+ return m_aScrollWindow->getMarkedSection(nsa);
+}
+
+OSectionWindow* ODesignView::getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const
+{
+ return m_aScrollWindow->getSectionWindow(_xSection);
+}
+
+void ODesignView::markSection(const sal_uInt16 _nPos)
+{
+ m_aScrollWindow->markSection(_nPos);
+}
+
+void ODesignView::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const
+{
+ m_aScrollWindow->fillCollapsedSections(_rCollapsedPositions);
+}
+
+void ODesignView::collapseSections(const uno::Sequence< beans::PropertyValue>& _aCollapsedSections)
+{
+ m_aScrollWindow->collapseSections(_aCollapsedSections);
+}
+
+OUString ODesignView::getCurrentPage() const
+{
+ return m_pPropWin ? m_pPropWin->getCurrentPage() : OUString();
+}
+
+void ODesignView::setCurrentPage(const OUString& _sLastActivePage)
+{
+ if ( m_pPropWin )
+ m_pPropWin->setCurrentPage(_sLastActivePage);
+}
+
+void ODesignView::alignMarkedObjects(ControlModification _nControlModification,bool _bAlignAtSection)
+{
+ m_aScrollWindow->alignMarkedObjects(_nControlModification, _bAlignAtSection);
+}
+
+bool ODesignView::handleKeyEvent(const KeyEvent& _rEvent)
+{
+ if ( m_pPropWin && m_pPropWin->HasChildPathFocus() )
+ return false;
+ if (m_xAddField && m_xAddField->getDialog()->has_toplevel_focus())
+ return false;
+ if (m_xReportExplorer && m_xReportExplorer->getDialog()->has_toplevel_focus())
+ return false;
+ return m_aScrollWindow->handleKeyEvent(_rEvent);
+}
+
+void ODesignView::setMarked(const uno::Reference< report::XSection>& _xSection,bool _bMark)
+{
+ m_aScrollWindow->setMarked(_xSection,_bMark);
+ if ( _bMark )
+ UpdatePropertyBrowserDelayed(getMarkedSection()->getReportSection().getSectionView());
+ else
+ m_pCurrentView = nullptr;
+}
+
+void ODesignView::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _aShapes,bool _bMark)
+{
+ m_aScrollWindow->setMarked(_aShapes,_bMark);
+ if ( _aShapes.hasElements() && _bMark )
+ showProperties(_aShapes[0]);
+ else
+ m_xReportComponent.clear();
+}
+
+void ODesignView::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ {
+ const uno::Sequence< beans::PropertyValue> aArgs;
+ getController().executeChecked(SID_SELECT_REPORT,aArgs);
+ }
+ ODataView::MouseButtonDown(rMEvt);
+}
+
+uno::Any ODesignView::getCurrentlyShownProperty() const
+{
+ uno::Any aRet;
+ OSectionWindow* pSectionWindow = getMarkedSection();
+ if ( pSectionWindow )
+ {
+ ::std::vector< uno::Reference< uno::XInterface > > aSelection;
+ pSectionWindow->getReportSection().fillControlModelSelection(aSelection);
+ if ( !aSelection.empty() )
+ {
+ uno::Sequence< uno::Reference< report::XReportComponent > > aSeq(aSelection.size());
+ std::transform(
+ aSelection.begin(), aSelection.end(), aSeq.getArray(),
+ [](const auto& rxInterface)
+ { return uno::Reference<report::XReportComponent>(rxInterface, uno::UNO_QUERY); });
+ aRet <<= aSeq;
+ }
+ }
+ return aRet;
+}
+
+void ODesignView::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const
+{
+ m_aScrollWindow->fillControlModelSelection(_rSelection);
+}
+
+void ODesignView::setGridSnap(bool bOn)
+{
+ m_aScrollWindow->setGridSnap(bOn);
+
+}
+
+void ODesignView::setDragStripes(bool bOn)
+{
+ m_aScrollWindow->setDragStripes(bOn);
+}
+
+bool ODesignView::isHandleEvent() const
+{
+ return m_pPropWin && m_pPropWin->HasChildPathFocus();
+}
+
+sal_uInt32 ODesignView::getMarkedObjectCount() const
+{
+ return m_aScrollWindow->getMarkedObjectCount();
+}
+
+void ODesignView::zoom(const Fraction& _aZoom)
+{
+ m_aScrollWindow->zoom(_aZoom);
+}
+
+sal_uInt16 ODesignView::getZoomFactor(SvxZoomType _eType) const
+{
+ return m_aScrollWindow->getZoomFactor(_eType);
+}
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/EndMarker.cxx b/reportdesign/source/ui/report/EndMarker.cxx
new file mode 100644
index 000000000..fdd28f4db
--- /dev/null
+++ b/reportdesign/source/ui/report/EndMarker.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <EndMarker.hxx>
+#include <ColorChanger.hxx>
+#include <SectionWindow.hxx>
+
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/lineinfo.hxx>
+#include <vcl/event.hxx>
+
+
+#define CORNER_SPACE 5
+
+namespace rptui
+{
+
+OEndMarker::OEndMarker(vcl::Window* _pParent ,const OUString& _sColorEntry)
+ : OColorListener(_pParent, _sColorEntry)
+{
+ ImplInitSettings();
+}
+
+OEndMarker::~OEndMarker()
+{
+}
+
+void OEndMarker::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
+{
+ Fraction aCornerSpace(tools::Long(CORNER_SPACE));
+ aCornerSpace *= rRenderContext.GetMapMode().GetScaleX();
+ const tools::Long nCornerSpace = tools::Long(aCornerSpace);
+
+ Size aSize = GetSizePixel();
+ aSize.AdjustWidth(nCornerSpace );
+ tools::Rectangle aWholeRect(Point(-nCornerSpace,0),aSize);
+ tools::PolyPolygon aPoly;
+ aPoly.Insert( tools::Polygon(aWholeRect,nCornerSpace,nCornerSpace));
+
+ Color aStartColor(m_nColor);
+ aStartColor.IncreaseLuminance(10);
+ sal_uInt16 nHue = 0;
+ sal_uInt16 nSat = 0;
+ sal_uInt16 nBri = 0;
+ aStartColor.RGBtoHSB(nHue, nSat, nBri);
+ nSat += 40;
+ Color aEndColor(Color::HSBtoRGB(nHue, nSat, nBri));
+ Gradient aGradient(GradientStyle::Linear, aStartColor, aEndColor);
+ aGradient.SetSteps(static_cast<sal_uInt16>(aSize.Height()));
+
+ rRenderContext.DrawGradient(PixelToLogic(aPoly), aGradient);
+ if (m_bMarked)
+ {
+ tools::Rectangle aRect(Point(-nCornerSpace, nCornerSpace),
+ Size(aSize.Width() - nCornerSpace,
+ aSize.Height() - nCornerSpace - nCornerSpace));
+ ColorChanger aColors(GetOutDev(), COL_WHITE, COL_WHITE);
+ rRenderContext.DrawPolyLine( tools::Polygon(PixelToLogic(aRect)), LineInfo(LineStyle::Solid, 2));
+ }
+}
+
+void OEndMarker::ImplInitSettings()
+{
+ EnableChildTransparentMode();
+ SetParentClipMode( ParentClipMode::NoClip );
+ SetPaintTransparent( true );
+
+ SetBackground( Wallpaper( svtools::ColorConfig().GetColorValue(::svtools::APPBACKGROUND).nColor) );
+ GetOutDev()->SetFillColor( Application::GetSettings().GetStyleSettings().GetShadowColor() );
+}
+
+void OEndMarker::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( !rMEvt.IsLeft() && !rMEvt.IsRight())
+ return;
+ static_cast<OSectionWindow*>(GetParent())->showProperties();
+}
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/FixedTextColor.cxx b/reportdesign/source/ui/report/FixedTextColor.cxx
new file mode 100644
index 000000000..b0dd3c496
--- /dev/null
+++ b/reportdesign/source/ui/report/FixedTextColor.cxx
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <FixedTextColor.hxx>
+#include <com/sun/star/report/XFixedText.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+
+#include <RptObject.hxx>
+#include <RptModel.hxx>
+#include <RptPage.hxx>
+#include <ReportSection.hxx>
+#include <ReportController.hxx>
+#include <strings.hxx>
+
+#include <tools/color.hxx>
+
+// DBG_UNHANDLED_EXCEPTION
+#include <tools/diagnose_ex.h>
+
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+
+namespace rptui
+{
+ using namespace ::com::sun::star;
+
+
+ FixedTextColor::FixedTextColor(const OReportController& _aController)
+ :m_rReportController(_aController)
+ {
+ }
+
+
+ FixedTextColor::~FixedTextColor()
+ {
+ }
+
+
+ void FixedTextColor::notifyPropertyChange( const beans::PropertyChangeEvent& _rEvent )
+ {
+ uno::Reference< report::XFixedText > xFixedText( _rEvent.Source, uno::UNO_QUERY );
+ if ( ! xFixedText.is() )
+ {
+ return;
+ }
+
+ try
+ {
+ uno::Reference< lang::XComponent > xComponent( xFixedText, uno::UNO_QUERY_THROW );
+ handle(xComponent);
+ }
+ catch (uno::Exception const&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ }
+
+
+ void FixedTextColor::setPropertyTextColor(const uno::Reference< awt::XVclWindowPeer >& _xVclWindowPeer, Color _nTextColor)
+ {
+ _xVclWindowPeer->setProperty(PROPERTY_TEXTCOLOR, uno::Any(_nTextColor));
+ }
+
+
+ void FixedTextColor::notifyElementInserted( const uno::Reference< uno::XInterface >& _rxElement )
+ {
+ handle(_rxElement);
+ }
+
+
+ void FixedTextColor::handle( const uno::Reference< uno::XInterface >& _rxElement )
+ {
+ uno::Reference< report::XFixedText > xFixedText( _rxElement, uno::UNO_QUERY );
+ if ( ! xFixedText.is() )
+ {
+ return;
+ }
+
+ try
+ {
+ bool bIsDark = false;
+ const Color nBackColor( ColorTransparency, xFixedText->getControlBackground() );
+ if (nBackColor == COL_TRANSPARENT)
+ {
+ uno::Reference <report::XSection> xSection(xFixedText->getParent(), uno::UNO_QUERY_THROW);
+
+ bool bSectionBackColorIsTransparent = xSection->getBackTransparent();
+ if (bSectionBackColorIsTransparent)
+ {
+ // Label Transparent, Section Transparent set LabelTextColor
+ const StyleSettings& aStyleSettings = Application::GetSettings().GetStyleSettings();
+ Color aWindowColor = aStyleSettings.GetWindowColor();
+ bIsDark = aWindowColor.IsDark();
+ }
+ else
+ {
+ css::util::Color aColor2 = xSection->getBackColor();
+ Color aBackColor(ColorTransparency, aColor2);
+ bIsDark = aBackColor.IsDark();
+ }
+ }
+ else
+ {
+ Color aLabelBackColor(nBackColor);
+ bIsDark = aLabelBackColor.IsDark();
+ }
+
+ uno::Reference<awt::XVclWindowPeer> xVclWindowPeer = getVclWindowPeer(xFixedText);
+ if (bIsDark)
+ {
+ const StyleSettings& aStyleSettings = Application::GetSettings().GetStyleSettings();
+ Color aLabelTextColor = aStyleSettings.GetLabelTextColor();
+ setPropertyTextColor(xVclWindowPeer, aLabelTextColor);
+ }
+ else
+ {
+ util::Color aLabelColor = xFixedText->getCharColor();
+ setPropertyTextColor(xVclWindowPeer, ::Color(ColorTransparency, aLabelColor));
+ }
+
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ }
+
+
+ // XPropertyChangeListener
+ uno::Reference<awt::XControl> FixedTextColor::getXControl(const uno::Reference< report::XFixedText >& _xFixedText)
+ {
+
+ uno::Reference<awt::XControl> xControl;
+ OReportController *pController = const_cast<OReportController *>(&m_rReportController);
+
+ std::shared_ptr<OReportModel> pModel = pController->getSdrModel();
+
+ uno::Reference<report::XSection> xSection(_xFixedText->getSection());
+ if ( xSection.is() )
+ {
+ OReportPage *pPage = pModel->getPage(xSection);
+ const size_t nIndex = pPage->getIndexOf(_xFixedText);
+ if (nIndex < pPage->GetObjCount() )
+ {
+ SdrObject *pObject = pPage->GetObj(nIndex);
+ OUnoObject* pUnoObj = dynamic_cast<OUnoObject*>(pObject);
+ if ( pUnoObj ) // this doesn't need to be done for shapes
+ {
+ OSectionWindow* pSectionWindow = pController->getSectionWindow(xSection);
+ if (pSectionWindow != nullptr)
+ {
+ OReportSection& aOutputDevice = pSectionWindow->getReportSection(); // OutputDevice
+ OSectionView& aSdrView = aOutputDevice.getSectionView(); // SdrView
+ xControl = pUnoObj->GetUnoControl(aSdrView, *aOutputDevice.GetOutDev());
+ }
+ }
+ }
+ }
+ return xControl;
+ }
+
+
+ uno::Reference<awt::XVclWindowPeer> FixedTextColor::getVclWindowPeer(const uno::Reference< report::XFixedText >& _xComponent)
+ {
+ uno::Reference<awt::XVclWindowPeer> xVclWindowPeer;
+ uno::Reference<awt::XControl> xControl = getXControl(_xComponent);
+
+ xVclWindowPeer.set( xControl->getPeer(), uno::UNO_QUERY);
+
+ return xVclWindowPeer;
+ }
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx b/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx
new file mode 100644
index 000000000..d4fec971e
--- /dev/null
+++ b/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <FormattedFieldBeautifier.hxx>
+
+#include <com/sun/star/report/XFormattedField.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+
+#include <RptObject.hxx>
+#include <RptModel.hxx>
+#include <RptPage.hxx>
+#include <ReportSection.hxx>
+#include <ReportController.hxx>
+#include <strings.hxx>
+#include <reportformula.hxx>
+
+#include <svtools/extcolorcfg.hxx>
+
+// DBG_UNHANDLED_EXCEPTION
+#include <tools/diagnose_ex.h>
+
+namespace rptui
+{
+ using namespace ::com::sun::star;
+
+
+ FormattedFieldBeautifier::FormattedFieldBeautifier(const OReportController& _aController)
+ :m_rReportController(_aController)
+ ,m_nTextColor(COL_AUTO)
+ {
+ }
+
+
+ Color FormattedFieldBeautifier::getTextColor()
+ {
+ if (m_nTextColor == COL_AUTO)
+ {
+ svtools::ExtendedColorConfig aConfig;
+ m_nTextColor = aConfig.GetColorValue(CFG_REPORTDESIGNER, DBTEXTBOXBOUNDCONTENT).getColor();
+ }
+ return m_nTextColor;
+ }
+
+
+ FormattedFieldBeautifier::~FormattedFieldBeautifier()
+ {
+ }
+
+
+ void FormattedFieldBeautifier::setPlaceholderText( const uno::Reference< uno::XInterface >& _rxComponent )
+ {
+ try
+ {
+ uno::Reference< report::XFormattedField > xControlModel( _rxComponent, uno::UNO_QUERY );
+ if ( xControlModel.is() )
+ {
+ OUString sDataField = xControlModel->getDataField();
+
+ if ( !sDataField.isEmpty() )
+ {
+ ReportFormula aFormula( sDataField );
+ bool bSet = true;
+ if ( aFormula.getType() == ReportFormula::Field )
+ {
+ const OUString& sColumnName = aFormula.getFieldName();
+ OUString sLabel = m_rReportController.getColumnLabel_throw(sColumnName);
+ if ( !sLabel.isEmpty() )
+ {
+ sDataField = "=" + sLabel;
+ bSet = false;
+ }
+ }
+ if ( bSet )
+ sDataField = aFormula.getEqualUndecoratedContent();
+ }
+
+ setPlaceholderText( getVclWindowPeer( xControlModel ), sDataField );
+ }
+ }
+ catch (const uno::Exception &)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ }
+
+
+ void FormattedFieldBeautifier::setPlaceholderText( const uno::Reference< awt::XVclWindowPeer >& _xVclWindowPeer, const OUString& _rText )
+ {
+ OSL_ENSURE( _xVclWindowPeer.is(), "FormattedFieldBeautifier::setPlaceholderText: invalid peer!" );
+ if ( !_xVclWindowPeer.is() )
+ throw uno::RuntimeException();
+
+ // the actual text
+ _xVclWindowPeer->setProperty(PROPERTY_TEXT, uno::Any(_rText));
+ // the text color
+ _xVclWindowPeer->setProperty(PROPERTY_TEXTCOLOR, uno::Any(getTextColor()));
+ // font->italic
+ uno::Any aFontDescriptor = _xVclWindowPeer->getProperty(PROPERTY_FONTDESCRIPTOR);
+ awt::FontDescriptor aFontDescriptorStructure;
+ aFontDescriptor >>= aFontDescriptorStructure;
+ aFontDescriptorStructure.Slant = css::awt::FontSlant_ITALIC;
+ _xVclWindowPeer->setProperty(PROPERTY_FONTDESCRIPTOR, uno::Any(aFontDescriptorStructure));
+ }
+
+
+ void FormattedFieldBeautifier::notifyPropertyChange( const beans::PropertyChangeEvent& _rEvent )
+ {
+ if ( _rEvent.PropertyName != "DataField" )
+ // not interested in
+ return;
+
+ setPlaceholderText( _rEvent.Source );
+ }
+
+
+ void FormattedFieldBeautifier::handle( const uno::Reference< uno::XInterface >& _rxElement )
+ {
+ setPlaceholderText( _rxElement );
+ }
+
+
+ void FormattedFieldBeautifier::notifyElementInserted( const uno::Reference< uno::XInterface >& _rxElement )
+ {
+ handle( _rxElement );
+ }
+
+
+ uno::Reference<awt::XVclWindowPeer> FormattedFieldBeautifier::getVclWindowPeer(const uno::Reference< report::XReportComponent >& _xComponent)
+ {
+ uno::Reference<awt::XVclWindowPeer> xVclWindowPeer;
+
+ std::shared_ptr<OReportModel> pModel = m_rReportController.getSdrModel();
+
+ uno::Reference<report::XSection> xSection(_xComponent->getSection());
+ if ( xSection.is() )
+ {
+ OReportPage *pPage = pModel->getPage(xSection);
+ const size_t nIndex = pPage->getIndexOf(_xComponent);
+ if (nIndex < pPage->GetObjCount() )
+ {
+ SdrObject *pObject = pPage->GetObj(nIndex);
+ OUnoObject* pUnoObj = dynamic_cast<OUnoObject*>(pObject);
+ if ( pUnoObj ) // this doesn't need to be done for shapes
+ {
+ OSectionWindow* pSectionWindow = m_rReportController.getSectionWindow(xSection);
+ if (pSectionWindow != nullptr)
+ {
+ OReportSection& aOutputDevice = pSectionWindow->getReportSection(); // OutputDevice
+ OSectionView& aSdrView = aOutputDevice.getSectionView(); // SdrView
+ uno::Reference<awt::XControl> xControl = pUnoObj->GetUnoControl(aSdrView, *aOutputDevice.GetOutDev());
+ xVclWindowPeer.set( xControl->getPeer(), uno::UNO_QUERY);
+ }
+ }
+ }
+ }
+ return xVclWindowPeer;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/ReportController.cxx b/reportdesign/source/ui/report/ReportController.cxx
new file mode 100644
index 000000000..82edfba92
--- /dev/null
+++ b/reportdesign/source/ui/report/ReportController.cxx
@@ -0,0 +1,4365 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <ReportController.hxx>
+#include <ReportDefinition.hxx>
+#include <CondFormat.hxx>
+#include <UITools.hxx>
+#include <AddField.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <DateTime.hxx>
+
+#include <sfx2/filedlghelper.hxx>
+#include <tools/diagnose_ex.h>
+#include <rptui_slotid.hrc>
+#include <reportformula.hxx>
+
+#include <comphelper/documentconstants.hxx>
+#include <unotools/mediadescriptor.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/types.hxx>
+
+#include <connectivity/dbtools.hxx>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+#include <com/sun/star/util/NumberFormatter.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/report/XImageControl.hpp>
+#include <com/sun/star/report/XFixedLine.hpp>
+#include <com/sun/star/report/Function.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/sdb/XParametersSupplier.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/embed/EmbedMapUnits.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/status/FontHeight.hpp>
+#include <com/sun/star/report/ReportEngine.hpp>
+#include <com/sun/star/report/XFormattedField.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/document/XUndoManagerSupplier.hpp>
+
+#include <vcl/svapp.hxx>
+
+#include <i18nutil/paper.hxx>
+#include <svx/fmview.hxx>
+#include <editeng/memberids.h>
+#include <svx/svxids.hrc>
+#include <svx/svdobj.hxx>
+#include <svx/unomid.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xsflclit.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/xflbmpit.hxx>
+#include <svx/xflbmsli.hxx>
+#include <svx/xflbmsxy.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xflboxy.hxx>
+#include <svx/xflbstit.hxx>
+#include <svx/xflbtoxy.hxx>
+#include <svx/xfltrit.hxx>
+#include <svx/xgrscit.hxx>
+#include <editeng/svxenum.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <sfx2/zoomitem.hxx>
+#include <svx/zoomslideritem.hxx>
+#include <editeng/brushitem.hxx>
+#include <svx/flagsdef.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svxdlg.hxx>
+
+#include <core_resource.hxx>
+#include <DesignView.hxx>
+#include <RptObject.hxx>
+#include <RptUndo.hxx>
+#include <strings.hxx>
+#include <RptDef.hxx>
+#include <ReportSection.hxx>
+#include <SectionView.hxx>
+#include <UndoActions.hxx>
+#include <dlgpage.hxx>
+#include <strings.hrc>
+
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svtools/cliplistener.hxx>
+#include <unotools/syslocale.hxx>
+#include <unotools/viewoptions.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include <osl/mutex.hxx>
+#include <PropertyForward.hxx>
+#include <SectionWindow.hxx>
+
+#include <toolkit/helper/convert.hxx>
+#include <GroupsSorting.hxx>
+#include <PageNumber.hxx>
+#include <UndoEnv.hxx>
+
+#include <memory>
+#include <string_view>
+
+#include <cppuhelper/exc_hlp.hxx>
+#include <unotools/confignode.hxx>
+
+#include <ReportControllerObserver.hxx>
+
+#define MAX_ROWS_FOR_PREVIEW 20
+
+#define RPTUI_ID_LRSPACE TypedWhichId<SvxLRSpaceItem>(XATTR_FILL_FIRST - 8)
+#define RPTUI_ID_ULSPACE TypedWhichId<SvxULSpaceItem>(XATTR_FILL_FIRST - 7)
+#define RPTUI_ID_PAGE TypedWhichId<SvxPageItem>(XATTR_FILL_FIRST - 6)
+#define RPTUI_ID_SIZE TypedWhichId<SvxSizeItem>(XATTR_FILL_FIRST - 5)
+#define RPTUI_ID_PAGE_MODE XATTR_FILL_FIRST - 4
+#define RPTUI_ID_START XATTR_FILL_FIRST - 3
+#define RPTUI_ID_END XATTR_FILL_FIRST - 2
+#define RPTUI_ID_BRUSH TypedWhichId<SvxBrushItem>(XATTR_FILL_FIRST - 1)
+/// Note that we deliberately overlap an existing item id, so that we can have contiguous item ids for
+/// the static defaults.
+#define RPTUI_ID_METRIC XATTR_FILL_LAST
+
+using namespace ::com::sun::star;
+using namespace uno;
+using namespace io;
+using namespace beans;
+using namespace frame;
+using namespace util;
+using namespace lang;
+using namespace container;
+using namespace sdbcx;
+using namespace sdbc;
+using namespace sdb;
+using namespace ui;
+using namespace ui::dialogs;
+using namespace ::dbtools;
+using namespace ::rptui;
+using namespace ::dbaui;
+using namespace ::comphelper;
+using namespace ::cppu;
+
+
+namespace
+{
+ void lcl_setFontWPU_nothrow(const uno::Reference< report::XReportControlFormat>& _xReportControlFormat,const sal_Int32 _nId)
+ {
+ if ( !_xReportControlFormat.is() )
+ return;
+
+ try
+ {
+ awt::FontDescriptor aFontDescriptor = _xReportControlFormat->getFontDescriptor();
+ switch(_nId)
+ {
+ case SID_ATTR_CHAR_WEIGHT:
+ aFontDescriptor.Weight = (awt::FontWeight::NORMAL + awt::FontWeight::BOLD) - aFontDescriptor.Weight;
+ break;
+ case SID_ATTR_CHAR_POSTURE:
+ aFontDescriptor.Slant = static_cast<awt::FontSlant>(static_cast<sal_Int16>(awt::FontSlant_ITALIC) - static_cast<sal_Int16>(aFontDescriptor.Slant));
+ break;
+ case SID_ATTR_CHAR_UNDERLINE:
+ aFontDescriptor.Underline = awt::FontUnderline::SINGLE - aFontDescriptor.Underline;
+ break;
+ default:
+ OSL_FAIL("Illegal value in default!");
+ break;
+ }
+
+ _xReportControlFormat->setFontDescriptor(aFontDescriptor);
+ }
+ catch(const beans::UnknownPropertyException&)
+ {
+ }
+ }
+}
+
+
+static void lcl_getReportControlFormat(const Sequence< PropertyValue >& aArgs,
+ ODesignView* _pView,
+ uno::Reference< awt::XWindow>& _xWindow,
+ ::std::vector< uno::Reference< uno::XInterface > >& _rControlsFormats)
+{
+ uno::Reference< report::XReportControlFormat> xReportControlFormat;
+ if ( aArgs.hasElements() )
+ {
+ SequenceAsHashMap aMap(aArgs);
+ xReportControlFormat = aMap.getUnpackedValueOrDefault(REPORTCONTROLFORMAT,uno::Reference< report::XReportControlFormat>());
+ _xWindow = aMap.getUnpackedValueOrDefault(CURRENT_WINDOW,uno::Reference< awt::XWindow>());
+ }
+
+ if ( !xReportControlFormat.is() )
+ {
+ _pView->fillControlModelSelection(_rControlsFormats);
+ }
+ else
+ {
+ uno::Reference<uno::XInterface> xInterface(xReportControlFormat);
+ _rControlsFormats.push_back(xInterface);
+ }
+
+ if ( !_xWindow.is() )
+ _xWindow = VCLUnoHelper::GetInterface(_pView);
+}
+
+OUString SAL_CALL OReportController::getImplementationName()
+{
+ return "com.sun.star.report.comp.ReportDesign";
+}
+
+Sequence< OUString> SAL_CALL OReportController::getSupportedServiceNames()
+{
+ return { "com.sun.star.sdb.ReportDesign" };
+}
+
+#define PROPERTY_ID_ZOOMVALUE 1
+
+
+OReportController::OReportController(Reference< XComponentContext > const & xContext)
+ :OReportController_BASE(xContext)
+ ,OPropertyStateContainer(OGenericUnoController_Base::rBHelper)
+ ,m_aSelectionListeners( getMutex() )
+ ,m_sMode("normal")
+ ,m_nSplitPos(-1)
+ ,m_nPageNum(-1)
+ ,m_nSelectionCount(0)
+ ,m_nAspect(0)
+ ,m_nZoomValue(100)
+ ,m_eZoomType(SvxZoomType::PERCENT)
+ ,m_bShowRuler(true)
+ ,m_bGridVisible(true)
+ ,m_bGridUse(true)
+ ,m_bShowProperties(true)
+ ,m_bHelplinesMove(true)
+ ,m_bChartEnabled(false)
+ ,m_bChartEnabledAsked(false)
+ ,m_bInGeneratePreview(false)
+{
+ // new Observer
+ m_pReportControllerObserver = new OXReportControllerObserver(*this);
+ registerProperty("ZoomValue", PROPERTY_ID_ZOOMVALUE,
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::TRANSIENT,
+ &m_nZoomValue, ::cppu::UnoType<sal_Int16>::get());
+
+}
+
+OReportController::~OReportController()
+{
+}
+
+IMPLEMENT_FORWARD_XTYPEPROVIDER2(OReportController,OReportController_BASE,OReportController_Listener)
+IMPLEMENT_FORWARD_XINTERFACE2(OReportController,OReportController_BASE,OReportController_Listener)
+
+void OReportController::disposing()
+{
+
+ if ( m_pClipboardNotifier.is() )
+ {
+ m_pClipboardNotifier->ClearCallbackLink();
+ m_pClipboardNotifier->RemoveListener( getView() );
+ m_pClipboardNotifier.clear();
+ }
+ if ( m_xGroupsFloater )
+ {
+ SvtViewOptions aDlgOpt(EViewType::Window, OStringToOUString(m_xGroupsFloater->get_help_id(), RTL_TEXTENCODING_UTF8));
+ aDlgOpt.SetWindowState(OStringToOUString(m_xGroupsFloater->getDialog()->get_window_state(WindowStateMask::All), RTL_TEXTENCODING_ASCII_US));
+ if (m_xGroupsFloater->getDialog()->get_visible())
+ m_xGroupsFloater->response(RET_CANCEL);
+ m_xGroupsFloater.reset();
+ }
+
+ try
+ {
+ m_xHoldAlive.clear();
+ m_xColumns.clear();
+ ::comphelper::disposeComponent( m_xRowSet );
+ ::comphelper::disposeComponent( m_xRowSetMediator );
+ ::comphelper::disposeComponent( m_xFormatter );
+ }
+ catch(const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while disposing row sets.");
+ }
+ m_xRowSet.clear();
+ m_xRowSetMediator.clear();
+
+ if ( m_xReportDefinition.is() )
+ {
+ try
+ {
+ OSectionWindow* pSectionWindow = nullptr;
+ if ( getDesignView() )
+ pSectionWindow = getDesignView()->getMarkedSection();
+ if ( pSectionWindow )
+ pSectionWindow->getReportSection().deactivateOle();
+ clearUndoManager();
+ if ( m_aReportModel )
+ listen(false);
+ m_pReportControllerObserver->Clear();
+ m_pReportControllerObserver.clear();
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ }
+
+ {
+ EventObject aDisposingEvent( *this );
+ m_aSelectionListeners.disposeAndClear( aDisposingEvent );
+ }
+
+ OReportController_BASE::disposing();
+
+
+ try
+ {
+ m_xReportDefinition.clear();
+ m_aReportModel.reset();
+ m_xFrameLoader.clear();
+ m_xReportEngine.clear();
+ }
+ catch(const uno::Exception&)
+ {
+ }
+ if ( getDesignView() )
+ EndListening( *getDesignView() );
+ clearView();
+}
+
+FeatureState OReportController::GetState(sal_uInt16 _nId) const
+{
+ FeatureState aReturn;
+ // (disabled automatically)
+ aReturn.bEnabled = false;
+ // check this first
+ if ( !getView() )
+ return aReturn;
+
+ switch (_nId)
+ {
+ case SID_RPT_TEXTDOCUMENT:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = (m_xReportDefinition.is() && m_xReportDefinition->getMimeType() == MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII);
+ break;
+ case SID_RPT_SPREADSHEET:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = (m_xReportDefinition.is() && m_xReportDefinition->getMimeType() == MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII);
+ break;
+ case SID_REPORTHEADER_WITHOUT_UNDO:
+ case SID_REPORTFOOTER_WITHOUT_UNDO:
+ case SID_REPORTHEADERFOOTER:
+ {
+ aReturn.bEnabled = isEditable();
+ OUString sText = RptResId((m_xReportDefinition.is() && m_xReportDefinition->getReportHeaderOn()) ? RID_STR_REPORTHEADERFOOTER_DELETE : RID_STR_REPORTHEADERFOOTER_INSERT);
+ aReturn.sTitle = sText;
+ }
+ break;
+ case SID_PAGEHEADER_WITHOUT_UNDO:
+ case SID_PAGEFOOTER_WITHOUT_UNDO:
+ case SID_PAGEHEADERFOOTER:
+ {
+ aReturn.bEnabled = isEditable();
+ OUString sText = RptResId((m_xReportDefinition.is() && m_xReportDefinition->getPageHeaderOn()) ? RID_STR_PAGEHEADERFOOTER_DELETE : RID_STR_PAGEHEADERFOOTER_INSERT);
+ aReturn.sTitle = sText;
+ }
+ break;
+ case SID_GROUP_APPEND:
+ case SID_GROUP_REMOVE:
+ case SID_GROUPHEADER_WITHOUT_UNDO:
+ case SID_GROUPHEADER:
+ case SID_GROUPFOOTER_WITHOUT_UNDO:
+ case SID_GROUPFOOTER:
+ aReturn.bEnabled = isEditable();
+ break;
+ case SID_ADD_CONTROL_PAIR:
+ aReturn.bEnabled = isEditable();
+ break;
+ case SID_REDO:
+ case SID_UNDO:
+ {
+ size_t ( SfxUndoManager::*retrieveCount )( bool const ) const =
+ ( _nId == SID_UNDO ) ? &SfxUndoManager::GetUndoActionCount : &SfxUndoManager::GetRedoActionCount;
+
+ SfxUndoManager& rUndoManager( getUndoManager() );
+ aReturn.bEnabled = ( rUndoManager.*retrieveCount )( SfxUndoManager::TopLevel ) > 0;
+ if ( aReturn.bEnabled )
+ {
+ // TODO: add "Undo/Redo: prefix"
+ OUString ( SfxUndoManager::*retrieveComment )( size_t, bool const ) const =
+ ( _nId == SID_UNDO ) ? &SfxUndoManager::GetUndoActionComment : &SfxUndoManager::GetRedoActionComment;
+ aReturn.sTitle = (rUndoManager.*retrieveComment)( 0, SfxUndoManager::TopLevel );
+ }
+ }
+ break;
+ case SID_GETUNDOSTRINGS:
+ case SID_GETREDOSTRINGS:
+ {
+ size_t ( SfxUndoManager::*retrieveCount )( bool const ) const =
+ ( _nId == SID_GETUNDOSTRINGS ) ? &SfxUndoManager::GetUndoActionCount : &SfxUndoManager::GetRedoActionCount;
+
+ OUString ( SfxUndoManager::*retrieveComment )( size_t, bool const ) const =
+ ( _nId == SID_GETUNDOSTRINGS ) ? &SfxUndoManager::GetUndoActionComment : &SfxUndoManager::GetRedoActionComment;
+
+ SfxUndoManager& rUndoManager( getUndoManager() );
+ size_t nCount(( rUndoManager.*retrieveCount )( SfxUndoManager::TopLevel ));
+ Sequence<OUString> aSeq(nCount);
+ auto aSeqRange = asNonConstRange(aSeq);
+ for (size_t n = 0; n < nCount; ++n)
+ aSeqRange[n] = (rUndoManager.*retrieveComment)( n, SfxUndoManager::TopLevel );
+ aReturn.aValue <<= aSeq;
+ aReturn.bEnabled = true;
+ }
+ break;
+ case SID_OBJECT_RESIZING:
+ case SID_OBJECT_SMALLESTWIDTH:
+ case SID_OBJECT_SMALLESTHEIGHT:
+ case SID_OBJECT_GREATESTWIDTH:
+ case SID_OBJECT_GREATESTHEIGHT:
+ aReturn.bEnabled = isEditable() && getDesignView()->HasSelection();
+ if ( aReturn.bEnabled )
+ aReturn.bEnabled = m_nSelectionCount > 1;
+ break;
+
+ case SID_DISTRIBUTE_HLEFT:
+ case SID_DISTRIBUTE_HCENTER:
+ case SID_DISTRIBUTE_HDISTANCE:
+ case SID_DISTRIBUTE_HRIGHT:
+ case SID_DISTRIBUTE_VTOP:
+ case SID_DISTRIBUTE_VCENTER:
+ case SID_DISTRIBUTE_VDISTANCE:
+ case SID_DISTRIBUTE_VBOTTOM:
+ aReturn.bEnabled = isEditable() && getDesignView()->HasSelection();
+ if ( aReturn.bEnabled )
+ {
+ OSectionView* pSectionView = getCurrentSectionView();
+ aReturn.bEnabled = pSectionView && pSectionView->GetMarkedObjectCount() > 2;
+ }
+ break;
+ case SID_ARRANGEMENU:
+ case SID_FRAME_DOWN:
+ case SID_FRAME_UP:
+ case SID_FRAME_TO_TOP:
+ case SID_FRAME_TO_BOTTOM:
+ case SID_OBJECT_HEAVEN:
+ case SID_OBJECT_HELL:
+ aReturn.bEnabled = isEditable() && getDesignView()->HasSelection();
+ if ( aReturn.bEnabled )
+ {
+ OSectionView* pSectionView = getCurrentSectionView();
+ aReturn.bEnabled = pSectionView && pSectionView->OnlyShapesMarked();
+ if ( aReturn.bEnabled )
+ {
+ if ( SID_OBJECT_HEAVEN == _nId )
+ aReturn.bEnabled = pSectionView->GetLayerIdOfMarkedObjects() != RPT_LAYER_FRONT;
+ else if ( SID_OBJECT_HELL == _nId )
+ aReturn.bEnabled = pSectionView->GetLayerIdOfMarkedObjects() != RPT_LAYER_BACK;
+ }
+ }
+ break;
+
+ case SID_SECTION_SHRINK:
+ case SID_SECTION_SHRINK_TOP:
+ case SID_SECTION_SHRINK_BOTTOM:
+ {
+ sal_Int32 nCount = 0;
+ uno::Reference<report::XSection> xSection = getDesignView()->getCurrentSection();
+ if ( xSection.is() )
+ {
+ nCount = xSection->getCount();
+ }
+ aReturn.bEnabled = isEditable() && nCount > 0;
+ }
+ break;
+ case SID_OBJECT_ALIGN:
+ case SID_OBJECT_ALIGN_LEFT:
+ case SID_OBJECT_ALIGN_CENTER:
+ case SID_OBJECT_ALIGN_RIGHT:
+ case SID_OBJECT_ALIGN_UP:
+ case SID_OBJECT_ALIGN_MIDDLE:
+ case SID_OBJECT_ALIGN_DOWN:
+ case SID_SECTION_ALIGN:
+ case SID_SECTION_ALIGN_LEFT:
+ case SID_SECTION_ALIGN_CENTER:
+ case SID_SECTION_ALIGN_RIGHT:
+ case SID_SECTION_ALIGN_UP:
+ case SID_SECTION_ALIGN_MIDDLE:
+ case SID_SECTION_ALIGN_DOWN:
+ aReturn.bEnabled = isEditable() && getDesignView()->HasSelection();
+ break;
+ case SID_CUT:
+ aReturn.bEnabled = isEditable() && getDesignView()->HasSelection() && !getDesignView()->isHandleEvent();
+ break;
+ case SID_COPY:
+ aReturn.bEnabled = getDesignView()->HasSelection() && !getDesignView()->isHandleEvent();
+ break;
+ case SID_PASTE:
+ aReturn.bEnabled = isEditable() && !getDesignView()->isHandleEvent() && getDesignView()->IsPasteAllowed();
+ break;
+ case SID_SELECTALL:
+ aReturn.bEnabled = !getDesignView()->isHandleEvent();
+ break;
+ case SID_SELECTALL_IN_SECTION:
+ aReturn.bEnabled = !getDesignView()->isHandleEvent();
+ if ( aReturn.bEnabled )
+ aReturn.bEnabled = getCurrentSectionView() != nullptr;
+ break;
+ case SID_ESCAPE:
+ aReturn.bEnabled = getDesignView()->GetMode() == DlgEdMode::Insert;
+ break;
+ case SID_TERMINATE_INPLACEACTIVATION:
+ aReturn.bEnabled = true;
+ break;
+ case SID_SELECT_ALL_EDITS:
+ case SID_SELECT_ALL_LABELS:
+ aReturn.bEnabled = true;
+ break;
+ case SID_RPT_NEW_FUNCTION:
+ aReturn.bEnabled = isEditable();
+ break;
+ case SID_COLLAPSE_SECTION:
+ case SID_EXPAND_SECTION:
+ case SID_NEXT_MARK:
+ case SID_PREV_MARK:
+ aReturn.bEnabled = isEditable() && !getDesignView()->isHandleEvent();
+ break;
+ case SID_SELECT:
+ case SID_SELECT_REPORT:
+ aReturn.bEnabled = true;
+ break;
+ case SID_EXECUTE_REPORT:
+ aReturn.bEnabled = isConnected() && m_xReportDefinition.is();
+ break;
+ case SID_DELETE:
+ aReturn.bEnabled = isEditable() && getDesignView()->HasSelection() && !getDesignView()->isHandleEvent();
+ if ( aReturn.bEnabled )
+ {
+ OSectionWindow* pSectionWindow = getDesignView()->getMarkedSection();
+ if ( pSectionWindow )
+ aReturn.bEnabled = !pSectionWindow->getReportSection().isUiActive();
+ }
+ {
+ OUString sText = RptResId(RID_STR_DELETE);
+ aReturn.sTitle = sText;
+ }
+ break;
+ case SID_GRID_VISIBLE:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = m_bGridVisible;
+ break;
+ case SID_GRID_USE:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = m_bGridUse;
+ break;
+ case SID_HELPLINES_MOVE:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = m_bHelplinesMove;
+ break;
+ case SID_RULER:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = m_bShowRuler;
+ break;
+ case SID_OBJECT_SELECT:
+ aReturn.bEnabled = true;
+ aReturn.bChecked = getDesignView()->GetMode() == DlgEdMode::Select;
+ break;
+ case SID_INSERT_DIAGRAM:
+ aReturn.bEnabled = isEditable();
+ aReturn.bInvisible = !m_bChartEnabled;
+ aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::OLE2;
+ break;
+ case SID_FM_FIXEDTEXT:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignFixedText;
+ break;
+ case SID_INSERT_HFIXEDLINE:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignHorizontalFixedLine;
+ break;
+ case SID_INSERT_VFIXEDLINE:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignVerticalFixedLine;
+ break;
+ case SID_FM_EDIT:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignFormattedField;
+ break;
+ case SID_FM_IMAGECONTROL:
+ aReturn.bEnabled = isEditable();
+ aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignImageControl;
+ break;
+ case SID_DRAWTBX_CS_BASIC:
+ case SID_DRAWTBX_CS_BASIC1:
+ case SID_DRAWTBX_CS_BASIC2:
+ case SID_DRAWTBX_CS_BASIC3:
+ case SID_DRAWTBX_CS_BASIC4:
+ case SID_DRAWTBX_CS_BASIC5:
+ case SID_DRAWTBX_CS_BASIC6:
+ case SID_DRAWTBX_CS_BASIC7:
+ case SID_DRAWTBX_CS_BASIC8:
+ case SID_DRAWTBX_CS_BASIC9:
+ case SID_DRAWTBX_CS_BASIC10:
+ case SID_DRAWTBX_CS_BASIC11:
+ case SID_DRAWTBX_CS_BASIC12:
+ case SID_DRAWTBX_CS_BASIC13:
+ case SID_DRAWTBX_CS_BASIC14:
+ case SID_DRAWTBX_CS_BASIC15:
+ case SID_DRAWTBX_CS_BASIC16:
+ case SID_DRAWTBX_CS_BASIC17:
+ case SID_DRAWTBX_CS_BASIC18:
+ case SID_DRAWTBX_CS_BASIC19:
+ case SID_DRAWTBX_CS_BASIC20:
+ case SID_DRAWTBX_CS_BASIC21:
+ case SID_DRAWTBX_CS_BASIC22:
+ impl_fillCustomShapeState_nothrow("diamond",aReturn);
+ break;
+ case SID_DRAWTBX_CS_SYMBOL:
+ case SID_DRAWTBX_CS_SYMBOL1:
+ case SID_DRAWTBX_CS_SYMBOL2:
+ case SID_DRAWTBX_CS_SYMBOL3:
+ case SID_DRAWTBX_CS_SYMBOL4:
+ case SID_DRAWTBX_CS_SYMBOL5:
+ case SID_DRAWTBX_CS_SYMBOL6:
+ case SID_DRAWTBX_CS_SYMBOL7:
+ case SID_DRAWTBX_CS_SYMBOL8:
+ case SID_DRAWTBX_CS_SYMBOL9:
+ case SID_DRAWTBX_CS_SYMBOL10:
+ case SID_DRAWTBX_CS_SYMBOL11:
+ case SID_DRAWTBX_CS_SYMBOL12:
+ case SID_DRAWTBX_CS_SYMBOL13:
+ case SID_DRAWTBX_CS_SYMBOL14:
+ case SID_DRAWTBX_CS_SYMBOL15:
+ case SID_DRAWTBX_CS_SYMBOL16:
+ case SID_DRAWTBX_CS_SYMBOL17:
+ case SID_DRAWTBX_CS_SYMBOL18:
+ impl_fillCustomShapeState_nothrow("smiley",aReturn);
+ break;
+ case SID_DRAWTBX_CS_ARROW:
+ case SID_DRAWTBX_CS_ARROW1:
+ case SID_DRAWTBX_CS_ARROW2:
+ case SID_DRAWTBX_CS_ARROW3:
+ case SID_DRAWTBX_CS_ARROW4:
+ case SID_DRAWTBX_CS_ARROW5:
+ case SID_DRAWTBX_CS_ARROW6:
+ case SID_DRAWTBX_CS_ARROW7:
+ case SID_DRAWTBX_CS_ARROW8:
+ case SID_DRAWTBX_CS_ARROW9:
+ case SID_DRAWTBX_CS_ARROW10:
+ case SID_DRAWTBX_CS_ARROW11:
+ case SID_DRAWTBX_CS_ARROW12:
+ case SID_DRAWTBX_CS_ARROW13:
+ case SID_DRAWTBX_CS_ARROW14:
+ case SID_DRAWTBX_CS_ARROW15:
+ case SID_DRAWTBX_CS_ARROW16:
+ case SID_DRAWTBX_CS_ARROW17:
+ case SID_DRAWTBX_CS_ARROW18:
+ case SID_DRAWTBX_CS_ARROW19:
+ case SID_DRAWTBX_CS_ARROW20:
+ case SID_DRAWTBX_CS_ARROW21:
+ case SID_DRAWTBX_CS_ARROW22:
+ case SID_DRAWTBX_CS_ARROW23:
+ case SID_DRAWTBX_CS_ARROW24:
+ case SID_DRAWTBX_CS_ARROW25:
+ case SID_DRAWTBX_CS_ARROW26:
+ impl_fillCustomShapeState_nothrow("left-right-arrow",aReturn);
+ break;
+ case SID_DRAWTBX_CS_STAR:
+ case SID_DRAWTBX_CS_STAR1:
+ case SID_DRAWTBX_CS_STAR2:
+ case SID_DRAWTBX_CS_STAR3:
+ case SID_DRAWTBX_CS_STAR4:
+ case SID_DRAWTBX_CS_STAR5:
+ case SID_DRAWTBX_CS_STAR6:
+ case SID_DRAWTBX_CS_STAR7:
+ case SID_DRAWTBX_CS_STAR8:
+ case SID_DRAWTBX_CS_STAR9:
+ case SID_DRAWTBX_CS_STAR10:
+ case SID_DRAWTBX_CS_STAR11:
+ case SID_DRAWTBX_CS_STAR12:
+ impl_fillCustomShapeState_nothrow("star5",aReturn);
+ break;
+ case SID_DRAWTBX_CS_FLOWCHART:
+ case SID_DRAWTBX_CS_FLOWCHART1:
+ case SID_DRAWTBX_CS_FLOWCHART2:
+ case SID_DRAWTBX_CS_FLOWCHART3:
+ case SID_DRAWTBX_CS_FLOWCHART4:
+ case SID_DRAWTBX_CS_FLOWCHART5:
+ case SID_DRAWTBX_CS_FLOWCHART6:
+ case SID_DRAWTBX_CS_FLOWCHART7:
+ case SID_DRAWTBX_CS_FLOWCHART8:
+ case SID_DRAWTBX_CS_FLOWCHART9:
+ case SID_DRAWTBX_CS_FLOWCHART10:
+ case SID_DRAWTBX_CS_FLOWCHART11:
+ case SID_DRAWTBX_CS_FLOWCHART12:
+ case SID_DRAWTBX_CS_FLOWCHART13:
+ case SID_DRAWTBX_CS_FLOWCHART14:
+ case SID_DRAWTBX_CS_FLOWCHART15:
+ case SID_DRAWTBX_CS_FLOWCHART16:
+ case SID_DRAWTBX_CS_FLOWCHART17:
+ case SID_DRAWTBX_CS_FLOWCHART18:
+ case SID_DRAWTBX_CS_FLOWCHART19:
+ case SID_DRAWTBX_CS_FLOWCHART20:
+ case SID_DRAWTBX_CS_FLOWCHART21:
+ case SID_DRAWTBX_CS_FLOWCHART22:
+ case SID_DRAWTBX_CS_FLOWCHART23:
+ case SID_DRAWTBX_CS_FLOWCHART24:
+ case SID_DRAWTBX_CS_FLOWCHART25:
+ case SID_DRAWTBX_CS_FLOWCHART26:
+ case SID_DRAWTBX_CS_FLOWCHART27:
+ case SID_DRAWTBX_CS_FLOWCHART28:
+ impl_fillCustomShapeState_nothrow("flowchart-internal-storage",aReturn);
+ break;
+ case SID_DRAWTBX_CS_CALLOUT:
+ case SID_DRAWTBX_CS_CALLOUT1:
+ case SID_DRAWTBX_CS_CALLOUT2:
+ case SID_DRAWTBX_CS_CALLOUT3:
+ case SID_DRAWTBX_CS_CALLOUT4:
+ case SID_DRAWTBX_CS_CALLOUT5:
+ case SID_DRAWTBX_CS_CALLOUT6:
+ case SID_DRAWTBX_CS_CALLOUT7:
+ impl_fillCustomShapeState_nothrow("round-rectangular-callout",aReturn);
+ break;
+ case SID_RPT_SHOWREPORTEXPLORER:
+ aReturn.bEnabled = m_xReportDefinition.is();
+ aReturn.bChecked = getDesignView() && getDesignView()->isReportExplorerVisible();
+ break;
+ case SID_FM_ADD_FIELD:
+ aReturn.bEnabled = isConnected() && isEditable() && m_xReportDefinition.is()
+ && !m_xReportDefinition->getCommand().isEmpty();
+ aReturn.bChecked = getDesignView() && getDesignView()->isAddFieldVisible();
+ break;
+ case SID_SHOW_PROPERTYBROWSER:
+ aReturn.bEnabled = true;
+ aReturn.bChecked = m_bShowProperties;
+ break;
+ case SID_PROPERTYBROWSER_LAST_PAGE:
+ aReturn.bEnabled = true;
+ aReturn.aValue <<= m_sLastActivePage;
+ break;
+ case SID_SPLIT_POSITION:
+ aReturn.bEnabled = true;
+ aReturn.aValue <<= getSplitPos();
+ break;
+ case SID_SAVEDOC:
+ case SID_SAVEASDOC:
+ case SID_SAVEACOPY:
+ aReturn.bEnabled = isConnected() && isEditable();
+ break;
+ case SID_EDITDOC:
+ aReturn.bChecked = isEditable();
+ break;
+ case SID_PAGEDIALOG:
+ aReturn.bEnabled = isEditable();
+ break;
+ case SID_BACKGROUND_COLOR:
+ impl_fillState_nothrow(PROPERTY_CONTROLBACKGROUND,aReturn);
+ break;
+ case SID_ATTR_CHAR_COLOR_BACKGROUND:
+ aReturn.bEnabled = isEditable();
+ {
+ uno::Reference<report::XSection> xSection = getDesignView()->getCurrentSection();
+ if ( xSection.is() )
+ try
+ {
+ aReturn.aValue <<= xSection->getBackColor();
+ const uno::Reference< report::XReportControlModel> xControlModel(getDesignView()->getCurrentControlModel(),uno::UNO_QUERY);
+ aReturn.bEnabled = !xControlModel.is();
+ }
+ catch(const beans::UnknownPropertyException&)
+ {
+ }
+ else
+ aReturn.bEnabled = false;
+ }
+ break;
+ case SID_SORTINGANDGROUPING:
+ aReturn.bEnabled = true;
+ aReturn.bChecked = m_xGroupsFloater && m_xGroupsFloater->getDialog()->get_visible();
+ break;
+ case SID_ATTR_CHAR_WEIGHT:
+ case SID_ATTR_CHAR_POSTURE:
+ case SID_ATTR_CHAR_UNDERLINE:
+ impl_fillState_nothrow(PROPERTY_FONTDESCRIPTOR,aReturn);
+ if ( aReturn.bEnabled )
+ {
+ awt::FontDescriptor aFontDescriptor;
+ aReturn.aValue >>= aFontDescriptor;
+ aReturn.aValue.clear();
+
+ switch(_nId)
+ {
+ case SID_ATTR_CHAR_WEIGHT:
+ aReturn.bChecked = awt::FontWeight::BOLD == aFontDescriptor.Weight;
+ break;
+ case SID_ATTR_CHAR_POSTURE:
+ aReturn.bChecked = awt::FontSlant_ITALIC == aFontDescriptor.Slant;
+ break;
+ case SID_ATTR_CHAR_UNDERLINE:
+ aReturn.bChecked = awt::FontUnderline::SINGLE == aFontDescriptor.Underline;
+ break;
+ default:
+ ;
+ }
+ }
+ break;
+ case SID_ATTR_CHAR_COLOR:
+ case SID_ATTR_CHAR_COLOR2:
+ impl_fillState_nothrow(PROPERTY_CHARCOLOR,aReturn);
+ break;
+ case SID_ATTR_CHAR_FONT:
+ impl_fillState_nothrow(PROPERTY_FONTDESCRIPTOR,aReturn);
+ break;
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ impl_fillState_nothrow(PROPERTY_CHARHEIGHT,aReturn);
+ if ( aReturn.aValue.hasValue() )
+ {
+ frame::status::FontHeight aFontHeight;
+ aReturn.aValue >>= aFontHeight.Height;
+ aReturn.aValue <<= aFontHeight; // another type is needed here, so
+ }
+ break;
+ case SID_ATTR_PARA_ADJUST_LEFT:
+ case SID_ATTR_PARA_ADJUST_CENTER:
+ case SID_ATTR_PARA_ADJUST_RIGHT:
+ case SID_ATTR_PARA_ADJUST_BLOCK:
+ impl_fillState_nothrow(PROPERTY_PARAADJUST,aReturn);
+ if ( aReturn.bEnabled )
+ {
+ ::sal_Int16 nParaAdjust = 0;
+ if ( aReturn.aValue >>= nParaAdjust )
+ {
+ switch(static_cast<style::ParagraphAdjust>(nParaAdjust))
+ {
+ case style::ParagraphAdjust_LEFT:
+ aReturn.bChecked = _nId == SID_ATTR_PARA_ADJUST_LEFT;
+ break;
+ case style::ParagraphAdjust_RIGHT:
+ aReturn.bChecked = _nId == SID_ATTR_PARA_ADJUST_RIGHT;
+ break;
+ case style::ParagraphAdjust_BLOCK:
+ case style::ParagraphAdjust_STRETCH:
+ aReturn.bChecked = _nId == SID_ATTR_PARA_ADJUST_BLOCK;
+ break;
+ case style::ParagraphAdjust_CENTER:
+ aReturn.bChecked = _nId == SID_ATTR_PARA_ADJUST_CENTER;
+ break;
+ default: break;
+ }
+ }
+ aReturn.aValue.clear();
+ }
+ break;
+
+ case SID_INSERT_GRAPHIC:
+ aReturn.bEnabled = m_xReportDefinition.is() && isEditable() && getDesignView()->getCurrentSection().is();
+ break;
+ case SID_CHAR_DLG:
+ case SID_SETCONTROLDEFAULTS:
+ aReturn.bEnabled = m_xReportDefinition.is() && isEditable();
+ if ( aReturn.bEnabled )
+ {
+ ::std::vector< uno::Reference< uno::XInterface > > aSelection;
+ getDesignView()->fillControlModelSelection(aSelection);
+ aReturn.bEnabled = !aSelection.empty()
+ && std::all_of(aSelection.begin(), aSelection.end(), [](const uno::Reference<uno::XInterface>& rxInterface) {
+ return !uno::Reference<report::XFixedLine>(rxInterface, uno::UNO_QUERY).is()
+ && !uno::Reference<report::XImageControl>(rxInterface, uno::UNO_QUERY).is()
+ && uno::Reference<report::XReportControlFormat>(rxInterface, uno::UNO_QUERY).is(); });
+ }
+ break;
+ case SID_CONDITIONALFORMATTING:
+ {
+ const uno::Reference< report::XFormattedField> xFormattedField(getDesignView()->getCurrentControlModel(),uno::UNO_QUERY);
+ aReturn.bEnabled = xFormattedField.is();
+ }
+ break;
+ case SID_INSERT_FLD_PGNUMBER:
+ case SID_DATETIME:
+ aReturn.bEnabled = m_xReportDefinition.is() && isEditable() && getDesignView()->getCurrentSection().is();
+ break;
+ case SID_EXPORTDOC:
+ case SID_EXPORTDOCASPDF:
+ aReturn.bEnabled = m_xReportDefinition.is();
+ break;
+ case SID_PRINTPREVIEW:
+ aReturn.bEnabled = false;
+ break;
+ case SID_ATTR_ZOOM:
+ aReturn.bEnabled = true;
+ {
+ SvxZoomItem aZoom(m_eZoomType,m_nZoomValue);
+ aZoom.SetValueSet(SvxZoomEnableFlags::N50|SvxZoomEnableFlags::N75|SvxZoomEnableFlags::N100|SvxZoomEnableFlags::N200);
+ aZoom.QueryValue(aReturn.aValue);
+ }
+ break;
+ case SID_ATTR_ZOOMSLIDER:
+ aReturn.bEnabled = true;
+ {
+ SvxZoomSliderItem aZoomSlider(m_nZoomValue,20,400);
+ aZoomSlider.AddSnappingPoint(50);
+ aZoomSlider.AddSnappingPoint(75);
+ aZoomSlider.AddSnappingPoint(100);
+ aZoomSlider.AddSnappingPoint(200);
+ aZoomSlider.QueryValue(aReturn.aValue);
+ }
+ break;
+ default:
+ aReturn = OReportController_BASE::GetState(_nId);
+ }
+ return aReturn;
+}
+
+
+namespace
+{
+ /** extracts a background color from a dispatched SID_BACKGROUND_COLOR call
+
+ The dispatch might originate from either the toolbar, or the conditional
+ formatting dialog. In both cases, argument formats are different.
+ */
+ util::Color lcl_extractBackgroundColor( const Sequence< PropertyValue >& _rDispatchArgs )
+ {
+ util::Color aColor( COL_TRANSPARENT );
+ if ( _rDispatchArgs.getLength() == 1 )
+ {
+ OSL_VERIFY( _rDispatchArgs[0].Value >>= aColor );
+ }
+ else
+ {
+ SequenceAsHashMap aMap( _rDispatchArgs );
+ aColor = aMap.getUnpackedValueOrDefault( PROPERTY_FONTCOLOR, aColor );
+ }
+ return aColor;
+ }
+}
+
+
+void OReportController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs)
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+
+ bool bForceBroadcast = false;
+ switch(_nId)
+ {
+ case SID_RPT_TEXTDOCUMENT:
+ if ( m_xReportDefinition.is() )
+ m_xReportDefinition->setMimeType( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII );
+ break;
+ case SID_RPT_SPREADSHEET:
+ if (m_xReportDefinition.is() )
+ m_xReportDefinition->setMimeType( MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII );
+ break;
+ case SID_REPORTHEADER_WITHOUT_UNDO:
+ case SID_REPORTFOOTER_WITHOUT_UNDO:
+ case SID_REPORTHEADERFOOTER:
+ switchReportSection(_nId);
+ break;
+ case SID_PAGEHEADER_WITHOUT_UNDO:
+ case SID_PAGEFOOTER_WITHOUT_UNDO:
+ case SID_PAGEHEADERFOOTER:
+ switchPageSection(_nId);
+ break;
+ case SID_GROUP_APPEND:
+ case SID_GROUP_REMOVE:
+ modifyGroup(_nId == SID_GROUP_APPEND,aArgs);
+ break;
+ case SID_GROUPHEADER_WITHOUT_UNDO:
+ case SID_GROUPHEADER:
+ createGroupSection(SID_GROUPHEADER == _nId,true,aArgs);
+ break;
+ case SID_GROUPFOOTER_WITHOUT_UNDO:
+ case SID_GROUPFOOTER:
+ createGroupSection(SID_GROUPFOOTER == _nId,false,aArgs);
+ break;
+ case SID_ADD_CONTROL_PAIR:
+ addPairControls(aArgs);
+ break;
+ case SID_REDO:
+ case SID_UNDO:
+ {
+ const OXUndoEnvironment::OUndoMode aLock( m_aReportModel->GetUndoEnv() );
+ bool ( SfxUndoManager::*doXDo )() =
+ ( _nId == SID_UNDO ) ? &SfxUndoManager::Undo : &SfxUndoManager::Redo;
+ SfxUndoManager& rUndoManager( getUndoManager() );
+
+ sal_Int16 nCount(1);
+ if (aArgs.hasElements() && aArgs[0].Name != "KeyModifier")
+ aArgs[0].Value >>= nCount;
+ while (nCount--)
+ (rUndoManager.*doXDo)();
+ InvalidateAll();
+ if (m_xGroupsFloater && m_xGroupsFloater->getDialog()->get_visible())
+ m_xGroupsFloater->UpdateData();
+ }
+ break;
+ case SID_CUT:
+ executeMethodWithUndo(RID_STR_UNDO_REMOVE_SELECTION,::std::mem_fn(&ODesignView::Cut));
+ break;
+ case SID_COPY:
+ getDesignView()->Copy();
+ break;
+ case SID_PASTE:
+ executeMethodWithUndo(RID_STR_UNDO_PASTE,::std::mem_fn(&ODesignView::Paste));
+ break;
+
+ case SID_FRAME_TO_TOP:
+ case SID_FRAME_DOWN:
+ case SID_FRAME_UP:
+ case SID_FRAME_TO_BOTTOM:
+ case SID_OBJECT_HEAVEN:
+ case SID_OBJECT_HELL:
+ changeZOrder(_nId);
+ break;
+ case SID_DISTRIBUTE_HLEFT:
+ case SID_DISTRIBUTE_HCENTER:
+ case SID_DISTRIBUTE_HDISTANCE:
+ case SID_DISTRIBUTE_HRIGHT:
+ case SID_DISTRIBUTE_VTOP:
+ case SID_DISTRIBUTE_VCENTER:
+ case SID_DISTRIBUTE_VDISTANCE:
+ case SID_DISTRIBUTE_VBOTTOM:
+ {
+ OSectionView* pSectionView = getCurrentSectionView();
+ if ( pSectionView )
+ pSectionView->DistributeMarkedObjects(_nId);
+ }
+ break;
+ case SID_OBJECT_SMALLESTWIDTH:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::WIDTH_SMALLEST);
+ break;
+ case SID_OBJECT_SMALLESTHEIGHT:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::HEIGHT_SMALLEST);
+ break;
+ case SID_OBJECT_GREATESTWIDTH:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::WIDTH_GREATEST);
+ break;
+ case SID_OBJECT_GREATESTHEIGHT:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::HEIGHT_GREATEST);
+ break;
+ case SID_SECTION_ALIGN_LEFT:
+ case SID_OBJECT_ALIGN_LEFT:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::LEFT,SID_SECTION_ALIGN_LEFT == _nId);
+ break;
+ case SID_SECTION_ALIGN_CENTER:
+ case SID_OBJECT_ALIGN_CENTER:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::CENTER_HORIZONTAL,SID_SECTION_ALIGN_CENTER == _nId);
+ break;
+ case SID_SECTION_ALIGN_RIGHT:
+ case SID_OBJECT_ALIGN_RIGHT:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::RIGHT,SID_SECTION_ALIGN_RIGHT == _nId);
+ break;
+ case SID_SECTION_ALIGN_UP:
+ case SID_OBJECT_ALIGN_UP:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::TOP,SID_SECTION_ALIGN_UP == _nId);
+ break;
+ case SID_SECTION_ALIGN_MIDDLE:
+ case SID_OBJECT_ALIGN_MIDDLE:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::CENTER_VERTICAL,SID_SECTION_ALIGN_MIDDLE == _nId);
+ break;
+ case SID_SECTION_ALIGN_DOWN:
+ case SID_OBJECT_ALIGN_DOWN:
+ alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::BOTTOM,SID_SECTION_ALIGN_DOWN == _nId);
+ break;
+
+ case SID_SECTION_SHRINK_BOTTOM:
+ case SID_SECTION_SHRINK_TOP:
+ case SID_SECTION_SHRINK:
+ {
+ uno::Reference<report::XSection> xSection = getDesignView()->getCurrentSection();
+ shrinkSection(RID_STR_UNDO_SHRINK, xSection, _nId);
+ }
+ break;
+
+ case SID_SELECTALL:
+ getDesignView()->SelectAll(SdrObjKind::NONE);
+ break;
+ case SID_SELECTALL_IN_SECTION:
+ {
+ OSectionView* pSectionView = getCurrentSectionView();
+ if ( pSectionView )
+ pSectionView->MarkAll();
+ }
+ break;
+ case SID_ESCAPE:
+ getDesignView()->SetMode(DlgEdMode::Select);
+ InvalidateFeature( SID_OBJECT_SELECT );
+ break;
+ case SID_SELECT_ALL_EDITS:
+ getDesignView()->SelectAll(SdrObjKind::ReportDesignFormattedField);
+ break;
+ case SID_SELECT_ALL_LABELS:
+ getDesignView()->SelectAll(SdrObjKind::ReportDesignFixedText);
+ break;
+ case SID_TERMINATE_INPLACEACTIVATION:
+ {
+ OSectionWindow* pSection = getDesignView()->getMarkedSection();
+ if ( pSection )
+ pSection->getReportSection().deactivateOle();
+ }
+ break;
+ case SID_SELECT:
+ if ( aArgs.getLength() == 1 )
+ select(aArgs[0].Value);
+ break;
+ case SID_SELECT_REPORT:
+ select(uno::Any(m_xReportDefinition));
+ break;
+ case SID_EXECUTE_REPORT:
+ getView()->PostUserEvent(LINK(this, OReportController,OnExecuteReport));
+ break;
+ case SID_RPT_NEW_FUNCTION:
+ createNewFunction(aArgs[0].Value);
+ break;
+ case SID_COLLAPSE_SECTION:
+ collapseSection(true);
+ break;
+ case SID_EXPAND_SECTION:
+ collapseSection(false);
+ break;
+ case SID_NEXT_MARK:
+ markSection(true);
+ break;
+ case SID_PREV_MARK:
+ markSection(false);
+ break;
+ case SID_DELETE:
+ if ( aArgs.getLength() == 1 )
+ {
+ uno::Reference< report::XFunction> xFunction;
+ aArgs[0].Value >>= xFunction;
+ if ( xFunction.is() )
+ {
+ uno::Reference< report::XFunctions> xFunctions(xFunction->getParent(),uno::UNO_QUERY_THROW);
+ sal_Int32 nIndex = getPositionInIndexAccess(xFunctions, xFunction);
+ const OUString sUndoAction = RptResId(RID_STR_UNDO_REMOVE_FUNCTION);
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+ xFunctions->removeByIndex(nIndex);
+ select(uno::Any(xFunctions->getParent()));
+ InvalidateFeature( SID_UNDO );
+ }
+ }
+ else
+ executeMethodWithUndo(RID_STR_UNDO_REMOVE_SELECTION,::std::mem_fn(&ODesignView::Delete));
+ break;
+ case SID_GRID_USE:
+ m_bGridUse = !m_bGridUse;
+ getDesignView()->setGridSnap(m_bGridUse);
+ break;
+ case SID_HELPLINES_MOVE:
+ m_bHelplinesMove = !m_bHelplinesMove;
+ getDesignView()->setDragStripes(m_bHelplinesMove);
+ break;
+ case SID_GRID_VISIBLE:
+ m_bGridVisible = !m_bGridVisible;
+ getDesignView()->toggleGrid(m_bGridVisible);
+ break;
+ case SID_RULER:
+ m_bShowRuler = !m_bShowRuler;
+ getDesignView()->showRuler(m_bShowRuler);
+ break;
+ case SID_OBJECT_SELECT:
+ getDesignView()->SetMode(DlgEdMode::Select);
+ InvalidateAll();
+ break;
+ case SID_INSERT_DIAGRAM:
+ getDesignView()->SetMode( DlgEdMode::Insert );
+ getDesignView()->SetInsertObj( SdrObjKind::OLE2);
+ createDefaultControl(aArgs);
+ InvalidateAll();
+ break;
+ case SID_FM_FIXEDTEXT:
+ getDesignView()->SetMode( DlgEdMode::Insert );
+ getDesignView()->SetInsertObj( SdrObjKind::ReportDesignFixedText );
+ createDefaultControl(aArgs);
+ InvalidateAll();
+ break;
+ case SID_INSERT_HFIXEDLINE:
+ getDesignView()->SetMode( DlgEdMode::Insert );
+ getDesignView()->SetInsertObj( SdrObjKind::ReportDesignHorizontalFixedLine );
+ createDefaultControl(aArgs);
+ InvalidateAll();
+ break;
+ case SID_INSERT_VFIXEDLINE:
+ getDesignView()->SetMode( DlgEdMode::Insert );
+ getDesignView()->SetInsertObj( SdrObjKind::ReportDesignVerticalFixedLine );
+ createDefaultControl(aArgs);
+ InvalidateAll();
+ break;
+ case SID_FM_EDIT:
+ getDesignView()->SetMode( DlgEdMode::Insert );
+ getDesignView()->SetInsertObj( SdrObjKind::ReportDesignFormattedField );
+ createDefaultControl(aArgs);
+ InvalidateAll();
+ break;
+ case SID_FM_IMAGECONTROL:
+ getDesignView()->SetMode( DlgEdMode::Insert );
+ getDesignView()->SetInsertObj( SdrObjKind::ReportDesignImageControl );
+ createDefaultControl(aArgs);
+ InvalidateAll();
+ break;
+ case SID_DRAWTBX_CS_BASIC:
+ case SID_DRAWTBX_CS_BASIC1:
+ case SID_DRAWTBX_CS_BASIC2:
+ case SID_DRAWTBX_CS_BASIC3:
+ case SID_DRAWTBX_CS_BASIC4:
+ case SID_DRAWTBX_CS_BASIC5:
+ case SID_DRAWTBX_CS_BASIC6:
+ case SID_DRAWTBX_CS_BASIC7:
+ case SID_DRAWTBX_CS_BASIC8:
+ case SID_DRAWTBX_CS_BASIC9:
+ case SID_DRAWTBX_CS_BASIC10:
+ case SID_DRAWTBX_CS_BASIC11:
+ case SID_DRAWTBX_CS_BASIC12:
+ case SID_DRAWTBX_CS_BASIC13:
+ case SID_DRAWTBX_CS_BASIC14:
+ case SID_DRAWTBX_CS_BASIC15:
+ case SID_DRAWTBX_CS_BASIC16:
+ case SID_DRAWTBX_CS_BASIC17:
+ case SID_DRAWTBX_CS_BASIC18:
+ case SID_DRAWTBX_CS_BASIC19:
+ case SID_DRAWTBX_CS_BASIC20:
+ case SID_DRAWTBX_CS_BASIC21:
+ case SID_DRAWTBX_CS_BASIC22:
+ case SID_DRAWTBX_CS_SYMBOL1:
+ case SID_DRAWTBX_CS_SYMBOL2:
+ case SID_DRAWTBX_CS_SYMBOL3:
+ case SID_DRAWTBX_CS_SYMBOL4:
+ case SID_DRAWTBX_CS_SYMBOL5:
+ case SID_DRAWTBX_CS_SYMBOL6:
+ case SID_DRAWTBX_CS_SYMBOL7:
+ case SID_DRAWTBX_CS_SYMBOL8:
+ case SID_DRAWTBX_CS_SYMBOL9:
+ case SID_DRAWTBX_CS_SYMBOL10:
+ case SID_DRAWTBX_CS_SYMBOL11:
+ case SID_DRAWTBX_CS_SYMBOL12:
+ case SID_DRAWTBX_CS_SYMBOL13:
+ case SID_DRAWTBX_CS_SYMBOL14:
+ case SID_DRAWTBX_CS_SYMBOL15:
+ case SID_DRAWTBX_CS_SYMBOL16:
+ case SID_DRAWTBX_CS_SYMBOL17:
+ case SID_DRAWTBX_CS_SYMBOL18:
+ case SID_DRAWTBX_CS_ARROW1:
+ case SID_DRAWTBX_CS_ARROW2:
+ case SID_DRAWTBX_CS_ARROW3:
+ case SID_DRAWTBX_CS_ARROW4:
+ case SID_DRAWTBX_CS_ARROW5:
+ case SID_DRAWTBX_CS_ARROW6:
+ case SID_DRAWTBX_CS_ARROW7:
+ case SID_DRAWTBX_CS_ARROW8:
+ case SID_DRAWTBX_CS_ARROW9:
+ case SID_DRAWTBX_CS_ARROW10:
+ case SID_DRAWTBX_CS_ARROW11:
+ case SID_DRAWTBX_CS_ARROW12:
+ case SID_DRAWTBX_CS_ARROW13:
+ case SID_DRAWTBX_CS_ARROW14:
+ case SID_DRAWTBX_CS_ARROW15:
+ case SID_DRAWTBX_CS_ARROW16:
+ case SID_DRAWTBX_CS_ARROW17:
+ case SID_DRAWTBX_CS_ARROW18:
+ case SID_DRAWTBX_CS_ARROW19:
+ case SID_DRAWTBX_CS_ARROW20:
+ case SID_DRAWTBX_CS_ARROW21:
+ case SID_DRAWTBX_CS_ARROW22:
+ case SID_DRAWTBX_CS_ARROW23:
+ case SID_DRAWTBX_CS_ARROW24:
+ case SID_DRAWTBX_CS_ARROW25:
+ case SID_DRAWTBX_CS_ARROW26:
+ case SID_DRAWTBX_CS_STAR1:
+ case SID_DRAWTBX_CS_STAR2:
+ case SID_DRAWTBX_CS_STAR3:
+ case SID_DRAWTBX_CS_STAR4:
+ case SID_DRAWTBX_CS_STAR5:
+ case SID_DRAWTBX_CS_STAR6:
+ case SID_DRAWTBX_CS_STAR7:
+ case SID_DRAWTBX_CS_STAR8:
+ case SID_DRAWTBX_CS_STAR9:
+ case SID_DRAWTBX_CS_STAR10:
+ case SID_DRAWTBX_CS_STAR11:
+ case SID_DRAWTBX_CS_STAR12:
+ case SID_DRAWTBX_CS_FLOWCHART1:
+ case SID_DRAWTBX_CS_FLOWCHART2:
+ case SID_DRAWTBX_CS_FLOWCHART3:
+ case SID_DRAWTBX_CS_FLOWCHART4:
+ case SID_DRAWTBX_CS_FLOWCHART5:
+ case SID_DRAWTBX_CS_FLOWCHART6:
+ case SID_DRAWTBX_CS_FLOWCHART7:
+ case SID_DRAWTBX_CS_FLOWCHART8:
+ case SID_DRAWTBX_CS_FLOWCHART9:
+ case SID_DRAWTBX_CS_FLOWCHART10:
+ case SID_DRAWTBX_CS_FLOWCHART11:
+ case SID_DRAWTBX_CS_FLOWCHART12:
+ case SID_DRAWTBX_CS_FLOWCHART13:
+ case SID_DRAWTBX_CS_FLOWCHART14:
+ case SID_DRAWTBX_CS_FLOWCHART15:
+ case SID_DRAWTBX_CS_FLOWCHART16:
+ case SID_DRAWTBX_CS_FLOWCHART17:
+ case SID_DRAWTBX_CS_FLOWCHART18:
+ case SID_DRAWTBX_CS_FLOWCHART19:
+ case SID_DRAWTBX_CS_FLOWCHART20:
+ case SID_DRAWTBX_CS_FLOWCHART21:
+ case SID_DRAWTBX_CS_FLOWCHART22:
+ case SID_DRAWTBX_CS_FLOWCHART23:
+ case SID_DRAWTBX_CS_FLOWCHART24:
+ case SID_DRAWTBX_CS_FLOWCHART25:
+ case SID_DRAWTBX_CS_FLOWCHART26:
+ case SID_DRAWTBX_CS_FLOWCHART27:
+ case SID_DRAWTBX_CS_FLOWCHART28:
+ case SID_DRAWTBX_CS_CALLOUT1:
+ case SID_DRAWTBX_CS_CALLOUT2:
+ case SID_DRAWTBX_CS_CALLOUT3:
+ case SID_DRAWTBX_CS_CALLOUT4:
+ case SID_DRAWTBX_CS_CALLOUT5:
+ case SID_DRAWTBX_CS_CALLOUT6:
+ case SID_DRAWTBX_CS_CALLOUT7:
+ case SID_DRAWTBX_CS_SYMBOL:
+ case SID_DRAWTBX_CS_ARROW:
+ case SID_DRAWTBX_CS_FLOWCHART:
+ case SID_DRAWTBX_CS_CALLOUT:
+ case SID_DRAWTBX_CS_STAR:
+ getDesignView()->SetMode( DlgEdMode::Insert );
+ {
+ URL aUrl = getURLForId(_nId);
+ sal_Int32 nIndex = 1;
+ std::u16string_view sType = o3tl::getToken(aUrl.Complete, 0,'.',nIndex);
+ if ( nIndex == -1 || sType.empty() )
+ {
+ switch(_nId)
+ {
+ case SID_DRAWTBX_CS_SYMBOL:
+ sType = u"smiley";
+ break;
+ case SID_DRAWTBX_CS_ARROW:
+ sType = u"left-right-arrow";
+ break;
+ case SID_DRAWTBX_CS_FLOWCHART:
+ sType = u"flowchart-internal-storage";
+ break;
+ case SID_DRAWTBX_CS_CALLOUT:
+ sType = u"round-rectangular-callout";
+ break;
+ case SID_DRAWTBX_CS_STAR:
+ sType = u"star5";
+ break;
+ default:
+ sType = u"diamond";
+ }
+ }
+ else
+ sType = o3tl::getToken(aUrl.Complete, 0,'.',nIndex);
+
+ getDesignView()->SetInsertObj( SdrObjKind::CustomShape, OUString(sType));
+ createDefaultControl(aArgs);
+ }
+ InvalidateAll();
+ break;
+ case SID_RPT_SHOWREPORTEXPLORER:
+ if ( isUiVisible() )
+ getDesignView()->toggleReportExplorer();
+ break;
+ case SID_FM_ADD_FIELD:
+ if ( isUiVisible() )
+ getDesignView()->toggleAddField();
+ break;
+ case SID_SHOW_PROPERTYBROWSER:
+ if ( m_bShowProperties )
+ m_sLastActivePage = getDesignView()->getCurrentPage();
+ else
+ getDesignView()->setCurrentPage(m_sLastActivePage);
+
+ if ( isUiVisible() )
+ {
+ m_bShowProperties = !m_bShowProperties;
+ if ( aArgs.getLength() == 1 )
+ aArgs[0].Value >>= m_bShowProperties;
+
+ getDesignView()->togglePropertyBrowser(m_bShowProperties);
+ }
+ break;
+ case SID_PROPERTYBROWSER_LAST_PAGE: // nothing to do
+ m_sLastActivePage = getDesignView()->getCurrentPage();
+ break;
+ case SID_SPLIT_POSITION:
+ getDesignView()->Resize();
+ break;
+ case SID_PAGEDIALOG:
+ case SID_ATTR_CHAR_COLOR_BACKGROUND:
+ {
+ uno::Reference<report::XSection> xSection;
+ if (aArgs.getLength() == 1 )
+ aArgs[0].Value >>= xSection;
+ else if (_nId == SID_ATTR_CHAR_COLOR_BACKGROUND)
+ xSection.set(getDesignView()->getMarkedSection()->getReportSection().getSection());
+ openPageDialog(xSection);
+ bForceBroadcast = true;
+ }
+ break;
+ case SID_SORTINGANDGROUPING:
+ openSortingAndGroupingDialog();
+ break;
+ case SID_BACKGROUND_COLOR:
+ {
+ const util::Color aColor( lcl_extractBackgroundColor( aArgs ) );
+ if ( !impl_setPropertyAtControls_throw(RID_STR_UNDO_CHANGEFONT,PROPERTY_CONTROLBACKGROUND,uno::Any(aColor),aArgs) )
+ {
+ uno::Reference< report::XSection > xSection = getDesignView()->getCurrentSection();
+ if ( xSection.is() )
+ {
+ xSection->setBackColor( aColor );
+ }
+ }
+ bForceBroadcast = true;
+ }
+ break;
+ case SID_ATTR_CHAR_WEIGHT:
+ case SID_ATTR_CHAR_POSTURE:
+ case SID_ATTR_CHAR_UNDERLINE:
+ {
+ uno::Reference< awt::XWindow> xWindow;
+ ::std::vector< uno::Reference< uno::XInterface > > aControlsFormats;
+ lcl_getReportControlFormat( aArgs, getDesignView(), xWindow, aControlsFormats );
+
+ const OUString sUndoAction(RptResId(RID_STR_UNDO_CHANGEFONT));
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+
+ for (const auto& rxControlFormat : aControlsFormats)
+ {
+ uno::Reference< report::XReportControlFormat> xReportControlFormat(rxControlFormat,uno::UNO_QUERY);
+ lcl_setFontWPU_nothrow(xReportControlFormat,_nId);
+ }
+ }
+ break;
+ case SID_ATTR_CHAR_COLOR:
+ case SID_ATTR_CHAR_COLOR2:
+ case SID_ATTR_CHAR_COLOR_EXT:
+ {
+ const SequenceAsHashMap aMap(aArgs);
+ const util::Color aColor = aMap.getUnpackedValueOrDefault(PROPERTY_FONTCOLOR,util::Color());
+ impl_setPropertyAtControls_throw(RID_STR_UNDO_CHANGEFONT,PROPERTY_CHARCOLOR,uno::Any(aColor),aArgs);
+ bForceBroadcast = true;
+ }
+ break;
+ case SID_ATTR_CHAR_FONT:
+ if ( aArgs.getLength() == 1 )
+ {
+ awt::FontDescriptor aFont;
+ if ( aArgs[0].Value >>= aFont )
+ {
+ impl_setPropertyAtControls_throw(RID_STR_UNDO_CHANGEFONT,PROPERTY_CHARFONTNAME,uno::Any(aFont.Name),aArgs);
+ }
+ }
+ break;
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ if ( aArgs.getLength() == 1 )
+ {
+ float fSelVal = 0.0;
+ if ( aArgs[0].Value >>= fSelVal )
+ impl_setPropertyAtControls_throw(RID_STR_UNDO_CHANGEFONT,PROPERTY_CHARHEIGHT,aArgs[0].Value,aArgs);
+ }
+ break;
+ case SID_ATTR_PARA_ADJUST_LEFT:
+ case SID_ATTR_PARA_ADJUST_CENTER:
+ case SID_ATTR_PARA_ADJUST_RIGHT:
+ case SID_ATTR_PARA_ADJUST_BLOCK:
+ {
+ style::ParagraphAdjust eParagraphAdjust = style::ParagraphAdjust_LEFT;
+ switch(_nId)
+ {
+ case SID_ATTR_PARA_ADJUST_LEFT:
+ eParagraphAdjust = style::ParagraphAdjust_LEFT;
+ break;
+ case SID_ATTR_PARA_ADJUST_CENTER:
+ eParagraphAdjust = style::ParagraphAdjust_CENTER;
+ break;
+ case SID_ATTR_PARA_ADJUST_RIGHT:
+ eParagraphAdjust = style::ParagraphAdjust_RIGHT;
+ break;
+ case SID_ATTR_PARA_ADJUST_BLOCK:
+ eParagraphAdjust = style::ParagraphAdjust_BLOCK;
+ break;
+ }
+ impl_setPropertyAtControls_throw(RID_STR_UNDO_ALIGNMENT,PROPERTY_PARAADJUST,uno::Any(static_cast<sal_Int16>(eParagraphAdjust)),aArgs);
+
+ InvalidateFeature(SID_ATTR_PARA_ADJUST_LEFT);
+ InvalidateFeature(SID_ATTR_PARA_ADJUST_CENTER);
+ InvalidateFeature(SID_ATTR_PARA_ADJUST_RIGHT);
+ InvalidateFeature(SID_ATTR_PARA_ADJUST_BLOCK);
+ }
+ break;
+ case SID_CHAR_DLG:
+ {
+ uno::Sequence< beans::NamedValue > aSettings;
+ uno::Reference< awt::XWindow> xWindow;
+ ::std::vector< uno::Reference< uno::XInterface > > aControlsFormats;
+ lcl_getReportControlFormat( aArgs, getDesignView(), xWindow, aControlsFormats );
+
+ if ( !aControlsFormats.empty() )
+ {
+ const OUString sUndoAction( RptResId( RID_STR_UNDO_CHANGEFONT ) );
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+
+ for (const auto& rxControlFormat : aControlsFormats)
+ {
+ uno::Reference< report::XReportControlFormat > xFormat( rxControlFormat, uno::UNO_QUERY );
+ if ( !xFormat.is() )
+ continue;
+
+ if ( !aSettings.hasElements() )
+ {
+ ::rptui::openCharDialog( xFormat, xWindow, aSettings );
+ if ( !aSettings.hasElements() )
+ break;
+ }
+
+ applyCharacterSettings( xFormat, aSettings );
+ }
+
+ InvalidateAll();
+ }
+ }
+ break;
+ case SID_INSERT_GRAPHIC:
+ insertGraphic();
+ break;
+ case SID_SETCONTROLDEFAULTS:
+ break;
+ case SID_CONDITIONALFORMATTING:
+ {
+ uno::Reference< report::XFormattedField> xFormattedField(getDesignView()->getCurrentControlModel(),uno::UNO_QUERY);
+ if ( xFormattedField.is() )
+ {
+ ConditionalFormattingDialog aDlg(getFrameWeld(), xFormattedField, *this);
+ aDlg.run();
+ }
+ }
+ break;
+ case SID_DATETIME:
+ if ( m_xReportDefinition.is() )
+ {
+ if ( !aArgs.hasElements() )
+ {
+ ODateTimeDialog aDlg(getFrameWeld(), getDesignView()->getCurrentSection(), this);
+ aDlg.run();
+ }
+ else
+ createDateTime(aArgs);
+ }
+ break;
+ case SID_INSERT_FLD_PGNUMBER:
+ if ( m_xReportDefinition.is() )
+ {
+ if ( !aArgs.hasElements() )
+ {
+ OPageNumberDialog aDlg(getFrameWeld(), m_xReportDefinition, this);
+ aDlg.run();
+ }
+ else
+ createPageNumber(aArgs);
+ }
+ break;
+ case SID_EXPORTDOC:
+ case SID_EXPORTDOCASPDF:
+ case SID_PRINTPREVIEW:
+ break;
+ case SID_EDITDOC:
+ if(isEditable())
+ { // the state should be changed to not editable
+ setModified(false); // and we are not modified yet
+ }
+ setEditable(!isEditable());
+ InvalidateAll();
+ return;
+ case SID_GROUP:
+ break;
+ case SID_ATTR_ZOOM:
+ if ( !aArgs.hasElements() )
+ {
+ openZoomDialog();
+ }
+ else if ( aArgs.getLength() == 1 && aArgs[0].Name == "Zoom" )
+ {
+ SvxZoomItem aZoomItem;
+ aZoomItem.PutValue(aArgs[0].Value, 0);
+ m_nZoomValue = aZoomItem.GetValue();
+ m_eZoomType = aZoomItem.GetType();
+ impl_zoom_nothrow();
+ }
+ break;
+ case SID_ATTR_ZOOMSLIDER:
+ if ( aArgs.getLength() == 1 && aArgs[0].Name == "ZoomSlider" )
+ {
+ SvxZoomSliderItem aZoomSlider;
+ aZoomSlider.PutValue(aArgs[0].Value, 0);
+ m_nZoomValue = aZoomSlider.GetValue();
+ m_eZoomType = SvxZoomType::PERCENT;
+ impl_zoom_nothrow();
+ }
+ break;
+ default:
+ OReportController_BASE::Execute(_nId,aArgs);
+ }
+ InvalidateFeature(_nId,Reference< XStatusListener >(),bForceBroadcast);
+}
+
+void OReportController::impl_initialize( )
+{
+ OReportController_BASE::impl_initialize();
+
+ const ::comphelper::NamedValueCollection& rArguments( getInitParams() );
+
+ rArguments.get_ensureType( PROPERTY_REPORTNAME, m_sName );
+ if ( m_sName.isEmpty() )
+ rArguments.get_ensureType( "DocumentTitle", m_sName );
+
+ try
+ {
+ if ( m_xReportDefinition.is() )
+ {
+ getView()->initialize(); // show the windows and fill with our information
+
+ m_aReportModel = reportdesign::OReportDefinition::getSdrModel(m_xReportDefinition);
+ if ( !m_aReportModel )
+ throw RuntimeException();
+ m_aReportModel->attachController( *this );
+
+ clearUndoManager();
+ UndoSuppressor aSuppressUndo( getUndoManager() );
+
+ setMode(::comphelper::NamedValueCollection::getOrDefault(getModel()->getArgs(), u"Mode", OUString("normal")));
+
+ listen(true);
+ setEditable( !m_aReportModel->IsReadOnly() );
+ m_xFormatter.set(util::NumberFormatter::create(m_xContext), UNO_QUERY_THROW);
+ m_xFormatter->attachNumberFormatsSupplier(Reference< XNumberFormatsSupplier>(m_xReportDefinition,uno::UNO_QUERY));
+
+ utl::MediaDescriptor aDescriptor( m_xReportDefinition->getArgs() );
+ OUString sHierarchicalDocumentName = aDescriptor.getUnpackedValueOrDefault("HierarchicalDocumentName",OUString());
+
+ if ( sHierarchicalDocumentName.isEmpty() && getConnection().is() )
+ {
+ uno::Reference<sdbcx::XTablesSupplier> xTablesSup(getConnection(),uno::UNO_QUERY_THROW);
+ uno::Reference<container::XNameAccess> xTables = xTablesSup->getTables();
+ const uno::Sequence< OUString > aNames( xTables->getElementNames() );
+
+ if ( aNames.hasElements() )
+ {
+ m_xReportDefinition->setCommand(aNames[0]);
+ m_xReportDefinition->setCommandType(sdb::CommandType::TABLE);
+ }
+ }
+
+ m_aVisualAreaSize = m_xReportDefinition->getVisualAreaSize(0);
+
+ }
+
+ // check if chart is supported by the engine
+ checkChartEnabled();
+ // restore the view data
+ getDesignView()->toggleGrid(m_bGridVisible);
+ getDesignView()->showRuler(m_bShowRuler);
+ getDesignView()->togglePropertyBrowser(m_bShowProperties);
+ getDesignView()->setCurrentPage(m_sLastActivePage);
+ getDesignView()->unmarkAllObjects();
+
+ if ( m_nPageNum != -1 )
+ {
+ if ( m_nPageNum < m_aReportModel->GetPageCount() )
+ {
+ const OReportPage* pPage = dynamic_cast<OReportPage*>(m_aReportModel->GetPage(static_cast<sal_uInt16>(m_nPageNum)));
+ if ( pPage )
+ {
+ executeUnChecked(SID_SELECT,{ comphelper::makePropertyValue("", pPage->getSection() ) });
+ }
+ }
+ else
+ m_nPageNum = -1;
+ }
+ getDesignView()->collapseSections(m_aCollapsedSections);
+ impl_zoom_nothrow();
+ getDesignView()->Resize();
+ getDesignView()->Invalidate();
+ InvalidateAll();
+
+ if ( m_bShowProperties && m_nPageNum == -1 )
+ {
+ m_sLastActivePage = "Data";
+ getDesignView()->setCurrentPage(m_sLastActivePage);
+ executeUnChecked(SID_SELECT_REPORT,{});
+ }
+
+ setModified(false); // and we are not modified yet
+ }
+ catch(const SQLException&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+IMPL_LINK( OReportController, OnCreateHdl, OAddFieldWindow& ,_rAddFieldDlg, void)
+{
+ weld::WaitObject aObj(getFrameWeld());
+ uno::Sequence< beans::PropertyValue > aArgs = _rAddFieldDlg.getSelectedFieldDescriptors();
+ // we use this way to create undo actions
+ if ( aArgs.hasElements() )
+ {
+ executeChecked(SID_ADD_CONTROL_PAIR,aArgs);
+ }
+}
+
+bool OReportController::Construct(vcl::Window* pParent)
+{
+ VclPtrInstance<ODesignView> pMyOwnView( pParent, m_xContext, *this );
+ StartListening( *pMyOwnView );
+ setView( pMyOwnView );
+
+ // now that we have a view we can create the clipboard listener
+ m_aSystemClipboard = TransferableDataHelper::CreateFromSystemClipboard( getView() );
+ m_aSystemClipboard.StartClipboardListening( );
+ m_pClipboardNotifier = new TransferableClipboardListener( LINK( this, OReportController, OnClipboardChanged ) );
+ m_pClipboardNotifier->AddListener( getView() );
+
+ OReportController_BASE::Construct(pParent);
+ return true;
+}
+
+sal_Bool SAL_CALL OReportController::suspend(sal_Bool /*_bSuspend*/)
+{
+ if ( getBroadcastHelper().bInDispose || getBroadcastHelper().bDisposed )
+ return true;
+
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+
+ if ( getView() && getView()->IsInModalMode() )
+ return false;
+
+ // this suspend will be handled in the DBAccess interceptor implementation
+ return true;
+}
+
+void OReportController::describeSupportedFeatures()
+{
+ DBSubComponentController::describeSupportedFeatures();
+
+ implDescribeSupportedFeature( ".uno:TextDocument", SID_RPT_TEXTDOCUMENT, CommandGroup::APPLICATION );
+ implDescribeSupportedFeature( ".uno:Spreadsheet", SID_RPT_SPREADSHEET, CommandGroup::APPLICATION );
+
+ implDescribeSupportedFeature( ".uno:Redo", SID_REDO, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:Undo", SID_UNDO, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:SelectAll", SID_SELECTALL, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:SelectAllInSection", SID_SELECTALL_IN_SECTION, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:Delete", SID_DELETE, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:SelectReport", SID_SELECT_REPORT, CommandGroup::EDIT );
+ implDescribeSupportedFeature( ".uno:ExecuteReport", SID_EXECUTE_REPORT, CommandGroup::EDIT );
+
+ implDescribeSupportedFeature( ".uno:GridVisible", SID_GRID_VISIBLE, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:GridUse", SID_GRID_USE, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:HelplinesMove", SID_HELPLINES_MOVE, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:ShowRuler", SID_RULER, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:AddField", SID_FM_ADD_FIELD, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:ReportNavigator", SID_RPT_SHOWREPORTEXPLORER, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:ControlProperties", SID_SHOW_PROPERTYBROWSER, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:DbSortingAndGrouping", SID_SORTINGANDGROUPING, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:PageHeaderFooter", SID_PAGEHEADERFOOTER, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:ReportHeaderFooter", SID_REPORTHEADERFOOTER, CommandGroup::VIEW );
+ implDescribeSupportedFeature( ".uno:ZoomSlider", SID_ATTR_ZOOMSLIDER );
+ implDescribeSupportedFeature( ".uno:Zoom", SID_ATTR_ZOOM, CommandGroup::VIEW );
+
+ implDescribeSupportedFeature( ".uno:ConditionalFormatting", SID_CONDITIONALFORMATTING, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:PageDialog", SID_PAGEDIALOG, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:ResetAttributes", SID_SETCONTROLDEFAULTS, CommandGroup::FORMAT );
+
+ implDescribeSupportedFeature( ".uno:Bold", SID_ATTR_CHAR_WEIGHT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:Italic", SID_ATTR_CHAR_POSTURE, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:Underline", SID_ATTR_CHAR_UNDERLINE, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DBBackgroundColor", SID_ATTR_CHAR_COLOR_BACKGROUND, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:BackgroundColor", SID_BACKGROUND_COLOR, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:CharColorExt", SID_ATTR_CHAR_COLOR_EXT);
+ implDescribeSupportedFeature( ".uno:Color", SID_ATTR_CHAR_COLOR);
+ implDescribeSupportedFeature( ".uno:FontColor", SID_ATTR_CHAR_COLOR2, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:FontDialog", SID_CHAR_DLG, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:LeftPara", SID_ATTR_PARA_ADJUST_LEFT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:CenterPara", SID_ATTR_PARA_ADJUST_CENTER, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:RightPara", SID_ATTR_PARA_ADJUST_RIGHT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:JustifyPara", SID_ATTR_PARA_ADJUST_BLOCK, CommandGroup::FORMAT );
+
+ implDescribeSupportedFeature( ".uno:FontHeight", SID_ATTR_CHAR_FONTHEIGHT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:CharFontName", SID_ATTR_CHAR_FONT, CommandGroup::FORMAT );
+
+ implDescribeSupportedFeature( ".uno:ArrangeMenu", SID_ARRANGEMENU, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:BringToFront", SID_FRAME_TO_TOP, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:ObjectBackOne", SID_FRAME_DOWN, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:ObjectForwardOne", SID_FRAME_UP, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SendToBack", SID_FRAME_TO_BOTTOM, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SetObjectToForeground", SID_OBJECT_HEAVEN, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SetObjectToBackground", SID_OBJECT_HELL, CommandGroup::FORMAT );
+
+ implDescribeSupportedFeature( ".uno:ObjectAlign", SID_OBJECT_ALIGN, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:ObjectAlignLeft", SID_OBJECT_ALIGN_LEFT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:AlignCenter", SID_OBJECT_ALIGN_CENTER, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:ObjectAlignRight", SID_OBJECT_ALIGN_RIGHT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:AlignUp", SID_OBJECT_ALIGN_UP, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:AlignMiddle", SID_OBJECT_ALIGN_MIDDLE, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:AlignDown", SID_OBJECT_ALIGN_DOWN, CommandGroup::FORMAT );
+
+ implDescribeSupportedFeature( ".uno:SectionAlign", SID_SECTION_ALIGN );
+ implDescribeSupportedFeature( ".uno:SectionAlignLeft", SID_SECTION_ALIGN_LEFT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SectionAlignCenter", SID_SECTION_ALIGN_CENTER, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SectionAlignRight", SID_SECTION_ALIGN_RIGHT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SectionAlignTop", SID_SECTION_ALIGN_UP, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SectionAlignMiddle", SID_SECTION_ALIGN_MIDDLE, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SectionAlignBottom", SID_SECTION_ALIGN_DOWN, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SectionShrink", SID_SECTION_SHRINK, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SectionShrinkTop", SID_SECTION_SHRINK_TOP, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SectionShrinkBottom", SID_SECTION_SHRINK_BOTTOM, CommandGroup::FORMAT );
+
+ implDescribeSupportedFeature( ".uno:ObjectResize", SID_OBJECT_RESIZING, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SmallestWidth", SID_OBJECT_SMALLESTWIDTH, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:SmallestHeight", SID_OBJECT_SMALLESTHEIGHT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:GreatestWidth", SID_OBJECT_GREATESTWIDTH, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:GreatestHeight", SID_OBJECT_GREATESTHEIGHT, CommandGroup::FORMAT );
+
+ implDescribeSupportedFeature( ".uno:DistributeSelection", SID_DISTRIBUTE_DLG, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DistributeHorzLeft", SID_DISTRIBUTE_HLEFT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DistributeHorzCenter", SID_DISTRIBUTE_HCENTER, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DistributeHorzDistance", SID_DISTRIBUTE_HDISTANCE, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DistributeHorzRight", SID_DISTRIBUTE_HRIGHT, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DistributeVertTop", SID_DISTRIBUTE_VTOP, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DistributeVertCenter", SID_DISTRIBUTE_VCENTER, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DistributeVertDistance", SID_DISTRIBUTE_VDISTANCE, CommandGroup::FORMAT );
+ implDescribeSupportedFeature( ".uno:DistributeVertBottom", SID_DISTRIBUTE_VBOTTOM, CommandGroup::FORMAT );
+
+ implDescribeSupportedFeature( ".uno:ExportTo", SID_EXPORTDOC, CommandGroup::APPLICATION );
+ implDescribeSupportedFeature( ".uno:ExportToPDF", SID_EXPORTDOCASPDF, CommandGroup::APPLICATION );
+ implDescribeSupportedFeature( ".uno:PrintPreview", SID_PRINTPREVIEW, CommandGroup::APPLICATION );
+
+ implDescribeSupportedFeature( ".uno:NewDoc", SID_NEWDOC, CommandGroup::DOCUMENT );
+ implDescribeSupportedFeature( ".uno:Save", SID_SAVEDOC, CommandGroup::DOCUMENT );
+ implDescribeSupportedFeature( ".uno:SaveAs", SID_SAVEASDOC, CommandGroup::DOCUMENT );
+ implDescribeSupportedFeature( ".uno:SaveACopy", SID_SAVEACOPY, CommandGroup::DOCUMENT );
+
+ implDescribeSupportedFeature( ".uno:InsertPageNumberField", SID_INSERT_FLD_PGNUMBER, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:InsertDateTimeField", SID_DATETIME, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:InsertObjectChart", SID_INSERT_DIAGRAM, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:InsertGraphic", SID_INSERT_GRAPHIC, CommandGroup::INSERT );
+ // controls
+ implDescribeSupportedFeature( ".uno:SelectObject", SID_OBJECT_SELECT, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:Label", SID_FM_FIXEDTEXT, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:Edit", SID_FM_EDIT, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ImageControl", SID_FM_IMAGECONTROL, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:HFixedLine", SID_INSERT_HFIXEDLINE, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:VFixedLine", SID_INSERT_VFIXEDLINE, CommandGroup::INSERT );
+
+ // shapes
+ implDescribeSupportedFeature( ".uno:BasicShapes", SID_DRAWTBX_CS_BASIC, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.rectangle", SID_DRAWTBX_CS_BASIC1, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.round-rectangle",SID_DRAWTBX_CS_BASIC2, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.quadrat", SID_DRAWTBX_CS_BASIC3, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.round-quadrat", SID_DRAWTBX_CS_BASIC4, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.circle", SID_DRAWTBX_CS_BASIC5, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.ellipse", SID_DRAWTBX_CS_BASIC6, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.circle-pie", SID_DRAWTBX_CS_BASIC7, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.isosceles-triangle",SID_DRAWTBX_CS_BASIC8, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.right-triangle",SID_DRAWTBX_CS_BASIC9, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.trapezoid", SID_DRAWTBX_CS_BASIC10, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.diamond", SID_DRAWTBX_CS_BASIC11, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.parallelogram", SID_DRAWTBX_CS_BASIC12, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.pentagon", SID_DRAWTBX_CS_BASIC13, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.hexagon", SID_DRAWTBX_CS_BASIC14, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.octagon", SID_DRAWTBX_CS_BASIC15, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.cross", SID_DRAWTBX_CS_BASIC16, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.ring", SID_DRAWTBX_CS_BASIC17, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.block-arc", SID_DRAWTBX_CS_BASIC18, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.can", SID_DRAWTBX_CS_BASIC19, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.cube", SID_DRAWTBX_CS_BASIC20, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.paper", SID_DRAWTBX_CS_BASIC21, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:BasicShapes.frame", SID_DRAWTBX_CS_BASIC22, CommandGroup::INSERT );
+
+ implDescribeSupportedFeature( ".uno:SymbolShapes", SID_DRAWTBX_CS_SYMBOL, CommandGroup::INSERT );
+
+ implDescribeSupportedFeature( ".uno:SymbolShapes.smiley" , SID_DRAWTBX_CS_SYMBOL1, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.sun" , SID_DRAWTBX_CS_SYMBOL2, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.moon" , SID_DRAWTBX_CS_SYMBOL3, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.lightning" , SID_DRAWTBX_CS_SYMBOL4, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.heart" , SID_DRAWTBX_CS_SYMBOL5, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.flower" , SID_DRAWTBX_CS_SYMBOL6, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.cloud" , SID_DRAWTBX_CS_SYMBOL7, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.forbidden" , SID_DRAWTBX_CS_SYMBOL8, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.puzzle" , SID_DRAWTBX_CS_SYMBOL9, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.bracket-pair" ,SID_DRAWTBX_CS_SYMBOL10, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.left-bracket" ,SID_DRAWTBX_CS_SYMBOL11, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.right-bracket",SID_DRAWTBX_CS_SYMBOL12, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.brace-pair" , SID_DRAWTBX_CS_SYMBOL13, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.left-brace" , SID_DRAWTBX_CS_SYMBOL14, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.right-brace" , SID_DRAWTBX_CS_SYMBOL15, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.quad-bevel" , SID_DRAWTBX_CS_SYMBOL16, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.octagon-bevel",SID_DRAWTBX_CS_SYMBOL17, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:SymbolShapes.diamond-bevel",SID_DRAWTBX_CS_SYMBOL18, CommandGroup::INSERT );
+
+ implDescribeSupportedFeature( ".uno:ArrowShapes.left-arrow" , SID_DRAWTBX_CS_ARROW1, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.right-arrow" , SID_DRAWTBX_CS_ARROW2, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.up-arrow" , SID_DRAWTBX_CS_ARROW3, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.down-arrow" , SID_DRAWTBX_CS_ARROW4, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.left-right-arrow" , SID_DRAWTBX_CS_ARROW5, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.up-down-arrow" , SID_DRAWTBX_CS_ARROW6, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.up-right-arrow" , SID_DRAWTBX_CS_ARROW7, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.up-right-down-arrow" , SID_DRAWTBX_CS_ARROW8, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.quad-arrow" , SID_DRAWTBX_CS_ARROW9, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.corner-right-arrow" , SID_DRAWTBX_CS_ARROW10, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.split-arrow" , SID_DRAWTBX_CS_ARROW11, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.striped-right-arrow" , SID_DRAWTBX_CS_ARROW12, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.notched-right-arrow" , SID_DRAWTBX_CS_ARROW13, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.pentagon-right" , SID_DRAWTBX_CS_ARROW14, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.chevron" , SID_DRAWTBX_CS_ARROW15, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.right-arrow-callout" , SID_DRAWTBX_CS_ARROW16, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.left-arrow-callout" , SID_DRAWTBX_CS_ARROW17, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.up-arrow-callout" , SID_DRAWTBX_CS_ARROW18, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.down-arrow-callout" , SID_DRAWTBX_CS_ARROW19, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.left-right-arrow-callout",SID_DRAWTBX_CS_ARROW20, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.up-down-arrow-callout" ,SID_DRAWTBX_CS_ARROW21, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.up-right-arrow-callout",SID_DRAWTBX_CS_ARROW22, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.quad-arrow-callout" , SID_DRAWTBX_CS_ARROW23, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.circular-arrow" , SID_DRAWTBX_CS_ARROW24, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.split-round-arrow" , SID_DRAWTBX_CS_ARROW25, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:ArrowShapes.s-sharped-arrow" , SID_DRAWTBX_CS_ARROW26, CommandGroup::INSERT );
+
+ implDescribeSupportedFeature( ".uno:StarShapes.bang" , SID_DRAWTBX_CS_STAR1, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.star4" , SID_DRAWTBX_CS_STAR2, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.star5" , SID_DRAWTBX_CS_STAR3, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.star6" , SID_DRAWTBX_CS_STAR4, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.star8" , SID_DRAWTBX_CS_STAR5, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.star12" , SID_DRAWTBX_CS_STAR6, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.star24" , SID_DRAWTBX_CS_STAR7, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.concave-star6" , SID_DRAWTBX_CS_STAR8, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.vertical-scroll" , SID_DRAWTBX_CS_STAR9, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.horizontal-scroll" , SID_DRAWTBX_CS_STAR10, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.signet" , SID_DRAWTBX_CS_STAR11, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes.doorplate" , SID_DRAWTBX_CS_STAR12, CommandGroup::INSERT );
+
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-process" , SID_DRAWTBX_CS_FLOWCHART1, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-alternate-process" , SID_DRAWTBX_CS_FLOWCHART2, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-decision" , SID_DRAWTBX_CS_FLOWCHART3, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-data" , SID_DRAWTBX_CS_FLOWCHART4, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-predefined-process" , SID_DRAWTBX_CS_FLOWCHART5, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-internal-storage" , SID_DRAWTBX_CS_FLOWCHART6, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-document" , SID_DRAWTBX_CS_FLOWCHART7, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-multidocument" , SID_DRAWTBX_CS_FLOWCHART8, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-terminator" , SID_DRAWTBX_CS_FLOWCHART9, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-preparation" , SID_DRAWTBX_CS_FLOWCHART10, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-manual-input" , SID_DRAWTBX_CS_FLOWCHART11, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-manual-operation" , SID_DRAWTBX_CS_FLOWCHART12, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-connector" , SID_DRAWTBX_CS_FLOWCHART13, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-off-page-connector" , SID_DRAWTBX_CS_FLOWCHART14, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-card" , SID_DRAWTBX_CS_FLOWCHART15, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-punched-tape" , SID_DRAWTBX_CS_FLOWCHART16, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-summing-junction" , SID_DRAWTBX_CS_FLOWCHART17, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-or" , SID_DRAWTBX_CS_FLOWCHART18, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-collate" , SID_DRAWTBX_CS_FLOWCHART19, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-sort" , SID_DRAWTBX_CS_FLOWCHART20, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-extract" , SID_DRAWTBX_CS_FLOWCHART21, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-merge" , SID_DRAWTBX_CS_FLOWCHART22, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-stored-data" , SID_DRAWTBX_CS_FLOWCHART23, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-delay" , SID_DRAWTBX_CS_FLOWCHART24, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-sequential-access" , SID_DRAWTBX_CS_FLOWCHART25, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-magnetic-disk" , SID_DRAWTBX_CS_FLOWCHART26, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-direct-access-storage",SID_DRAWTBX_CS_FLOWCHART27, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-display" , SID_DRAWTBX_CS_FLOWCHART28, CommandGroup::INSERT );
+
+ implDescribeSupportedFeature( ".uno:CalloutShapes.rectangular-callout" , SID_DRAWTBX_CS_CALLOUT1, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:CalloutShapes.round-rectangular-callout" , SID_DRAWTBX_CS_CALLOUT2, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:CalloutShapes.round-callout" , SID_DRAWTBX_CS_CALLOUT3, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:CalloutShapes.cloud-callout" , SID_DRAWTBX_CS_CALLOUT4, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:CalloutShapes.line-callout-1" , SID_DRAWTBX_CS_CALLOUT5, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:CalloutShapes.line-callout-2" , SID_DRAWTBX_CS_CALLOUT6, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:CalloutShapes.line-callout-3" , SID_DRAWTBX_CS_CALLOUT7, CommandGroup::INSERT );
+
+ implDescribeSupportedFeature( ".uno:ArrowShapes", SID_DRAWTBX_CS_ARROW, CommandGroup::INSERT );
+
+ implDescribeSupportedFeature( ".uno:FlowChartShapes", SID_DRAWTBX_CS_FLOWCHART, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:CalloutShapes", SID_DRAWTBX_CS_CALLOUT, CommandGroup::INSERT );
+ implDescribeSupportedFeature( ".uno:StarShapes", SID_DRAWTBX_CS_STAR, CommandGroup::INSERT );
+
+
+ // keys
+ implDescribeSupportedFeature( ".uno:Escape", SID_ESCAPE);
+
+ // internal one
+ implDescribeSupportedFeature( ".uno:RPT_RPTHEADER_UNDO", SID_REPORTHEADER_WITHOUT_UNDO);
+ implDescribeSupportedFeature( ".uno:RPT_RPTFOOTER_UNDO", SID_REPORTFOOTER_WITHOUT_UNDO);
+ implDescribeSupportedFeature( ".uno:RPT_PGHEADER_UNDO", SID_PAGEHEADER_WITHOUT_UNDO);
+ implDescribeSupportedFeature( ".uno:RPT_PGFOOTER_UNDO", SID_PAGEFOOTER_WITHOUT_UNDO);
+ implDescribeSupportedFeature( ".uno:SID_GROUPHEADER", SID_GROUPHEADER);
+ implDescribeSupportedFeature( ".uno:SID_GROUPHEADER_WITHOUT_UNDO", SID_GROUPHEADER_WITHOUT_UNDO);
+ implDescribeSupportedFeature( ".uno:SID_GROUPFOOTER", SID_GROUPFOOTER);
+ implDescribeSupportedFeature( ".uno:SID_GROUPFOOTER_WITHOUT_UNDO", SID_GROUPFOOTER_WITHOUT_UNDO);
+ implDescribeSupportedFeature( ".uno:SID_GROUP_REMOVE", SID_GROUP_REMOVE);
+ implDescribeSupportedFeature( ".uno:SID_GROUP_APPEND", SID_GROUP_APPEND);
+ implDescribeSupportedFeature( ".uno:SID_ADD_CONTROL_PAIR", SID_ADD_CONTROL_PAIR);
+ implDescribeSupportedFeature( ".uno:SplitPosition", SID_SPLIT_POSITION);
+ implDescribeSupportedFeature( ".uno:LastPropertyBrowserPage", SID_PROPERTYBROWSER_LAST_PAGE);
+ implDescribeSupportedFeature( ".uno:Select", SID_SELECT);
+ implDescribeSupportedFeature( ".uno:InsertFunction", SID_RPT_NEW_FUNCTION);
+ implDescribeSupportedFeature( ".uno:NextMark", SID_NEXT_MARK);
+ implDescribeSupportedFeature( ".uno:PrevMark", SID_PREV_MARK);
+ implDescribeSupportedFeature( ".uno:TerminateInplaceActivation", SID_TERMINATE_INPLACEACTIVATION);
+ implDescribeSupportedFeature( ".uno:SelectAllLabels", SID_SELECT_ALL_LABELS);
+ implDescribeSupportedFeature( ".uno:SelectAllEdits", SID_SELECT_ALL_EDITS);
+ implDescribeSupportedFeature( ".uno:CollapseSection", SID_COLLAPSE_SECTION);
+ implDescribeSupportedFeature( ".uno:ExpandSection", SID_EXPAND_SECTION);
+ implDescribeSupportedFeature( ".uno:GetUndoStrings", SID_GETUNDOSTRINGS);
+ implDescribeSupportedFeature( ".uno:GetRedoStrings", SID_GETREDOSTRINGS);
+}
+
+void OReportController::impl_onModifyChanged()
+{
+ try
+ {
+ if ( m_xReportDefinition.is() )
+ m_xReportDefinition->setModified( impl_isModified() );
+ DBSubComponentController::impl_onModifyChanged();
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+void OReportController::onLoadedMenu(const Reference< frame::XLayoutManager >& _xLayoutManager)
+{
+ if ( !_xLayoutManager.is() )
+ return;
+
+ static const std::u16string_view s_sMenu[] = {
+ u"private:resource/statusbar/statusbar"
+ ,u"private:resource/toolbar/reportcontrols"
+ ,u"private:resource/toolbar/drawbar"
+ ,u"private:resource/toolbar/Formatting"
+ ,u"private:resource/toolbar/alignmentbar"
+ ,u"private:resource/toolbar/sectionalignmentbar"
+ ,u"private:resource/toolbar/resizebar"
+ ,u"private:resource/toolbar/sectionshrinkbar"
+ };
+ for (const auto & i : s_sMenu)
+ {
+ _xLayoutManager->createElement( OUString(i) );
+ _xLayoutManager->requestElement( OUString(i) );
+ }
+}
+
+void OReportController::notifyGroupSections(const ContainerEvent& _rEvent,bool _bShow)
+{
+ uno::Reference< report::XGroup> xGroup(_rEvent.Element,uno::UNO_QUERY);
+ if ( !xGroup.is() )
+ return;
+
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+ sal_Int32 nGroupPos = 0;
+ _rEvent.Accessor >>= nGroupPos;
+
+ if ( _bShow )
+ {
+ xGroup->addPropertyChangeListener(PROPERTY_HEADERON, static_cast<XPropertyChangeListener*>(this));
+ xGroup->addPropertyChangeListener(PROPERTY_FOOTERON, static_cast<XPropertyChangeListener*>(this));
+ }
+ else
+ {
+ xGroup->removePropertyChangeListener(PROPERTY_HEADERON, static_cast<XPropertyChangeListener*>(this));
+ xGroup->removePropertyChangeListener(PROPERTY_FOOTERON, static_cast<XPropertyChangeListener*>(this));
+ }
+
+ if ( xGroup->getHeaderOn() )
+ {
+ groupChange(xGroup,PROPERTY_HEADERON,nGroupPos,_bShow);
+ if (_bShow)
+ {
+ m_pReportControllerObserver->AddSection(xGroup->getHeader());
+ }
+ else
+ {
+ m_pReportControllerObserver->RemoveSection(xGroup->getHeader());
+ }
+ }
+ if ( xGroup->getFooterOn() )
+ {
+ groupChange(xGroup,PROPERTY_FOOTERON,nGroupPos,_bShow);
+ if (_bShow)
+ {
+ m_pReportControllerObserver->AddSection(xGroup->getFooter());
+ }
+ else
+ {
+ m_pReportControllerObserver->RemoveSection(xGroup->getFooter());
+ }
+ }
+}
+
+// ::container::XContainerListener
+void SAL_CALL OReportController::elementInserted( const ContainerEvent& _rEvent )
+{
+ notifyGroupSections(_rEvent,true);
+}
+
+void SAL_CALL OReportController::elementRemoved( const ContainerEvent& _rEvent )
+{
+ notifyGroupSections(_rEvent,false);
+}
+
+void SAL_CALL OReportController::elementReplaced( const ContainerEvent& /*_rEvent*/ )
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+ OSL_FAIL("Not yet implemented!");
+}
+
+void SAL_CALL OReportController::propertyChange( const beans::PropertyChangeEvent& evt )
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+ try
+ {
+ bool bShow = false;
+ evt.NewValue >>= bShow;
+ if ( evt.Source == m_xReportDefinition )
+ {
+ if ( evt.PropertyName == PROPERTY_REPORTHEADERON )
+ {
+ const sal_uInt16 nPosition = m_xReportDefinition->getPageHeaderOn() ? 1 : 0;
+ if ( bShow )
+ {
+ getDesignView()->addSection(m_xReportDefinition->getReportHeader(),DBREPORTHEADER,nPosition);
+ m_pReportControllerObserver->AddSection(m_xReportDefinition->getReportHeader());
+ }
+ else
+ {
+ getDesignView()->removeSection(nPosition);
+ }
+ }
+ else if ( evt.PropertyName == PROPERTY_REPORTFOOTERON )
+ {
+ sal_uInt16 nPosition = getDesignView()->getSectionCount();
+ if ( m_xReportDefinition->getPageFooterOn() )
+ --nPosition;
+ if ( bShow )
+ {
+ getDesignView()->addSection(m_xReportDefinition->getReportFooter(),DBREPORTFOOTER,nPosition);
+ m_pReportControllerObserver->AddSection(m_xReportDefinition->getReportFooter());
+ }
+ else
+ {
+ getDesignView()->removeSection(nPosition - 1);
+ }
+ }
+ else if ( evt.PropertyName == PROPERTY_PAGEHEADERON )
+ {
+ if ( bShow )
+ {
+ getDesignView()->addSection(m_xReportDefinition->getPageHeader(),DBPAGEHEADER,0);
+ m_pReportControllerObserver->AddSection(m_xReportDefinition->getPageHeader());
+ }
+ else
+ {
+ getDesignView()->removeSection(sal_uInt16(0));
+ }
+ }
+ else if ( evt.PropertyName == PROPERTY_PAGEFOOTERON )
+ {
+ if ( bShow )
+ {
+ getDesignView()->addSection(m_xReportDefinition->getPageFooter(),DBPAGEFOOTER);
+ m_pReportControllerObserver->AddSection(m_xReportDefinition->getPageFooter());
+ }
+ else
+ {
+ getDesignView()->removeSection(getDesignView()->getSectionCount() - 1);
+ }
+ }
+ else if ( evt.PropertyName == PROPERTY_COMMAND
+ || evt.PropertyName == PROPERTY_COMMANDTYPE
+ || evt.PropertyName == PROPERTY_ESCAPEPROCESSING
+ || evt.PropertyName == PROPERTY_FILTER
+ )
+ {
+ m_xColumns.clear();
+ m_xHoldAlive.clear();
+ InvalidateFeature(SID_FM_ADD_FIELD);
+ if ( !getDesignView()->isAddFieldVisible() && isUiVisible() )
+ getDesignView()->toggleAddField();
+ }
+ /// TODO: check what we need to notify here TitleHelper
+ /*else if ( evt.PropertyName.equals( PROPERTY_CAPTION ) )
+ updateTitle();*/
+ }
+ else
+ {
+ uno::Reference< report::XGroup> xGroup(evt.Source,uno::UNO_QUERY);
+ if ( xGroup.is() )
+ {
+ sal_Int32 nGroupPos = getGroupPosition(xGroup);
+
+ groupChange(xGroup,evt.PropertyName,nGroupPos,bShow);
+ }
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+
+void SAL_CALL OReportController::disposing( const lang::EventObject& Source )
+{
+ // simply disambiguate
+ OReportController_BASE::disposing(Source);
+}
+
+
+static sal_uInt16 lcl_getNonVisibleGroupsBefore( const uno::Reference< report::XGroups>& _xGroups
+ ,sal_Int32 _nGroupPos
+ ,::std::function<bool(OGroupHelper *)> const & _pGroupMemberFunction)
+{
+ uno::Reference< report::XGroup> xGroup;
+ sal_uInt16 nNonVisibleGroups = 0;
+ sal_Int32 nCount = _xGroups->getCount();
+ for( sal_Int32 i = 0; i < _nGroupPos && i < nCount; ++i)
+ {
+ xGroup.set(_xGroups->getByIndex(i),uno::UNO_QUERY);
+ OSL_ENSURE(xGroup.is(),"Group is NULL! -> GPF");
+ OGroupHelper aGroupHelper(xGroup);
+ if ( !_pGroupMemberFunction(&aGroupHelper) )
+ ++nNonVisibleGroups;
+ }
+ return nNonVisibleGroups;
+}
+
+void OReportController::groupChange( const uno::Reference< report::XGroup>& _xGroup,std::u16string_view _sPropName,sal_Int32 _nGroupPos,bool _bShow)
+{
+ ::std::function<bool(OGroupHelper *)> pMemFun = ::std::mem_fn(&OGroupHelper::getHeaderOn);
+ ::std::function<uno::Reference<report::XSection>(OGroupHelper *)> pMemFunSection = ::std::mem_fn(&OGroupHelper::getHeader);
+ OUString sColor(DBGROUPHEADER);
+ sal_uInt16 nPosition = 0;
+ bool bHandle = false;
+ if ( _sPropName == PROPERTY_HEADERON )
+ {
+ nPosition = m_xReportDefinition->getPageHeaderOn() ? (m_xReportDefinition->getReportHeaderOn() ? 2 : 1) : (m_xReportDefinition->getReportHeaderOn() ? 1 : 0);
+ nPosition += (static_cast<sal_uInt16>(_nGroupPos) - lcl_getNonVisibleGroupsBefore(m_xReportDefinition->getGroups(),_nGroupPos,pMemFun));
+ bHandle = true;
+ }
+ else if ( _sPropName == PROPERTY_FOOTERON )
+ {
+ pMemFun = ::std::mem_fn(&OGroupHelper::getFooterOn);
+ pMemFunSection = ::std::mem_fn(&OGroupHelper::getFooter);
+ nPosition = getDesignView()->getSectionCount();
+
+ if ( m_xReportDefinition->getPageFooterOn() )
+ --nPosition;
+ if ( m_xReportDefinition->getReportFooterOn() )
+ --nPosition;
+ sColor = DBGROUPFOOTER;
+ nPosition -= (static_cast<sal_uInt16>(_nGroupPos) - lcl_getNonVisibleGroupsBefore(m_xReportDefinition->getGroups(),_nGroupPos,pMemFun));
+ if ( !_bShow )
+ --nPosition;
+ bHandle = true;
+ }
+ if ( bHandle )
+ {
+ if ( _bShow )
+ {
+ OGroupHelper aGroupHelper(_xGroup);
+ getDesignView()->addSection(pMemFunSection(&aGroupHelper),sColor,nPosition);
+ }
+ else
+ {
+ getDesignView()->removeSection(nPosition);
+ }
+ }
+}
+
+IMPL_LINK_NOARG(OReportController, OnClipboardChanged, TransferableDataHelper*, void)
+{
+ OnInvalidateClipboard();
+}
+
+void OReportController::OnInvalidateClipboard()
+{
+ InvalidateFeature(SID_CUT);
+ InvalidateFeature(SID_COPY);
+ InvalidateFeature(SID_PASTE);
+}
+
+void OReportController::openPageDialog(const uno::Reference<report::XSection>& _xSection)
+{
+ if ( !m_xReportDefinition.is() )
+ return;
+
+ // UNO->ItemSet
+ static SfxItemInfo aItemInfos[] =
+ {
+ { SID_ATTR_LRSPACE, true },
+ { SID_ATTR_ULSPACE, true },
+ { SID_ATTR_PAGE, true },
+ { SID_ATTR_PAGE_SIZE, true },
+ { SID_ENUM_PAGE_MODE, true },
+ { SID_PAPER_START, true },
+ { SID_PAPER_END, true },
+ { SID_ATTR_BRUSH, true },
+ { 0, true }, // XATTR_FILLSTYLE
+ { 0, true }, // XATTR_FILLCOLOR
+ { 0, true }, // XATTR_FILLGRADIENT
+ { 0, true }, // XATTR_FILLHATCH
+ { 0, true }, // XATTR_FILLBITMAP
+ { 0, true }, // XATTR_FILLTRANSPARENCE
+ { 0, true }, // XATTR_GRADIENTSTEPCOUNT
+ { 0, true }, // XATTR_FILLBMP_TILE
+ { 0, true }, // XATTR_FILLBMP_POS
+ { 0, true }, // XATTR_FILLBMP_SIZEX
+ { 0, true }, // XATTR_FILLBMP_SIZEY
+ { 0, true }, // XATTR_FILLFLOATTRANSPARENCE
+ { 0, true }, // XATTR_SECONDARYFILLCOLOR
+ { 0, true }, // XATTR_FILLBMP_SIZELOG
+ { 0, true }, // XATTR_FILLBMP_TILEOFFSETX
+ { 0, true }, // XATTR_FILLBMP_TILEOFFSETY
+ { 0, true }, // XATTR_FILLBMP_STRETCH
+ { 0, true }, // XATTR_FILLBMP_POSOFFSETX
+ { 0, true }, // XATTR_FILLBMP_POSOFFSETY
+ { 0, true }, // XATTR_FILLBACKGROUND
+ { SID_ATTR_METRIC, true }
+ };
+
+ MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
+ FieldUnit eUserMetric = MeasurementSystem::Metric == eSystem ? FieldUnit::CM : FieldUnit::INCH;
+ static const WhichRangesContainer pRanges(svl::Items<
+ RPTUI_ID_LRSPACE, XATTR_FILL_LAST,
+ SID_ATTR_METRIC,SID_ATTR_METRIC
+ >);
+ rtl::Reference<SfxItemPool> pPool( new SfxItemPool("ReportPageProperties", RPTUI_ID_LRSPACE, RPTUI_ID_METRIC, aItemInfos ) );
+
+ const Graphic aNullGraphic;
+ const ::Color aNullLineCol(COL_DEFAULT_SHAPE_STROKE); // #i121448# Use defined default color
+ const ::Color aNullFillCol(COL_DEFAULT_SHAPE_FILLING); // #i121448# Use defined default color
+ const XGradient aNullGrad(COL_BLACK, COL_WHITE);
+ const XHatch aNullHatch(aNullLineCol);
+
+ std::vector<SfxPoolItem*> pDefaults
+ {
+ new SvxLRSpaceItem(RPTUI_ID_LRSPACE),
+ new SvxULSpaceItem(RPTUI_ID_ULSPACE),
+ new SvxPageItem(RPTUI_ID_PAGE),
+ new SvxSizeItem(RPTUI_ID_SIZE),
+ new SfxUInt16Item(RPTUI_ID_PAGE_MODE,SVX_PAGE_MODE_STANDARD),
+ new SfxUInt16Item(RPTUI_ID_START,PAPER_A4),
+ new SfxUInt16Item(RPTUI_ID_END,PAPER_E),
+ new SvxBrushItem(RPTUI_ID_BRUSH),
+ new XFillStyleItem,
+ new XFillColorItem("", aNullFillCol),
+ new XFillGradientItem(aNullGrad),
+ new XFillHatchItem(aNullHatch),
+ new XFillBitmapItem(aNullGraphic),
+ new XFillTransparenceItem,
+ new XGradientStepCountItem,
+ new XFillBmpTileItem,
+ new XFillBmpPosItem,
+ new XFillBmpSizeXItem,
+ new XFillBmpSizeYItem,
+ new XFillFloatTransparenceItem(aNullGrad, false),
+ new XSecondaryFillColorItem("", aNullFillCol),
+ new XFillBmpSizeLogItem,
+ new XFillBmpTileOffsetXItem,
+ new XFillBmpTileOffsetYItem,
+ new XFillBmpStretchItem,
+ new XFillBmpPosOffsetXItem,
+ new XFillBmpPosOffsetYItem,
+ new XFillBackgroundItem,
+ new SfxUInt16Item(RPTUI_ID_METRIC,static_cast<sal_uInt16>(eUserMetric))
+ };
+
+ pPool->SetDefaults(&pDefaults);
+
+
+ pPool->SetDefaultMetric( MapUnit::Map100thMM ); // ripped, don't understand why
+ pPool->FreezeIdRanges(); // the same
+
+ try
+ {
+ SfxItemSet aDescriptor(*pPool, pRanges);
+ // fill it
+ if ( _xSection.is() )
+ aDescriptor.Put(SvxBrushItem(::Color(ColorTransparency, _xSection->getBackColor()),RPTUI_ID_BRUSH));
+ else
+ {
+ aDescriptor.Put(SvxSizeItem(RPTUI_ID_SIZE,VCLSize(getStyleProperty<awt::Size>(m_xReportDefinition,PROPERTY_PAPERSIZE))));
+ aDescriptor.Put(SvxLRSpaceItem(getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_LEFTMARGIN)
+ ,getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_RIGHTMARGIN),0,0,RPTUI_ID_LRSPACE));
+ aDescriptor.Put(SvxULSpaceItem(static_cast<sal_uInt16>(getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_TOPMARGIN))
+ ,static_cast<sal_uInt16>(getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_BOTTOMMARGIN)),RPTUI_ID_ULSPACE));
+ aDescriptor.Put(SfxUInt16Item(SID_ATTR_METRIC,static_cast<sal_uInt16>(eUserMetric)));
+
+ uno::Reference< style::XStyle> xPageStyle(getUsedStyle(m_xReportDefinition));
+ if ( xPageStyle.is() )
+ {
+ SvxPageItem aPageItem(RPTUI_ID_PAGE);
+ aPageItem.SetDescName(xPageStyle->getName());
+ uno::Reference<beans::XPropertySet> xProp(xPageStyle,uno::UNO_QUERY_THROW);
+ aPageItem.PutValue(xProp->getPropertyValue(PROPERTY_PAGESTYLELAYOUT),MID_PAGE_LAYOUT);
+ aPageItem.SetLandscape(getStyleProperty<bool>(m_xReportDefinition,PROPERTY_ISLANDSCAPE));
+ aPageItem.SetNumType(static_cast<SvxNumType>(getStyleProperty<sal_Int16>(m_xReportDefinition,PROPERTY_NUMBERINGTYPE)));
+ aDescriptor.Put(aPageItem);
+ aDescriptor.Put(SvxBrushItem(::Color(ColorTransparency, getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_BACKCOLOR)),RPTUI_ID_BRUSH));
+ }
+ }
+
+ { // want the dialog to be destroyed before our set
+ ORptPageDialog aDlg(
+ getFrameWeld(), &aDescriptor,_xSection.is()
+ ? OUString("BackgroundDialog")
+ : OUString("PageDialog"));
+ if (aDlg.run() == RET_OK)
+ {
+
+ // ItemSet->UNO
+ // UNO-properties
+ const SfxItemSet* pSet = aDlg.GetOutputItemSet();
+ if ( _xSection.is() )
+ {
+ if ( const SvxBrushItem* pBrushItem = pSet->GetItemIfSet( RPTUI_ID_BRUSH ))
+ _xSection->setBackColor(sal_Int32(pBrushItem->GetColor()));
+ }
+ else
+ {
+ uno::Reference< beans::XPropertySet> xProp(getUsedStyle(m_xReportDefinition),uno::UNO_QUERY_THROW);
+ const OUString sUndoAction(RptResId(RID_STR_UNDO_CHANGEPAGE));
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+ if ( const SvxSizeItem* pSizeItem = pSet->GetItemIfSet( RPTUI_ID_SIZE ))
+ {
+ uno::Any aValue;
+ pSizeItem->QueryValue(aValue);
+ xProp->setPropertyValue(PROPERTY_PAPERSIZE,aValue);
+ resetZoomType();
+ }
+
+ if ( const SvxLRSpaceItem* pSpaceItem = pSet->GetItemIfSet( RPTUI_ID_LRSPACE ))
+ {
+ Any aValue;
+ pSpaceItem->QueryValue(aValue,MID_L_MARGIN);
+ xProp->setPropertyValue(PROPERTY_LEFTMARGIN,aValue);
+ pSpaceItem->QueryValue(aValue,MID_R_MARGIN);
+ xProp->setPropertyValue(PROPERTY_RIGHTMARGIN,aValue);
+ }
+ if ( const SvxULSpaceItem* pSpaceItem = pSet->GetItemIfSet( RPTUI_ID_ULSPACE ))
+ {
+ xProp->setPropertyValue(PROPERTY_TOPMARGIN,uno::Any(pSpaceItem->GetUpper()));
+ xProp->setPropertyValue(PROPERTY_BOTTOMMARGIN,uno::Any(pSpaceItem->GetLower()));
+ }
+ if ( const SvxPageItem* pPageItem = pSet->GetItemIfSet( RPTUI_ID_PAGE ))
+ {
+ xProp->setPropertyValue(PROPERTY_ISLANDSCAPE,uno::Any(pPageItem->IsLandscape()));
+ xProp->setPropertyValue(PROPERTY_NUMBERINGTYPE,uno::Any(static_cast<sal_Int16>(pPageItem->GetNumType())));
+ uno::Any aValue;
+ pPageItem->QueryValue(aValue,MID_PAGE_LAYOUT);
+ xProp->setPropertyValue(PROPERTY_PAGESTYLELAYOUT,aValue);
+ resetZoomType();
+ }
+ if ( const SvxBrushItem* pBrushItem = pSet->GetItemIfSet( RPTUI_ID_BRUSH ))
+ {
+ ::Color aBackColor = pBrushItem->GetColor();
+ xProp->setPropertyValue(PROPERTY_BACKTRANSPARENT,uno::Any(aBackColor == COL_TRANSPARENT));
+ xProp->setPropertyValue(PROPERTY_BACKCOLOR,uno::Any(aBackColor));
+ }
+ }
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ pPool.clear();
+
+ for (SfxPoolItem* pDefault : pDefaults)
+ delete pDefault;
+
+}
+
+
+sal_Bool SAL_CALL OReportController::attachModel(const uno::Reference< frame::XModel > & xModel)
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+
+ uno::Reference< report::XReportDefinition > xReportDefinition( xModel, UNO_QUERY );
+ if ( !xReportDefinition.is() )
+ return false;
+
+ uno::Reference< document::XUndoManagerSupplier > xTestSuppUndo( xModel, UNO_QUERY );
+ if ( !xTestSuppUndo.is() )
+ return false;
+
+ m_xReportDefinition = xReportDefinition;
+ return true;
+}
+
+
+void OReportController::openSortingAndGroupingDialog()
+{
+ if ( !m_xReportDefinition.is() )
+ return;
+ if (!m_xGroupsFloater)
+ {
+ m_xGroupsFloater = std::make_shared<OGroupsSortingDialog>(getFrameWeld(), !isEditable(), this);
+ SvtViewOptions aDlgOpt(EViewType::Window, OStringToOUString(m_xGroupsFloater->get_help_id(), RTL_TEXTENCODING_UTF8));
+ if ( aDlgOpt.Exists() )
+ m_xGroupsFloater->getDialog()->set_window_state(OUStringToOString(aDlgOpt.GetWindowState(), RTL_TEXTENCODING_ASCII_US));
+ }
+ if (isUiVisible())
+ {
+ if (!m_xGroupsFloater->getDialog()->get_visible())
+ weld::DialogController::runAsync(m_xGroupsFloater, [this](sal_Int32 /*nResult*/) { m_xGroupsFloater.reset(); });
+ else
+ m_xGroupsFloater->response(RET_CANCEL);
+ }
+}
+
+sal_Int32 OReportController::getGroupPosition(const uno::Reference< report::XGroup >& _xGroup)
+{
+ return rptui::getPositionInIndexAccess(m_xReportDefinition->getGroups(),_xGroup);
+}
+
+
+void OReportController::Notify(SfxBroadcaster & /* _rBc */, SfxHint const & _rHint)
+{
+ const DlgEdHint* pDlgEdHint = dynamic_cast<const DlgEdHint*>(&_rHint);
+ if (!(pDlgEdHint && pDlgEdHint->GetKind() == RPTUI_HINT_SELECTIONCHANGED))
+ return;
+
+ const sal_Int32 nSelectionCount = getDesignView()->getMarkedObjectCount();
+ if ( m_nSelectionCount != nSelectionCount )
+ {
+ m_nSelectionCount = nSelectionCount;
+ InvalidateAll();
+ }
+ lang::EventObject aEvent(*this);
+ m_aSelectionListeners.forEach(
+ [&aEvent] (uno::Reference<view::XSelectionChangeListener> const& xListener) {
+ return xListener->selectionChanged(aEvent);
+ });
+}
+
+void OReportController::executeMethodWithUndo(TranslateId pUndoStrId,const ::std::function<void(ODesignView *)>& _pMemfun)
+{
+ const OUString sUndoAction = RptResId(pUndoStrId);
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+ _pMemfun( getDesignView() );
+ InvalidateFeature( SID_UNDO );
+}
+
+void OReportController::alignControlsWithUndo(TranslateId pUndoStrId, ControlModification _nControlModification, bool _bAlignAtSection)
+{
+ const OUString sUndoAction = RptResId(pUndoStrId);
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+ getDesignView()->alignMarkedObjects(_nControlModification,_bAlignAtSection);
+ InvalidateFeature( SID_UNDO );
+}
+
+void OReportController::shrinkSectionBottom(const uno::Reference<report::XSection>& _xSection)
+{
+ const sal_Int32 nElements = _xSection->getCount();
+ if (nElements == 0)
+ {
+ // there are no elements
+ return;
+ }
+ const sal_Int32 nSectionHeight = _xSection->getHeight();
+ sal_Int32 nMaxPositionY = 0;
+ uno::Reference< report::XReportComponent> xReportComponent;
+
+ // for every component get its Y-position and compare it to the current Y-position
+ for (int i=0;i<nElements;i++)
+ {
+ xReportComponent.set(_xSection->getByIndex(i), uno::UNO_QUERY);
+ const sal_Int32 nReportComponentPositionY = xReportComponent->getPositionY();
+ const sal_Int32 nReportComponentHeight = xReportComponent->getHeight();
+ const sal_Int32 nReportComponentPositionYAndHeight = nReportComponentPositionY + nReportComponentHeight;
+ nMaxPositionY = std::max(nReportComponentPositionYAndHeight, nMaxPositionY);
+ }
+ // now we know the minimal Y-Position and maximal Y-Position
+
+ if (nMaxPositionY > (nSectionHeight - 7) ) // Magic Number, we use a little bit less heights for right positioning
+ {
+ // the lowest position is already 0
+ return;
+ }
+ _xSection->setHeight(nMaxPositionY);
+}
+
+void OReportController::shrinkSectionTop(const uno::Reference<report::XSection>& _xSection)
+{
+ const sal_Int32 nElements = _xSection->getCount();
+ if (nElements == 0)
+ {
+ // there are no elements
+ return;
+ }
+
+ const sal_Int32 nSectionHeight = _xSection->getHeight();
+ sal_Int32 nMinPositionY = nSectionHeight;
+ uno::Reference< report::XReportComponent> xReportComponent;
+
+ // for every component get its Y-position and compare it to the current Y-position
+ for (int i=0;i<nElements;i++)
+ {
+ xReportComponent.set(_xSection->getByIndex(i), uno::UNO_QUERY);
+ const sal_Int32 nReportComponentPositionY = xReportComponent->getPositionY();
+ nMinPositionY = std::min(nReportComponentPositionY, nMinPositionY);
+ }
+ // now we know the minimal Y-Position and maximal Y-Position
+ if (nMinPositionY == 0)
+ {
+ // the lowest position is already 0
+ return;
+ }
+ for (int i=0;i<nElements;i++)
+ {
+ xReportComponent.set(_xSection->getByIndex(i), uno::UNO_QUERY);
+ const sal_Int32 nReportComponentPositionY = xReportComponent->getPositionY();
+ const sal_Int32 nNewPositionY = nReportComponentPositionY - nMinPositionY;
+ xReportComponent->setPositionY(nNewPositionY);
+ }
+ const sal_Int32 nNewSectionHeight = nSectionHeight - nMinPositionY;
+ _xSection->setHeight(nNewSectionHeight);
+}
+
+void OReportController::shrinkSection(TranslateId pUndoStrId, const uno::Reference<report::XSection>& _xSection, sal_Int32 _nSid)
+{
+ if ( _xSection.is() )
+ {
+ const OUString sUndoAction = RptResId(pUndoStrId);
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+
+ if (_nSid == SID_SECTION_SHRINK)
+ {
+ shrinkSectionTop(_xSection);
+ shrinkSectionBottom(_xSection);
+ }
+ else if (_nSid == SID_SECTION_SHRINK_TOP)
+ {
+ shrinkSectionTop(_xSection);
+ }
+ else if (_nSid == SID_SECTION_SHRINK_BOTTOM)
+ {
+ shrinkSectionBottom(_xSection);
+ }
+ }
+
+ InvalidateFeature( SID_UNDO );
+}
+
+
+uno::Any SAL_CALL OReportController::getViewData()
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+
+ const sal_Int32 nCommandIDs[] =
+ {
+ SID_GRID_VISIBLE,
+ SID_GRID_USE,
+ SID_HELPLINES_MOVE,
+ SID_RULER,
+ SID_SHOW_PROPERTYBROWSER,
+ SID_PROPERTYBROWSER_LAST_PAGE,
+ SID_SPLIT_POSITION
+ };
+
+ ::comphelper::NamedValueCollection aCommandProperties;
+ for (sal_Int32 nCommandID : nCommandIDs)
+ {
+ const FeatureState aFeatureState = GetState( nCommandID );
+
+ OUString sCommandURL( getURLForId( nCommandID ).Main );
+ OSL_ENSURE( sCommandURL.startsWith( ".uno:" ), "OReportController::getViewData: illegal command URL!" );
+ sCommandURL = sCommandURL.copy( 5 );
+
+ Any aCommandState;
+ if ( !!aFeatureState.bChecked )
+ aCommandState <<= *aFeatureState.bChecked;
+ else if ( aFeatureState.aValue.hasValue() )
+ aCommandState = aFeatureState.aValue;
+
+ aCommandProperties.put( sCommandURL, aCommandState );
+ }
+
+ ::comphelper::NamedValueCollection aViewData;
+ aViewData.put( "CommandProperties", aCommandProperties.getPropertyValues() );
+
+ if ( getDesignView() )
+ {
+ ::std::vector<sal_uInt16> aCollapsedPositions;
+ getDesignView()->fillCollapsedSections(aCollapsedPositions);
+ if ( !aCollapsedPositions.empty() )
+ {
+ uno::Sequence<beans::PropertyValue> aCollapsedSections(aCollapsedPositions.size());
+ beans::PropertyValue* pCollapsedIter = aCollapsedSections.getArray();
+ sal_Int32 i = 1;
+ for (const auto& rPos : aCollapsedPositions)
+ {
+ pCollapsedIter->Name = PROPERTY_SECTION + OUString::number(i);
+ pCollapsedIter->Value <<= static_cast<sal_Int32>(rPos);
+ ++pCollapsedIter;
+ ++i;
+ }
+
+ aViewData.put( "CollapsedSections", aCollapsedSections );
+ }
+
+ OSectionWindow* pSectionWindow = getDesignView()->getMarkedSection();
+ if ( pSectionWindow )
+ {
+ aViewData.put( "MarkedSection", static_cast<sal_Int32>(pSectionWindow->getReportSection().getPage()->GetPageNum()) );
+ }
+ }
+
+ aViewData.put( "ZoomFactor", m_nZoomValue );
+ return uno::Any( aViewData.getPropertyValues() );
+}
+
+void SAL_CALL OReportController::restoreViewData(const uno::Any& i_data)
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+
+ try
+ {
+ const ::comphelper::NamedValueCollection aViewData( i_data );
+
+ m_aCollapsedSections = aViewData.getOrDefault( "CollapsedSections", m_aCollapsedSections );
+ m_nPageNum = aViewData.getOrDefault( "MarkedSection", m_nPageNum );
+ m_nZoomValue = aViewData.getOrDefault( "ZoomFactor", m_nZoomValue );
+ // TODO: setting those 3 members is not enough - in theory, restoreViewData can be called when the
+ // view is fully alive, so we need to reflect those 3 values in the view.
+ // (At the moment, the method is called only during construction phase)
+
+
+ ::comphelper::NamedValueCollection aCommandProperties( aViewData.get( "CommandProperties" ) );
+ const ::std::vector< OUString > aCommandNames( aCommandProperties.getNames() );
+
+ for ( const auto& rCommandName : aCommandNames )
+ {
+ const Any& rCommandValue = aCommandProperties.get( rCommandName );
+ if ( !rCommandValue.hasValue() )
+ continue;
+
+ if ( getView() )
+ {
+ util::URL aCommand;
+ aCommand.Complete = ".uno:" + rCommandName;
+
+ executeUnChecked( aCommand, { comphelper::makePropertyValue("Value", rCommandValue) } );
+ }
+ else
+ {
+ if ( rCommandName == "ShowRuler" )
+ OSL_VERIFY( rCommandValue >>= m_bShowRuler );
+ else if ( rCommandName == "HelplinesMove" )
+ OSL_VERIFY( rCommandValue >>= m_bHelplinesMove );
+ else if ( rCommandName == "GridVisible" )
+ OSL_VERIFY( rCommandValue >>= m_bGridVisible );
+ else if ( rCommandName == "GridUse" )
+ OSL_VERIFY( rCommandValue >>= m_bGridUse );
+ else if ( rCommandName == "ControlProperties" )
+ OSL_VERIFY( rCommandValue >>= m_bShowProperties );
+ else if ( rCommandName == "LastPropertyBrowserPage" )
+ OSL_VERIFY( rCommandValue >>= m_sLastActivePage );
+ else if ( rCommandName == "SplitPosition" )
+ OSL_VERIFY( rCommandValue >>= m_nSplitPos );
+ }
+ }
+ }
+ catch(const IllegalArgumentException&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+Reference<XFrame> OReportController::getXFrame()
+{
+ if ( !m_xFrameLoader.is() )
+ {
+ m_xFrameLoader.set( frame::Desktop::create(m_xContext) );
+ }
+ const sal_Int32 nFrameSearchFlag = frame::FrameSearchFlag::TASKS | frame::FrameSearchFlag::CREATE;
+ Reference<XFrame> xFrame = m_xFrameLoader->findFrame("_blank",nFrameSearchFlag);
+ return xFrame;
+}
+
+
+uno::Reference<frame::XModel> OReportController::executeReport()
+{
+ OSL_ENSURE(m_xReportDefinition.is(),"Where is my report?");
+
+ uno::Reference<frame::XModel> xModel;
+ if ( m_xReportDefinition.is() )
+ {
+ TranslateId pErrorId = RID_ERR_NO_COMMAND;
+ bool bEnabled = !m_xReportDefinition->getCommand().isEmpty();
+ if ( bEnabled )
+ {
+ bEnabled = false;
+ const sal_uInt16 nCount = m_aReportModel->GetPageCount();
+ sal_uInt16 i = 0;
+ for (; i < nCount && !bEnabled ; ++i)
+ {
+ const SdrPage* pPage = m_aReportModel->GetPage(i);
+ bEnabled = pPage->GetObjCount() != 0;
+ }
+ if ( !bEnabled )
+ pErrorId = RID_ERR_NO_OBJECTS;
+ }
+
+ dbtools::SQLExceptionInfo aInfo;
+ if ( !bEnabled )
+ {
+ sdb::SQLContext aFirstMessage;
+ OUString sInfo = RptResId( pErrorId );
+ aFirstMessage.Message = sInfo;
+ aInfo = aFirstMessage;
+ if ( isEditable() )
+ {
+ sal_uInt16 nCommand = 0;
+ if (pErrorId != RID_ERR_NO_COMMAND)
+ {
+ if ( !m_bShowProperties )
+ executeUnChecked(SID_SHOW_PROPERTYBROWSER, {});
+
+ m_sLastActivePage = "Data";
+ getDesignView()->setCurrentPage(m_sLastActivePage);
+ nCommand = SID_SELECT_REPORT;
+ }
+ else if ( getDesignView() && !getDesignView()->isAddFieldVisible() )
+ {
+ nCommand = SID_FM_ADD_FIELD;
+ }
+ if ( nCommand )
+ {
+ executeUnChecked(nCommand, {});
+ }
+ }
+ }
+ else
+ {
+ m_bInGeneratePreview = true;
+ try
+ {
+ weld::WaitObject aWait(getFrameWeld()); // cursor
+ if ( !m_xReportEngine.is() )
+ m_xReportEngine.set( report::ReportEngine::create(m_xContext) );
+ m_xReportEngine->setReportDefinition(m_xReportDefinition);
+ m_xReportEngine->setActiveConnection(getConnection());
+ Reference<XFrame> xFrame = getXFrame();
+ xModel = m_xReportEngine->createDocumentAlive(xFrame);
+ }
+ catch(const sdbc::SQLException&)
+ { // SQLExceptions and derived exceptions must not be translated
+ aInfo = ::cppu::getCaughtException();
+ }
+ catch(const uno::Exception& e)
+ {
+ uno::Any aCaughtException( ::cppu::getCaughtException() );
+
+ // our first message says: we caught an exception
+ sdb::SQLContext aFirstMessage;
+ OUString sInfo(RptResId(RID_STR_CAUGHT_FOREIGN_EXCEPTION));
+ sInfo = sInfo.replaceAll("$type$", aCaughtException.getValueTypeName());
+ aFirstMessage.Message = sInfo;
+
+ // our second message: the message of the exception we caught
+ sdbc::SQLException aSecondMessage;
+ aSecondMessage.Message = e.Message;
+ aSecondMessage.Context = e.Context;
+
+ // maybe our third message: the message which is wrapped in the exception we caught
+ sdbc::SQLException aThirdMessage;
+ lang::WrappedTargetException aWrapped;
+ if ( aCaughtException >>= aWrapped )
+ {
+ aThirdMessage.Message = aWrapped.Message;
+ aThirdMessage.Context = aWrapped.Context;
+ }
+
+ if ( !aThirdMessage.Message.isEmpty() )
+ aSecondMessage.NextException <<= aThirdMessage;
+ aFirstMessage.NextException <<= aSecondMessage;
+
+ aInfo = aFirstMessage;
+ }
+ if (aInfo.isValid())
+ {
+ const OUString suSQLContext = RptResId( RID_STR_COULD_NOT_CREATE_REPORT );
+ aInfo.prepend(suSQLContext);
+ }
+ m_bInGeneratePreview = false;
+ }
+
+ if (aInfo.isValid())
+ {
+ showError(aInfo);
+ }
+ }
+ return xModel;
+}
+
+uno::Reference< frame::XModel > SAL_CALL OReportController::getModel()
+{
+ return m_xReportDefinition;
+}
+
+uno::Reference< sdbc::XRowSet > const & OReportController::getRowSet()
+{
+ OSL_PRECOND( m_xReportDefinition.is(), "OReportController::getRowSet: no report definition?!" );
+
+ if ( m_xRowSet.is() || !m_xReportDefinition.is() )
+ return m_xRowSet;
+
+ try
+ {
+ uno::Reference< sdbc::XRowSet > xRowSet(
+ getORB()->getServiceManager()->createInstanceWithContext("com.sun.star.sdb.RowSet", getORB()),
+ uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySet> xRowSetProp( xRowSet, uno::UNO_QUERY_THROW );
+
+ xRowSetProp->setPropertyValue( PROPERTY_ACTIVECONNECTION, uno::Any( getConnection() ) );
+ xRowSetProp->setPropertyValue( PROPERTY_APPLYFILTER, uno::Any( true ) );
+
+ auto aNoConverter = std::make_shared<AnyConverter>();
+ TPropertyNamePair aPropertyMediation;
+ aPropertyMediation.emplace( PROPERTY_COMMAND, TPropertyConverter(PROPERTY_COMMAND,aNoConverter) );
+ aPropertyMediation.emplace( PROPERTY_COMMANDTYPE, TPropertyConverter(PROPERTY_COMMANDTYPE,aNoConverter) );
+ aPropertyMediation.emplace( PROPERTY_ESCAPEPROCESSING, TPropertyConverter(PROPERTY_ESCAPEPROCESSING,aNoConverter) );
+ aPropertyMediation.emplace( PROPERTY_FILTER, TPropertyConverter(PROPERTY_FILTER,aNoConverter) );
+
+ m_xRowSetMediator = new OPropertyMediator( m_xReportDefinition, xRowSetProp, std::move(aPropertyMediation) );
+ m_xRowSet = xRowSet;
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+
+ return m_xRowSet;
+}
+
+void OReportController::insertGraphic()
+{
+ const OUString sTitle(RptResId(RID_STR_IMPORT_GRAPHIC));
+ // build some arguments for the upcoming dialog
+ try
+ {
+ uno::Reference< report::XSection> xSection = getDesignView()->getCurrentSection();
+ ::sfx2::FileDialogHelper aDialog(ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW, FileDialogFlags::Graphic, getFrameWeld());
+ aDialog.SetContext(sfx2::FileDialogHelper::ReportInsertImage);
+ aDialog.SetTitle( sTitle );
+
+ uno::Reference< ui::dialogs::XFilePickerControlAccess > xController(aDialog.GetFilePicker(), UNO_QUERY_THROW);
+ xController->setValue(ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, css::uno::Any(true));
+ xController->enableControl(ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, false/*sal_True*/);
+ xController->setValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, css::uno::Any(true) );
+
+ if ( ERRCODE_NONE == aDialog.Execute() )
+ {
+ bool bLink = true;
+ xController->getValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bLink;
+ uno::Sequence<beans::PropertyValue> aArgs( comphelper::InitPropertySequence({
+ { PROPERTY_IMAGEURL, Any(aDialog.GetPath()) },
+ { PROPERTY_PRESERVEIRI, Any(bLink) }
+ }));
+ createControl(aArgs,xSection,OUString(),SdrObjKind::ReportDesignImageControl);
+ }
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+
+sal_Bool SAL_CALL OReportController::select( const Any& aSelection )
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+ if ( !getDesignView() )
+ return true;
+
+ getDesignView()->unmarkAllObjects();
+ getDesignView()->SetMode(DlgEdMode::Select);
+
+ uno::Sequence< uno::Reference<report::XReportComponent> > aElements;
+ if ( aSelection >>= aElements )
+ {
+ if ( aElements.hasElements() )
+ getDesignView()->showProperties(uno::Reference<uno::XInterface>(aElements[0],uno::UNO_QUERY));
+ getDesignView()->setMarked(aElements, true);
+ }
+ else
+ {
+ uno::Reference<uno::XInterface> xObject(aSelection,uno::UNO_QUERY);
+ uno::Reference<report::XReportComponent> xProp(xObject,uno::UNO_QUERY);
+ if ( xProp.is() )
+ {
+ getDesignView()->showProperties(xObject);
+ aElements = { xProp };
+ getDesignView()->setMarked(aElements, true);
+ }
+ else
+ {
+ uno::Reference<report::XSection> xSection(aSelection,uno::UNO_QUERY);
+ if ( !xSection.is() && xObject.is() )
+ getDesignView()->showProperties(xObject);
+ getDesignView()->setMarked(xSection,xSection.is());
+ }
+ }
+ InvalidateAll();
+ return true;
+}
+
+Any SAL_CALL OReportController::getSelection( )
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+ Any aRet;
+ if ( getDesignView() )
+ {
+ aRet = getDesignView()->getCurrentlyShownProperty();
+ if ( !aRet.hasValue() )
+ aRet <<= getDesignView()->getCurrentSection();
+ }
+ return aRet;
+}
+
+void SAL_CALL OReportController::addSelectionChangeListener( const Reference< view::XSelectionChangeListener >& Listener )
+{
+ m_aSelectionListeners.addInterface( Listener );
+}
+
+void SAL_CALL OReportController::removeSelectionChangeListener( const Reference< view::XSelectionChangeListener >& Listener )
+{
+ m_aSelectionListeners.removeInterface( Listener );
+}
+
+void OReportController::createNewFunction(const uno::Any& _aValue)
+{
+ uno::Reference< container::XIndexContainer> xFunctions(_aValue,uno::UNO_QUERY_THROW);
+ const OUString sNewName = RptResId(RID_STR_FUNCTION);
+ uno::Reference< report::XFunction> xFunction(report::Function::create(m_xContext));
+ xFunction->setName(sNewName);
+ // the call below will also create an undo action -> listener
+ xFunctions->insertByIndex(xFunctions->getCount(),uno::Any(xFunction));
+}
+
+IMPL_LINK_NOARG( OReportController, OnExecuteReport, void*, void )
+{
+ executeReport();
+}
+
+void OReportController::createControl(const Sequence< PropertyValue >& _aArgs,const uno::Reference< report::XSection>& _xSection,const OUString& _sFunction,SdrObjKind _nObjectId)
+{
+ SequenceAsHashMap aMap(_aArgs);
+ getDesignView()->setMarked(_xSection, true);
+ OSectionWindow* pSectionWindow = getDesignView()->getMarkedSection();
+ if ( !pSectionWindow )
+ return;
+
+ OSL_ENSURE(pSectionWindow->getReportSection().getSection() == _xSection,"Invalid section after marking the correct one.");
+
+ sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_LEFTMARGIN);
+ const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_RIGHTMARGIN);
+ const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(m_xReportDefinition,PROPERTY_PAPERSIZE).Width - nRightMargin;
+ awt::Point aPos = aMap.getUnpackedValueOrDefault(PROPERTY_POSITION,awt::Point(nLeftMargin,0));
+ if ( aPos.X < nLeftMargin )
+ aPos.X = nLeftMargin;
+
+ SdrObject* pNewControl = nullptr;
+ uno::Reference< report::XReportComponent> xShapeProp;
+ if ( _nObjectId == SdrObjKind::CustomShape )
+ {
+ pNewControl = SdrObjFactory::MakeNewObject(
+ *m_aReportModel,
+ SdrInventor::ReportDesign,
+ _nObjectId);
+ xShapeProp.set(pNewControl->getUnoShape(),uno::UNO_QUERY);
+ OUString sCustomShapeType = getDesignView()->GetInsertObjString();
+ if ( sCustomShapeType.isEmpty() )
+ sCustomShapeType = "diamond";
+ OReportSection::createDefault(sCustomShapeType,pNewControl);
+ pNewControl->SetLogicRect(tools::Rectangle(3000,500,6000,3500)); // switch height and width
+ }
+ else if ( _nObjectId == SdrObjKind::OLE2 || SdrObjKind::ReportDesignSubReport == _nObjectId )
+ {
+ pNewControl = SdrObjFactory::MakeNewObject(
+ *m_aReportModel,
+ SdrInventor::ReportDesign,
+ _nObjectId);
+
+ pNewControl->SetLogicRect(tools::Rectangle(3000,500,8000,5500)); // switch height and width
+ xShapeProp.set(pNewControl->getUnoShape(),uno::UNO_QUERY_THROW);
+ OOle2Obj* pObj = dynamic_cast<OOle2Obj*>(pNewControl);
+ if ( pObj && !pObj->IsEmpty() )
+ {
+ pObj->initializeChart(getModel());
+ }
+ }
+ else
+ {
+ std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pLabel;
+ std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pControl;
+
+ FmFormView::createControlLabelPair(
+ getDesignView()->GetOutDev(),
+ nLeftMargin,
+ 0,
+ nullptr,
+ nullptr,
+ _nObjectId,
+ SdrInventor::ReportDesign,
+ SdrObjKind::ReportDesignFixedText,
+
+ // tdf#118963 Need a SdrModel for SdrObject creation. Dereferencing
+ // m_aReportModel seems pretty safe, it's done in other places, initialized
+ // in impl_initialize and throws a RuntimeException if not existing.
+ *m_aReportModel,
+
+ pLabel,
+ pControl);
+
+ pLabel.reset();
+
+ pNewControl = pControl.release();
+ OUnoObject* pObj = dynamic_cast<OUnoObject*>(pNewControl);
+ assert(pObj);
+ if(pObj)
+ {
+ uno::Reference<beans::XPropertySet> xUnoProp(pObj->GetUnoControlModel(),uno::UNO_QUERY);
+ xShapeProp.set(pObj->getUnoShape(),uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySetInfo> xShapeInfo = xShapeProp->getPropertySetInfo();
+ uno::Reference<beans::XPropertySetInfo> xInfo = xUnoProp->getPropertySetInfo();
+
+ const OUString sProps[] = { OUString(PROPERTY_NAME)
+ ,OUString(PROPERTY_FONTDESCRIPTOR)
+ ,OUString(PROPERTY_FONTDESCRIPTORASIAN)
+ ,OUString(PROPERTY_FONTDESCRIPTORCOMPLEX)
+ ,OUString(PROPERTY_ORIENTATION)
+ ,OUString(PROPERTY_BORDER)
+ ,OUString(PROPERTY_FORMATSSUPPLIER)
+ ,OUString(PROPERTY_BACKGROUNDCOLOR)
+ };
+ for(const auto & sProp : sProps)
+ {
+ if ( xInfo->hasPropertyByName(sProp) && xShapeInfo->hasPropertyByName(sProp) )
+ xUnoProp->setPropertyValue(sProp,xShapeProp->getPropertyValue(sProp));
+ }
+
+ if ( xInfo->hasPropertyByName(PROPERTY_BORDER) && xShapeInfo->hasPropertyByName(PROPERTY_CONTROLBORDER) )
+ xUnoProp->setPropertyValue(PROPERTY_BORDER,xShapeProp->getPropertyValue(PROPERTY_CONTROLBORDER));
+
+
+ if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) && !_sFunction.isEmpty() )
+ {
+ ReportFormula aFunctionFormula( ReportFormula::Expression, _sFunction );
+ xUnoProp->setPropertyValue( PROPERTY_DATAFIELD, uno::Any( aFunctionFormula.getCompleteFormula() ) );
+ }
+
+ sal_Int32 nFormatKey = aMap.getUnpackedValueOrDefault(PROPERTY_FORMATKEY,sal_Int32(0));
+ if ( nFormatKey && xInfo->hasPropertyByName(PROPERTY_FORMATKEY) )
+ xUnoProp->setPropertyValue( PROPERTY_FORMATKEY, uno::Any( nFormatKey ) );
+
+ OUString sUrl = aMap.getUnpackedValueOrDefault(PROPERTY_IMAGEURL,OUString());
+ if ( !sUrl.isEmpty() && xInfo->hasPropertyByName(PROPERTY_IMAGEURL) )
+ xUnoProp->setPropertyValue( PROPERTY_IMAGEURL, uno::Any( sUrl ) );
+
+ pObj->CreateMediator(true);
+
+ if ( _nObjectId == SdrObjKind::ReportDesignFixedText ) // special case for fixed text
+ xUnoProp->setPropertyValue(PROPERTY_LABEL,uno::Any(OUnoObject::GetDefaultName(pObj)));
+ else if ( _nObjectId == SdrObjKind::ReportDesignVerticalFixedLine )
+ {
+ awt::Size aOlSize = xShapeProp->getSize();
+ xShapeProp->setSize(awt::Size(aOlSize.Height,aOlSize.Width)); // switch height and width
+ }
+ }
+ }
+
+ const sal_Int32 nShapeWidth = aMap.getUnpackedValueOrDefault(PROPERTY_WIDTH,xShapeProp->getWidth());
+ if ( nShapeWidth != xShapeProp->getWidth() )
+ xShapeProp->setWidth( nShapeWidth );
+
+ const bool bChangedPos = (aPos.X + nShapeWidth) > nPaperWidth;
+ if ( bChangedPos )
+ aPos.X = nPaperWidth - nShapeWidth;
+ xShapeProp->setPosition(aPos);
+
+ correctOverlapping(pNewControl,pSectionWindow->getReportSection());
+}
+
+void OReportController::createDateTime(const Sequence< PropertyValue >& _aArgs)
+{
+ getDesignView()->unmarkAllObjects();
+
+ const OUString sUndoAction(RptResId(RID_STR_UNDO_INSERT_CONTROL));
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+
+ SequenceAsHashMap aMap(_aArgs);
+ aMap.createItemIfMissing(PROPERTY_FORMATKEY,aMap.getUnpackedValueOrDefault(PROPERTY_FORMATKEYDATE,sal_Int32(0)));
+
+ uno::Reference< report::XSection> xSection = aMap.getUnpackedValueOrDefault(PROPERTY_SECTION,uno::Reference< report::XSection>());
+ OUString sFunction;
+
+ bool bDate = aMap.getUnpackedValueOrDefault(PROPERTY_DATE_STATE, false);
+ if ( bDate )
+ {
+ sFunction = "TODAY()";
+ createControl(aMap.getAsConstPropertyValueList(),xSection,sFunction);
+ }
+ bool bTime = aMap.getUnpackedValueOrDefault(PROPERTY_TIME_STATE, false);
+ if ( bTime )
+ {
+ sFunction = "TIMEVALUE(NOW())";
+ aMap[PROPERTY_FORMATKEY] <<= aMap.getUnpackedValueOrDefault(PROPERTY_FORMATKEYTIME,sal_Int32(0));
+ createControl(aMap.getAsConstPropertyValueList(),xSection,sFunction);
+ }
+}
+
+void OReportController::createPageNumber(const Sequence< PropertyValue >& _aArgs)
+{
+ getDesignView()->unmarkAllObjects();
+
+ const OUString sUndoAction(RptResId(RID_STR_UNDO_INSERT_CONTROL));
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+
+ if ( !m_xReportDefinition->getPageHeaderOn() )
+ {
+ uno::Sequence< beans::PropertyValue > aArgs;
+ executeChecked(SID_PAGEHEADERFOOTER,aArgs);
+ }
+
+ SequenceAsHashMap aMap(_aArgs);
+ bool bStateOfPage = aMap.getUnpackedValueOrDefault(PROPERTY_STATE, false);
+
+ OUString sFunction( RptResId(STR_RPT_PN_PAGE) );
+ sFunction = sFunction.replaceFirst("#PAGENUMBER#", "PageNumber()");
+
+ if ( bStateOfPage )
+ {
+ sFunction += RptResId(STR_RPT_PN_PAGE_OF);
+ sFunction = sFunction.replaceFirst("#PAGECOUNT#", "PageCount()");
+ }
+
+ bool bInPageHeader = aMap.getUnpackedValueOrDefault(PROPERTY_PAGEHEADERON, true);
+ createControl(_aArgs,bInPageHeader ? m_xReportDefinition->getPageHeader() : m_xReportDefinition->getPageFooter(),sFunction);
+}
+
+
+void OReportController::addPairControls(const Sequence< PropertyValue >& aArgs)
+{
+ getDesignView()->unmarkAllObjects();
+
+ // the FormatKey determines which field is required
+ OSectionWindow* pSectionWindow[2];
+ pSectionWindow[0] = getDesignView()->getMarkedSection();
+
+ if ( !pSectionWindow[0] )
+ {
+ select(uno::Any(m_xReportDefinition->getDetail()));
+ pSectionWindow[0] = getDesignView()->getMarkedSection();
+ if ( !pSectionWindow[0] )
+ return;
+ }
+
+ uno::Reference<report::XSection> xCurrentSection = getDesignView()->getCurrentSection();
+ UndoContext aUndoContext(getUndoManager(), RptResId(RID_STR_UNDO_INSERT_CONTROL));
+
+ try
+ {
+ bool bHandleOnlyOne = false;
+ for(const PropertyValue& rArg : aArgs)
+ {
+ if (bHandleOnlyOne)
+ break;
+ Sequence< PropertyValue > aValue;
+ if ( !(rArg.Value >>= aValue) )
+ { // the sequence has only one element which already contains the descriptor
+ bHandleOnlyOne = true;
+ aValue = aArgs;
+ }
+ svx::ODataAccessDescriptor aDescriptor(aValue);
+ SequenceAsHashMap aMap(aValue);
+ uno::Reference<report::XSection> xSection = aMap.getUnpackedValueOrDefault("Section",xCurrentSection);
+ uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
+
+ getDesignView()->setMarked(xSection, true);
+ pSectionWindow[0] = getDesignView()->getMarkedSection();
+
+ sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_LEFTMARGIN);
+ awt::Point aPos = aMap.getUnpackedValueOrDefault(PROPERTY_POSITION,awt::Point(nLeftMargin,0));
+ if ( aPos.X < nLeftMargin )
+ aPos.X = nLeftMargin;
+
+ // LLA: new feature, add the Label in dependency of the given DND_ACTION one section up, normal or one section down
+ sal_Int8 nDNDAction = aMap.getUnpackedValueOrDefault("DNDAction", sal_Int8(0));
+ pSectionWindow[1] = pSectionWindow[0];
+ bool bLabelAboveTextField = nDNDAction == DND_ACTION_COPY;
+ if ( bLabelAboveTextField || nDNDAction == DND_ACTION_LINK )
+ {
+ // Add the Label one Section up
+ pSectionWindow[1] = getDesignView()->getMarkedSection(bLabelAboveTextField ? PREVIOUS : POST);
+ if (!pSectionWindow[1])
+ {
+ // maybe out of bounds
+ pSectionWindow[1] = pSectionWindow[0];
+ }
+ }
+ // clear all selections
+ getDesignView()->unmarkAllObjects();
+
+ uno::Reference< beans::XPropertySet > xField( aDescriptor[ svx::DataAccessDescriptorProperty::ColumnObject ], uno::UNO_QUERY );
+ uno::Reference< lang::XComponent > xHoldAlive;
+ if ( !xField.is() )
+ {
+ OUString sCommand;
+ OUString sColumnName;
+ sal_Int32 nCommandType( -1 );
+ OSL_VERIFY( aDescriptor[ svx::DataAccessDescriptorProperty::Command ] >>= sCommand );
+ OSL_VERIFY( aDescriptor[ svx::DataAccessDescriptorProperty::ColumnName ] >>= sColumnName );
+ OSL_VERIFY( aDescriptor[ svx::DataAccessDescriptorProperty::CommandType ] >>= nCommandType );
+
+ uno::Reference< container::XNameAccess > xColumns;
+ uno::Reference< sdbc::XConnection > xConnection( getConnection() );
+ if ( !sCommand.isEmpty() && nCommandType != -1 && !sColumnName.isEmpty() && xConnection.is() )
+ {
+ if ( xReportDefinition->getCommand().isEmpty() )
+ {
+ xReportDefinition->setCommand(sCommand);
+ xReportDefinition->setCommandType(nCommandType);
+ }
+
+ xColumns = dbtools::getFieldsByCommandDescriptor(xConnection,nCommandType,sCommand,xHoldAlive);
+ if ( xColumns.is() && xColumns->hasByName(sColumnName) )
+ xField.set( xColumns->getByName( sColumnName ), uno::UNO_QUERY );
+ }
+
+ if ( !xField.is() )
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ try
+ {
+ uno::Reference< beans::XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
+ OUString sRowSetCommand;
+ sal_Int32 nRowSetCommandType( -1 );
+ OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_COMMAND ) >>= sRowSetCommand );
+ OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nRowSetCommandType );
+ OSL_ENSURE( ( sRowSetCommand == sCommand ) && ( nCommandType == nRowSetCommandType ),
+ "OReportController::addPairControls: this only works for a data source which equals our current settings!" );
+ // if this asserts, then either our row set and our report definition are not in sync, or somebody
+ // requested the creation of a control/pair for another data source than what our report
+ // definition is bound to - which is not supported for the parameters case, since we
+ // can retrieve parameters from the RowSet only.
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ #endif
+
+ // no column name - perhaps a parameter name?
+ uno::Reference< sdb::XParametersSupplier > xSuppParam( getRowSet(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xParams( xSuppParam->getParameters(), uno::UNO_SET_THROW );
+ sal_Int32 nParamCount( xParams->getCount() );
+ for ( sal_Int32 i=0; i<nParamCount; ++i)
+ {
+ uno::Reference< beans::XPropertySet > xParamCol( xParams->getByIndex(i), uno::UNO_QUERY_THROW );
+ OUString sParamName;
+ OSL_VERIFY( xParamCol->getPropertyValue("Name") >>= sParamName );
+ if ( sParamName == sColumnName )
+ {
+ xField = xParamCol;
+ break;
+ }
+ }
+ }
+ }
+ if ( !xField.is() )
+ continue;
+
+ SdrObjKind nOBJID = SdrObjKind::NONE;
+ sal_Int32 nDataType = sdbc::DataType::BINARY;
+ xField->getPropertyValue(PROPERTY_TYPE) >>= nDataType;
+ switch ( nDataType )
+ {
+ case sdbc::DataType::BINARY:
+ case sdbc::DataType::VARBINARY:
+ case sdbc::DataType::LONGVARBINARY:
+ nOBJID = SdrObjKind::ReportDesignImageControl;
+ break;
+ default:
+ nOBJID = SdrObjKind::ReportDesignFormattedField;
+ break;
+ }
+
+ if ( nOBJID == SdrObjKind::NONE )
+ continue;
+
+ Reference< util::XNumberFormatsSupplier > xSupplier = getReportNumberFormatter()->getNumberFormatsSupplier();
+ if ( !xSupplier.is() )
+ continue;
+
+ Reference< XNumberFormats > xNumberFormats(xSupplier->getNumberFormats());
+ std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pControl[2];
+ const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_RIGHTMARGIN);
+ const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(m_xReportDefinition,PROPERTY_PAPERSIZE).Width - nRightMargin;
+ OSectionView* pSectionViews[2];
+ pSectionViews[0] = &pSectionWindow[1]->getReportSection().getSectionView();
+ pSectionViews[1] = &pSectionWindow[0]->getReportSection().getSectionView();
+
+ // find this in svx
+ FmFormView::createControlLabelPair(
+ getDesignView()->GetOutDev(),
+ nLeftMargin,
+ 0,
+ xField,
+ xNumberFormats,
+ nOBJID,
+ SdrInventor::ReportDesign,
+ SdrObjKind::ReportDesignFixedText,
+
+ // tdf#118963 Need a SdrModel for SdrObject creation. Dereferencing
+ // m_aReportModel seems pretty safe, it's done in other places, initialized
+ // in impl_initialize and throws a RuntimeException if not existing.
+ *m_aReportModel,
+
+ pControl[0],
+ pControl[1]);
+
+ if ( pControl[0] && pControl[1] )
+ {
+ SdrPageView* pPgViews[2];
+ pPgViews[0] = pSectionViews[0]->GetSdrPageView();
+ pPgViews[1] = pSectionViews[1]->GetSdrPageView();
+ if ( pPgViews[0] && pPgViews[1] )
+ {
+ OUString sDefaultName;
+ size_t i = 0;
+ OUnoObject* pObjs[2];
+ for(i = 0; i < SAL_N_ELEMENTS(pControl); ++i)
+ {
+ pObjs[i] = dynamic_cast<OUnoObject*>(pControl[i].get());
+ assert(pObjs[i]);
+ uno::Reference<beans::XPropertySet> xUnoProp(pObjs[i]->GetUnoControlModel(),uno::UNO_QUERY_THROW);
+ uno::Reference< report::XReportComponent> xShapeProp(pObjs[i]->getUnoShape(),uno::UNO_QUERY_THROW);
+ xUnoProp->setPropertyValue(PROPERTY_NAME,xShapeProp->getPropertyValue(PROPERTY_NAME));
+
+ uno::Reference<beans::XPropertySetInfo> xShapeInfo = xShapeProp->getPropertySetInfo();
+ uno::Reference<beans::XPropertySetInfo> xInfo = xUnoProp->getPropertySetInfo();
+ const OUString sProps[] = { OUString(PROPERTY_FONTDESCRIPTOR)
+ ,OUString(PROPERTY_FONTDESCRIPTORASIAN)
+ ,OUString(PROPERTY_FONTDESCRIPTORCOMPLEX)
+ ,OUString(PROPERTY_BORDER)
+ ,OUString(PROPERTY_BACKGROUNDCOLOR)
+ };
+ for(const auto & sProp : sProps)
+ {
+ if ( xInfo->hasPropertyByName(sProp) && xShapeInfo->hasPropertyByName(sProp) )
+ xUnoProp->setPropertyValue(sProp,xShapeProp->getPropertyValue(sProp));
+ }
+ if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) )
+ {
+ OUString sName;
+ xUnoProp->getPropertyValue(PROPERTY_DATAFIELD) >>= sName;
+ sDefaultName = sName;
+ xUnoProp->setPropertyValue(PROPERTY_NAME,uno::Any(sDefaultName));
+
+ ReportFormula aFormula( ReportFormula::Field, sName );
+ xUnoProp->setPropertyValue( PROPERTY_DATAFIELD, uno::Any( aFormula.getCompleteFormula() ) );
+ }
+
+ if ( xInfo->hasPropertyByName(PROPERTY_BORDER) && xShapeInfo->hasPropertyByName(PROPERTY_CONTROLBORDER) )
+ xUnoProp->setPropertyValue(PROPERTY_BORDER,xShapeProp->getPropertyValue(PROPERTY_CONTROLBORDER));
+
+ pObjs[i]->CreateMediator(true);
+
+ const sal_Int32 nShapeWidth = xShapeProp->getWidth();
+ const bool bChangedPos = (aPos.X + nShapeWidth) > nPaperWidth;
+ if ( bChangedPos )
+ aPos.X = nPaperWidth - nShapeWidth;
+ xShapeProp->setPosition(aPos);
+ if ( bChangedPos )
+ aPos.Y += xShapeProp->getHeight();
+ aPos.X += nShapeWidth;
+ }
+ OUString sLabel;
+ if ( xField->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) )
+ xField->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
+
+ if (pSectionViews[0] != pSectionViews[1] &&
+ nOBJID == SdrObjKind::ReportDesignFormattedField) // we want this nice feature only at FORMATTEDFIELD
+ {
+ uno::Reference< report::XReportComponent> xShapePropLabel(pObjs[0]->getUnoShape(),uno::UNO_QUERY_THROW);
+ uno::Reference< report::XReportComponent> xShapePropTextField(pObjs[1]->getUnoShape(),uno::UNO_QUERY_THROW);
+ if ( !sLabel.isEmpty() )
+ xShapePropTextField->setName(sLabel);
+ awt::Point aPosLabel = xShapePropLabel->getPosition();
+ awt::Point aPosTextField = xShapePropTextField->getPosition();
+ aPosTextField.X = aPosLabel.X;
+ xShapePropTextField->setPosition(aPosTextField);
+ if (bLabelAboveTextField)
+ {
+ // move the label down near the splitter
+ const uno::Reference<report::XSection> xLabelSection = pSectionWindow[1]->getReportSection().getSection();
+ aPosLabel.Y = xLabelSection->getHeight() - xShapePropLabel->getHeight();
+ }
+ else
+ {
+ // move the label up to the splitter
+ aPosLabel.Y = 0;
+ }
+ xShapePropLabel->setPosition(aPosLabel);
+ }
+ OUnoObject* pObj = dynamic_cast<OUnoObject*>(pControl[0].get());
+ assert(pObj);
+ uno::Reference< report::XFixedText> xShapeProp(pObj->getUnoShape(),uno::UNO_QUERY_THROW);
+ xShapeProp->setName(xShapeProp->getName() + sDefaultName );
+
+ for(i = 0; i < SAL_N_ELEMENTS(pControl); ++i) // insert controls
+ {
+ correctOverlapping(pControl[i].get(), pSectionWindow[1-i]->getReportSection());
+ }
+
+ if (!bLabelAboveTextField )
+ {
+ if ( pSectionViews[0] == pSectionViews[1] )
+ {
+ tools::Rectangle aLabel = getRectangleFromControl(pControl[0].get());
+ tools::Rectangle aTextfield = getRectangleFromControl(pControl[1].get());
+
+ // create a Union of the given Label and Textfield
+ tools::Rectangle aLabelAndTextfield( aLabel );
+ aLabelAndTextfield.Union(aTextfield);
+
+ // check if there exists other fields and if yes, move down
+ bool bOverlapping = true;
+ bool bHasToMove = false;
+ while ( bOverlapping )
+ {
+ const SdrObject* pOverlappedObj = isOver(aLabelAndTextfield, *pSectionWindow[0]->getReportSection().getPage(), *pSectionViews[0], true, pControl, 2);
+ bOverlapping = pOverlappedObj != nullptr;
+ if ( bOverlapping )
+ {
+ const tools::Rectangle& aLogicRect = pOverlappedObj->GetLogicRect();
+ aLabelAndTextfield.Move(0,aLogicRect.Top() + aLogicRect.getHeight() - aLabelAndTextfield.Top());
+ bHasToMove = true;
+ }
+ }
+
+ if (bHasToMove)
+ {
+ // There was a move down, we need to move the Label and the Textfield down
+ aLabel.Move(0, aLabelAndTextfield.Top() - aLabel.Top());
+ aTextfield.Move(0, aLabelAndTextfield.Top() - aTextfield.Top());
+
+ uno::Reference< report::XReportComponent> xLabel(pControl[0]->getUnoShape(),uno::UNO_QUERY_THROW);
+ xLabel->setPositionY(aLabel.Top());
+
+ uno::Reference< report::XReportComponent> xTextfield(pControl[1]->getUnoShape(),uno::UNO_QUERY_THROW);
+ xTextfield->setPositionY(aTextfield.Top());
+ }
+ }
+ }
+ }
+ // not sure where the ownership of these passes too...
+ pControl[0].release();
+ pControl[1].release();
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+
+OSectionView* OReportController::getCurrentSectionView() const
+{
+ OSectionView* pSectionView = nullptr;
+ OSectionWindow* pSectionWindow = getDesignView()->getMarkedSection();
+ if ( pSectionWindow )
+ pSectionView = &pSectionWindow->getReportSection().getSectionView();
+ return pSectionView;
+}
+
+void OReportController::changeZOrder(sal_Int32 _nId)
+{
+ OSectionView* pSectionView = getCurrentSectionView();
+ if ( !pSectionView )
+ return;
+
+ switch(_nId)
+ {
+ case SID_FRAME_TO_BOTTOM:
+ pSectionView->PutMarkedToBtm();
+ break;
+ case SID_FRAME_TO_TOP:
+ pSectionView->PutMarkedToTop();
+ break;
+ case SID_FRAME_DOWN:
+ pSectionView->MovMarkedToBtm();
+ break;
+ case SID_FRAME_UP:
+ pSectionView->MovMarkedToTop();
+ break;
+
+ case SID_OBJECT_HEAVEN:
+ pSectionView->SetMarkedToLayer( RPT_LAYER_FRONT );
+ break;
+ case SID_OBJECT_HELL:
+ pSectionView->SetMarkedToLayer( RPT_LAYER_BACK );
+ break;
+ }
+}
+
+void OReportController::listen(const bool _bAdd)
+{
+ const OUString aProps [] = { OUString(PROPERTY_REPORTHEADERON),OUString(PROPERTY_REPORTFOOTERON)
+ ,OUString(PROPERTY_PAGEHEADERON),OUString(PROPERTY_PAGEFOOTERON)
+ ,OUString(PROPERTY_COMMAND), OUString(PROPERTY_COMMANDTYPE),OUString(PROPERTY_CAPTION)
+ };
+
+ void (SAL_CALL XPropertySet::*pPropertyListenerAction)( const OUString&, const uno::Reference< XPropertyChangeListener >& ) =
+ _bAdd ? &XPropertySet::addPropertyChangeListener : &XPropertySet::removePropertyChangeListener;
+
+ for (const auto & aProp : aProps)
+ (m_xReportDefinition.get()->*pPropertyListenerAction)( aProp, static_cast< XPropertyChangeListener* >( this ) );
+
+ OXUndoEnvironment& rUndoEnv = m_aReportModel->GetUndoEnv();
+ uno::Reference< XPropertyChangeListener > xUndo = &rUndoEnv;
+ const uno::Sequence< beans::Property> aSeq = m_xReportDefinition->getPropertySetInfo()->getProperties();
+ const OUString* pPropsBegin = &aProps[0];
+ const OUString* pPropsEnd = pPropsBegin + SAL_N_ELEMENTS(aProps) - 3;
+ for(const beans::Property& rProp : aSeq)
+ {
+ if ( ::std::find(pPropsBegin,pPropsEnd,rProp.Name) == pPropsEnd )
+ (m_xReportDefinition.get()->*pPropertyListenerAction)( rProp.Name, xUndo );
+ }
+
+ // Add Listeners to UndoEnvironment
+ void (OXUndoEnvironment::*pElementUndoFunction)( const uno::Reference< uno::XInterface >& ) =
+ _bAdd ? &OXUndoEnvironment::AddElement : &OXUndoEnvironment::RemoveElement;
+
+ (rUndoEnv.*pElementUndoFunction)( m_xReportDefinition->getStyleFamilies() );
+ (rUndoEnv.*pElementUndoFunction)( m_xReportDefinition->getFunctions() );
+
+ // Add Listeners to ReportControllerObserver
+ OXReportControllerObserver& rObserver = *m_pReportControllerObserver;
+
+ if ( m_xReportDefinition->getPageHeaderOn() && _bAdd )
+ {
+ getDesignView()->addSection(m_xReportDefinition->getPageHeader(),DBPAGEHEADER);
+ rObserver.AddSection(m_xReportDefinition->getPageHeader());
+ }
+ if ( m_xReportDefinition->getReportHeaderOn() && _bAdd )
+ {
+ getDesignView()->addSection(m_xReportDefinition->getReportHeader(),DBREPORTHEADER);
+ rObserver.AddSection(m_xReportDefinition->getReportHeader());
+ }
+
+ uno::Reference< report::XGroups > xGroups = m_xReportDefinition->getGroups();
+ const sal_Int32 nCount = xGroups->getCount();
+ _bAdd ? xGroups->addContainerListener(&rUndoEnv) : xGroups->removeContainerListener(&rUndoEnv);
+ _bAdd ? xGroups->addContainerListener(&rObserver) : xGroups->removeContainerListener(&rObserver);
+
+ for (sal_Int32 i=0;i<nCount ; ++i)
+ {
+ uno::Reference< report::XGroup > xGroup(xGroups->getByIndex(i),uno::UNO_QUERY);
+ (xGroup.get()->*pPropertyListenerAction)( OUString(PROPERTY_HEADERON), static_cast< XPropertyChangeListener* >( this ) );
+ (xGroup.get()->*pPropertyListenerAction)( OUString(PROPERTY_FOOTERON), static_cast< XPropertyChangeListener* >( this ) );
+
+ (rUndoEnv.*pElementUndoFunction)( xGroup );
+ (rUndoEnv.*pElementUndoFunction)( xGroup->getFunctions() );
+ if ( xGroup->getHeaderOn() && _bAdd )
+ {
+ getDesignView()->addSection(xGroup->getHeader(),DBGROUPHEADER);
+ rObserver.AddSection(xGroup->getHeader());
+ }
+ }
+
+ if ( _bAdd )
+ {
+ getDesignView()->addSection(m_xReportDefinition->getDetail(),DBDETAIL);
+ rObserver.AddSection(m_xReportDefinition->getDetail());
+
+ for (sal_Int32 i=nCount;i > 0 ; --i)
+ {
+ uno::Reference< report::XGroup > xGroup(xGroups->getByIndex(i-1),uno::UNO_QUERY);
+ if ( xGroup->getFooterOn() )
+ {
+ getDesignView()->addSection(xGroup->getFooter(),DBGROUPFOOTER);
+ rObserver.AddSection(xGroup->getFooter());
+ }
+ }
+ if ( m_xReportDefinition->getReportFooterOn() )
+ {
+ getDesignView()->addSection(m_xReportDefinition->getReportFooter(),DBREPORTFOOTER);
+ rObserver.AddSection(m_xReportDefinition->getReportFooter());
+ }
+ if ( m_xReportDefinition->getPageFooterOn())
+ {
+ getDesignView()->addSection(m_xReportDefinition->getPageFooter(),DBPAGEFOOTER);
+ rObserver.AddSection(m_xReportDefinition->getPageFooter());
+ }
+
+ xGroups->addContainerListener(static_cast<XContainerListener*>(this));
+ m_xReportDefinition->addModifyListener(static_cast<XModifyListener*>(this));
+ }
+ else /* ! _bAdd */
+ {
+ rObserver.RemoveSection(m_xReportDefinition->getDetail());
+ xGroups->removeContainerListener(static_cast<XContainerListener*>(this));
+ m_xReportDefinition->removeModifyListener(static_cast<XModifyListener*>(this));
+ m_aReportModel->detachController();
+ }
+}
+
+void OReportController::switchReportSection(const sal_Int16 _nId)
+{
+ OSL_ENSURE(_nId == SID_REPORTHEADER_WITHOUT_UNDO || _nId == SID_REPORTFOOTER_WITHOUT_UNDO || _nId == SID_REPORTHEADERFOOTER ,"Illegal id given!");
+
+ if ( !m_xReportDefinition.is() )
+ return;
+
+ const OXUndoEnvironment::OUndoEnvLock aLock( m_aReportModel->GetUndoEnv() );
+ const bool bSwitchOn = !m_xReportDefinition->getReportHeaderOn();
+
+ std::unique_ptr< UndoContext > pUndoContext;
+ if ( SID_REPORTHEADERFOOTER == _nId )
+ {
+ const OUString sUndoAction(RptResId(bSwitchOn ? RID_STR_UNDO_ADD_REPORTHEADERFOOTER : RID_STR_UNDO_REMOVE_REPORTHEADERFOOTER));
+ pUndoContext.reset( new UndoContext( getUndoManager(), sUndoAction ) );
+
+ addUndoAction(std::make_unique<OReportSectionUndo>(*m_aReportModel,SID_REPORTHEADER_WITHOUT_UNDO
+ ,::std::mem_fn(&OReportHelper::getReportHeader)
+ ,m_xReportDefinition
+ ,bSwitchOn ? Inserted : Removed
+ ));
+
+ addUndoAction(std::make_unique<OReportSectionUndo>(*m_aReportModel,SID_REPORTFOOTER_WITHOUT_UNDO
+ ,::std::mem_fn(&OReportHelper::getReportFooter)
+ ,m_xReportDefinition
+ ,bSwitchOn ? Inserted : Removed
+ ));
+ }
+
+ switch( _nId )
+ {
+ case SID_REPORTHEADER_WITHOUT_UNDO:
+ m_xReportDefinition->setReportHeaderOn( bSwitchOn );
+ break;
+ case SID_REPORTFOOTER_WITHOUT_UNDO:
+ m_xReportDefinition->setReportFooterOn( !m_xReportDefinition->getReportFooterOn() );
+ break;
+ case SID_REPORTHEADERFOOTER:
+ m_xReportDefinition->setReportHeaderOn( bSwitchOn );
+ m_xReportDefinition->setReportFooterOn( bSwitchOn );
+ break;
+ }
+
+ if ( SID_REPORTHEADERFOOTER == _nId )
+ pUndoContext.reset();
+ getView()->Resize();
+}
+
+void OReportController::switchPageSection(const sal_Int16 _nId)
+{
+ OSL_ENSURE(_nId == SID_PAGEHEADERFOOTER || _nId == SID_PAGEHEADER_WITHOUT_UNDO || _nId == SID_PAGEFOOTER_WITHOUT_UNDO ,"Illegal id given!");
+ if ( !m_xReportDefinition.is() )
+ return;
+
+ const OXUndoEnvironment::OUndoEnvLock aLock( m_aReportModel->GetUndoEnv() );
+ const bool bSwitchOn = !m_xReportDefinition->getPageHeaderOn();
+
+ std::unique_ptr< UndoContext > pUndoContext;
+ if ( SID_PAGEHEADERFOOTER == _nId )
+ {
+ const OUString sUndoAction(RptResId(bSwitchOn ? RID_STR_UNDO_ADD_REPORTHEADERFOOTER : RID_STR_UNDO_REMOVE_REPORTHEADERFOOTER));
+ pUndoContext.reset( new UndoContext( getUndoManager(), sUndoAction ) );
+
+ addUndoAction(std::make_unique<OReportSectionUndo>(*m_aReportModel
+ ,SID_PAGEHEADER_WITHOUT_UNDO
+ ,::std::mem_fn(&OReportHelper::getPageHeader)
+ ,m_xReportDefinition
+ ,bSwitchOn ? Inserted : Removed
+ ));
+
+ addUndoAction(std::make_unique<OReportSectionUndo>(*m_aReportModel
+ ,SID_PAGEFOOTER_WITHOUT_UNDO
+ ,::std::mem_fn(&OReportHelper::getPageFooter)
+ ,m_xReportDefinition
+ ,bSwitchOn ? Inserted : Removed
+ ));
+ }
+ switch( _nId )
+ {
+ case SID_PAGEHEADER_WITHOUT_UNDO:
+ m_xReportDefinition->setPageHeaderOn( bSwitchOn );
+ break;
+ case SID_PAGEFOOTER_WITHOUT_UNDO:
+ m_xReportDefinition->setPageFooterOn( !m_xReportDefinition->getPageFooterOn() );
+ break;
+ case SID_PAGEHEADERFOOTER:
+ m_xReportDefinition->setPageHeaderOn( bSwitchOn );
+ m_xReportDefinition->setPageFooterOn( bSwitchOn );
+ break;
+ }
+ if ( SID_PAGEHEADERFOOTER == _nId )
+ pUndoContext.reset();
+ getView()->Resize();
+}
+
+void OReportController::modifyGroup(const bool _bAppend, const Sequence< PropertyValue >& _aArgs)
+{
+ if ( !m_xReportDefinition.is() )
+ return;
+
+ try
+ {
+ const SequenceAsHashMap aMap( _aArgs );
+ uno::Reference< report::XGroup > xGroup = aMap.getUnpackedValueOrDefault( PROPERTY_GROUP, uno::Reference< report::XGroup >() );
+ if ( !xGroup.is() )
+ return;
+
+ OXUndoEnvironment& rUndoEnv = m_aReportModel->GetUndoEnv();
+ uno::Reference< report::XGroups > xGroups = m_xReportDefinition->getGroups();
+ if ( _bAppend )
+ {
+ const sal_Int32 nPos = aMap.getUnpackedValueOrDefault( PROPERTY_POSITIONY, xGroups->getCount() );
+ xGroups->insertByIndex( nPos, uno::Any( xGroup ) );
+ rUndoEnv.AddElement( xGroup->getFunctions() );
+ }
+
+ addUndoAction( std::make_unique<OGroupUndo>(
+ *m_aReportModel,
+ _bAppend ? RID_STR_UNDO_APPEND_GROUP : RID_STR_UNDO_REMOVE_GROUP,
+ _bAppend ? Inserted : Removed,
+ xGroup,
+ m_xReportDefinition
+ ) );
+
+ if ( !_bAppend )
+ {
+ rUndoEnv.RemoveElement( xGroup->getFunctions() );
+ const sal_Int32 nPos = getGroupPosition( xGroup );
+ const OXUndoEnvironment::OUndoEnvLock aLock( m_aReportModel->GetUndoEnv() );
+ xGroups->removeByIndex( nPos );
+ }
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+
+void OReportController::createGroupSection(const bool _bUndo,const bool _bHeader, const Sequence< PropertyValue >& _aArgs)
+{
+ if ( !m_xReportDefinition.is() )
+ return;
+
+ const SequenceAsHashMap aMap(_aArgs);
+ const bool bSwitchOn = aMap.getUnpackedValueOrDefault(_bHeader ? OUString(PROPERTY_HEADERON) : OUString(PROPERTY_FOOTERON), false);
+ uno::Reference< report::XGroup> xGroup = aMap.getUnpackedValueOrDefault(PROPERTY_GROUP,uno::Reference< report::XGroup>());
+ if ( !xGroup.is() )
+ return;
+
+ const OXUndoEnvironment::OUndoEnvLock aLock(m_aReportModel->GetUndoEnv());
+ if ( _bUndo )
+ addUndoAction(std::make_unique<OGroupSectionUndo>(*m_aReportModel
+ ,_bHeader ? SID_GROUPHEADER_WITHOUT_UNDO : SID_GROUPFOOTER_WITHOUT_UNDO
+ ,_bHeader ? ::std::mem_fn(&OGroupHelper::getHeader) : ::std::mem_fn(&OGroupHelper::getFooter)
+ ,xGroup
+ ,bSwitchOn ? Inserted : Removed
+ , ( _bHeader ?
+ (bSwitchOn ? RID_STR_UNDO_ADD_GROUP_HEADER : RID_STR_UNDO_REMOVE_GROUP_HEADER)
+ :(bSwitchOn ? RID_STR_UNDO_ADD_GROUP_FOOTER : RID_STR_UNDO_REMOVE_GROUP_FOOTER)
+ )
+ ));
+
+ if ( _bHeader )
+ xGroup->setHeaderOn( bSwitchOn );
+ else
+ xGroup->setFooterOn( bSwitchOn );
+}
+
+void OReportController::collapseSection(const bool _bCollapse)
+{
+ OSectionWindow *pSection = getDesignView()->getMarkedSection();
+ if ( pSection )
+ {
+ pSection->setCollapsed(_bCollapse);
+ }
+}
+
+void OReportController::markSection(const bool _bNext)
+{
+ OSectionWindow *pSection = getDesignView()->getMarkedSection();
+ if ( pSection )
+ {
+ OSectionWindow *pPrevSection = getDesignView()->getMarkedSection(_bNext ? POST : PREVIOUS);
+ if ( pPrevSection != pSection && pPrevSection )
+ select(uno::Any(pPrevSection->getReportSection().getSection()));
+ else
+ select(uno::Any(m_xReportDefinition));
+ }
+ else
+ {
+ getDesignView()->markSection(_bNext ? 0 : getDesignView()->getSectionCount() - 1);
+ pSection = getDesignView()->getMarkedSection();
+ if ( pSection )
+ select(uno::Any(pSection->getReportSection().getSection()));
+ }
+}
+
+void OReportController::createDefaultControl(const uno::Sequence< beans::PropertyValue>& _aArgs)
+{
+ uno::Reference< report::XSection > xSection = getDesignView()->getCurrentSection();
+ if ( !xSection.is() )
+ xSection = m_xReportDefinition->getDetail();
+
+ if ( !xSection.is() )
+ return;
+
+ const beans::PropertyValue* pIter = _aArgs.getConstArray();
+ const beans::PropertyValue* pEnd = pIter + _aArgs.getLength();
+ const beans::PropertyValue* pKeyModifier = ::std::find_if(pIter, pEnd,
+ [] (const beans::PropertyValue& x) -> bool {
+ return x.Name == "KeyModifier";
+ });
+ sal_Int16 nKeyModifier = 0;
+ if ( pKeyModifier == pEnd || ((pKeyModifier->Value >>= nKeyModifier) && nKeyModifier == KEY_MOD1) )
+ {
+ Sequence< PropertyValue > aCreateArgs;
+ getDesignView()->unmarkAllObjects();
+ createControl(aCreateArgs,xSection,OUString(),getDesignView()->GetInsertObj());
+ }
+}
+
+
+void OReportController::checkChartEnabled()
+{
+ if ( m_bChartEnabledAsked )
+ return;
+
+ m_bChartEnabledAsked = true;
+
+ try
+ {
+ ::utl::OConfigurationTreeRoot aConfiguration(
+ ::utl::OConfigurationTreeRoot::createWithComponentContext( m_xContext, "/org.openoffice.Office.ReportDesign" ) );
+
+ bool bChartEnabled = false;
+ static const OUStringLiteral sPropertyName( u"UserData/Chart" );
+ if ( aConfiguration.hasByHierarchicalName(sPropertyName) )
+ aConfiguration.getNodeValue( sPropertyName ) >>= bChartEnabled;
+ m_bChartEnabled = bChartEnabled;
+ }
+ catch(const Exception&)
+ {
+ }
+}
+
+
+// css.frame.XTitle
+OUString SAL_CALL OReportController::getTitle()
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+
+ uno::Reference< frame::XTitle> xTitle(m_xReportDefinition,uno::UNO_QUERY_THROW);
+
+ return xTitle->getTitle ();
+}
+
+void OReportController::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const
+{
+ _rDefault <<= sal_Int16(100);
+}
+
+// comphelper::OPropertyArrayUsageHelper
+::cppu::IPropertyArrayHelper* OReportController::createArrayHelper( ) const
+{
+ Sequence< Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+
+
+// cppu::OPropertySetHelper
+::cppu::IPropertyArrayHelper& SAL_CALL OReportController::getInfoHelper()
+{
+ return *::comphelper::OPropertyArrayUsageHelper<OReportController_BASE>::getArrayHelper();
+}
+
+void SAL_CALL OReportController::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle,const Any& _aValue)
+{
+ if ( _nHandle == PROPERTY_ID_ZOOMVALUE )
+ {
+ _aValue >>= m_nZoomValue;
+ impl_zoom_nothrow();
+ }
+}
+void SAL_CALL OReportController::setMode( const OUString& aMode )
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+ m_sMode = aMode;
+}
+OUString SAL_CALL OReportController::getMode( )
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+ return m_sMode;
+}
+css::uno::Sequence< OUString > SAL_CALL OReportController::getSupportedModes( )
+{
+ return uno::Sequence< OUString> { OUString("remote"), OUString("normal") };
+}
+sal_Bool SAL_CALL OReportController::supportsMode( const OUString& aMode )
+{
+ uno::Sequence< OUString> aModes = getSupportedModes();
+ return comphelper::findValue(aModes, aMode) != -1;
+}
+
+bool OReportController::isUiVisible() const
+{
+ return m_sMode != "remote";
+}
+
+void OReportController::impl_fillState_nothrow(const OUString& _sProperty,dbaui::FeatureState& _rState) const
+{
+ _rState.bEnabled = isEditable();
+ if ( !_rState.bEnabled )
+ return;
+
+ ::std::vector< uno::Reference< uno::XInterface > > aSelection;
+ getDesignView()->fillControlModelSelection(aSelection);
+ _rState.bEnabled = !aSelection.empty();
+ if ( !_rState.bEnabled )
+ return;
+
+ uno::Any aTemp;
+ ::std::vector< uno::Reference< uno::XInterface > >::const_iterator aIter = aSelection.begin();
+ for(; aIter != aSelection.end() && _rState.bEnabled ;++aIter)
+ {
+ uno::Reference< beans::XPropertySet> xProp(*aIter,uno::UNO_QUERY);
+ try
+ {
+ uno::Any aTemp2 = xProp->getPropertyValue(_sProperty);
+ if ( aIter == aSelection.begin() )
+ {
+ aTemp = aTemp2;
+ }
+ else if ( aTemp != aTemp2 )
+ break;
+ }
+ catch(const beans::UnknownPropertyException&)
+ {
+ _rState.bEnabled = false;
+ }
+ }
+ if ( aIter == aSelection.end() )
+ _rState.aValue = aTemp;
+}
+
+void OReportController::impl_zoom_nothrow()
+{
+ Fraction aZoom(m_nZoomValue,100);
+ setZoomFactor( aZoom, *getDesignView() );
+ getDesignView()->zoom(aZoom);
+ InvalidateFeature(SID_ATTR_ZOOM,Reference< XStatusListener >(), true);
+ InvalidateFeature(SID_ATTR_ZOOMSLIDER,Reference< XStatusListener >(), true);
+}
+
+bool OReportController::isFormatCommandEnabled(sal_uInt16 _nCommand,const uno::Reference< report::XReportControlFormat>& _xReportControlFormat)
+{
+ bool bRet = false;
+ if ( _xReportControlFormat.is() && !uno::Reference< report::XFixedLine>(_xReportControlFormat,uno::UNO_QUERY).is() ) // this command is really often called so we need a short cut here
+ {
+ try
+ {
+ const awt::FontDescriptor aFontDescriptor = _xReportControlFormat->getFontDescriptor();
+
+ switch(_nCommand)
+ {
+ case SID_ATTR_CHAR_WEIGHT:
+ bRet = awt::FontWeight::BOLD == aFontDescriptor.Weight;
+ break;
+ case SID_ATTR_CHAR_POSTURE:
+ bRet = awt::FontSlant_ITALIC == aFontDescriptor.Slant;
+ break;
+ case SID_ATTR_CHAR_UNDERLINE:
+ bRet = awt::FontUnderline::SINGLE == aFontDescriptor.Underline;
+ break;
+ default:
+ ;
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ }
+ }
+ return bRet;
+}
+
+bool OReportController::impl_setPropertyAtControls_throw(TranslateId pUndoResId,const OUString& _sProperty,const uno::Any& _aValue,const Sequence< PropertyValue >& _aArgs)
+{
+ ::std::vector< uno::Reference< uno::XInterface > > aSelection;
+ uno::Reference< awt::XWindow> xWindow;
+ lcl_getReportControlFormat( _aArgs, getDesignView(), xWindow, aSelection );
+
+ const OUString sUndoAction = RptResId( pUndoResId );
+ UndoContext aUndoContext( getUndoManager(), sUndoAction );
+
+ for (const auto& rxInterface : aSelection)
+ {
+ const uno::Reference< beans::XPropertySet > xControlModel(rxInterface,uno::UNO_QUERY);
+ if ( xControlModel.is() )
+ // tdf#117795: some elements may have not some property
+ // eg class "OFixedLine" doesn't have property "CharFontName"
+ // so in this case, instead of crashing when selecting all and changing font
+ // just display a warning
+ try
+ {
+ xControlModel->setPropertyValue(_sProperty,_aValue);
+ }
+ catch(const UnknownPropertyException&)
+ {
+ TOOLS_WARN_EXCEPTION("reportdesign", "");
+ }
+ }
+
+ return !aSelection.empty();
+}
+
+void OReportController::impl_fillCustomShapeState_nothrow(const char* _pCustomShapeType,dbaui::FeatureState& _rState) const
+{
+ _rState.bEnabled = isEditable();
+ _rState.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::CustomShape && getDesignView()->GetInsertObjString().equalsAscii(_pCustomShapeType);
+}
+
+
+OSectionWindow* OReportController::getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const
+{
+ if ( getDesignView() )
+ {
+ return getDesignView()->getSectionWindow(_xSection);
+ }
+
+ // throw NullPointerException?
+ return nullptr;
+}
+
+
+void OReportController::openZoomDialog()
+{
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+
+ static SfxItemInfo aItemInfos[] =
+ {
+ { SID_ATTR_ZOOM, true }
+ };
+ std::vector<SfxPoolItem*> pDefaults
+ {
+ new SvxZoomItem()
+ };
+ rtl::Reference<SfxItemPool> pPool( new SfxItemPool("ZoomProperties", SID_ATTR_ZOOM,SID_ATTR_ZOOM, aItemInfos, &pDefaults) );
+ pPool->SetDefaultMetric( MapUnit::Map100thMM ); // ripped, don't understand why
+ pPool->FreezeIdRanges(); // the same
+ try
+ {
+ SfxItemSetFixed<SID_ATTR_ZOOM,SID_ATTR_ZOOM> aDescriptor(*pPool);
+ // fill it
+ SvxZoomItem aZoomItem( m_eZoomType, m_nZoomValue, SID_ATTR_ZOOM );
+ aZoomItem.SetValueSet(SvxZoomEnableFlags::N100|SvxZoomEnableFlags::WHOLEPAGE|SvxZoomEnableFlags::PAGEWIDTH);
+ aDescriptor.Put(aZoomItem);
+
+ ScopedVclPtr<AbstractSvxZoomDialog> pDlg(pFact->CreateSvxZoomDialog(nullptr, aDescriptor));
+ pDlg->SetLimits( 20, 400 );
+ bool bCancel = ( RET_CANCEL == pDlg->Execute() );
+
+ if ( !bCancel )
+ {
+ const SvxZoomItem& rZoomItem = pDlg->GetOutputItemSet()->Get( SID_ATTR_ZOOM );
+ m_eZoomType = rZoomItem.GetType();
+ m_nZoomValue = rZoomItem.GetValue();
+ if ( m_eZoomType != SvxZoomType::PERCENT )
+ m_nZoomValue = getDesignView()->getZoomFactor( m_eZoomType );
+
+ impl_zoom_nothrow();
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ pPool.clear();
+
+ for (SfxPoolItem* pDefault : pDefaults)
+ delete pDefault;
+}
+
+
+// XVisualObject
+void SAL_CALL OReportController::setVisualAreaSize( ::sal_Int64 _nAspect, const awt::Size& _aSize )
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+ bool bChanged =
+ (m_aVisualAreaSize.Width != _aSize.Width ||
+ m_aVisualAreaSize.Height != _aSize.Height);
+ m_aVisualAreaSize = _aSize;
+ if( bChanged )
+ setModified( true );
+ m_nAspect = _nAspect;
+}
+
+awt::Size SAL_CALL OReportController::getVisualAreaSize( ::sal_Int64 /*nAspect*/ )
+{
+ ::osl::MutexGuard aGuard( getMutex() );
+ return m_aVisualAreaSize;
+}
+
+embed::VisualRepresentation SAL_CALL OReportController::getPreferredVisualRepresentation( ::sal_Int64 _nAspect )
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( getMutex() );
+ embed::VisualRepresentation aResult;
+ if ( !m_bInGeneratePreview )
+ {
+ m_bInGeneratePreview = true;
+ try
+ {
+ if ( !m_xReportEngine.is() )
+ m_xReportEngine.set( report::ReportEngine::create(m_xContext) );
+ const sal_Int32 nOldMaxRows = m_xReportEngine->getMaxRows();
+ m_xReportEngine->setMaxRows(MAX_ROWS_FOR_PREVIEW);
+ m_xReportEngine->setReportDefinition(m_xReportDefinition);
+ m_xReportEngine->setActiveConnection(getConnection());
+ try
+ {
+ Reference<embed::XVisualObject> xTransfer(m_xReportEngine->createDocumentModel(),UNO_QUERY);
+ if ( xTransfer.is() )
+ {
+ xTransfer->setVisualAreaSize(m_nAspect,m_aVisualAreaSize);
+ aResult = xTransfer->getPreferredVisualRepresentation( _nAspect );
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ }
+ m_xReportEngine->setMaxRows(nOldMaxRows);
+ }
+ catch(const uno::Exception&)
+ {
+ }
+ m_bInGeneratePreview = false;
+ }
+ return aResult;
+}
+
+::sal_Int32 SAL_CALL OReportController::getMapUnit( ::sal_Int64 /*nAspect*/ )
+{
+ return embed::EmbedMapUnits::ONE_100TH_MM;
+}
+
+uno::Reference< container::XNameAccess > const & OReportController::getColumns() const
+{
+ if ( !m_xColumns.is() && m_xReportDefinition.is() && !m_xReportDefinition->getCommand().isEmpty() )
+ {
+ m_xColumns = dbtools::getFieldsByCommandDescriptor(getConnection(),m_xReportDefinition->getCommandType(),m_xReportDefinition->getCommand(),m_xHoldAlive);
+ }
+ return m_xColumns;
+}
+
+OUString OReportController::getColumnLabel_throw(const OUString& i_sColumnName) const
+{
+ OUString sLabel;
+ uno::Reference< container::XNameAccess > xColumns = getColumns();
+ if ( xColumns.is() && xColumns->hasByName(i_sColumnName) )
+ {
+ uno::Reference< beans::XPropertySet> xColumn(xColumns->getByName(i_sColumnName),uno::UNO_QUERY_THROW);
+ if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) )
+ xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
+ }
+ return sLabel;
+}
+
+
+SfxUndoManager& OReportController::getUndoManager() const
+{
+ DBG_TESTSOLARMUTEX();
+ // this is expected to be called during UI actions, so the SM is assumed to be locked
+
+ std::shared_ptr< OReportModel > pReportModel( getSdrModel() );
+ ENSURE_OR_THROW( !!pReportModel, "no access to our model" );
+
+ SfxUndoManager* pUndoManager( pReportModel->GetSdrUndoManager() );
+ ENSURE_OR_THROW( pUndoManager != nullptr, "no access to our model's UndoManager" );
+
+ return *pUndoManager;
+}
+
+
+void OReportController::clearUndoManager() const
+{
+ getUndoManager().Clear();
+}
+
+
+void OReportController::addUndoAction( std::unique_ptr<SfxUndoAction> i_pAction )
+{
+ getUndoManager().AddUndoAction( std::move(i_pAction) );
+
+ InvalidateFeature( SID_UNDO );
+ InvalidateFeature( SID_REDO );
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+reportdesign_OReportController_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new OReportController(context));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/ReportControllerObserver.cxx b/reportdesign/source/ui/report/ReportControllerObserver.cxx
new file mode 100644
index 000000000..514624388
--- /dev/null
+++ b/reportdesign/source/ui/report/ReportControllerObserver.cxx
@@ -0,0 +1,342 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <map>
+
+#include <ReportControllerObserver.hxx>
+#include <ReportController.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+
+#include <FormattedFieldBeautifier.hxx>
+
+// DBG_UNHANDLED_EXCEPTION
+#include <tools/diagnose_ex.h>
+
+namespace rptui
+{
+
+ using namespace ::com::sun::star;
+
+typedef std::map<OUString, bool> AllProperties;
+typedef std::map<uno::Reference< beans::XPropertySet >, AllProperties> PropertySetInfoCache;
+
+class OXReportControllerObserverImpl
+{
+public:
+ ::std::vector< uno::Reference< container::XChild> > m_aSections;
+ ::osl::Mutex m_aMutex;
+ oslInterlockedCount m_nLocks;
+
+ explicit OXReportControllerObserverImpl();
+ OXReportControllerObserverImpl(const OXReportControllerObserverImpl&) = delete;
+ OXReportControllerObserverImpl& operator=(const OXReportControllerObserverImpl&) = delete;
+};
+
+
+ OXReportControllerObserverImpl::OXReportControllerObserverImpl()
+ :m_nLocks(0)
+ {
+ }
+
+
+ OXReportControllerObserver::OXReportControllerObserver(const OReportController& _rController)
+ :m_pImpl(new OXReportControllerObserverImpl )
+ ,m_aFormattedFieldBeautifier(_rController)
+ ,m_aFixedTextColor(_rController)
+ {
+
+ Application::AddEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) );
+ }
+
+ OXReportControllerObserver::~OXReportControllerObserver()
+ {
+ Application::RemoveEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) );
+ }
+
+
+ IMPL_LINK(OXReportControllerObserver, SettingsChanged, VclSimpleEvent&, _rEvt, void)
+ {
+ VclEventId nEvent = _rEvt.GetId();
+
+ if (nEvent != VclEventId::ApplicationDataChanged )
+ return;
+
+ DataChangedEvent* pData = static_cast<DataChangedEvent*>(static_cast<VclWindowEvent&>(_rEvt).GetData());
+ if ( !(pData && ((( pData->GetType() == DataChangedEventType::SETTINGS ) ||
+ ( pData->GetType() == DataChangedEventType::DISPLAY )) &&
+ ( pData->GetFlags() & AllSettingsFlags::STYLE ))))
+ return;
+
+ OEnvLock aLock(*this);
+
+ // send all Section Objects a 'tingle'
+ // maybe they need a change in format, color, etc
+ for (const uno::Reference<container::XChild>& xChild : m_pImpl->m_aSections)
+ {
+ if (xChild.is())
+ {
+ uno::Reference<report::XSection> xSection(xChild, uno::UNO_QUERY);
+ if (xSection.is())
+ {
+ const sal_Int32 nCount = xSection->getCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ const uno::Any aObj = xSection->getByIndex(i);
+ uno::Reference < report::XReportComponent > xReportComponent(aObj, uno::UNO_QUERY);
+ if (xReportComponent.is())
+ {
+ m_aFormattedFieldBeautifier.handle(xReportComponent);
+ m_aFixedTextColor.handle(xReportComponent);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // XEventListener
+ void SAL_CALL OXReportControllerObserver::disposing(const lang::EventObject& e)
+ {
+ // check if it's an object we have cached information about
+ uno::Reference< beans::XPropertySet > xSourceSet(e.Source, uno::UNO_QUERY);
+ if ( xSourceSet.is() )
+ {
+ uno::Reference< report::XSection> xSection(xSourceSet,uno::UNO_QUERY);
+ if ( xSection.is() )
+ RemoveSection(xSection);
+ else
+ RemoveElement(xSourceSet);
+ }
+ }
+
+ void OXReportControllerObserver::Clear()
+ {
+ OEnvLock aLock(*this);
+ m_pImpl->m_aSections.clear();
+ }
+
+ // XPropertyChangeListener
+ void SAL_CALL OXReportControllerObserver::propertyChange(const beans::PropertyChangeEvent& _rEvent)
+ {
+ osl::MutexGuard aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_nLocks != 0 )
+ return;
+
+ m_aFormattedFieldBeautifier.notifyPropertyChange(_rEvent);
+ m_aFixedTextColor.notifyPropertyChange(_rEvent);
+ }
+
+
+void OXReportControllerObserver::Lock()
+{
+ OSL_ENSURE(m_refCount,"Illegal call to dead object!");
+ osl_atomic_increment( &m_pImpl->m_nLocks );
+}
+
+void OXReportControllerObserver::UnLock()
+{
+ OSL_ENSURE(m_refCount,"Illegal call to dead object!");
+
+ osl_atomic_decrement( &m_pImpl->m_nLocks );
+}
+
+void OXReportControllerObserver::AddSection(const uno::Reference< report::XSection > & _xSection)
+{
+ OEnvLock aLock(*this);
+ try
+ {
+ uno::Reference<container::XChild> xChild = _xSection;
+ m_pImpl->m_aSections.push_back(xChild);
+ uno::Reference< uno::XInterface > xInt(_xSection);
+ AddElement(xInt);
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+
+void OXReportControllerObserver::RemoveSection(const uno::Reference< report::XSection > & _xSection)
+{
+ OEnvLock aLock(*this);
+ try
+ {
+ uno::Reference<container::XChild> xChild(_xSection);
+ m_pImpl->m_aSections.erase(::std::remove(m_pImpl->m_aSections.begin(),m_pImpl->m_aSections.end(),
+ xChild), m_pImpl->m_aSections.end());
+ uno::Reference< uno::XInterface > xInt(_xSection);
+ RemoveElement(xInt);
+ }
+ catch(uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+
+void OXReportControllerObserver::switchListening( const uno::Reference< container::XIndexAccess >& _rxContainer, bool _bStartListening )
+{
+ OSL_PRECOND( _rxContainer.is(), "OXReportControllerObserver::switchListening: invalid container!" );
+ if ( !_rxContainer.is() )
+ return;
+
+ try
+ {
+ // also handle all children of this element
+ uno::Reference< uno::XInterface > xInterface;
+ sal_Int32 nCount = _rxContainer->getCount();
+ for(sal_Int32 i = 0;i != nCount;++i)
+ {
+ xInterface.set(_rxContainer->getByIndex( i ),uno::UNO_QUERY);
+ if ( _bStartListening )
+ AddElement( xInterface );
+ else
+ RemoveElement( xInterface );
+ }
+
+ // be notified of any changes in the container elements
+ uno::Reference< container::XContainer > xSimpleContainer( _rxContainer, uno::UNO_QUERY );
+ if ( xSimpleContainer.is() )
+ {
+ if ( _bStartListening )
+ xSimpleContainer->addContainerListener( this );
+ else
+ xSimpleContainer->removeContainerListener( this );
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+
+void OXReportControllerObserver::switchListening( const uno::Reference< uno::XInterface >& _rxObject, bool _bStartListening )
+{
+ OSL_PRECOND( _rxObject.is(), "OXReportControllerObserver::switchListening: how should I listen at a NULL object?" );
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps( _rxObject, uno::UNO_QUERY );
+ if ( xProps.is() )
+ {
+ if ( _bStartListening )
+ xProps->addPropertyChangeListener( OUString(), this );
+ else
+ xProps->removePropertyChangeListener( OUString(), this );
+ }
+
+ uno::Reference< util::XModifyBroadcaster > xBroadcaster( _rxObject, uno::UNO_QUERY );
+ if ( xBroadcaster.is() )
+ {
+ if ( _bStartListening )
+ xBroadcaster->addModifyListener( this );
+ else
+ xBroadcaster->removeModifyListener( this );
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+
+void SAL_CALL OXReportControllerObserver::modified( const lang::EventObject& /*aEvent*/ )
+{
+}
+
+
+void OXReportControllerObserver::AddElement(const uno::Reference< uno::XInterface >& _rxElement )
+{
+ m_aFormattedFieldBeautifier.notifyElementInserted(_rxElement);
+ m_aFixedTextColor.notifyElementInserted(_rxElement);
+
+ // if it's a container, start listening at all elements
+ uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
+ if ( xContainer.is() )
+ switchListening( xContainer, true );
+
+ switchListening( _rxElement, true );
+}
+
+
+void OXReportControllerObserver::RemoveElement(const uno::Reference< uno::XInterface >& _rxElement)
+{
+ switchListening( _rxElement, false );
+
+ uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY );
+ if ( xContainer.is() )
+ switchListening( xContainer, false );
+}
+
+
+// XContainerListener
+
+void SAL_CALL OXReportControllerObserver::elementInserted(const container::ContainerEvent& evt)
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
+
+ // new listener object
+ uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
+ if ( xIface.is() )
+ {
+ AddElement(xIface);
+ }
+}
+
+
+void SAL_CALL OXReportControllerObserver::elementReplaced(const container::ContainerEvent& evt)
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
+
+ uno::Reference< uno::XInterface > xIface(evt.ReplacedElement,uno::UNO_QUERY);
+ OSL_ENSURE(xIface.is(), "OXReportControllerObserver::elementReplaced: invalid container notification!");
+ RemoveElement(xIface);
+
+ xIface.set(evt.Element,uno::UNO_QUERY);
+ AddElement(xIface);
+}
+
+
+void SAL_CALL OXReportControllerObserver::elementRemoved(const container::ContainerEvent& evt)
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( m_pImpl->m_aMutex );
+
+ uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY );
+ if ( xIface.is() )
+ {
+ RemoveElement(xIface);
+ }
+}
+
+
+} // namespace rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/ReportSection.cxx b/reportdesign/source/ui/report/ReportSection.cxx
new file mode 100644
index 000000000..95d063c1d
--- /dev/null
+++ b/reportdesign/source/ui/report/ReportSection.cxx
@@ -0,0 +1,805 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <memory>
+#include <ReportSection.hxx>
+#include <ReportWindow.hxx>
+#include <DesignView.hxx>
+#include <strings.hxx>
+#include <RptObject.hxx>
+#include <RptModel.hxx>
+#include <SectionView.hxx>
+#include <RptPage.hxx>
+#include <ReportController.hxx>
+#include <UITools.hxx>
+#include <ViewsWindow.hxx>
+
+#include <svx/svdpagv.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <svx/gallery.hxx>
+#include <svx/svxids.hrc>
+#include <svx/svditer.hxx>
+#include <svx/dbaexchange.hxx>
+#include <svx/sdtagitm.hxx>
+
+#include <com/sun/star/awt/PopupMenuDirection.hpp>
+#include <com/sun/star/frame/XPopupMenuController.hpp>
+#include <comphelper/propertyvalue.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <tools/diagnose_ex.h>
+#include <RptDef.hxx>
+#include <SectionWindow.hxx>
+#include <helpids.h>
+#include <dlgedclip.hxx>
+#include <rptui_slotid.hrc>
+
+#include <vcl/commandevent.hxx>
+#include <o3tl/safeint.hxx>
+
+#include <svl/itempool.hxx>
+#include <svtools/extcolorcfg.hxx>
+
+
+namespace rptui
+{
+
+using namespace ::com::sun::star;
+
+
+static Color lcl_getOverlappedControlColor(/*const uno::Reference <lang::XMultiServiceFactory> _rxFactory*/)
+{
+ svtools::ExtendedColorConfig aConfig;
+ return aConfig.GetColorValue(CFG_REPORTDESIGNER, DBOVERLAPPEDCONTROL).getColor();
+}
+
+OReportSection::OReportSection(OSectionWindow* _pParent,const uno::Reference< report::XSection >& _xSection)
+ : Window(_pParent,WB_DIALOGCONTROL)
+ , ::comphelper::OPropertyChangeListener(m_aMutex)
+ , DropTargetHelper(this)
+ , m_pPage(nullptr)
+ , m_pView(nullptr)
+ , m_pParent(_pParent)
+ , m_xSection(_xSection)
+ , m_nPaintEntranceCount(0)
+ , m_eMode(DlgEdMode::Select)
+{
+ //EnableChildTransparentMode();
+ SetHelpId(HID_REPORTSECTION);
+ SetMapMode(MapMode(MapUnit::Map100thMM));
+ SetParentClipMode(ParentClipMode::Clip);
+ EnableChildTransparentMode( false );
+ SetPaintTransparent( false );
+
+ try
+ {
+ fill();
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "");
+ }
+
+ m_pFunc.reset(new DlgEdFuncSelect( this ));
+ m_pFunc->setOverlappedControlColor(lcl_getOverlappedControlColor() );
+}
+
+OReportSection::~OReportSection()
+{
+ disposeOnce();
+}
+
+void OReportSection::dispose()
+{
+ m_pPage = nullptr;
+ if ( m_pMulti.is() )
+ m_pMulti->dispose();
+ m_pMulti.clear();
+
+ if ( m_pReportListener.is() )
+ m_pReportListener->dispose();
+ m_pReportListener.clear();
+ m_pFunc.reset();
+
+ {
+ if ( m_pView )
+ m_pView->EndListening( *m_pModel );
+ delete m_pView;
+ m_pView = nullptr;
+ }
+ m_pParent.clear();
+ vcl::Window::dispose();
+}
+
+void OReportSection::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect )
+{
+ Window::Paint(rRenderContext, rRect);
+
+ if ( !(m_pView && m_nPaintEntranceCount == 0))
+ return;
+
+ ++m_nPaintEntranceCount;
+ // repaint, get PageView and prepare Region
+ SdrPageView* pPgView = m_pView->GetSdrPageView();
+ const vcl::Region aPaintRectRegion(rRect);
+
+ // #i74769#
+ SdrPaintWindow* pTargetPaintWindow = nullptr;
+
+ // mark repaint start
+ if (pPgView)
+ {
+ pTargetPaintWindow = pPgView->GetView().BeginDrawLayers(GetOutDev(), aPaintRectRegion);
+ OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
+ // draw background self using wallpaper
+ OutputDevice& rTargetOutDev = pTargetPaintWindow->GetTargetOutputDevice();
+ rTargetOutDev.DrawWallpaper(rRect, Wallpaper(pPgView->GetApplicationDocumentColor()));
+
+ // do paint (unbuffered) and mark repaint end
+ pPgView->DrawLayer(RPT_LAYER_FRONT, &rRenderContext);
+ pPgView->GetView().EndDrawLayers(*pTargetPaintWindow, true);
+ }
+
+ m_pView->CompleteRedraw(&rRenderContext, aPaintRectRegion);
+ --m_nPaintEntranceCount;
+}
+
+void OReportSection::fill()
+{
+ if ( !m_xSection.is() )
+ return;
+
+ m_pMulti = new comphelper::OPropertyChangeMultiplexer(this,m_xSection);
+ m_pMulti->addProperty(PROPERTY_BACKCOLOR);
+
+ m_pReportListener = addStyleListener(m_xSection->getReportDefinition(),this);
+
+ m_pModel = m_pParent->getViewsWindow()->getView()->getReportView()->getController().getSdrModel();
+ m_pPage = m_pModel->getPage(m_xSection);
+
+ m_pView = new OSectionView(
+ *m_pModel,
+ this,
+ m_pParent->getViewsWindow()->getView());
+
+ // #i93597# tell SdrPage that only left and right page border is defined
+ // instead of the full rectangle definition
+ m_pPage->setPageBorderOnlyLeftRight(true);
+
+ // without the following call, no grid is painted
+ m_pView->ShowSdrPage( m_pPage );
+
+ m_pView->SetMoveSnapOnlyTopLeft( true );
+ ODesignView* pDesignView = m_pParent->getViewsWindow()->getView()->getReportView();
+
+ // #i93595# Adapted grid to a more coarse grid and subdivisions for better visualisation. This
+ // is only for visualisation and has nothing to do with the actual snap
+ const Size aGridSizeCoarse(pDesignView->getGridSizeCoarse());
+ const Size aGridSizeFine(pDesignView->getGridSizeFine());
+ m_pView->SetGridCoarse(aGridSizeCoarse);
+ m_pView->SetGridFine(aGridSizeFine);
+
+ // #i93595# set snap grid width to snap to all existing subdivisions
+ const Fraction aX(aGridSizeFine.Width());
+ const Fraction aY(aGridSizeFine.Height());
+ m_pView->SetSnapGridWidth(aX, aY);
+
+ m_pView->SetGridSnap( true );
+ m_pView->SetGridFront( false );
+ m_pView->SetDragStripes( true );
+ m_pView->SetPageVisible();
+ sal_Int32 nColor = m_xSection->getBackColor();
+ if ( nColor == static_cast<sal_Int32>(COL_TRANSPARENT) )
+ nColor = getStyleProperty<sal_Int32>(m_xSection->getReportDefinition(),PROPERTY_BACKCOLOR);
+ m_pView->SetApplicationDocumentColor(Color(ColorTransparency, nColor));
+
+ uno::Reference<report::XReportDefinition> xReportDefinition = m_xSection->getReportDefinition();
+ const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN);
+ const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN);
+ m_pPage->SetLeftBorder(nLeftMargin);
+ m_pPage->SetRightBorder(nRightMargin);
+
+// LLA: TODO
+// m_pPage->SetUpperBorder(-10000);
+
+ m_pView->SetDesignMode();
+
+ m_pPage->SetSize( Size( getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width,5*m_xSection->getHeight()) );
+ const Size aPageSize = m_pPage->GetSize();
+ m_pView->SetWorkArea( tools::Rectangle( Point( nLeftMargin, 0), Size(aPageSize.Width() - nLeftMargin - nRightMargin,aPageSize.Height()) ) );
+}
+
+void OReportSection::Paste(const uno::Sequence< beans::NamedValue >& _aAllreadyCopiedObjects,bool _bForce)
+{
+ OSL_ENSURE(m_xSection.is(),"Why is the section here NULL!");
+ if ( !(m_xSection.is() && _aAllreadyCopiedObjects.hasElements()) )
+ return;
+
+ // stop all drawing actions
+ m_pView->BrkAction();
+
+ // unmark all objects
+ m_pView->UnmarkAll();
+ const OUString sSectionName = m_xSection->getName();
+ for(const beans::NamedValue& rObject : _aAllreadyCopiedObjects)
+ {
+ if ( _bForce || rObject.Name == sSectionName)
+ {
+ try
+ {
+ uno::Sequence< uno::Reference<report::XReportComponent> > aCopies;
+ rObject.Value >>= aCopies;
+ for (const uno::Reference<report::XReportComponent>& rCopy : std::as_const(aCopies))
+ {
+ SdrObject* pObject = SdrObject::getSdrObjectFromXShape( rCopy );
+ if ( pObject )
+ {
+ // Clone to target SdrModel
+ SdrObject* pNewObj(pObject->CloneSdrObject(*m_pModel));
+ m_pPage->InsertObject(pNewObj, SAL_MAX_SIZE);
+ tools::Rectangle aRet(VCLPoint(rCopy->getPosition()),VCLSize(rCopy->getSize()));
+ aRet.setHeight(aRet.getHeight() + 1);
+ aRet.setWidth(aRet.getWidth() + 1);
+ bool bOverlapping = true;
+ while ( bOverlapping )
+ {
+ bOverlapping = isOver(aRet,*m_pPage,*m_pView,true,pNewObj) != nullptr;
+ if ( bOverlapping )
+ {
+ aRet.Move(0,aRet.getHeight()+1);
+ pNewObj->SetLogicRect(aRet);
+ }
+ }
+ m_pView->AddUndo( m_pView->GetModel()->GetSdrUndoFactory().CreateUndoNewObject( *pNewObj ) );
+ m_pView->MarkObj( pNewObj, m_pView->GetSdrPageView() );
+ if ( m_xSection.is() && (o3tl::make_unsigned(aRet.getHeight() + aRet.Top()) > m_xSection->getHeight()) )
+ m_xSection->setHeight(aRet.getHeight() + aRet.Top());
+ }
+ }
+ }
+ catch(uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while pasting a new object!");
+ }
+ if ( !_bForce )
+ break;
+ }
+ }
+}
+
+void OReportSection::Delete()
+{
+ if( !m_pView->AreObjectsMarked() )
+ return;
+
+ m_pView->BrkAction();
+ m_pView->DeleteMarked();
+}
+
+void OReportSection::SetMode( DlgEdMode eNewMode )
+{
+ if ( eNewMode == m_eMode )
+ return;
+
+ if ( eNewMode == DlgEdMode::Insert )
+ {
+ m_pFunc.reset(new DlgEdFuncInsert( this ));
+ }
+ else
+ {
+ m_pFunc.reset(new DlgEdFuncSelect( this ));
+ }
+ m_pFunc->setOverlappedControlColor(lcl_getOverlappedControlColor( ) );
+ m_pModel->SetReadOnly(false);
+ m_eMode = eNewMode;
+}
+
+void OReportSection::Copy(uno::Sequence< beans::NamedValue >& _rAllreadyCopiedObjects)
+{
+ Copy(_rAllreadyCopiedObjects,false);
+}
+
+void OReportSection::Copy(uno::Sequence< beans::NamedValue >& _rAllreadyCopiedObjects,bool _bEraseAnddNoClone)
+{
+ OSL_ENSURE(m_xSection.is(),"Why is the section here NULL!");
+ if( !m_pView->AreObjectsMarked() || !m_xSection.is() )
+ return;
+
+ // insert control models of marked objects into clipboard dialog model
+ const SdrMarkList& rMarkedList = m_pView->GetMarkedObjectList();
+ const size_t nMark = rMarkedList.GetMarkCount();
+
+ ::std::vector< uno::Reference<report::XReportComponent> > aCopies;
+ aCopies.reserve(nMark);
+
+ SdrUndoFactory& rUndo = m_pView->GetModel()->GetSdrUndoFactory();
+
+ for( size_t i = nMark; i > 0; )
+ {
+ --i;
+ SdrObject* pSdrObject = rMarkedList.GetMark(i)->GetMarkedSdrObj();
+ OObjectBase* pObj = dynamic_cast<OObjectBase*>(pSdrObject);
+ if ( pObj )
+ {
+ try
+ {
+ SdrObject* pNewObj(pSdrObject->CloneSdrObject(pSdrObject->getSdrModelFromSdrObject()));
+ aCopies.emplace_back(pNewObj->getUnoShape(),uno::UNO_QUERY);
+ if ( _bEraseAnddNoClone )
+ {
+ m_pView->AddUndo( rUndo.CreateUndoDeleteObject( *pSdrObject ) );
+ m_pPage->RemoveObject(pSdrObject->GetOrdNum());
+ }
+
+ }
+ catch(uno::Exception&)
+ {
+ OSL_FAIL("Can't copy report elements!");
+ }
+ }
+ }
+
+ if ( !aCopies.empty() )
+ {
+ ::std::reverse(aCopies.begin(),aCopies.end());
+ const sal_Int32 nLength = _rAllreadyCopiedObjects.getLength();
+ _rAllreadyCopiedObjects.realloc( nLength + 1);
+ beans::NamedValue* pNewValue = _rAllreadyCopiedObjects.getArray() + nLength;
+ pNewValue->Name = m_xSection->getName();
+ pNewValue->Value <<= uno::Sequence< uno::Reference<report::XReportComponent> >(&(*aCopies.begin()),aCopies.size());
+ }
+}
+
+void OReportSection::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ m_pParent->getViewsWindow()->getView()->setMarked(m_pView, true); // mark the section in which is clicked
+ m_pFunc->MouseButtonDown( rMEvt );
+ Window::MouseButtonDown(rMEvt);
+}
+
+void OReportSection::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( !m_pFunc->MouseButtonUp( rMEvt ) )
+ m_pParent->getViewsWindow()->getView()->getReportView()->getController().executeUnChecked(SID_OBJECT_SELECT,uno::Sequence< beans::PropertyValue>());
+}
+
+
+void OReportSection::MouseMove( const MouseEvent& rMEvt )
+{
+ m_pFunc->MouseMove( rMEvt );
+
+}
+
+void OReportSection::SetGridVisible(bool _bVisible)
+{
+ m_pView->SetGridVisible( _bVisible );
+}
+
+void OReportSection::SelectAll(const SdrObjKind _nObjectType)
+{
+ if ( !m_pView )
+ return;
+
+ if ( _nObjectType == SdrObjKind::NONE )
+ m_pView->MarkAllObj();
+ else
+ {
+ m_pView->UnmarkAll();
+ SdrObjListIter aIter(m_pPage,SdrIterMode::DeepNoGroups);
+ SdrObject* pObjIter = nullptr;
+ while( (pObjIter = aIter.Next()) != nullptr )
+ {
+ if ( pObjIter->GetObjIdentifier() == _nObjectType )
+ m_pView->MarkObj( pObjIter, m_pView->GetSdrPageView() );
+ }
+ }
+}
+
+void OReportSection::Command( const CommandEvent& _rCEvt )
+{
+ Window::Command(_rCEvt);
+ if (_rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return;
+
+ OReportController& rController = m_pParent->getViewsWindow()->getView()->getReportView()->getController();
+ uno::Reference<frame::XFrame> xFrame = rController.getFrame();
+ css::uno::Sequence<css::uno::Any> aArgs {
+ css::uno::Any(comphelper::makePropertyValue("Value", OUString("report"))),
+ css::uno::Any(comphelper::makePropertyValue("Frame", xFrame)),
+ css::uno::Any(comphelper::makePropertyValue("IsContextMenu", true))
+ };
+
+ css::uno::Reference<css::uno::XComponentContext> xContext(rController.getORB());
+ css::uno::Reference<css::frame::XPopupMenuController> xMenuController(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext), css::uno::UNO_QUERY);
+
+ if (!xMenuController.is())
+ return;
+
+ css::uno::Reference<css::awt::XPopupMenu> xPopupMenu(
+ xContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.awt.PopupMenu", xContext), css::uno::UNO_QUERY);
+
+ if (!xPopupMenu.is())
+ return;
+
+ xMenuController->setPopupMenu(xPopupMenu);
+
+ Point aPos = _rCEvt.GetMousePosPixel();
+ m_pView->EndAction();
+
+ xPopupMenu->execute(GetComponentInterface(),
+ css::awt::Rectangle(aPos.X(), aPos.Y(), 1, 1),
+ css::awt::PopupMenuDirection::EXECUTE_DOWN);
+
+ css::uno::Reference<css::lang::XComponent> xComponent(xMenuController, css::uno::UNO_QUERY);
+ xComponent->dispose();
+}
+
+void OReportSection::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
+{
+ if ( !m_xSection.is() )
+ return;
+
+ if ( _rEvent.Source == m_xSection || PROPERTY_BACKCOLOR == _rEvent.PropertyName )
+ {
+ sal_Int32 nColor = m_xSection->getBackColor();
+ if ( nColor == static_cast<sal_Int32>(COL_TRANSPARENT) )
+ nColor = getStyleProperty<sal_Int32>(m_xSection->getReportDefinition(),PROPERTY_BACKCOLOR);
+ m_pView->SetApplicationDocumentColor(Color(ColorTransparency, nColor));
+ Invalidate(InvalidateFlags::NoChildren|InvalidateFlags::NoErase);
+ }
+ else
+ {
+ uno::Reference<report::XReportDefinition> xReportDefinition = m_xSection->getReportDefinition();
+ const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN);
+ const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN);
+ const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width;
+
+ if ( _rEvent.PropertyName == PROPERTY_LEFTMARGIN )
+ {
+ m_pPage->SetLeftBorder(nLeftMargin);
+ }
+ else if ( _rEvent.PropertyName == PROPERTY_RIGHTMARGIN )
+ {
+ m_pPage->SetRightBorder(nRightMargin);
+ }
+ const Size aOldPageSize = m_pPage->GetSize();
+ sal_Int32 nNewHeight = 5*m_xSection->getHeight();
+ if ( aOldPageSize.Height() != nNewHeight || nPaperWidth != aOldPageSize.Width() )
+ {
+ m_pPage->SetSize( Size( nPaperWidth,nNewHeight) );
+ const Size aPageSize = m_pPage->GetSize();
+ m_pView->SetWorkArea( tools::Rectangle( Point( nLeftMargin, 0), Size(aPageSize.Width() - nLeftMargin - nRightMargin,aPageSize.Height()) ) );
+ }
+ impl_adjustObjectSizePosition(nPaperWidth,nLeftMargin,nRightMargin);
+ m_pParent->Invalidate(InvalidateFlags::Update | InvalidateFlags::Transparent);
+ }
+}
+void OReportSection::impl_adjustObjectSizePosition(sal_Int32 i_nPaperWidth,sal_Int32 i_nLeftMargin,sal_Int32 i_nRightMargin)
+{
+ try
+ {
+ sal_Int32 nRightBorder = i_nPaperWidth - i_nRightMargin;
+ const sal_Int32 nCount = m_xSection->getCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference< report::XReportComponent> xReportComponent(m_xSection->getByIndex(i),uno::UNO_QUERY_THROW);
+ awt::Point aPos = xReportComponent->getPosition();
+ awt::Size aSize = xReportComponent->getSize();
+ SdrObject* pObject = SdrObject::getSdrObjectFromXShape( xReportComponent );
+ if ( pObject )
+ {
+ bool bChanged = false;
+
+ OObjectBase& rBase = dynamic_cast<OObjectBase&>(*pObject);
+ rBase.EndListening();
+ if ( aPos.X < i_nLeftMargin )
+ {
+ aPos.X = i_nLeftMargin;
+ bChanged = true;
+ }
+ if ( (aPos.X + aSize.Width) > nRightBorder )
+ {
+ aPos.X = nRightBorder - aSize.Width;
+ if ( aPos.X < i_nLeftMargin )
+ {
+ aSize.Width += aPos.X - i_nLeftMargin;
+ aPos.X = i_nLeftMargin;
+ // add listener around
+ rBase.StartListening();
+ xReportComponent->setSize(aSize);
+ rBase.EndListening();
+ }
+ bChanged = true;
+ }
+ if ( aPos.Y < 0 )
+ aPos.Y = 0;
+ if ( bChanged )
+ {
+ xReportComponent->setPosition(aPos);
+ correctOverlapping(pObject,*this,false);
+ tools::Rectangle aRet(VCLPoint(xReportComponent->getPosition()),VCLSize(xReportComponent->getSize()));
+ aRet.setHeight(aRet.getHeight() + 1);
+ aRet.setWidth(aRet.getWidth() + 1);
+ if ( m_xSection.is() && (o3tl::make_unsigned(aRet.getHeight() + aRet.Top()) > m_xSection->getHeight()) )
+ m_xSection->setHeight(aRet.getHeight() + aRet.Top());
+
+ pObject->RecalcBoundRect();
+ }
+ rBase.StartListening();
+ }
+ }
+ }
+ catch(const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "OReportSection::impl_adjustObjectSizePosition()");
+ }
+}
+
+bool OReportSection::handleKeyEvent(const KeyEvent& _rEvent)
+{
+ return m_pFunc && m_pFunc->handleKeyEvent(_rEvent);
+}
+
+void OReportSection::deactivateOle()
+{
+ if (m_pFunc)
+ m_pFunc->deactivateOle(true);
+}
+
+void OReportSection::createDefault(const OUString& _sType)
+{
+ SdrObject* pObj = m_pView->GetCreateObj();
+ if ( !pObj )
+ return;
+ createDefault(_sType,pObj);
+}
+
+void OReportSection::createDefault(const OUString& _sType,SdrObject* _pObj)
+{
+ bool bAttributesAppliedFromGallery = false;
+
+ if ( GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT ) )
+ {
+ std::vector< OUString > aObjList;
+ if ( GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT, aObjList ) )
+ {
+ auto aIter = std::find_if(aObjList.begin(), aObjList.end(),
+ [&_sType](const OUString& rObj) { return rObj.equalsIgnoreAsciiCase(_sType); });
+ if (aIter != aObjList.end())
+ {
+ auto i = static_cast<sal_uInt32>(std::distance(aObjList.begin(), aIter));
+ OReportModel aReportModel(nullptr);
+ SfxItemPool& rPool = aReportModel.GetItemPool();
+ rPool.FreezeIdRanges();
+ if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT, i, &aReportModel ) )
+ {
+ const SdrObject* pSourceObj = aReportModel.GetPage( 0 )->GetObj( 0 );
+ if( pSourceObj )
+ {
+ const SfxItemSet& rSource = pSourceObj->GetMergedItemSet();
+ SfxItemSetFixed<
+ // Ranges from SdrAttrObj:
+ SDRATTR_START, SDRATTR_SHADOW_LAST,
+ SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
+ SDRATTR_TEXTDIRECTION,
+ SDRATTR_TEXTDIRECTION,
+ // Graphic attributes, 3D properties,
+ // CustomShape properties:
+ SDRATTR_GRAF_FIRST,
+ SDRATTR_CUSTOMSHAPE_LAST,
+ // Range from SdrTextObj:
+ EE_ITEMS_START, EE_ITEMS_END>
+ aDest( _pObj->getSdrModelFromSdrObject().GetItemPool() );
+ aDest.Set( rSource );
+ _pObj->SetMergedItemSet( aDest );
+ Degree100 nAngle = pSourceObj->GetRotateAngle();
+ if ( nAngle )
+ _pObj->NbcRotate( _pObj->GetSnapRect().Center(), nAngle );
+ bAttributesAppliedFromGallery = true;
+ }
+ }
+ }
+ }
+ }
+ if ( !bAttributesAppliedFromGallery )
+ {
+ _pObj->SetMergedItem( SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST) );
+ _pObj->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) );
+ _pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) );
+ _pObj->SetMergedItem( makeSdrTextAutoGrowHeightItem( false ) );
+ static_cast<SdrObjCustomShape*>(_pObj)->MergeDefaultAttributes( &_sType );
+ }
+}
+
+uno::Reference< report::XReportComponent > OReportSection::getCurrentControlModel() const
+{
+ uno::Reference< report::XReportComponent > xModel;
+ if ( m_pView )
+ {
+ const SdrMarkList& rMarkList = m_pView->GetMarkedObjectList();
+
+ if ( rMarkList.GetMarkCount() == 1 )
+ {
+ SdrObject* pDlgEdObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ OObjectBase* pObj = dynamic_cast<OObjectBase*>(pDlgEdObj);
+ if ( pObj )
+ xModel = pObj->getReportComponent().get();
+ }
+ }
+ return xModel;
+}
+
+void OReportSection::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const
+{
+ if ( !m_pView )
+ return;
+
+ const SdrMarkList& rMarkList = m_pView->GetMarkedObjectList();
+ const size_t nMarkCount = rMarkList.GetMarkCount();
+
+ for (size_t i=0; i < nMarkCount; ++i)
+ {
+ const SdrObject* pDlgEdObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+ const OObjectBase* pObj = dynamic_cast<const OObjectBase*>(pDlgEdObj);
+ if ( pObj )
+ {
+ uno::Reference<uno::XInterface> xInterface(pObj->getReportComponent());
+ _rSelection.push_back(xInterface);
+ }
+ }
+}
+
+sal_Int8 OReportSection::AcceptDrop( const AcceptDropEvent& _rEvt )
+{
+ ::Point aDropPos(_rEvt.maPosPixel);
+ const MouseEvent aMouseEvt(aDropPos);
+ if ( m_pFunc->isOverlapping(aMouseEvt) )
+ return DND_ACTION_NONE;
+
+ if ( _rEvt.mnAction == DND_ACTION_COPY ||
+ _rEvt.mnAction == DND_ACTION_LINK
+ )
+ {
+ if (!m_pParent) return DND_ACTION_NONE;
+ sal_uInt16 nCurrentPosition = m_pParent->getViewsWindow()->getPosition(m_pParent);
+ if (_rEvt.mnAction == DND_ACTION_COPY )
+ {
+ // we must assure, we can't drop in the top section
+ if (nCurrentPosition < 1)
+ {
+ return DND_ACTION_NONE;
+ }
+ return DND_ACTION_LINK;
+ }
+ if (_rEvt.mnAction == DND_ACTION_LINK)
+ {
+ // we must assure, we can't drop in the bottom section
+ if (m_pParent->getViewsWindow()->getSectionCount() > (nCurrentPosition + 1) )
+ {
+ return DND_ACTION_COPY;
+ }
+ return DND_ACTION_NONE;
+ }
+ }
+ else
+ {
+ const DataFlavorExVector& rFlavors = GetDataFlavorExVector();
+ if ( svx::OMultiColumnTransferable::canExtractDescriptor(rFlavors)
+ || svx::OColumnTransferable::canExtractColumnDescriptor(rFlavors, ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR) )
+ return _rEvt.mnAction;
+
+ const sal_Int8 nDropOption = ( OReportExchange::canExtract(rFlavors) ) ? DND_ACTION_COPYMOVE : DND_ACTION_NONE;
+
+ return nDropOption;
+ }
+ return DND_ACTION_NONE;
+}
+
+
+sal_Int8 OReportSection::ExecuteDrop( const ExecuteDropEvent& _rEvt )
+{
+ ::Point aDropPos(PixelToLogic(_rEvt.maPosPixel));
+ const MouseEvent aMouseEvt(aDropPos);
+ if ( m_pFunc->isOverlapping(aMouseEvt) )
+ return DND_ACTION_NONE;
+
+ sal_Int8 nDropOption = DND_ACTION_NONE;
+ const TransferableDataHelper aDropped(_rEvt.maDropEvent.Transferable);
+ const DataFlavorExVector& rFlavors = aDropped.GetDataFlavorExVector();
+ bool bMultipleFormat = svx::OMultiColumnTransferable::canExtractDescriptor(rFlavors);
+ if ( OReportExchange::canExtract(rFlavors) )
+ {
+ OReportExchange::TSectionElements aCopies = OReportExchange::extractCopies(aDropped);
+ Paste(aCopies,true);
+ nDropOption = DND_ACTION_COPYMOVE;
+ m_pParent->getViewsWindow()->BrkAction();
+ m_pParent->getViewsWindow()->unmarkAllObjects(m_pView);
+ }
+ else if ( bMultipleFormat
+ || svx::OColumnTransferable::canExtractColumnDescriptor(rFlavors, ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR) )
+ {
+ m_pParent->getViewsWindow()->getView()->setMarked(m_pView, true);
+ m_pView->UnmarkAll();
+ const tools::Rectangle& rRect = m_pView->GetWorkArea();
+ if ( aDropPos.X() < rRect.Left() )
+ aDropPos.setX( rRect.Left() );
+ else if ( aDropPos.X() > rRect.Right() )
+ aDropPos.setX( rRect.Right() );
+
+ if ( aDropPos.Y() > rRect.Bottom() )
+ aDropPos.setY( rRect.Bottom() );
+
+ uno::Sequence<beans::PropertyValue> aValues;
+ if ( !bMultipleFormat )
+ {
+ svx::ODataAccessDescriptor aDescriptor = svx::OColumnTransferable::extractColumnDescriptor(aDropped);
+
+ aValues.realloc(1);
+ aValues.getArray()[0].Value <<= aDescriptor.createPropertyValueSequence();
+ }
+ else
+ aValues = svx::OMultiColumnTransferable::extractDescriptor(aDropped);
+
+ for(beans::PropertyValue & propVal : asNonConstRange(aValues))
+ {
+ uno::Sequence<beans::PropertyValue> aCurrent;
+ propVal.Value >>= aCurrent;
+ sal_Int32 nLength = aCurrent.getLength();
+ if ( nLength )
+ {
+ aCurrent.realloc(nLength + 3);
+ auto pCurrent = aCurrent.getArray();
+ pCurrent[nLength].Name = PROPERTY_POSITION;
+ pCurrent[nLength++].Value <<= AWTPoint(aDropPos);
+ // give also the DND Action (Shift|Ctrl) Key to really say what we want
+ pCurrent[nLength].Name = "DNDAction";
+ pCurrent[nLength++].Value <<= _rEvt.mnAction;
+
+ pCurrent[nLength].Name = "Section";
+ pCurrent[nLength++].Value <<= getSection();
+ propVal.Value <<= aCurrent;
+ }
+ }
+
+ // we use this way to create undo actions
+ OReportController& rController = m_pParent->getViewsWindow()->getView()->getReportView()->getController();
+ rController.executeChecked(SID_ADD_CONTROL_PAIR,aValues);
+ nDropOption = DND_ACTION_COPY;
+ }
+ return nDropOption;
+}
+
+void OReportSection::stopScrollTimer()
+{
+ m_pFunc->stopScrollTimer();
+}
+
+bool OReportSection::isUiActive() const
+{
+ return m_pFunc->isUiActive();
+}
+
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/ReportWindow.cxx b/reportdesign/source/ui/report/ReportWindow.cxx
new file mode 100644
index 000000000..8da0855f6
--- /dev/null
+++ b/reportdesign/source/ui/report/ReportWindow.cxx
@@ -0,0 +1,433 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <ReportWindow.hxx>
+#include <ReportSection.hxx>
+#include <SectionView.hxx>
+#include <ViewsWindow.hxx>
+#include <DesignView.hxx>
+#include <UITools.hxx>
+
+#include <unotools/syslocale.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include <vcl/settings.hxx>
+
+#include <RptDef.hxx>
+#include <strings.hxx>
+#include <ReportController.hxx>
+#include <ScrollHelper.hxx>
+
+#include <helpids.h>
+#include <dlgedfac.hxx>
+
+
+#define SECTION_OFFSET 3
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace ::comphelper;
+
+
+
+OReportWindow::OReportWindow(OScrollWindowHelper* _pParent,ODesignView* _pView)
+: Window(_pParent,WB_DIALOGCONTROL)
+, ::comphelper::OPropertyChangeListener(m_aMutex)
+,m_aHRuler(VclPtr<Ruler>::Create(this))
+,m_pView(_pView)
+,m_pParent(_pParent)
+,m_aViewsWindow(VclPtr<rptui::OViewsWindow>::Create(this))
+,m_pObjFac( new DlgEdFactory() )
+{
+ SetHelpId(UID_RPT_REPORTWINDOW);
+ SetMapMode( MapMode( MapUnit::Map100thMM ) );
+
+ m_aViewsWindow->Show();
+
+ m_aHRuler->Show();
+ m_aHRuler->Activate();
+ m_aHRuler->SetPagePos();
+ m_aHRuler->SetBorders();
+ m_aHRuler->SetIndents();
+ m_aHRuler->SetMargin1();
+ m_aHRuler->SetMargin2();
+ const MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
+ m_aHRuler->SetUnit(MeasurementSystem::Metric == eSystem ? FieldUnit::CM : FieldUnit::INCH);
+
+ ImplInitSettings();
+ m_pReportListener = addStyleListener(_pView->getController().getReportDefinition(),this);
+}
+
+OReportWindow::~OReportWindow()
+{
+ disposeOnce();
+}
+
+void OReportWindow::dispose()
+{
+ if ( m_pReportListener.is() )
+ m_pReportListener->dispose();
+ m_aHRuler.disposeAndClear();
+ m_aViewsWindow.disposeAndClear();
+ m_pView.clear();
+ m_pParent.clear();
+ vcl::Window::dispose();
+}
+
+void OReportWindow::SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType )
+{
+ m_aViewsWindow->SetInsertObj( eObj,_sShapeType);
+}
+
+OUString const & OReportWindow::GetInsertObjString() const
+{
+ return m_aViewsWindow->GetInsertObjString();
+}
+
+void OReportWindow::SetMode( DlgEdMode eNewMode )
+{
+ m_aViewsWindow->SetMode(eNewMode);
+}
+
+void OReportWindow::removeSection(sal_uInt16 _nPosition)
+{
+ m_aViewsWindow->removeSection(_nPosition);
+ m_pParent->setTotalSize(GetTotalWidth(),GetTotalHeight());
+ m_aViewsWindow->Invalidate(InvalidateFlags::Transparent);
+}
+
+void OReportWindow::addSection(const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry,sal_uInt16 _nPosition)
+{
+ if ( !_xSection.is() )
+ return;
+
+ m_aViewsWindow->addSection(_xSection,_sColorEntry,_nPosition);
+
+ m_pParent->setTotalSize(GetTotalWidth(),GetTotalHeight());
+}
+
+void OReportWindow::toggleGrid(bool _bVisible)
+{
+ m_aViewsWindow->toggleGrid(_bVisible);
+}
+
+void OReportWindow::showRuler(bool _bShow)
+{
+ m_aHRuler->Show(_bShow);
+
+ m_aViewsWindow->showRuler(_bShow);
+}
+
+sal_Int32 OReportWindow::getMaxMarkerWidth() const
+{
+ Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH));
+ aStartWidth *= m_aViewsWindow->GetMapMode().GetScaleX();
+ return sal_Int32(static_cast<tools::Long>(aStartWidth));
+}
+
+sal_Int32 OReportWindow::GetTotalWidth() const
+{
+ sal_Int32 nWidth = 0;
+ if ( !m_aViewsWindow->empty() )
+ {
+ Fraction aStartWidth(tools::Long(REPORT_ENDMARKER_WIDTH + REPORT_STARTMARKER_WIDTH ));
+ const Fraction aZoom(m_pView->getController().getZoomValue(),100);
+ aStartWidth *= aZoom;
+ sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(m_pView->getController().getReportDefinition(),PROPERTY_PAPERSIZE).Width;
+ nPaperWidth = tools::Long(nPaperWidth * aZoom);
+ const Size aPageSize = LogicToPixel(Size(nPaperWidth,0));
+ nWidth = aPageSize.Width() + tools::Long(aStartWidth);
+ }
+ return nWidth;
+}
+
+void OReportWindow::Resize()
+{
+ Window::Resize();
+ if ( m_aViewsWindow->empty() )
+ return;
+
+ const Size aTotalOutputSize = GetOutputSizePixel();
+ Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH)*m_pView->getController().getZoomValue(),100);
+
+ const Point aOffset = LogicToPixel(Point(SECTION_OFFSET, 0), MapMode(MapUnit::MapAppFont));
+ Point aStartPoint(static_cast<tools::Long>(aStartWidth) + aOffset.X(),0);
+ uno::Reference<report::XReportDefinition> xReportDefinition = getReportView()->getController().getReportDefinition();
+ const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width;
+ sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN);
+ sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN);
+ Size aPageSize = m_aViewsWindow->LogicToPixel(Size(nPaperWidth ,0));
+ nLeftMargin = m_aViewsWindow->LogicToPixel(Size(nLeftMargin,0)).Width();
+ nRightMargin = m_aViewsWindow->LogicToPixel(Size(nRightMargin,0)).Width();
+
+ aPageSize.setHeight( m_aHRuler->GetSizePixel().Height() );
+
+ const tools::Long nTermp(m_aViewsWindow->getTotalHeight() + aPageSize.Height());
+ tools::Long nSectionsHeight = ::std::max<tools::Long>(nTermp,aTotalOutputSize.Height());
+
+ m_aHRuler->SetPosSizePixel(aStartPoint,aPageSize);
+ m_aHRuler->SetNullOffset(nLeftMargin);
+ m_aHRuler->SetMargin1(0);
+ m_aHRuler->SetMargin2(aPageSize.Width() - nLeftMargin - nRightMargin);
+
+ aStartPoint.AdjustY(aPageSize.Height() );
+ nSectionsHeight -= aStartPoint.Y();
+
+ aStartPoint.setX( aOffset.X() );
+
+ m_aViewsWindow->SetPosSizePixel(aStartPoint,Size(aTotalOutputSize.Width(),nSectionsHeight));
+}
+
+Point OReportWindow::getThumbPos() const
+{
+ return m_pParent->getThumbPos();
+}
+
+void OReportWindow::ImplInitSettings()
+{
+ SetBackground( );
+}
+
+void OReportWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+sal_Int32 OReportWindow::GetTotalHeight() const
+{
+ return m_aViewsWindow->getTotalHeight();
+}
+
+void OReportWindow::ScrollChildren(const Point& _aThumbPos)
+{
+ MapMode aMap = m_aHRuler->GetMapMode();
+ Point aOrg( aMap.GetOrigin() );
+ if ( aOrg.X() != (-_aThumbPos.X()) )
+ {
+ aMap.SetOrigin( Point(- _aThumbPos.X(), aOrg.Y()));
+ m_aHRuler->SetMapMode( aMap );
+ m_aHRuler->Scroll(-(aOrg.X() + _aThumbPos.X()),0);
+ }
+
+ m_aViewsWindow->scrollChildren(_aThumbPos);
+}
+
+sal_uInt16 OReportWindow::getSectionCount() const
+{
+ return m_aViewsWindow->getSectionCount();
+}
+
+void OReportWindow::notifySizeChanged()
+{
+ m_pParent->setTotalSize(GetTotalWidth(),GetTotalHeight());
+}
+
+bool OReportWindow::HasSelection() const
+{
+ return m_aViewsWindow->HasSelection();
+}
+
+void OReportWindow::Delete()
+{
+
+ m_aViewsWindow->Delete();
+}
+
+void OReportWindow::Copy()
+{
+
+ m_aViewsWindow->Copy();
+}
+
+void OReportWindow::Paste()
+{
+
+ m_aViewsWindow->Paste();
+}
+
+bool OReportWindow::IsPasteAllowed() const
+{
+ return m_aViewsWindow->IsPasteAllowed();
+}
+
+void OReportWindow::SelectAll(const SdrObjKind _nObjectType)
+{
+
+ m_aViewsWindow->SelectAll(_nObjectType);
+}
+
+void OReportWindow::unmarkAllObjects()
+{
+
+ m_aViewsWindow->unmarkAllObjects(nullptr);
+}
+
+void OReportWindow::showProperties(const uno::Reference< report::XSection>& _xReportComponent)
+{
+ OSectionWindow* pSectionWindow = m_aViewsWindow->getSectionWindow( _xReportComponent );
+ m_pView->UpdatePropertyBrowserDelayed(pSectionWindow->getReportSection().getSectionView());
+}
+
+bool OReportWindow::handleKeyEvent(const KeyEvent& _rEvent)
+{
+ return m_aViewsWindow->handleKeyEvent(_rEvent);
+}
+
+void OReportWindow::setMarked(OSectionView const * _pSectionView, bool _bMark)
+{
+ if ( _pSectionView )
+ m_aViewsWindow->setMarked(_pSectionView,_bMark);
+}
+
+void OReportWindow::setMarked(const uno::Reference< report::XSection>& _xSection, bool _bMark)
+{
+
+ m_aViewsWindow->setMarked(_xSection,_bMark);
+}
+
+void OReportWindow::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _xShape, bool _bMark)
+{
+
+ m_aViewsWindow->setMarked(_xShape,_bMark);
+}
+
+OSectionWindow* OReportWindow::getMarkedSection(NearSectionAccess nsa) const
+{
+ return m_aViewsWindow->getMarkedSection(nsa);
+}
+
+OSectionWindow* OReportWindow::getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const
+{
+ return m_aViewsWindow->getSectionWindow(_xSection);
+}
+
+void OReportWindow::markSection(const sal_uInt16 _nPos)
+{
+
+ m_aViewsWindow->markSection(_nPos);
+}
+
+void OReportWindow::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const
+{
+
+ m_aViewsWindow->fillCollapsedSections(_rCollapsedPositions);
+}
+
+void OReportWindow::collapseSections(const uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections)
+{
+
+ m_aViewsWindow->collapseSections(_aCollapsedSections);
+}
+
+void OReportWindow::alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection)
+{
+ m_aViewsWindow->alignMarkedObjects(_nControlModification, _bAlignAtSection);
+}
+
+void OReportWindow::setGridSnap(bool bOn)
+{
+
+ m_aViewsWindow->setGridSnap(bOn);
+}
+
+void OReportWindow::setDragStripes(bool bOn)
+{
+ m_aViewsWindow->setDragStripes(bOn);
+}
+
+sal_uInt32 OReportWindow::getMarkedObjectCount() const
+{
+ return m_aViewsWindow->getMarkedObjectCount();
+}
+
+void OReportWindow::zoom(const Fraction& _aZoom)
+{
+ m_aHRuler->SetZoom(_aZoom);
+ m_aHRuler->Invalidate();
+
+ m_aViewsWindow->zoom(_aZoom);
+
+ notifySizeChanged();
+ const Point aNewThumbPos( m_pParent->getThumbPos() );
+
+ ScrollChildren( aNewThumbPos );
+ Resize();
+
+ Invalidate(InvalidateFlags::NoErase | InvalidateFlags::NoChildren | InvalidateFlags::Transparent);
+}
+
+void OReportWindow::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const
+{
+ m_aViewsWindow->fillControlModelSelection(_rSelection);
+}
+
+sal_Int32 OReportWindow::impl_getRealPixelWidth() const
+{
+ const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(m_pView->getController().getReportDefinition(),PROPERTY_PAPERSIZE).Width;
+ MapMode aMap( MapUnit::Map100thMM );
+ const Size aPageSize = LogicToPixel(Size(nPaperWidth,0),aMap);
+ return aPageSize.Width() + REPORT_ENDMARKER_WIDTH + REPORT_STARTMARKER_WIDTH + SECTION_OFFSET;
+}
+
+sal_uInt16 OReportWindow::getZoomFactor(SvxZoomType _eType) const
+{
+ sal_uInt16 nZoom(100);
+ const Size aSize( GetSizePixel() );
+ switch( _eType)
+ {
+ case SvxZoomType::PERCENT:
+ nZoom = m_pView->getController().getZoomValue();
+ break;
+ case SvxZoomType::OPTIMAL:
+ break;
+ case SvxZoomType::WHOLEPAGE:
+ {
+ nZoom = static_cast<sal_uInt16>(static_cast<tools::Long>(Fraction(aSize.Width()*100,impl_getRealPixelWidth())));
+ MapMode aMap( MapUnit::Map100thMM );
+ const Size aHeight = m_aViewsWindow->LogicToPixel(m_aViewsWindow->PixelToLogic(Size(0,GetTotalHeight() + m_aHRuler->GetSizePixel().Height())),aMap);
+ nZoom = ::std::min(nZoom,static_cast<sal_uInt16>(static_cast<tools::Long>(Fraction(aSize.Height()*100,aHeight.Height()))));
+ }
+ break;
+ case SvxZoomType::PAGEWIDTH:
+ nZoom = static_cast<sal_uInt16>(static_cast<tools::Long>(Fraction(aSize.Width()*100,impl_getRealPixelWidth())));
+ break;
+ default:
+ break;
+ }
+
+ return nZoom;
+}
+
+void OReportWindow::_propertyChanged(const beans::PropertyChangeEvent&)
+{
+ Resize();
+ m_aViewsWindow->Resize();
+ Invalidate(InvalidateFlags::Transparent);
+}
+
+} //rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/ScrollHelper.cxx b/reportdesign/source/ui/report/ScrollHelper.cxx
new file mode 100644
index 000000000..bf5f261cf
--- /dev/null
+++ b/reportdesign/source/ui/report/ScrollHelper.cxx
@@ -0,0 +1,412 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <ScrollHelper.hxx>
+#include <DesignView.hxx>
+#include <ReportController.hxx>
+#include <ReportWindow.hxx>
+#include <UITools.hxx>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+
+#include <vcl/commandevent.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+namespace rptui
+{
+#define SECTION_OFFSET 3
+#define SCR_LINE_SIZE 10
+using namespace ::com::sun::star;
+
+
+static void lcl_setScrollBar(sal_Int32 _nNewValue,const Point& _aPos,const Size& _aSize,ScrollBar& _rScrollBar)
+{
+ _rScrollBar.SetPosSizePixel(_aPos,_aSize);
+ _rScrollBar.SetPageSize( _nNewValue );
+ _rScrollBar.SetVisibleSize( _nNewValue );
+}
+
+
+OScrollWindowHelper::OScrollWindowHelper( ODesignView* _pDesignView)
+ : OScrollWindowHelper_BASE( _pDesignView,WB_DIALOGCONTROL)
+ ,OPropertyChangeListener(m_aMutex)
+ ,m_aHScroll( VclPtr<ScrollBar>::Create(this, WB_HSCROLL|WB_REPEAT|WB_DRAG) )
+ ,m_aVScroll( VclPtr<ScrollBar>::Create(this, WB_VSCROLL|WB_REPEAT|WB_DRAG) )
+ ,m_aCornerWin( VclPtr<ScrollBarBox>::Create(this) )
+ ,m_pParent(_pDesignView)
+ ,m_aReportWindow(VclPtr<rptui::OReportWindow>::Create(this,m_pParent))
+{
+ SetMapMode( MapMode( MapUnit::Map100thMM ) );
+
+ impl_initScrollBar( *m_aHScroll );
+ impl_initScrollBar( *m_aVScroll );
+
+ m_aReportWindow->SetMapMode( MapMode( MapUnit::Map100thMM ) );
+ m_aReportWindow->Show();
+
+ // normally we should be SCROLL_PANE
+ SetAccessibleRole(css::accessibility::AccessibleRole::SCROLL_PANE);
+ ImplInitSettings();
+}
+
+
+OScrollWindowHelper::~OScrollWindowHelper()
+{
+ disposeOnce();
+}
+
+void OScrollWindowHelper::dispose()
+{
+ if ( m_pReportDefinitionMultiPlexer.is() )
+ m_pReportDefinitionMultiPlexer->dispose();
+
+ m_aHScroll.disposeAndClear();
+ m_aVScroll.disposeAndClear();
+ m_aCornerWin.disposeAndClear();
+ m_aReportWindow.disposeAndClear();
+ m_pParent.clear();
+ OScrollWindowHelper_BASE::dispose();
+}
+
+
+void OScrollWindowHelper::impl_initScrollBar( ScrollBar& _rScrollBar ) const
+{
+ AllSettings aSettings( _rScrollBar.GetSettings() );
+ StyleSettings aStyle( aSettings.GetStyleSettings() );
+ aStyle.SetDragFullOptions( aStyle.GetDragFullOptions() | DragFullOptions::Scroll ); // live scrolling
+ aSettings.SetStyleSettings( aStyle );
+ _rScrollBar.SetSettings( aSettings );
+
+ _rScrollBar.SetScrollHdl( LINK( const_cast<OScrollWindowHelper*>(this), OScrollWindowHelper, ScrollHdl ) );
+ _rScrollBar.SetLineSize( SCR_LINE_SIZE );
+}
+
+
+void OScrollWindowHelper::initialize()
+{
+ uno::Reference<report::XReportDefinition> xReportDefinition = m_pParent->getController().getReportDefinition();
+ m_pReportDefinitionMultiPlexer = addStyleListener(xReportDefinition,this);
+}
+
+void OScrollWindowHelper::setTotalSize(sal_Int32 _nWidth ,sal_Int32 _nHeight)
+{
+ m_aTotalPixelSize.setWidth( _nWidth );
+ m_aTotalPixelSize.setHeight( _nHeight );
+
+ // now set the ranges without start marker
+ Fraction aStartWidth(REPORT_STARTMARKER_WIDTH * m_pParent->getController().getZoomValue(),100);
+ tools::Long nWidth = tools::Long(_nWidth - static_cast<double>(aStartWidth));
+ m_aHScroll->SetRangeMax( nWidth );
+ m_aVScroll->SetRangeMax( m_aTotalPixelSize.Height() );
+
+ Resize();
+}
+
+Size OScrollWindowHelper::ResizeScrollBars()
+{
+ // get the new output-size in pixel
+ Size aOutPixSz = GetOutputSizePixel();
+ if ( aOutPixSz.IsEmpty() )
+ return aOutPixSz;
+
+ aOutPixSz.AdjustHeight( -(m_aReportWindow->getRulerHeight()) );
+ // determine the size of the output-area and if we need scrollbars
+ const tools::Long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ bool bVVisible = false; // by default no vertical-ScrollBar
+ bool bHVisible = false; // by default no horizontal-ScrollBar
+ bool bChanged; // determines if a visiblility was changed
+ do
+ {
+ bChanged = false;
+
+ // does we need a vertical ScrollBar
+ if ( aOutPixSz.Width() < m_aTotalPixelSize.Width() && !bHVisible )
+ {
+ bHVisible = true;
+ aOutPixSz.AdjustHeight( -nScrSize );
+ bChanged = true;
+ }
+
+ // does we need a horizontal ScrollBar
+ if ( aOutPixSz.Height() < m_aTotalPixelSize.Height() && !bVVisible )
+ {
+ bVVisible = true;
+ aOutPixSz.AdjustWidth( -nScrSize );
+ bChanged = true;
+ }
+
+ }
+ while ( bChanged ); // until no visibility has changed
+
+ aOutPixSz.AdjustHeight(m_aReportWindow->getRulerHeight() );
+
+ // show or hide scrollbars
+ m_aVScroll->Show( bVVisible );
+ m_aHScroll->Show( bHVisible );
+
+ // disable painting in the corner between the scrollbars
+ if ( bVVisible && bHVisible )
+ {
+ m_aCornerWin->SetPosSizePixel(Point(aOutPixSz.Width(), aOutPixSz.Height()), Size(nScrSize, nScrSize) );
+ m_aCornerWin->Show();
+ }
+ else
+ m_aCornerWin->Hide();
+
+ const Point aOffset = LogicToPixel(Point(SECTION_OFFSET, SECTION_OFFSET), MapMode(MapUnit::MapAppFont));
+ // resize scrollbars and set their ranges
+ {
+ Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH*m_pParent->getController().getZoomValue()),100);
+ const sal_Int32 nNewWidth = aOutPixSz.Width() - aOffset.X() - static_cast<tools::Long>(aStartWidth);
+ lcl_setScrollBar(nNewWidth,Point( static_cast<tools::Long>(aStartWidth) + aOffset.X(), aOutPixSz.Height() ), Size( nNewWidth, nScrSize ), *m_aHScroll);
+ }
+ {
+ const sal_Int32 nNewHeight = aOutPixSz.Height() - m_aReportWindow->getRulerHeight();
+ lcl_setScrollBar(nNewHeight,Point( aOutPixSz.Width(), m_aReportWindow->getRulerHeight() ), Size( nScrSize,nNewHeight), *m_aVScroll);
+ }
+
+ return aOutPixSz;
+}
+
+void OScrollWindowHelper::Resize()
+{
+ OScrollWindowHelper_BASE::Resize();
+ const Size aTotalOutputSize = ResizeScrollBars();
+
+ m_aReportWindow->SetPosSizePixel(Point( 0, 0 ),aTotalOutputSize);
+}
+
+IMPL_LINK( OScrollWindowHelper, ScrollHdl, ScrollBar*, /*pScroll*/, void )
+{
+ m_aReportWindow->ScrollChildren( getThumbPos() );
+}
+
+void OScrollWindowHelper::addSection(const uno::Reference< report::XSection >& _xSection
+ ,const OUString& _sColorEntry
+ ,sal_uInt16 _nPosition)
+{
+ m_aReportWindow->addSection(_xSection,_sColorEntry,_nPosition);
+}
+
+void OScrollWindowHelper::removeSection(sal_uInt16 _nPosition)
+{
+ m_aReportWindow->removeSection(_nPosition);
+}
+
+void OScrollWindowHelper::toggleGrid(bool _bVisible)
+{
+ m_aReportWindow->toggleGrid(_bVisible);
+}
+
+sal_uInt16 OScrollWindowHelper::getSectionCount() const
+{
+ return m_aReportWindow->getSectionCount();
+}
+
+void OScrollWindowHelper::SetInsertObj(SdrObjKind eObj, const OUString& _sShapeType)
+{
+ m_aReportWindow->SetInsertObj(eObj,_sShapeType);
+}
+
+OUString const & OScrollWindowHelper::GetInsertObjString() const
+{
+ return m_aReportWindow->GetInsertObjString();
+}
+
+void OScrollWindowHelper::SetMode( DlgEdMode _eNewMode )
+{
+ m_aReportWindow->SetMode(_eNewMode);
+}
+
+bool OScrollWindowHelper::HasSelection() const
+{
+ return m_aReportWindow->HasSelection();
+}
+
+void OScrollWindowHelper::Delete()
+{
+ m_aReportWindow->Delete();
+}
+
+void OScrollWindowHelper::Copy()
+{
+ m_aReportWindow->Copy();
+}
+
+void OScrollWindowHelper::Paste()
+{
+ m_aReportWindow->Paste();
+}
+
+bool OScrollWindowHelper::IsPasteAllowed() const
+{
+ return m_aReportWindow->IsPasteAllowed();
+}
+
+void OScrollWindowHelper::SelectAll(const SdrObjKind _nObjectType)
+{
+ m_aReportWindow->SelectAll(_nObjectType);
+}
+
+void OScrollWindowHelper::unmarkAllObjects()
+{
+ m_aReportWindow->unmarkAllObjects();
+}
+
+sal_Int32 OScrollWindowHelper::getMaxMarkerWidth() const
+{
+ return m_aReportWindow->getMaxMarkerWidth();
+}
+
+void OScrollWindowHelper::showRuler(bool _bShow)
+{
+ m_aReportWindow->showRuler(_bShow);
+}
+
+bool OScrollWindowHelper::handleKeyEvent(const KeyEvent& _rEvent)
+{
+ return m_aReportWindow->handleKeyEvent(_rEvent);
+}
+
+void OScrollWindowHelper::setMarked(OSectionView const * _pSectionView, bool _bMark)
+{
+ m_aReportWindow->setMarked(_pSectionView,_bMark);
+}
+
+void OScrollWindowHelper::setMarked(const uno::Reference< report::XSection>& _xSection, bool _bMark)
+{
+ m_aReportWindow->setMarked(_xSection,_bMark);
+}
+
+void OScrollWindowHelper::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _xShape, bool _bMark)
+{
+ m_aReportWindow->setMarked(_xShape,_bMark);
+}
+
+OSectionWindow* OScrollWindowHelper::getMarkedSection(NearSectionAccess nsa) const
+{
+ return m_aReportWindow->getMarkedSection(nsa);
+}
+
+OSectionWindow* OScrollWindowHelper::getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const
+{
+ return m_aReportWindow->getSectionWindow(_xSection);
+}
+
+void OScrollWindowHelper::markSection(const sal_uInt16 _nPos)
+{
+ m_aReportWindow->markSection(_nPos);
+}
+
+void OScrollWindowHelper::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const
+{
+ m_aReportWindow->fillCollapsedSections(_rCollapsedPositions);
+}
+
+void OScrollWindowHelper::collapseSections(const uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections)
+{
+ m_aReportWindow->collapseSections(_aCollapsedSections);
+}
+
+bool OScrollWindowHelper::EventNotify( NotifyEvent& rNEvt )
+{
+ const CommandEvent* pCommandEvent = rNEvt.GetCommandEvent();
+ if ( pCommandEvent &&
+ ((pCommandEvent->GetCommand() == CommandEventId::Wheel) ||
+ (pCommandEvent->GetCommand() == CommandEventId::StartAutoScroll) ||
+ (pCommandEvent->GetCommand() == CommandEventId::AutoScroll)) )
+ {
+ ScrollBar* pHScrBar = nullptr;
+ ScrollBar* pVScrBar = nullptr;
+ if ( m_aHScroll->IsVisible() )
+ pHScrBar = m_aHScroll.get();
+
+ if ( m_aVScroll->IsVisible() )
+ pVScrBar = m_aVScroll.get();
+
+ if ( HandleScrollCommand( *pCommandEvent, pHScrBar, pVScrBar ) )
+ return true;
+ }
+ return OScrollWindowHelper_BASE::EventNotify(rNEvt);
+}
+
+void OScrollWindowHelper::alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection)
+{
+ m_aReportWindow->alignMarkedObjects(_nControlModification, _bAlignAtSection);
+}
+
+void OScrollWindowHelper::ImplInitSettings()
+{
+ SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor() ));
+ GetOutDev()->SetFillColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
+ SetTextFillColor( Application::GetSettings().GetStyleSettings().GetFaceColor() );
+}
+
+void OScrollWindowHelper::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+void OScrollWindowHelper::_propertyChanged(const beans::PropertyChangeEvent& /*_rEvent*/)
+{
+ m_aReportWindow->notifySizeChanged();
+}
+
+void OScrollWindowHelper::setGridSnap(bool bOn)
+{
+ m_aReportWindow->setGridSnap(bOn);
+}
+
+void OScrollWindowHelper::setDragStripes(bool bOn)
+{
+ m_aReportWindow->setDragStripes(bOn);
+}
+
+sal_uInt32 OScrollWindowHelper::getMarkedObjectCount() const
+{
+ return m_aReportWindow->getMarkedObjectCount();
+}
+
+void OScrollWindowHelper::zoom(const Fraction& _aZoom)
+{
+ m_aReportWindow->zoom(_aZoom);
+ Resize();
+ Invalidate(InvalidateFlags::NoChildren|InvalidateFlags::Transparent);
+}
+
+void OScrollWindowHelper::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const
+{
+ m_aReportWindow->fillControlModelSelection(_rSelection);
+}
+
+sal_uInt16 OScrollWindowHelper::getZoomFactor(SvxZoomType _eType) const
+{
+ return m_aReportWindow->getZoomFactor(_eType);
+}
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/SectionView.cxx b/reportdesign/source/ui/report/SectionView.cxx
new file mode 100644
index 000000000..f0da7c2e1
--- /dev/null
+++ b/reportdesign/source/ui/report/SectionView.cxx
@@ -0,0 +1,250 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <SectionView.hxx>
+#include <DesignView.hxx>
+#include <RptPage.hxx>
+#include <RptObject.hxx>
+#include <RptDef.hxx>
+#include <svx/svddrgmt.hxx>
+#include <ReportSection.hxx>
+#include <ReportWindow.hxx>
+#include <strings.hxx>
+#include <tools/diagnose_ex.h>
+
+namespace rptui
+{
+ using namespace ::com::sun::star;
+
+OSectionView::OSectionView(
+ SdrModel& rSdrModel,
+ OReportSection* _pSectionWindow,
+ OReportWindow* pEditor)
+: SdrView(rSdrModel, _pSectionWindow->GetOutDev())
+ ,m_pReportWindow( pEditor )
+ ,m_pSectionWindow(_pSectionWindow)
+{
+ // SetPagePaintingAllowed(false);
+ SetBufferedOutputAllowed(true);
+ SetBufferedOverlayAllowed(true);
+ SetPageBorderVisible(false);
+ SetBordVisible();
+ SetQuickTextEditMode(false);
+}
+
+
+OSectionView::~OSectionView()
+{
+}
+
+
+void OSectionView::MarkListHasChanged()
+{
+ SdrView::MarkListHasChanged();
+
+ if ( m_pReportWindow && m_pSectionWindow && !m_pSectionWindow->getPage()->getSpecialMode() )
+ {
+ DlgEdHint aHint( RPTUI_HINT_SELECTIONCHANGED );
+ m_pReportWindow->getReportView()->Broadcast( aHint );
+ m_pReportWindow->getReportView()->UpdatePropertyBrowserDelayed(*this);
+ }
+}
+
+
+void OSectionView::MakeVisible( const tools::Rectangle& rRect, vcl::Window& rWin )
+{
+ // visible area
+ MapMode aMap( rWin.GetMapMode() );
+ const Point aOrg( aMap.GetOrigin() );
+ const Size aVisSize( rWin.GetOutDev()->GetOutputSize() );
+ const tools::Rectangle aVisRect( Point(-aOrg.X(),-aOrg.Y()), aVisSize );
+
+ // check, if rectangle is inside visible area
+ if ( !aVisRect.Contains( rRect ) )
+ {
+ // calculate scroll distance; the rectangle must be inside the visible area
+ sal_Int32 nScrollX = 0, nScrollY = 0;
+
+ const sal_Int32 nVisLeft = aVisRect.Left();
+ const sal_Int32 nVisRight = aVisRect.Right();
+ const sal_Int32 nVisTop = aVisRect.Top();
+ const sal_Int32 nVisBottom = aVisRect.Bottom();
+
+ // don't scroll beyond the page size
+ Size aPageSize = m_pSectionWindow->getPage()->GetSize();
+ const sal_Int32 nPageWidth = aPageSize.Width();
+ const sal_Int32 nPageHeight = aPageSize.Height();
+
+ if ( nVisRight + nScrollX > nPageWidth )
+ nScrollX = nPageWidth - nVisRight;
+
+ if ( nVisLeft + nScrollX < 0 )
+ nScrollX = -nVisLeft;
+
+ if ( nVisBottom + nScrollY > nPageHeight )
+ nScrollY = nPageHeight - nVisBottom;
+
+ if ( nVisTop + nScrollY < 0 )
+ nScrollY = -nVisTop;
+
+ // scroll window
+ rWin.PaintImmediately();
+ rWin.Scroll( -nScrollX, -nScrollY );
+ aMap.SetOrigin( Point( aOrg.X() - nScrollX, aOrg.Y() - nScrollY ) );
+ rWin.SetMapMode( aMap );
+ rWin.Invalidate();
+
+ if ( m_pReportWindow )
+ {
+ const DlgEdHint aHint( RPTUI_HINT_WINDOWSCROLLED );
+ m_pReportWindow->getReportView()->Broadcast( aHint );
+ }
+ }
+ else
+ {
+ rWin.Invalidate(InvalidateFlags::NoErase);
+ }
+}
+
+void OSectionView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ SdrView::Notify(rBC,rHint);
+ if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
+ return;
+ const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
+ const SdrObject* pObj = pSdrHint->GetObject();
+ const SdrHintKind eKind = pSdrHint->GetKind();
+ // check for change of selected object
+ if(SdrHintKind::ObjectChange == eKind && pObj && IsObjMarked(pObj))
+ AdjustMarkHdl();
+ else if ( eKind == SdrHintKind::ObjectRemoved )
+ ObjectRemovedInAliveMode(pObj);
+}
+
+
+void OSectionView::ObjectRemovedInAliveMode( const SdrObject* _pObject )
+{
+ const SdrMarkList& rMarkedList = GetMarkedObjectList();
+ const size_t nMark = rMarkedList.GetMarkCount();
+
+ for( size_t i = 0; i < nMark; ++i )
+ {
+ SdrObject* pSdrObj = rMarkedList.GetMark(i)->GetMarkedSdrObj();
+ if (_pObject == pSdrObj)
+ {
+ SdrPageView* pPgView = GetSdrPageView();
+ BrkAction();
+ MarkObj( pSdrObj, pPgView, true );
+ break;
+ }
+ }
+}
+
+
+void OSectionView::SetMarkedToLayer( SdrLayerID _nLayerNo )
+{
+ if (!AreObjectsMarked())
+ return;
+
+ // #i11702# use SdrUndoObjectLayerChange for undo
+ // STR_UNDO_SELATTR is "Attributes" - should use a different text later
+ BegUndo( );
+
+ const SdrMarkList& rMark = GetMarkedObjectList();
+ const size_t nCount = rMark.GetMarkCount();
+ for (size_t i = 0; i<nCount; ++i)
+ {
+ SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
+ if ( dynamic_cast< const OCustomShape *>( pObj ) != nullptr )
+ {
+ AddUndo( std::make_unique<SdrUndoObjectLayerChange>( *pObj, pObj->GetLayer(), _nLayerNo) );
+ pObj->SetLayer( _nLayerNo );
+ OObjectBase& rBaseObj = dynamic_cast<OObjectBase&>(*pObj);
+ try
+ {
+ rBaseObj.getReportComponent()->setPropertyValue(PROPERTY_OPAQUE,uno::Any(_nLayerNo == RPT_LAYER_FRONT));
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+ }
+ }
+
+ EndUndo();
+
+ // check mark list now instead of later in a timer
+ CheckMarked();
+ MarkListHasChanged();
+}
+
+bool OSectionView::OnlyShapesMarked() const
+{
+ const SdrMarkList& rMark = GetMarkedObjectList();
+ const size_t nCount = rMark.GetMarkCount();
+ if ( !nCount )
+ return false;
+ for (size_t i = 0; i<nCount; ++i)
+ {
+ SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
+ if ( dynamic_cast< const OCustomShape *>( pObj ) == nullptr )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool OSectionView::IsDragResize() const
+{
+ const SdrDragMethod* pDragMethod = GetDragMethod();
+ if (pDragMethod)
+ {
+ bool bMoveOnly = pDragMethod->getMoveOnly();
+ if (!bMoveOnly)
+ {
+ // current marked components will be resized
+ return true;
+ }
+ }
+ return false;
+}
+
+
+SdrLayerID OSectionView::GetLayerIdOfMarkedObjects() const
+{
+ SdrLayerID nRet = SDRLAYER_NOTFOUND;
+ const SdrMarkList &rMrkList = GetMarkedObjectList();
+ for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ if ( nRet == SDRLAYER_NOTFOUND )
+ nRet = pObj->GetLayer();
+ else if ( nRet != pObj->GetLayer() )
+ {
+ break;
+ }
+ }
+ return nRet;
+}
+
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/SectionWindow.cxx b/reportdesign/source/ui/report/SectionWindow.cxx
new file mode 100644
index 000000000..60d5235f8
--- /dev/null
+++ b/reportdesign/source/ui/report/SectionWindow.cxx
@@ -0,0 +1,391 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <SectionWindow.hxx>
+#include <ReportWindow.hxx>
+#include <UITools.hxx>
+#include <ReportController.hxx>
+#include <ReportSection.hxx>
+#include <DesignView.hxx>
+#include <strings.hxx>
+#include <core_resource.hxx>
+#include <strings.hrc>
+#include <StartMarker.hxx>
+#include <EndMarker.hxx>
+#include <ViewsWindow.hxx>
+
+#include <functional>
+#include <algorithm>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace ::comphelper;
+
+OSectionWindow::OSectionWindow( OViewsWindow* _pParent,const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry)
+: Window( _pParent,WB_DIALOGCONTROL)
+,OPropertyChangeListener(m_aMutex)
+,m_pParent(_pParent)
+,m_aStartMarker( VclPtr<rptui::OStartMarker>::Create(this,_sColorEntry))
+,m_aReportSection( VclPtr<rptui::OReportSection>::Create(this,_xSection))
+,m_aSplitter(VclPtr<Splitter>::Create(this))
+,m_aEndMarker( VclPtr<rptui::OEndMarker>::Create(this,_sColorEntry))
+{
+ const MapMode& rMapMode = _pParent->GetMapMode();
+ SetMapMode( rMapMode );
+ ImplInitSettings();
+ // TRY
+ m_aSplitter->SetMapMode( MapMode( MapUnit::Map100thMM ) );
+ m_aSplitter->SetStartSplitHdl(LINK(this, OSectionWindow,StartSplitHdl));
+ m_aSplitter->SetSplitHdl(LINK(this, OSectionWindow,SplitHdl));
+ m_aSplitter->SetEndSplitHdl(LINK(this, OSectionWindow,EndSplitHdl));
+ m_aSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor() ));
+ m_aSplitter->SetSplitPosPixel(m_aSplitter->LogicToPixel(Size(0,_xSection->getHeight())).Height());
+
+
+ m_aStartMarker->setCollapsedHdl(LINK(this,OSectionWindow,Collapsed));
+
+ m_aStartMarker->zoom(rMapMode.GetScaleX());
+ setZoomFactor(rMapMode.GetScaleX(), *m_aReportSection);
+ setZoomFactor(rMapMode.GetScaleX(), *m_aSplitter);
+ setZoomFactor(rMapMode.GetScaleX(), *m_aEndMarker);
+
+ m_aSplitter->Show();
+ m_aStartMarker->Show();
+ m_aReportSection->Show();
+ m_aEndMarker->Show();
+ Show();
+
+ m_pSectionMulti = new OPropertyChangeMultiplexer(this,_xSection);
+ m_pSectionMulti->addProperty(PROPERTY_NAME);
+ m_pSectionMulti->addProperty(PROPERTY_HEIGHT);
+
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source = _xSection;
+ aEvent.PropertyName = PROPERTY_NAME;
+ uno::Reference< report::XGroup > xGroup(_xSection->getGroup());
+ if ( xGroup.is() )
+ {
+ m_pGroupMulti = new OPropertyChangeMultiplexer(this,xGroup);
+ m_pGroupMulti->addProperty(PROPERTY_EXPRESSION);
+ aEvent.Source = xGroup;
+ aEvent.PropertyName = PROPERTY_EXPRESSION;
+ }
+
+ _propertyChanged(aEvent);
+}
+
+OSectionWindow::~OSectionWindow()
+{
+ disposeOnce();
+}
+
+void OSectionWindow::dispose()
+{
+ try
+ {
+ if ( m_pSectionMulti.is() )
+ m_pSectionMulti->dispose();
+ m_pSectionMulti.clear();
+ if ( m_pGroupMulti.is() )
+ m_pGroupMulti->dispose();
+ m_pGroupMulti.clear();
+ }
+ catch (uno::Exception&)
+ {
+ }
+ m_aStartMarker.disposeAndClear();
+ m_aReportSection.disposeAndClear();
+ m_aSplitter.disposeAndClear();
+ m_aEndMarker.disposeAndClear();
+ m_pParent.clear();
+ vcl::Window::dispose();
+}
+
+void OSectionWindow::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
+{
+ SolarMutexGuard g;
+ const uno::Reference< report::XSection > xSection(_rEvent.Source,uno::UNO_QUERY);
+ if ( xSection.is() )
+ {
+ if ( _rEvent.PropertyName == PROPERTY_HEIGHT )
+ {
+ m_pParent->getView()->SetUpdateMode(false);
+ //Resize();
+ m_pParent->getView()->notifySizeChanged();
+ m_pParent->resize(*this);
+ m_pParent->getView()->SetUpdateMode(true);
+ // getViewsWindow()->getView()->getReportView()->getController().resetZoomType();
+ }
+ else if ( _rEvent.PropertyName == PROPERTY_NAME && !xSection->getGroup().is() )
+ {
+ uno::Reference< report::XReportDefinition > xReport = xSection->getReportDefinition();
+ if ( setReportSectionTitle(xReport,RID_STR_REPORT_HEADER,::std::mem_fn(&OReportHelper::getReportHeader),::std::mem_fn(&OReportHelper::getReportHeaderOn))
+ || setReportSectionTitle(xReport,RID_STR_REPORT_FOOTER,::std::mem_fn(&OReportHelper::getReportFooter),::std::mem_fn(&OReportHelper::getReportFooterOn))
+ || setReportSectionTitle(xReport,RID_STR_PAGE_HEADER,::std::mem_fn(&OReportHelper::getPageHeader),::std::mem_fn(&OReportHelper::getPageHeaderOn))
+ || setReportSectionTitle(xReport,RID_STR_PAGE_FOOTER,::std::mem_fn(&OReportHelper::getPageFooter),::std::mem_fn(&OReportHelper::getPageFooterOn)) )
+ {
+ m_aStartMarker->Invalidate(InvalidateFlags::NoErase);
+ }
+ else
+ {
+ OUString sTitle = RptResId(RID_STR_DETAIL);
+ m_aStartMarker->setTitle(sTitle);
+ m_aStartMarker->Invalidate(InvalidateFlags::Children);
+ }
+ }
+ }
+ else if ( _rEvent.PropertyName == PROPERTY_EXPRESSION )
+ {
+ uno::Reference< report::XGroup > xGroup(_rEvent.Source,uno::UNO_QUERY);
+ if ( xGroup.is() && !setGroupSectionTitle(xGroup,RID_STR_HEADER,::std::mem_fn(&OGroupHelper::getHeader),::std::mem_fn(&OGroupHelper::getHeaderOn)))
+ {
+ setGroupSectionTitle(xGroup,RID_STR_FOOTER,::std::mem_fn(&OGroupHelper::getFooter),::std::mem_fn(&OGroupHelper::getFooterOn));
+ }
+ }
+}
+
+bool OSectionWindow::setReportSectionTitle(
+ const uno::Reference<report::XReportDefinition>& _xReport, TranslateId pResId,
+ const ::std::function<uno::Reference<report::XSection>(OReportHelper*)>& _pGetSection,
+ const ::std::function<bool(OReportHelper*)>& _pIsSectionOn)
+{
+ OReportHelper aReportHelper(_xReport);
+ const bool bRet = _pIsSectionOn(&aReportHelper) && _pGetSection(&aReportHelper) == m_aReportSection->getSection();
+ if ( bRet )
+ {
+ OUString sTitle = RptResId(pResId);
+ m_aStartMarker->setTitle(sTitle);
+ m_aStartMarker->Invalidate(InvalidateFlags::Children);
+ }
+ return bRet;
+}
+
+bool OSectionWindow::setGroupSectionTitle(
+ const uno::Reference<report::XGroup>& _xGroup, TranslateId pResId,
+ const ::std::function<uno::Reference<report::XSection>(OGroupHelper*)>& _pGetSection,
+ const ::std::function<bool(OGroupHelper*)>& _pIsSectionOn)
+{
+ OGroupHelper aGroupHelper(_xGroup);
+ const bool bRet = _pIsSectionOn(&aGroupHelper) && _pGetSection(&aGroupHelper) == m_aReportSection->getSection() ;
+ if ( bRet )
+ {
+ OUString sExpression = _xGroup->getExpression();
+ OUString sLabel = getViewsWindow()->getView()->getReportView()->getController().getColumnLabel_throw(sExpression);
+ if ( !sLabel.isEmpty() )
+ {
+ sExpression = sLabel;
+ }
+
+ OUString sTitle(RptResId(pResId));
+ sTitle = sTitle.replaceFirst("#", sExpression);
+ m_aStartMarker->setTitle( sTitle );
+ m_aStartMarker->Invalidate(InvalidateFlags::Children);
+ }
+ return bRet;
+}
+
+void OSectionWindow::ImplInitSettings()
+{
+ EnableChildTransparentMode();
+ SetParentClipMode( ParentClipMode::NoClip );
+ SetPaintTransparent( true );
+ SetBackground( );
+}
+
+void OSectionWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+void OSectionWindow::Resize()
+{
+ Window::Resize();
+
+ Size aOutputSize = GetOutputSizePixel();
+ tools::Long nEndWidth = tools::Long(REPORT_ENDMARKER_WIDTH * GetMapMode().GetScaleX());
+
+ const Point aThumbPos = m_pParent->getView()->getThumbPos();
+ aOutputSize.AdjustWidth( -(aThumbPos.X()) );
+ aOutputSize.AdjustHeight( -m_aSplitter->GetSizePixel().Height() );
+
+ if ( m_aStartMarker->isCollapsed() )
+ {
+ Point aPos(0,0);
+ m_aStartMarker->SetPosSizePixel(aPos,aOutputSize);
+ }
+ else
+ {
+ const bool bShowEndMarker = m_pParent->getView()->GetTotalWidth() <= (aThumbPos.X() + aOutputSize.Width() );
+
+ tools::Long nStartWidth = tools::Long(REPORT_STARTMARKER_WIDTH * GetMapMode().GetScaleX());
+
+ // set start marker
+ m_aStartMarker->SetPosSizePixel(Point(0,0),Size(nStartWidth,aOutputSize.Height()));
+
+ // set report section
+ const uno::Reference< report::XSection> xSection = m_aReportSection->getSection();
+ Size aSectionSize = LogicToPixel( Size( 0,xSection->getHeight() ) );
+ Point aReportPos(nStartWidth,0);
+ aSectionSize.setWidth( aOutputSize.Width() - nStartWidth );
+ if ( bShowEndMarker )
+ aSectionSize.AdjustWidth( -nEndWidth );
+
+ m_aReportSection->SetPosSizePixel(aReportPos,aSectionSize);
+
+ // set splitter
+ aReportPos.AdjustY(aSectionSize.Height() );
+ m_aSplitter->SetPosSizePixel(aReportPos,Size(aSectionSize.Width(),m_aSplitter->GetSizePixel().Height()));
+ aSectionSize.setHeight( static_cast<tools::Long>(1000 * static_cast<double>(GetMapMode().GetScaleY())) );
+ m_aSplitter->SetDragRectPixel( tools::Rectangle(Point(nStartWidth,0),aSectionSize));
+
+ // set end marker
+ aReportPos.AdjustX(aSectionSize.Width() );
+ aReportPos.setY( 0 );
+ m_aEndMarker->Show(bShowEndMarker);
+ m_aEndMarker->SetPosSizePixel(aReportPos,Size(nEndWidth,aOutputSize.Height()));
+ }
+}
+
+void OSectionWindow::setCollapsed(bool _bCollapsed)
+{
+ if ( m_aStartMarker->isCollapsed() != _bCollapsed )
+ {
+ m_aStartMarker->setCollapsed(_bCollapsed);
+ }
+}
+
+void OSectionWindow::showProperties()
+{
+ m_pParent->getView()->showProperties( m_aReportSection->getSection() );
+}
+
+void OSectionWindow::setMarked(bool _bMark)
+{
+ m_aStartMarker->setMarked(_bMark);
+ m_aEndMarker->setMarked(_bMark);
+}
+
+IMPL_LINK( OSectionWindow, Collapsed, OColorListener&, _rMarker, void )
+{
+ bool bShow = !_rMarker.isCollapsed();
+ m_aReportSection->Show(bShow);
+ m_aEndMarker->Show(bShow);
+ m_aSplitter->Show(bShow);
+
+ m_pParent->resize(*this);
+}
+
+void OSectionWindow::zoom(const Fraction& _aZoom)
+{
+ setZoomFactor(_aZoom,*this);
+ m_aStartMarker->zoom(_aZoom);
+
+ setZoomFactor(_aZoom, *m_aReportSection);
+ setZoomFactor(_aZoom, *m_aSplitter);
+ setZoomFactor(_aZoom, *m_aEndMarker);
+ Invalidate();
+}
+
+IMPL_LINK_NOARG( OSectionWindow, StartSplitHdl, Splitter*, void)
+{
+ const OUString sUndoAction( RptResId( RID_STR_UNDO_CHANGE_SIZE ) );
+ getViewsWindow()->getView()->getReportView()->getController().getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) );
+}
+
+IMPL_LINK_NOARG( OSectionWindow, EndSplitHdl, Splitter*, void )
+{
+ getViewsWindow()->getView()->getReportView()->getController().getUndoManager().LeaveListAction();
+}
+
+IMPL_LINK( OSectionWindow, SplitHdl, Splitter*, _pSplitter, void )
+{
+ if ( !getViewsWindow()->getView()->getReportView()->getController().isEditable() )
+ {
+ return;
+ }
+
+ sal_Int32 nSplitPos = _pSplitter->GetSplitPosPixel();
+
+ const uno::Reference< report::XSection> xSection = m_aReportSection->getSection();
+ nSplitPos = m_aSplitter->PixelToLogic(Size(0,nSplitPos)).Height();
+
+ const sal_Int32 nCount = xSection->getCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference<report::XReportComponent> xReportComponent(xSection->getByIndex(i),uno::UNO_QUERY);
+ if ( xReportComponent.is() )
+ {
+ nSplitPos = ::std::max(nSplitPos,xReportComponent->getPositionY() + xReportComponent->getHeight());
+ }
+ }
+
+ if ( nSplitPos < 0 )
+ nSplitPos = 0;
+
+ xSection->setHeight(nSplitPos);
+ m_aSplitter->SetSplitPosPixel(m_aSplitter->LogicToPixel(Size(0,nSplitPos)).Height());
+}
+
+static void lcl_scroll(vcl::Window& _rWindow,const Point& _aDelta)
+{
+ _rWindow.Scroll(-_aDelta.X(),-_aDelta.Y());
+ _rWindow.Invalidate(InvalidateFlags::Transparent);
+}
+
+static void lcl_setOrigin(vcl::Window& _rWindow,tools::Long _nX, tools::Long _nY)
+{
+ MapMode aMap = _rWindow.GetMapMode();
+ aMap.SetOrigin( Point(- _nX, - _nY));
+ _rWindow.SetMapMode( aMap );
+}
+
+void OSectionWindow::scrollChildren(tools::Long _nX)
+{
+ const Point aDelta( _nX,0 );
+
+ MapMode aMapMode( m_aReportSection->GetMapMode() );
+ const Point aOld = aMapMode.GetOrigin();
+ lcl_setOrigin(*m_aReportSection, aDelta.X(), 0);
+
+ aMapMode = m_aReportSection->GetMapMode();
+ const Point aNew = aMapMode.GetOrigin();
+ const Point aDiff = aOld - aNew;
+ {
+ lcl_scroll(*m_aReportSection, aDiff);
+ }
+
+ lcl_scroll(*m_aEndMarker, m_aEndMarker->PixelToLogic(Point(_nX,0)));
+
+ lcl_setOrigin(*m_aSplitter,_nX, 0);
+ lcl_scroll(*m_aSplitter,aDiff);
+}
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/StartMarker.cxx b/reportdesign/source/ui/report/StartMarker.cxx
new file mode 100644
index 000000000..3d05f2910
--- /dev/null
+++ b/reportdesign/source/ui/report/StartMarker.cxx
@@ -0,0 +1,304 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <StartMarker.hxx>
+#include <UITools.hxx>
+#include <vcl/image.hxx>
+#include <vcl/svapp.hxx>
+#include <bitmaps.hlst>
+#include <ColorChanger.hxx>
+#include <ReportDefines.hxx>
+#include <SectionWindow.hxx>
+#include <vcl/event.hxx>
+#include <vcl/help.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/lineinfo.hxx>
+#include <vcl/settings.hxx>
+
+#include <unotools/syslocale.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#define CORNER_SPACE 5
+
+
+namespace rptui
+{
+
+
+Image* OStartMarker::s_pDefCollapsed = nullptr;
+Image* OStartMarker::s_pDefExpanded = nullptr;
+oslInterlockedCount OStartMarker::s_nImageRefCount = 0;
+
+
+OStartMarker::OStartMarker(OSectionWindow* _pParent,const OUString& _sColorEntry)
+ : OColorListener(_pParent,_sColorEntry)
+ , m_aVRuler(VclPtr<Ruler>::Create(this,WB_VERT))
+ , m_pParent(_pParent)
+ , m_bShowRuler(true)
+{
+ osl_atomic_increment(&s_nImageRefCount);
+ initDefaultNodeImages();
+ ImplInitSettings();
+ m_aVRuler->Show();
+ m_aVRuler->Activate();
+ m_aVRuler->SetPagePos();
+ m_aVRuler->SetBorders();
+ m_aVRuler->SetIndents();
+ m_aVRuler->SetMargin1();
+ m_aVRuler->SetMargin2();
+ const MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
+ m_aVRuler->SetUnit(MeasurementSystem::Metric == eSystem ? FieldUnit::CM : FieldUnit::INCH);
+ EnableChildTransparentMode();
+ SetParentClipMode( ParentClipMode::NoClip );
+ SetPaintTransparent( true );
+}
+
+OStartMarker::~OStartMarker()
+{
+ disposeOnce();
+}
+
+void OStartMarker::dispose()
+{
+ if ( osl_atomic_decrement(&s_nImageRefCount) == 0 )
+ {
+ delete s_pDefCollapsed;
+ s_pDefCollapsed = nullptr;
+ delete s_pDefExpanded;
+ s_pDefExpanded = nullptr;
+ }
+ m_aVRuler.disposeAndClear();
+ m_pParent.clear();
+ OColorListener::dispose();
+}
+
+sal_Int32 OStartMarker::getMinHeight() const
+{
+ Fraction aExtraWidth(tools::Long(2 * REPORT_EXTRA_SPACE));
+ aExtraWidth *= GetMapMode().GetScaleX();
+ return LogicToPixel(Size(0, GetTextHeight())).Height() + tools::Long(aExtraWidth);
+}
+
+void OStartMarker::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
+{
+ rRenderContext.Push(vcl::PushFlags::TEXTCOLOR);
+
+ Size aSize(GetOutputSizePixel());
+ const tools::Long nCornerWidth = tools::Long(CORNER_SPACE * double(GetMapMode().GetScaleX()));
+
+ if (isCollapsed())
+ {
+ rRenderContext.SetClipRegion();
+ }
+ else
+ {
+ const tools::Long nVRulerWidth = m_aVRuler->GetSizePixel().Width();
+ tools::Long nSize = aSize.Width() - nVRulerWidth;
+ aSize.AdjustWidth(nCornerWidth );
+ rRenderContext.SetClipRegion(vcl::Region(rRenderContext.PixelToLogic(tools::Rectangle(Point(),
+ Size(nSize, aSize.Height())))));
+ }
+
+ tools::Rectangle aWholeRect(Point(), aSize);
+ {
+ const ColorChanger aColors(&rRenderContext, m_nTextBoundaries, m_nColor);
+ tools::PolyPolygon aPoly;
+ aPoly.Insert( tools::Polygon(aWholeRect,nCornerWidth,nCornerWidth));
+
+ Color aStartColor(m_nColor);
+ aStartColor.IncreaseLuminance(10);
+ sal_uInt16 nHue = 0;
+ sal_uInt16 nSat = 0;
+ sal_uInt16 nBri = 0;
+ aStartColor.RGBtoHSB(nHue, nSat, nBri);
+ nSat += 40;
+ Color aEndColor(Color::HSBtoRGB(nHue, nSat, nBri));
+ Gradient aGradient(GradientStyle::Linear,aStartColor,aEndColor);
+ aGradient.SetSteps(static_cast<sal_uInt16>(aSize.Height()));
+
+ rRenderContext.DrawGradient(PixelToLogic(aPoly) ,aGradient);
+ }
+
+ rRenderContext.Push(vcl::PushFlags::MAPMODE);
+ rRenderContext.SetMapMode();
+
+ rRenderContext.DrawImage(m_aImageRect.TopLeft(), m_aImageRect.GetSize(), m_aImage);
+
+ const Color aColor(m_nColor);
+ Color aTextColor = GetTextColor();
+ if (aColor.GetLuminance() < 128)
+ aTextColor = COL_WHITE;
+ rRenderContext.SetTextColor(aTextColor);
+
+ rRenderContext.DrawText(m_aTextRect, m_aText, DrawTextFlags::MultiLine | DrawTextFlags::WordBreakHyphenation);
+
+ rRenderContext.Pop();
+
+ if (m_bMarked)
+ {
+ const tools::Long nCornerHeight = tools::Long(CORNER_SPACE * double(GetMapMode().GetScaleY()));
+ tools::Rectangle aRect(Point(nCornerWidth, nCornerHeight),
+ Size(aSize.Width() - nCornerWidth - nCornerWidth,
+ aSize.Height() - nCornerHeight - nCornerHeight));
+ ColorChanger aColors(&rRenderContext, COL_WHITE, COL_WHITE);
+ rRenderContext.DrawPolyLine( tools::Polygon(rRenderContext.PixelToLogic(aRect)),
+ LineInfo(LineStyle::Solid, 2));
+ }
+
+ rRenderContext.Pop();
+}
+
+void OStartMarker::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( !rMEvt.IsLeft() )
+ return;
+
+ Point aPos( rMEvt.GetPosPixel());
+
+ const Size aOutputSize = GetOutputSizePixel();
+ if( aPos.X() > aOutputSize.Width() || aPos.Y() > aOutputSize.Height() )
+ return;
+ if ( rMEvt.GetClicks() == 2 || m_aImageRect.Contains( aPos ) )
+ {
+ m_bCollapsed = !m_bCollapsed;
+
+ changeImage();
+
+ m_aVRuler->Show(!m_bCollapsed && m_bShowRuler);
+ m_aCollapsedLink.Call(*this);
+ }
+
+ m_pParent->showProperties();
+}
+
+void OStartMarker::changeImage()
+{
+ m_aImage = m_bCollapsed ? *s_pDefCollapsed : *s_pDefExpanded;
+}
+
+void OStartMarker::initDefaultNodeImages()
+{
+ if ( !s_pDefCollapsed )
+ {
+ s_pDefCollapsed = new Image(StockImage::Yes, RID_BMP_TREENODE_COLLAPSED);
+ s_pDefExpanded = new Image(StockImage::Yes, RID_BMP_TREENODE_EXPANDED);
+ }
+
+ m_aImage = m_bCollapsed ? *s_pDefCollapsed : *s_pDefExpanded;
+}
+
+void OStartMarker::ApplySettings(vcl::RenderContext& rRenderContext)
+{
+ rRenderContext.SetBackground();
+ rRenderContext.SetFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
+}
+
+void OStartMarker::ImplInitSettings()
+{
+ ApplySettings(*GetOutDev());
+}
+
+void OStartMarker::Resize()
+{
+ const Size aOutputSize( GetOutputSizePixel() );
+ const tools::Long nOutputWidth = aOutputSize.Width();
+ const tools::Long nOutputHeight = aOutputSize.Height();
+
+ const tools::Long nVRulerWidth = m_aVRuler->GetSizePixel().Width();
+ const Point aRulerPos(nOutputWidth - nVRulerWidth,0);
+ m_aVRuler->SetPosSizePixel(aRulerPos,Size(nVRulerWidth,nOutputHeight));
+
+ Size aImageSize = m_aImage.GetSizePixel();
+ const MapMode& rMapMode = GetMapMode();
+ aImageSize.setWidth( tools::Long(aImageSize.Width() * static_cast<double>(rMapMode.GetScaleX())) );
+ aImageSize.setHeight( tools::Long(aImageSize.Height() * static_cast<double>(rMapMode.GetScaleY())) );
+
+ tools::Long nExtraWidth = tools::Long(REPORT_EXTRA_SPACE * rMapMode.GetScaleX());
+
+ Point aPos(aImageSize.Width() + (nExtraWidth * 2), nExtraWidth);
+ const tools::Long nHeight = ::std::max<sal_Int32>(nOutputHeight - 2*aPos.Y(),LogicToPixel(Size(0, GetTextHeight())).Height());
+ m_aTextRect = tools::Rectangle(aPos, Size(aRulerPos.X() - aPos.X(),nHeight));
+
+ aPos.setX( nExtraWidth );
+ aPos.AdjustY(static_cast<sal_Int32>((LogicToPixel(Size(0, GetTextHeight())).Height() - aImageSize.Height()) * 0.5) ) ;
+ m_aImageRect = tools::Rectangle(aPos, aImageSize);
+
+ OColorListener::Resize();
+}
+
+void OStartMarker::setTitle(const OUString& rTitle)
+{
+ if (m_aText != rTitle)
+ {
+ m_aText = rTitle;
+ Invalidate();
+ }
+}
+
+void OStartMarker::Notify(SfxBroadcaster & rBc, SfxHint const & rHint)
+{
+ OColorListener::Notify(rBc, rHint);
+ if (rHint.GetId() == SfxHintId::ColorsChanged)
+ {
+ Invalidate(InvalidateFlags::Children);
+ }
+}
+
+void OStartMarker::showRuler(bool _bShow)
+{
+ m_bShowRuler = _bShow;
+ m_aVRuler->Show(!m_bCollapsed && m_bShowRuler);
+}
+
+void OStartMarker::RequestHelp( const HelpEvent& rHEvt )
+{
+ if (m_aText.isEmpty())
+ return;
+
+ // show help
+ tools::Rectangle aItemRect(rHEvt.GetMousePosPixel(),Size(GetSizePixel().Width(),getMinHeight()));
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.SetLeft( aPt.X() );
+ aItemRect.SetTop( aPt.Y() );
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.SetRight( aPt.X() );
+ aItemRect.SetBottom( aPt.Y() );
+ if( rHEvt.GetMode() == HelpEventMode::BALLOON )
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, m_aText);
+ else
+ Help::ShowQuickHelp( this, aItemRect, m_aText );
+}
+
+void OStartMarker::setCollapsed(bool _bCollapsed)
+{
+ OColorListener::setCollapsed(_bCollapsed);
+ showRuler(_bCollapsed);
+ changeImage();
+}
+
+void OStartMarker::zoom(const Fraction& _aZoom)
+{
+ setZoomFactor(_aZoom, *this);
+ m_aVRuler->SetZoom(_aZoom);
+ Resize();
+ Invalidate();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/ViewsWindow.cxx b/reportdesign/source/ui/report/ViewsWindow.cxx
new file mode 100644
index 000000000..b5ce7a48f
--- /dev/null
+++ b/reportdesign/source/ui/report/ViewsWindow.cxx
@@ -0,0 +1,1673 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <ViewsWindow.hxx>
+#include <ScrollHelper.hxx>
+#include <UndoActions.hxx>
+#include <ReportWindow.hxx>
+#include <DesignView.hxx>
+#include <svtools/colorcfg.hxx>
+#include <ReportController.hxx>
+#include <UITools.hxx>
+#include <RptDef.hxx>
+#include <strings.hrc>
+#include <SectionView.hxx>
+#include <ReportSection.hxx>
+#include <strings.hxx>
+#include <rptui_slotid.hrc>
+#include <dlgedclip.hxx>
+#include <RptObject.hxx>
+#include <EndMarker.hxx>
+#include <sal/log.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <core_resource.hxx>
+#include <svx/svdundo.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <algorithm>
+#include <cstdlib>
+#include <numeric>
+
+namespace rptui
+{
+#define DEFAUL_MOVE_SIZE 100
+
+using namespace ::com::sun::star;
+using namespace ::comphelper;
+
+static bool lcl_getNewRectSize(const tools::Rectangle& _aObjRect,tools::Long& _nXMov, tools::Long& _nYMov,SdrObject const * _pObj,SdrView const * _pView, ControlModification _nControlModification)
+{
+ bool bMoveAllowed = _nXMov != 0 || _nYMov != 0;
+ if ( bMoveAllowed )
+ {
+ tools::Rectangle aNewRect = _aObjRect;
+ SdrObject* pOverlappedObj = nullptr;
+ do
+ {
+ aNewRect = _aObjRect;
+ switch(_nControlModification)
+ {
+ case ControlModification::HEIGHT_GREATEST:
+ case ControlModification::WIDTH_GREATEST:
+ aNewRect.setWidth(_nXMov);
+ aNewRect.setHeight(_nYMov);
+ break;
+ default:
+ aNewRect.Move(_nXMov,_nYMov);
+ break;
+ }
+ if (dynamic_cast<OUnoObject const *>(_pObj) != nullptr || dynamic_cast<OOle2Obj const *>(_pObj) != nullptr)
+ {
+ pOverlappedObj = isOver(aNewRect,*_pObj->getSdrPageFromSdrObject(),*_pView,true,_pObj);
+ if ( pOverlappedObj && _pObj != pOverlappedObj )
+ {
+ tools::Rectangle aOverlappingRect = pOverlappedObj->GetSnapRect();
+ sal_Int32 nXTemp = _nXMov;
+ sal_Int32 nYTemp = _nYMov;
+ switch(_nControlModification)
+ {
+ case ControlModification::LEFT:
+ nXTemp += aOverlappingRect.Right() - aNewRect.Left();
+ bMoveAllowed = _nXMov != nXTemp;
+ break;
+ case ControlModification::RIGHT:
+ nXTemp += aOverlappingRect.Left() - aNewRect.Right();
+ bMoveAllowed = _nXMov != nXTemp;
+ break;
+ case ControlModification::TOP:
+ nYTemp += aOverlappingRect.Bottom() - aNewRect.Top();
+ bMoveAllowed = _nYMov != nYTemp;
+ break;
+ case ControlModification::BOTTOM:
+ nYTemp += aOverlappingRect.Top() - aNewRect.Bottom();
+ bMoveAllowed = _nYMov != nYTemp;
+ break;
+ case ControlModification::CENTER_HORIZONTAL:
+ if ( _aObjRect.Left() < aOverlappingRect.Left() )
+ nXTemp += aOverlappingRect.Left() - aNewRect.Left() - aNewRect.getWidth();
+ else
+ nXTemp += aOverlappingRect.Right() - aNewRect.Left();
+ bMoveAllowed = _nXMov != nXTemp;
+ break;
+ case ControlModification::CENTER_VERTICAL:
+ if ( _aObjRect.Top() < aOverlappingRect.Top() )
+ nYTemp += aOverlappingRect.Top() - aNewRect.Top() - aNewRect.getHeight();
+ else
+ nYTemp += aOverlappingRect.Bottom() - aNewRect.Top();
+ bMoveAllowed = _nYMov != nYTemp;
+ break;
+ case ControlModification::HEIGHT_GREATEST:
+ case ControlModification::WIDTH_GREATEST:
+ {
+ tools::Rectangle aIntersectionRect = aNewRect.GetIntersection(aOverlappingRect);
+ if ( !aIntersectionRect.IsEmpty() )
+ {
+ if ( _nControlModification == ControlModification::WIDTH_GREATEST )
+ {
+ if ( aNewRect.Left() < aIntersectionRect.Left() )
+ {
+ aNewRect.SetRight( aIntersectionRect.Left() );
+ }
+ else if ( aNewRect.Left() < aIntersectionRect.Right() )
+ {
+ aNewRect.SetLeft( aIntersectionRect.Right() );
+ }
+ }
+ else if ( _nControlModification == ControlModification::HEIGHT_GREATEST )
+ {
+ if ( aNewRect.Top() < aIntersectionRect.Top() )
+ {
+ aNewRect.SetBottom( aIntersectionRect.Top() );
+ }
+ else if ( aNewRect.Top() < aIntersectionRect.Bottom() )
+ {
+ aNewRect.SetTop( aIntersectionRect.Bottom() );
+ }
+ }
+ nYTemp = aNewRect.getHeight();
+ bMoveAllowed = _nYMov != nYTemp;
+ nXTemp = aNewRect.getWidth();
+ bMoveAllowed = bMoveAllowed && _nXMov != nXTemp;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ _nXMov = nXTemp;
+ _nYMov = nYTemp;
+ }
+ else
+ pOverlappedObj = nullptr;
+ }
+ }
+ while ( pOverlappedObj && bMoveAllowed );
+ }
+ return bMoveAllowed;
+}
+
+OViewsWindow::OViewsWindow( OReportWindow* _pReportWindow)
+ : Window( _pReportWindow,WB_DIALOGCONTROL)
+ , m_pParent(_pReportWindow)
+ , m_bInUnmark(false)
+{
+ SetPaintTransparent(true);
+ SetMapMode(MapMode(MapUnit::Map100thMM));
+ m_aColorConfig.AddListener(this);
+ ImplInitSettings();
+}
+
+OViewsWindow::~OViewsWindow()
+{
+ disposeOnce();
+}
+
+void OViewsWindow::dispose()
+{
+ m_aColorConfig.RemoveListener(this);
+ for (auto& rxSection : m_aSections)
+ rxSection.disposeAndClear();
+ m_aSections.clear();
+ m_pParent.clear();
+ vcl::Window::dispose();
+}
+
+void OViewsWindow::impl_resizeSectionWindow(OSectionWindow& _rSectionWindow,Point& _rStartPoint,bool _bSet)
+{
+ const uno::Reference< report::XSection> xSection = _rSectionWindow.getReportSection().getSection();
+
+ Size aSectionSize = _rSectionWindow.LogicToPixel( Size( 0,xSection->getHeight() ) );
+ aSectionSize.setWidth( getView()->GetTotalWidth() );
+
+ const sal_Int32 nMinHeight = _rSectionWindow.getStartMarker().getMinHeight();
+ if ( _rSectionWindow.getStartMarker().isCollapsed() || nMinHeight > aSectionSize.Height() )
+ {
+ aSectionSize.setHeight( nMinHeight );
+ }
+ aSectionSize.AdjustHeight(static_cast<tools::Long>(StyleSettings::GetSplitSize() * static_cast<double>(_rSectionWindow.GetMapMode().GetScaleY())) );
+
+ if ( _bSet )
+ _rSectionWindow.SetPosSizePixel(_rStartPoint,aSectionSize);
+
+ _rStartPoint.AdjustY(aSectionSize.Height() );
+}
+
+
+void OViewsWindow::resize(const OSectionWindow& _rSectionWindow)
+{
+ bool bSet = false;
+ Point aStartPoint;
+ for (VclPtr<OSectionWindow> const & pSectionWindow : m_aSections)
+ {
+ if ( pSectionWindow == &_rSectionWindow )
+ {
+ aStartPoint = pSectionWindow->GetPosPixel();
+ bSet = true;
+ }
+
+ if ( bSet )
+ {
+ impl_resizeSectionWindow(*pSectionWindow,aStartPoint,bSet);
+ static const InvalidateFlags nIn = InvalidateFlags::Update | InvalidateFlags::Transparent;
+ pSectionWindow->getStartMarker().Invalidate( nIn ); // InvalidateFlags::NoErase |InvalidateFlags::NoChildren| InvalidateFlags::Transparent
+ pSectionWindow->getEndMarker().Invalidate( nIn );
+ }
+ }
+ m_pParent->notifySizeChanged();
+}
+
+void OViewsWindow::Resize()
+{
+ Window::Resize();
+ if ( !m_aSections.empty() )
+ {
+ const Point aOffset(m_pParent->getThumbPos());
+ Point aStartPoint(0,-aOffset.Y());
+ for (VclPtr<OSectionWindow> const & pSectionWindow : m_aSections)
+ {
+ impl_resizeSectionWindow(*pSectionWindow,aStartPoint,true);
+ }
+ }
+}
+
+void OViewsWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+{
+ Window::Paint(rRenderContext, rRect);
+
+ rRenderContext.SetBackground();
+ rRenderContext.SetFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
+ rRenderContext.SetTextFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
+
+ Size aOut(GetOutputSizePixel());
+ tools::Long nStartWidth = tools::Long(REPORT_STARTMARKER_WIDTH * rRenderContext.GetMapMode().GetScaleX());
+
+ aOut.AdjustWidth( -nStartWidth );
+ aOut = rRenderContext.PixelToLogic(aOut);
+
+ tools::Rectangle aRect(rRenderContext.PixelToLogic(Point(nStartWidth,0)), aOut);
+ Wallpaper aWall(m_aColorConfig.GetColorValue(::svtools::APPBACKGROUND).nColor);
+ rRenderContext.DrawWallpaper(aRect, aWall);
+}
+
+void OViewsWindow::ImplInitSettings()
+{
+ EnableChildTransparentMode();
+}
+
+void OViewsWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+void OViewsWindow::addSection(const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry,sal_uInt16 _nPosition)
+{
+ VclPtrInstance<OSectionWindow> pSectionWindow(this,_xSection,_sColorEntry);
+ m_aSections.insert(getIteratorAtPos(_nPosition) , TSectionsMap::value_type(pSectionWindow));
+ m_pParent->setMarked(&pSectionWindow->getReportSection().getSectionView(),m_aSections.size() == 1);
+ Resize();
+}
+
+void OViewsWindow::removeSection(sal_uInt16 _nPosition)
+{
+ if ( _nPosition < m_aSections.size() )
+ {
+ TSectionsMap::iterator aPos = getIteratorAtPos(_nPosition);
+ TSectionsMap::const_iterator aNew = getIteratorAtPos(_nPosition == 0 ? _nPosition+1: _nPosition - 1);
+
+ m_pParent->getReportView()->UpdatePropertyBrowserDelayed((*aNew)->getReportSection().getSectionView());
+
+ aPos->disposeAndClear();
+ m_aSections.erase(aPos);
+ Resize();
+ }
+}
+
+void OViewsWindow::toggleGrid(bool _bVisible)
+{
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [_bVisible] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getReportSection().SetGridVisible(_bVisible);
+ });
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getReportSection().Window::Invalidate(InvalidateFlags::NoErase);
+ });
+}
+
+sal_Int32 OViewsWindow::getTotalHeight() const
+{
+ return std::accumulate(m_aSections.begin(), m_aSections.end(), sal_Int32(0),
+ [](const sal_Int32 nHeight, const VclPtr<OSectionWindow>& rxSection) { return nHeight + rxSection->GetSizePixel().Height(); });
+}
+
+sal_uInt16 OViewsWindow::getSectionCount() const
+{
+ return static_cast<sal_uInt16>(m_aSections.size());
+}
+
+void OViewsWindow::SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType )
+{
+ for (const auto& rxSection : m_aSections)
+ rxSection->getReportSection().getSectionView().SetCurrentObj( eObj, SdrInventor::ReportDesign );
+
+ m_sShapeType = _sShapeType;
+}
+
+
+void OViewsWindow::SetMode( DlgEdMode eNewMode )
+{
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [&eNewMode] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getReportSection().SetMode(eNewMode);
+ });
+}
+
+bool OViewsWindow::HasSelection() const
+{
+ return std::any_of(m_aSections.begin(), m_aSections.end(),
+ [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().AreObjectsMarked(); });
+}
+
+void OViewsWindow::Delete()
+{
+ m_bInUnmark = true;
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getReportSection().Delete();
+ });
+ m_bInUnmark = false;
+}
+
+void OViewsWindow::Copy()
+{
+ uno::Sequence< beans::NamedValue > aAllreadyCopiedObjects;
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [&aAllreadyCopiedObjects] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getReportSection().Copy(aAllreadyCopiedObjects);
+ });
+
+ rtl::Reference<OReportExchange> pCopy = new OReportExchange(aAllreadyCopiedObjects);
+ pCopy->CopyToClipboard(this);
+}
+
+void OViewsWindow::Paste()
+{
+ TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(this));
+ OReportExchange::TSectionElements aCopies = OReportExchange::extractCopies(aTransferData);
+ if ( aCopies.getLength() > 1 )
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [&aCopies] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getReportSection().Paste(aCopies);
+ });
+ else
+ {
+ OSectionWindow* pMarkedSection = getMarkedSection();
+ if ( pMarkedSection )
+ pMarkedSection->getReportSection().Paste(aCopies,true);
+ }
+}
+
+OSectionWindow* OViewsWindow::getSectionWindow(const uno::Reference< report::XSection>& _xSection) const
+{
+ OSL_ENSURE(_xSection.is(),"Section is NULL!");
+
+ OSectionWindow* pSectionWindow = nullptr;
+ for (VclPtr<OSectionWindow> const & p : m_aSections)
+ {
+ if (p->getReportSection().getSection() == _xSection)
+ {
+ pSectionWindow = p.get();
+ break;
+ }
+ }
+
+ return pSectionWindow;
+}
+
+
+OSectionWindow* OViewsWindow::getMarkedSection(NearSectionAccess nsa) const
+{
+ OSectionWindow* pRet = nullptr;
+ TSectionsMap::const_iterator aIter = m_aSections.begin();
+ TSectionsMap::const_iterator aEnd = m_aSections.end();
+ sal_uInt32 nCurrentPosition = 0;
+ for (; aIter != aEnd ; ++aIter)
+ {
+ if ( (*aIter)->getStartMarker().isMarked() )
+ {
+ if (nsa == CURRENT)
+ {
+ pRet = aIter->get();
+ break;
+ }
+ else if ( nsa == PREVIOUS )
+ {
+ if (nCurrentPosition > 0)
+ {
+ pRet = (--aIter)->get();
+ if (pRet == nullptr)
+ {
+ pRet = m_aSections.begin()->get();
+ }
+ }
+ else
+ {
+ // if we are out of bounds return the first one
+ pRet = m_aSections.begin()->get();
+ }
+ break;
+ }
+ else if ( nsa == POST )
+ {
+ sal_uInt32 nSize = m_aSections.size();
+ if ((nCurrentPosition + 1) < nSize)
+ {
+ pRet = (++aIter)->get();
+ if (pRet == nullptr)
+ {
+ pRet = (--aEnd)->get();
+ }
+ }
+ else
+ {
+ // if we are out of bounds return the last one
+ pRet = (--aEnd)->get();
+ }
+ break;
+ }
+ }
+ ++nCurrentPosition;
+ }
+
+ return pRet;
+}
+
+void OViewsWindow::markSection(const sal_uInt16 _nPos)
+{
+ if ( _nPos < m_aSections.size() )
+ m_pParent->setMarked(m_aSections[_nPos]->getReportSection().getSection(),true);
+}
+
+bool OViewsWindow::IsPasteAllowed() const
+{
+ TransferableDataHelper aTransferData( TransferableDataHelper::CreateFromSystemClipboard( const_cast< OViewsWindow* >( this ) ) );
+ return aTransferData.HasFormat(OReportExchange::getDescriptorFormatId());
+}
+
+void OViewsWindow::SelectAll(const SdrObjKind _nObjectType)
+{
+ m_bInUnmark = true;
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [&_nObjectType] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getReportSection().SelectAll(_nObjectType);
+ });
+ m_bInUnmark = false;
+}
+
+void OViewsWindow::unmarkAllObjects(OSectionView const * _pSectionView)
+{
+ if ( m_bInUnmark )
+ return;
+
+ m_bInUnmark = true;
+ for (const auto& rxSection : m_aSections)
+ {
+ if ( &rxSection->getReportSection().getSectionView() != _pSectionView )
+ {
+ rxSection->getReportSection().deactivateOle();
+ rxSection->getReportSection().getSectionView().UnmarkAllObj();
+ }
+ }
+ m_bInUnmark = false;
+}
+
+void OViewsWindow::ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints)
+{
+ ImplInitSettings();
+ Invalidate();
+}
+
+void OViewsWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ {
+ GrabFocus();
+ const uno::Sequence< beans::PropertyValue> aArgs;
+ getView()->getReportView()->getController().executeChecked(SID_SELECT_REPORT,aArgs);
+ }
+ Window::MouseButtonDown(rMEvt);
+}
+
+void OViewsWindow::showRuler(bool _bShow)
+{
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [_bShow] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getStartMarker().showRuler(_bShow);
+ });
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getStartMarker().Window::Invalidate(InvalidateFlags::NoErase);
+ });
+}
+
+void OViewsWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( !rMEvt.IsLeft() )
+ return;
+
+ auto aIter = std::find_if(m_aSections.begin(), m_aSections.end(),
+ [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().AreObjectsMarked(); });
+ if (aIter != m_aSections.end())
+ {
+ (*aIter)->getReportSection().MouseButtonUp(rMEvt);
+ }
+
+ // remove special insert mode
+ for (const auto& rxSection : m_aSections)
+ {
+ rxSection->getReportSection().getPage()->resetSpecialMode();
+ }
+}
+
+bool OViewsWindow::handleKeyEvent(const KeyEvent& _rEvent)
+{
+ bool bRet = false;
+ for (const auto& rxSection : m_aSections)
+ {
+ if ( rxSection->getStartMarker().isMarked() )
+ {
+ bRet = rxSection->getReportSection().handleKeyEvent(_rEvent);
+ }
+ }
+ return bRet;
+}
+
+OViewsWindow::TSectionsMap::iterator OViewsWindow::getIteratorAtPos(sal_uInt16 _nPos)
+{
+ TSectionsMap::iterator aRet = m_aSections.end();
+ if ( _nPos < m_aSections.size() )
+ aRet = m_aSections.begin() + _nPos;
+ return aRet;
+}
+
+void OViewsWindow::setMarked(OSectionView const * _pSectionView, bool _bMark)
+{
+ OSL_ENSURE(_pSectionView != nullptr,"SectionView is NULL!");
+ if ( _pSectionView )
+ setMarked(_pSectionView->getReportSection()->getSection(),_bMark);
+}
+
+void OViewsWindow::setMarked(const uno::Reference< report::XSection>& _xSection, bool _bMark)
+{
+ for (const auto& rxSection : m_aSections)
+ {
+ if ( rxSection->getReportSection().getSection() != _xSection )
+ {
+ rxSection->setMarked(false);
+ }
+ else if ( rxSection->getStartMarker().isMarked() != _bMark )
+ {
+ rxSection->setMarked(_bMark);
+ }
+ }
+}
+
+void OViewsWindow::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _aShapes, bool _bMark)
+{
+ bool bFirst = true;
+ for(const uno::Reference< report::XReportComponent>& rShape : _aShapes)
+ {
+ const uno::Reference< report::XSection> xSection = rShape->getSection();
+ if ( xSection.is() )
+ {
+ if ( bFirst )
+ {
+ bFirst = false;
+ m_pParent->setMarked(xSection,_bMark);
+ }
+ OSectionWindow* pSectionWindow = getSectionWindow(xSection);
+ if ( pSectionWindow )
+ {
+ SdrObject* pObject = SdrObject::getSdrObjectFromXShape( rShape );
+ OSL_ENSURE( pObject, "OViewsWindow::setMarked: no SdrObject for the shape!" );
+ if ( pObject )
+ pSectionWindow->getReportSection().getSectionView().MarkObj( pObject, pSectionWindow->getReportSection().getSectionView().GetSdrPageView(), !_bMark );
+ }
+ }
+ }
+}
+
+void OViewsWindow::collectRectangles(TRectangleMap& _rSortRectangles)
+{
+ for (const auto& rxSection : m_aSections)
+ {
+ OSectionView& rView = rxSection->getReportSection().getSectionView();
+ if ( rView.AreObjectsMarked() )
+ {
+ rView.SortMarkedObjects();
+ const size_t nCount = rView.GetMarkedObjectCount();
+ for (size_t i=0; i < nCount; ++i)
+ {
+ const SdrMark* pM = rView.GetSdrMarkByIndex(i);
+ SdrObject* pObj = pM->GetMarkedSdrObj();
+ tools::Rectangle aObjRect(pObj->GetSnapRect());
+ _rSortRectangles.emplace(aObjRect,TRectangleMap::mapped_type(pObj,&rView));
+ }
+ }
+ }
+}
+
+void OViewsWindow::collectBoundResizeRect(const TRectangleMap& _rSortRectangles, ControlModification _nControlModification,bool _bAlignAtSection, tools::Rectangle& _rBound, tools::Rectangle& _rResize)
+{
+ bool bOnlyOnce = false;
+ for (const auto& [aObjRect, rObjViewPair] : _rSortRectangles)
+ {
+ if ( _rResize.IsEmpty() )
+ _rResize = aObjRect;
+ switch(_nControlModification)
+ {
+ case ControlModification::WIDTH_SMALLEST:
+ if ( _rResize.getWidth() > aObjRect.getWidth() )
+ _rResize = aObjRect;
+ break;
+ case ControlModification::HEIGHT_SMALLEST:
+ if ( _rResize.getHeight() > aObjRect.getHeight() )
+ _rResize = aObjRect;
+ break;
+ case ControlModification::WIDTH_GREATEST:
+ if ( _rResize.getWidth() < aObjRect.getWidth() )
+ _rResize = aObjRect;
+ break;
+ case ControlModification::HEIGHT_GREATEST:
+ if ( _rResize.getHeight() < aObjRect.getHeight() )
+ _rResize = aObjRect;
+ break;
+ default: break;
+ }
+
+ SdrObjTransformInfoRec aInfo;
+ const SdrObject* pObj = rObjViewPair.first;
+ pObj->TakeObjInfo(aInfo);
+ bool bHasFixed = !aInfo.bMoveAllowed || pObj->IsMoveProtect();
+ if ( bHasFixed )
+ _rBound.Union(aObjRect);
+ else
+ {
+ if ( _bAlignAtSection || _rSortRectangles.size() == 1 )
+ { // align single object at the page
+ if ( ! bOnlyOnce )
+ {
+ bOnlyOnce = true;
+ OReportSection* pReportSection = rObjViewPair.second->getReportSection();
+ const uno::Reference< report::XSection>& xSection = pReportSection->getSection();
+ try
+ {
+ uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
+ _rBound.Union(tools::Rectangle(getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN),0,
+ getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width - getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN),
+ xSection->getHeight()));
+ }
+ catch(const uno::Exception &){}
+ }
+ }
+ else
+ {
+ _rBound.Union(rObjViewPair.second->GetMarkedObjRect());
+ }
+ }
+ }
+}
+
+void OViewsWindow::alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection)
+{
+ if ( _nControlModification == ControlModification::NONE )
+ return;
+
+ Point aRefPoint;
+ RectangleLess::CompareMode eCompareMode = RectangleLess::POS_LEFT;
+ switch (_nControlModification)
+ {
+ case ControlModification::TOP : eCompareMode = RectangleLess::POS_UPPER; break;
+ case ControlModification::BOTTOM: eCompareMode = RectangleLess::POS_DOWN; break;
+ case ControlModification::LEFT : eCompareMode = RectangleLess::POS_LEFT; break;
+ case ControlModification::RIGHT : eCompareMode = RectangleLess::POS_RIGHT; break;
+ case ControlModification::CENTER_HORIZONTAL :
+ case ControlModification::CENTER_VERTICAL :
+ {
+ eCompareMode = (ControlModification::CENTER_VERTICAL == _nControlModification) ? RectangleLess::POS_CENTER_VERTICAL : RectangleLess::POS_CENTER_HORIZONTAL;
+ uno::Reference<report::XSection> xSection = (*m_aSections.begin())->getReportSection().getSection();
+ uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition();
+ aRefPoint = tools::Rectangle(getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN),0,
+ getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width - getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN),
+ xSection->getHeight()).Center();
+ }
+ break;
+ default: break;
+ }
+ RectangleLess aCompare(eCompareMode,aRefPoint);
+ TRectangleMap aSortRectangles(aCompare);
+ collectRectangles(aSortRectangles);
+
+ tools::Rectangle aBound;
+ tools::Rectangle aResize;
+ collectBoundResizeRect(aSortRectangles,_nControlModification,_bAlignAtSection,aBound,aResize);
+
+ bool bMove = true;
+
+ auto aGetFun = ::std::mem_fn(&tools::Rectangle::Bottom);
+ auto aSetFun = ::std::mem_fn(&tools::Rectangle::SetBottom);
+ auto aRefFun = ::std::mem_fn(&tools::Rectangle::Top);
+ TRectangleMap::const_iterator aRectIter = aSortRectangles.begin();
+ TRectangleMap::const_iterator aRectEnd = aSortRectangles.end();
+ for (;aRectIter != aRectEnd ; ++aRectIter)
+ {
+ tools::Rectangle aObjRect = aRectIter->first;
+ SdrObject* pObj = aRectIter->second.first;
+ SdrView* pView = aRectIter->second.second;
+ Point aCenter(aBound.Center());
+ SdrObjTransformInfoRec aInfo;
+ pObj->TakeObjInfo(aInfo);
+ if (aInfo.bMoveAllowed && !pObj->IsMoveProtect())
+ {
+ tools::Long nXMov = 0;
+ tools::Long nYMov = 0;
+ tools::Long* pValue = &nXMov;
+ switch(_nControlModification)
+ {
+ case ControlModification::TOP :
+ aGetFun = ::std::mem_fn(&tools::Rectangle::Top);
+ aSetFun = ::std::mem_fn(&tools::Rectangle::SetTop);
+ aRefFun = ::std::mem_fn(&tools::Rectangle::Bottom);
+ pValue = &nYMov;
+ break;
+ case ControlModification::BOTTOM:
+ // defaults are already set
+ pValue = &nYMov;
+ break;
+ case ControlModification::CENTER_VERTICAL:
+ nYMov = aCenter.Y() - aObjRect.Center().Y();
+ pValue = &nYMov;
+ bMove = false;
+ break;
+ case ControlModification::RIGHT :
+ aGetFun = ::std::mem_fn(&tools::Rectangle::Right);
+ aSetFun = ::std::mem_fn(&tools::Rectangle::SetRight);
+ aRefFun = ::std::mem_fn(&tools::Rectangle::Left);
+ break;
+ case ControlModification::CENTER_HORIZONTAL:
+ nXMov = aCenter.X() - aObjRect.Center().X();
+ bMove = false;
+ break;
+ case ControlModification::LEFT :
+ aGetFun = ::std::mem_fn(&tools::Rectangle::Left);
+ aSetFun = ::std::mem_fn(&tools::Rectangle::SetLeft);
+ aRefFun = ::std::mem_fn(&tools::Rectangle::Right);
+ break;
+ default:
+ bMove = false;
+ break;
+ }
+ if ( bMove )
+ {
+ tools::Rectangle aTest = aObjRect;
+ aSetFun(&aTest, aGetFun(&aBound));
+ TRectangleMap::const_iterator aInterSectRectIter = aSortRectangles.begin();
+ for (; aInterSectRectIter != aRectIter; ++aInterSectRectIter)
+ {
+ if ( pView == aInterSectRectIter->second.second && (dynamic_cast<OUnoObject*>(aInterSectRectIter->second.first) || dynamic_cast<OOle2Obj*>(aInterSectRectIter->second.first)))
+ {
+ SdrObject* pPreviousObj = aInterSectRectIter->second.first;
+ tools::Rectangle aIntersectRect = aTest.GetIntersection( pPreviousObj->GetSnapRect());
+ if ( !aIntersectRect.IsEmpty() && (aIntersectRect.Left() != aIntersectRect.Right() && aIntersectRect.Top() != aIntersectRect.Bottom() ) )
+ {
+ *pValue = aRefFun(&aIntersectRect) - aGetFun(&aObjRect);
+ break;
+ }
+ }
+ }
+ if ( aInterSectRectIter == aRectIter )
+ *pValue = aGetFun(&aBound) - aGetFun(&aObjRect);
+ }
+
+ if ( lcl_getNewRectSize(aObjRect,nXMov,nYMov,pObj,pView,_nControlModification) )
+ {
+ const Size aSize(nXMov,nYMov);
+ pView->AddUndo(pView->GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,aSize));
+ pObj->Move(aSize);
+ aObjRect = pObj->GetSnapRect();
+ }
+
+ // resizing control
+ if ( !aResize.IsEmpty() && aObjRect != aResize )
+ {
+ nXMov = aResize.getWidth();
+ nYMov = aResize.getHeight();
+ switch(_nControlModification)
+ {
+ case ControlModification::WIDTH_GREATEST:
+ case ControlModification::HEIGHT_GREATEST:
+ if ( _nControlModification == ControlModification::HEIGHT_GREATEST )
+ nXMov = aObjRect.getWidth();
+ else if ( _nControlModification == ControlModification::WIDTH_GREATEST )
+ nYMov = aObjRect.getHeight();
+ lcl_getNewRectSize(aObjRect,nXMov,nYMov,pObj,pView,_nControlModification);
+ [[fallthrough]];
+ case ControlModification::WIDTH_SMALLEST:
+ case ControlModification::HEIGHT_SMALLEST:
+ pView->AddUndo( pView->GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+ {
+ OObjectBase* pObjBase = dynamic_cast<OObjectBase*>(pObj);
+ OSL_ENSURE(pObjBase,"Where comes this object from?");
+ if ( pObjBase )
+ {
+ if ( _nControlModification == ControlModification::WIDTH_SMALLEST || _nControlModification == ControlModification::WIDTH_GREATEST )
+ pObjBase->getReportComponent()->setSize(awt::Size(nXMov,aObjRect.getHeight()));
+ else if ( _nControlModification == ControlModification::HEIGHT_GREATEST || _nControlModification == ControlModification::HEIGHT_SMALLEST )
+ pObjBase->getReportComponent()->setSize(awt::Size(aObjRect.getWidth(),nYMov));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ pView->AdjustMarkHdl();
+ }
+}
+
+void OViewsWindow::createDefault()
+{
+ OSectionWindow* pMarkedSection = getMarkedSection();
+ if ( pMarkedSection )
+ pMarkedSection->getReportSection().createDefault(m_sShapeType);
+}
+
+void OViewsWindow::setGridSnap(bool bOn)
+{
+ for (const auto& rxSection : m_aSections)
+ {
+ rxSection->getReportSection().getSectionView().SetGridSnap(bOn);
+ rxSection->getReportSection().Invalidate();
+ }
+}
+
+void OViewsWindow::setDragStripes(bool bOn)
+{
+ for (const auto& rxSection : m_aSections)
+ rxSection->getReportSection().getSectionView().SetDragStripes(bOn);
+}
+
+sal_uInt16 OViewsWindow::getPosition(const OSectionWindow* _pSectionWindow) const
+{
+ auto aIter = std::find_if(m_aSections.begin(), m_aSections.end(),
+ [&_pSectionWindow](const VclPtr<OSectionWindow>& rxSection) { return _pSectionWindow == rxSection.get(); });
+ return static_cast<sal_uInt16>(std::distance(m_aSections.begin(), aIter));
+}
+
+OSectionWindow* OViewsWindow::getSectionWindow(const sal_uInt16 _nPos) const
+{
+ OSectionWindow* aReturn = nullptr;
+
+ if ( _nPos < m_aSections.size() )
+ aReturn = m_aSections[_nPos].get();
+
+ return aReturn;
+}
+
+namespace
+{
+ enum SectionViewAction
+ {
+ eEndDragObj,
+ eEndAction,
+ eForceToAnotherPage,
+ eBreakAction
+ };
+ class ApplySectionViewAction
+ {
+ private:
+ SectionViewAction m_eAction;
+
+ public:
+ explicit ApplySectionViewAction()
+ : m_eAction(eEndDragObj)
+ {
+ }
+
+ explicit ApplySectionViewAction(SectionViewAction _eAction)
+ : m_eAction(_eAction)
+ {
+ }
+
+ void operator() ( const OViewsWindow::TSectionsMap::value_type& _rhs )
+ {
+ OSectionView& rView( _rhs->getReportSection().getSectionView() );
+ switch ( m_eAction )
+ {
+ case eEndDragObj:
+ rView.EndDragObj();
+ break;
+ case eEndAction:
+ if ( rView.IsAction() )
+ rView.EndAction ( );
+ break;
+ case eForceToAnotherPage:
+ rView.ForceMarkedToAnotherPage();
+ break;
+ case eBreakAction:
+ if ( rView.IsAction() )
+ rView.BrkAction ( );
+ break;
+ // default:
+
+ }
+ }
+ };
+}
+
+void OViewsWindow::BrkAction()
+{
+ EndDragObj_removeInvisibleObjects();
+ ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eBreakAction) );
+}
+
+void OViewsWindow::BegDragObj_createInvisibleObjectAtPosition(const tools::Rectangle& _aRect, const OSectionView& _rSection)
+{
+ Point aNewPos(0,0);
+
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+ rReportSection.getPage()->setSpecialMode();
+ OSectionView& rView = rReportSection.getSectionView();
+
+ if ( &rView != &_rSection )
+ {
+ SdrObject *pNewObj = new SdrUnoObj(
+ rView.getSdrModelFromSdrView(),
+ "com.sun.star.form.component.FixedText");
+
+ pNewObj->SetLogicRect(_aRect);
+ pNewObj->Move(Size(0, aNewPos.Y()));
+ bool bChanged = rView.GetModel()->IsChanged();
+ rReportSection.getPage()->InsertObject(pNewObj);
+ rView.GetModel()->SetChanged(bChanged);
+ m_aBegDragTempList.push_back(pNewObj);
+
+ rView.MarkObj( pNewObj, rView.GetSdrPageView() );
+ }
+ const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
+ aNewPos.AdjustY( -nSectionHeight );
+ }
+}
+
+void OViewsWindow::BegDragObj(const Point& _aPnt, SdrHdl* _pHdl,const OSectionView* _pSection)
+{
+ SAL_INFO(
+ "reportdesign", "Clickpoint X:" << _aPnt.X() << " Y:" << _aPnt.Y());
+
+ m_aBegDragTempList.clear();
+
+ // Calculate the absolute clickpoint in the views
+ Point aAbsolutePnt = _aPnt;
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+ OSectionView* pView = &rReportSection.getSectionView();
+ if (pView == _pSection)
+ break;
+ const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
+ aAbsolutePnt.AdjustY(nSectionHeight );
+ }
+ m_aDragDelta = Point(SAL_MAX_INT32, SAL_MAX_INT32);
+ SAL_INFO(
+ "reportdesign",
+ "Absolute X:" << aAbsolutePnt.X() << " Y:" << aAbsolutePnt.Y());
+
+ // Create drag lines over all viewable Views
+ // Therefore we need to identify the marked objects
+ // and create temporary objects on all other views at the same position
+ // relative to its occurrence.
+
+ int nViewCount = 0;
+ Point aNewObjPos(0,0);
+ Point aLeftTop(SAL_MAX_INT32, SAL_MAX_INT32);
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+
+ OSectionView& rView = rReportSection.getSectionView();
+
+ if ( rView.AreObjectsMarked() )
+ {
+ const size_t nCount = rView.GetMarkedObjectCount();
+ for (size_t i=0; i < nCount; ++i)
+ {
+ const SdrMark* pM = rView.GetSdrMarkByIndex(i);
+ SdrObject* pObj = pM->GetMarkedSdrObj();
+ if (::std::find(m_aBegDragTempList.begin(),m_aBegDragTempList.end(),pObj) == m_aBegDragTempList.end())
+ {
+ tools::Rectangle aRect( pObj->GetCurrentBoundRect() );
+ aRect.Move(0, aNewObjPos.Y());
+
+ aLeftTop.setX( ::std::min( aRect.Left(), aLeftTop.X() ) );
+ aLeftTop.setY( ::std::min( aRect.Top(), aLeftTop.Y() ) );
+
+ SAL_INFO(
+ "reportdesign",
+ "createInvisible X:" << aRect.Left() << " Y:"
+ << aRect.Top() << " on View #" << nViewCount);
+
+ BegDragObj_createInvisibleObjectAtPosition(aRect, rView);
+ }
+ }
+ }
+ ++nViewCount;
+ tools::Rectangle aClipRect = rView.GetWorkArea();
+ aClipRect.SetTop( -aNewObjPos.Y() );
+ rView.SetWorkArea( aClipRect );
+
+ const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
+ aNewObjPos.AdjustY(nSectionHeight );
+ }
+
+ const sal_Int32 nDeltaX = std::abs(aLeftTop.X() - aAbsolutePnt.X());
+ const sal_Int32 nDeltaY = std::abs(aLeftTop.Y() - aAbsolutePnt.Y());
+ m_aDragDelta.setX( nDeltaX );
+ m_aDragDelta.setY( nDeltaY );
+
+ Point aNewPos = aAbsolutePnt;
+
+ const short nDrgLog = static_cast<short>(PixelToLogic(Size(3,0)).Width());
+ nViewCount = 0;
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+
+ SdrHdl* pHdl = _pHdl;
+ if ( pHdl )
+ {
+ if ( &rReportSection.getSectionView() != _pSection )
+ {
+ const SdrHdlList& rHdlList = rReportSection.getSectionView().GetHdlList();
+ pHdl = rHdlList.GetHdl(_pHdl->GetKind());
+ }
+ }
+ SAL_INFO(
+ "reportdesign",
+ "X:" << aNewPos.X() << " Y:" << aNewPos.Y() << " on View#"
+ << nViewCount++);
+ rReportSection.getSectionView().BegDragObj(aNewPos, nullptr, pHdl, nDrgLog);
+
+ const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
+ aNewPos.AdjustY( -nSectionHeight );
+ }
+}
+
+
+void OViewsWindow::ForceMarkedToAnotherPage()
+{
+ ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eForceToAnotherPage ) );
+}
+
+void OViewsWindow::BegMarkObj(const Point& _aPnt,const OSectionView* _pSection)
+{
+ bool bAdd = true;
+ Point aNewPos = _aPnt;
+
+ tools::Long nLastSectionHeight = 0;
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+ if ( &rReportSection.getSectionView() == _pSection )
+ {
+ bAdd = false;
+ aNewPos = _aPnt; // 2,2
+ }
+ else if ( bAdd )
+ {
+ const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
+ aNewPos.AdjustY(nSectionHeight );
+ }
+ else
+ {
+ aNewPos.AdjustY( -nLastSectionHeight );
+ }
+ rReportSection.getSectionView().BegMarkObj ( aNewPos );
+ nLastSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
+ }
+}
+
+OSectionView* OViewsWindow::getSectionRelativeToPosition(const OSectionView* _pSection,Point& _rPnt)
+{
+ OSectionView* pSection = nullptr;
+ TSectionsMap::const_iterator aIter = m_aSections.begin();
+ const TSectionsMap::const_iterator aEnd = m_aSections.end();
+ aIter = std::find_if(aIter, aEnd, [&_pSection](const VclPtr<OSectionWindow>& rxSection) {
+ return &rxSection->getReportSection().getSectionView() == _pSection; });
+ sal_Int32 nCount = static_cast<sal_Int32>(std::distance(m_aSections.cbegin(), aIter));
+ OSL_ENSURE(aIter != aEnd,"This can never happen!");
+ if ( _rPnt.Y() < 0 )
+ {
+ if ( nCount )
+ --aIter;
+ for (; nCount && (_rPnt.Y() < 0); --nCount)
+ {
+ OReportSection& rReportSection = (*aIter)->getReportSection();
+ const sal_Int32 nHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
+ _rPnt.AdjustY(nHeight );
+ if ( (nCount -1) > 0 && (_rPnt.Y() < 0) )
+ --aIter;
+ }
+ if ( nCount == 0 )
+ pSection = &(*m_aSections.begin())->getReportSection().getSectionView();
+ else
+ pSection = &(*aIter)->getReportSection().getSectionView();
+ }
+ else
+ {
+ for (; aIter != aEnd; ++aIter)
+ {
+ OReportSection& rReportSection = (*aIter)->getReportSection();
+ const tools::Long nHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
+ if ( (_rPnt.Y() - nHeight) < 0 )
+ break;
+ _rPnt.AdjustY( -nHeight );
+ }
+ if ( aIter != aEnd )
+ pSection = &(*aIter)->getReportSection().getSectionView();
+ else
+ pSection = &(*(aEnd-1))->getReportSection().getSectionView();
+ }
+
+ return pSection;
+}
+
+void OViewsWindow::EndDragObj_removeInvisibleObjects()
+{
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+ rReportSection.getPage()->resetSpecialMode();
+ }
+}
+
+void OViewsWindow::EndDragObj(bool _bControlKeyPressed, const OSectionView* _pSection, const Point& _aPnt)
+{
+ const OUString sUndoAction = RptResId(RID_STR_UNDO_CHANGEPOSITION);
+ const UndoContext aUndoContext( getView()->getReportView()->getController().getUndoManager(), sUndoAction );
+
+ Point aNewPos = _aPnt;
+ OSectionView* pInSection = getSectionRelativeToPosition(_pSection, aNewPos);
+ if (!_bControlKeyPressed &&
+ _pSection && !_pSection->IsDragResize() && /* Not in resize mode */
+ _pSection != pInSection)
+ {
+ EndDragObj_removeInvisibleObjects();
+
+ // we need to manipulate the current clickpoint, we subtract the old delta from BeginDrag
+ aNewPos -= m_aDragDelta;
+
+ uno::Sequence< beans::NamedValue > aAllreadyCopiedObjects;
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+ if ( pInSection != &rReportSection.getSectionView() )
+ {
+ rReportSection.getSectionView().BrkAction();
+ rReportSection.Copy(aAllreadyCopiedObjects,true);
+ }
+ else
+ pInSection->EndDragObj();
+ }
+
+ if ( aAllreadyCopiedObjects.hasElements() )
+ {
+ try
+ {
+ uno::Reference<report::XReportDefinition> xReportDefinition = getView()->getReportView()->getController().getReportDefinition();
+ const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN);
+ const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN);
+ const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width;
+
+ if ( aNewPos.X() < nLeftMargin )
+ aNewPos.setX( nLeftMargin );
+ if ( aNewPos.Y() < 0 )
+ aNewPos.setY( 0 );
+
+ Point aPrevious;
+ for (beans::NamedValue const & namedVal : std::as_const(aAllreadyCopiedObjects))
+ {
+ uno::Sequence< uno::Reference<report::XReportComponent> > aClones;
+ namedVal.Value >>= aClones;
+ uno::Reference<report::XReportComponent>* pColIter = aClones.getArray();
+ const uno::Reference<report::XReportComponent>* pColEnd = pColIter + aClones.getLength();
+
+ // move the cloned Components to new positions
+ for (; pColIter != pColEnd; ++pColIter)
+ {
+ uno::Reference< report::XReportComponent> xRC(*pColIter);
+ aPrevious = VCLPoint(xRC->getPosition());
+ awt::Size aSize = xRC->getSize();
+
+ if ( aNewPos.X() < nLeftMargin )
+ {
+ aNewPos.setX( nLeftMargin );
+ }
+ else if ( (aNewPos.X() + aSize.Width) > (nPaperWidth - nRightMargin) )
+ {
+ aNewPos.setX( nPaperWidth - nRightMargin - aSize.Width );
+ }
+ if ( aNewPos.Y() < 0 )
+ {
+ aNewPos.setY( 0 );
+ }
+ if ( aNewPos.X() < 0 )
+ {
+ aSize.Width += aNewPos.X();
+ aNewPos.setX( 0 );
+ xRC->setSize(aSize);
+ }
+ xRC->setPosition(AWTPoint(aNewPos));
+ if ( (pColIter+1) != pColEnd )
+ {
+ // bring aNewPos to the position of the next object
+ uno::Reference< report::XReportComponent> xRCNext = *(pColIter + 1);
+ Point aNextPosition = VCLPoint(xRCNext->getPosition());
+ aNewPos += aNextPosition - aPrevious;
+ }
+ }
+ }
+ }
+ catch(uno::Exception&)
+ {
+ }
+ pInSection->getReportSection()->Paste(aAllreadyCopiedObjects,true);
+ }
+ }
+ else
+ {
+ ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction() );
+ EndDragObj_removeInvisibleObjects();
+ }
+ m_aDragDelta = Point(SAL_MAX_INT32, SAL_MAX_INT32);
+}
+
+void OViewsWindow::EndAction()
+{
+ ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eEndAction) );
+}
+
+void OViewsWindow::MovAction(const Point& _aPnt,const OSectionView* _pSection, bool _bControlKeySet)
+{
+ Point aRealMousePos = _aPnt;
+ Point aCurrentSectionPos;
+ SAL_INFO(
+ "reportdesign",
+ "X:" << aRealMousePos.X() << " Y:" << aRealMousePos.Y());
+
+ Point aHdlPos;
+ SdrHdl* pHdl = _pSection->GetDragHdl();
+ if ( pHdl )
+ {
+ aHdlPos = pHdl->GetPos();
+ }
+
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+ if ( &rReportSection.getSectionView() == _pSection )
+ break;
+ const tools::Long nSectionHeight = rxSection->PixelToLogic(rReportSection.GetOutputSizePixel()).Height();
+ aCurrentSectionPos.AdjustY(nSectionHeight );
+ }
+ aRealMousePos += aCurrentSectionPos;
+
+ // If control key is pressed the work area is limited to the section with the current selection.
+ Point aPosForWorkArea(0,0);
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+ OSectionView& rView = rReportSection.getSectionView();
+ const tools::Long nSectionHeight = rxSection->PixelToLogic(rxSection->GetOutputSizePixel()).Height();
+
+ if (_bControlKeySet)
+ {
+ tools::Rectangle aClipRect = rView.GetWorkArea();
+ aClipRect.SetTop( aCurrentSectionPos.Y() - aPosForWorkArea.Y() );
+ aClipRect.SetBottom( aClipRect.Top() + nSectionHeight );
+ rView.SetWorkArea( aClipRect );
+ }
+ else
+ {
+ tools::Rectangle aClipRect = rView.GetWorkArea();
+ aClipRect.SetTop( -aPosForWorkArea.Y() );
+ rView.SetWorkArea( aClipRect );
+ }
+ aPosForWorkArea.AdjustY(nSectionHeight );
+ }
+
+
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+ SdrHdl* pCurrentHdl = rReportSection.getSectionView().GetDragHdl();
+ if ( pCurrentHdl && aRealMousePos.Y() > 0 )
+ aRealMousePos = _aPnt + pCurrentHdl->GetPos() - aHdlPos;
+ rReportSection.getSectionView().MovAction ( aRealMousePos );
+ const tools::Long nSectionHeight = rxSection->PixelToLogic(rxSection->GetOutputSizePixel()).Height();
+ aRealMousePos.AdjustY( -nSectionHeight );
+ }
+}
+
+bool OViewsWindow::IsAction() const
+{
+ return std::any_of(m_aSections.begin(), m_aSections.end(),
+ [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().IsAction(); });
+}
+
+bool OViewsWindow::IsDragObj() const
+{
+ return std::any_of(m_aSections.begin(), m_aSections.end(),
+ [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().IsAction(); });
+}
+
+sal_uInt32 OViewsWindow::getMarkedObjectCount() const
+{
+ return std::accumulate(m_aSections.begin(), m_aSections.end(), sal_uInt32(0),
+ [](const sal_uInt32 nCount, const VclPtr<OSectionWindow>& rxSection) {
+ return nCount + static_cast<sal_uInt32>(rxSection->getReportSection().getSectionView().GetMarkedObjectCount()); });
+}
+
+void OViewsWindow::handleKey(const vcl::KeyCode& _rCode)
+{
+ const sal_uInt16 nCode = _rCode.GetCode();
+ if ( _rCode.IsMod1() )
+ {
+ // scroll page
+ OScrollWindowHelper* pScrollWindow = getView()->getScrollWindow();
+ ScrollBar& rScrollBar = ( nCode == KEY_LEFT || nCode == KEY_RIGHT ) ? pScrollWindow->GetHScroll() : pScrollWindow->GetVScroll();
+ if ( rScrollBar.IsVisible() )
+ rScrollBar.DoScrollAction(( nCode == KEY_RIGHT || nCode == KEY_UP ) ? ScrollType::LineUp : ScrollType::LineDown );
+ return;
+ }
+
+ for (const auto& rxSection : m_aSections)
+ {
+ OReportSection& rReportSection = rxSection->getReportSection();
+ tools::Long nX = 0;
+ tools::Long nY = 0;
+
+ if ( nCode == KEY_UP )
+ nY = -1;
+ else if ( nCode == KEY_DOWN )
+ nY = 1;
+ else if ( nCode == KEY_LEFT )
+ nX = -1;
+ else if ( nCode == KEY_RIGHT )
+ nX = 1;
+
+ if ( rReportSection.getSectionView().AreObjectsMarked() )
+ {
+ if ( _rCode.IsMod2() )
+ {
+ // move in 1 pixel distance
+ const Size aPixelSize = rReportSection.PixelToLogic( Size( 1, 1 ) );
+ nX *= aPixelSize.Width();
+ nY *= aPixelSize.Height();
+ }
+ else
+ {
+ // move in 1 mm distance
+ nX *= DEFAUL_MOVE_SIZE;
+ nY *= DEFAUL_MOVE_SIZE;
+ }
+
+ OSectionView& rView = rReportSection.getSectionView();
+ const SdrHdlList& rHdlList = rView.GetHdlList();
+ SdrHdl* pHdl = rHdlList.GetFocusHdl();
+
+ if ( pHdl == nullptr )
+ {
+ // no handle selected
+ if ( rView.IsMoveAllowed() )
+ {
+ // restrict movement to work area
+ tools::Rectangle rWorkArea = rView.GetWorkArea();
+ rWorkArea.AdjustRight( 1 );
+
+ if ( !rWorkArea.IsEmpty() )
+ {
+ if ( rWorkArea.Top() < 0 )
+ rWorkArea.SetTop( 0 );
+ tools::Rectangle aMarkRect( rView.GetMarkedObjRect() );
+ aMarkRect.Move( nX, nY );
+
+ if ( !rWorkArea.Contains( aMarkRect ) )
+ {
+ if ( aMarkRect.Left() < rWorkArea.Left() )
+ nX += rWorkArea.Left() - aMarkRect.Left();
+
+ if ( aMarkRect.Right() > rWorkArea.Right() )
+ nX -= aMarkRect.Right() - rWorkArea.Right();
+
+ if ( aMarkRect.Top() < rWorkArea.Top() )
+ nY += rWorkArea.Top() - aMarkRect.Top();
+
+ if ( aMarkRect.Bottom() > rWorkArea.Bottom() )
+ nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
+ }
+ bool bCheck = false;
+ const SdrMarkList& rMarkList = rView.GetMarkedObjectList();
+ for (size_t i = 0; !bCheck && i < rMarkList.GetMarkCount(); ++i )
+ {
+ SdrMark* pMark = rMarkList.GetMark(i);
+ bCheck = dynamic_cast<OUnoObject*>(pMark->GetMarkedSdrObj()) != nullptr|| dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj());
+ }
+
+
+ if ( bCheck )
+ {
+ SdrObject* pOverlapped = isOver(aMarkRect,*rReportSection.getPage(),rView);
+ if ( pOverlapped )
+ {
+ do
+ {
+ tools::Rectangle aOver = pOverlapped->GetLastBoundRect();
+ Point aPos;
+ if ( nCode == KEY_UP )
+ {
+ aPos.setX( aMarkRect.Left() );
+ aPos.setY( aOver.Top() - aMarkRect.getHeight() );
+ nY += (aPos.Y() - aMarkRect.Top());
+ }
+ else if ( nCode == KEY_DOWN )
+ {
+ aPos.setX( aMarkRect.Left() );
+ aPos.setY( aOver.Bottom() );
+ nY += (aPos.Y() - aMarkRect.Top());
+ }
+ else if ( nCode == KEY_LEFT )
+ {
+ aPos.setX( aOver.Left() - aMarkRect.getWidth() );
+ aPos.setY( aMarkRect.Top() );
+ nX += (aPos.X() - aMarkRect.Left());
+ }
+ else if ( nCode == KEY_RIGHT )
+ {
+ aPos.setX( aOver.Right() );
+ aPos.setY( aMarkRect.Top() );
+ nX += (aPos.X() - aMarkRect.Left());
+ }
+
+ aMarkRect.SetPos(aPos);
+ if ( !rWorkArea.Contains( aMarkRect ) )
+ {
+ break;
+ }
+ pOverlapped = isOver(aMarkRect,*rReportSection.getPage(),rView);
+ }
+ while(pOverlapped != nullptr);
+ if (pOverlapped != nullptr)
+ break;
+ }
+ }
+ }
+
+ if ( nX != 0 || nY != 0 )
+ {
+ rView.MoveAllMarked( Size( nX, nY ) );
+ rView.MakeVisible( rView.GetAllMarkedRect(), rReportSection);
+ }
+ }
+ }
+ else // pHdl != nullptr
+ {
+ // move the handle
+ if (nX || nY)
+ {
+ const Point aStartPoint( pHdl->GetPos() );
+ const Point aEndPoint( pHdl->GetPos() + Point( nX, nY ) );
+ const SdrDragStat& rDragStat = rView.GetDragStat();
+
+ // start dragging
+ rView.BegDragObj( aStartPoint, nullptr, pHdl, 0 );
+
+ if ( rView.IsDragObj() )
+ {
+ const bool bWasNoSnap = rDragStat.IsNoSnap();
+ const bool bWasSnapEnabled = rView.IsSnapEnabled();
+
+ // switch snapping off
+ if ( !bWasNoSnap )
+ const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
+ if ( bWasSnapEnabled )
+ rView.SetSnapEnabled( false );
+
+ tools::Rectangle aNewRect;
+ bool bCheck = false;
+ const SdrMarkList& rMarkList = rView.GetMarkedObjectList();
+ for (size_t i = 0; !bCheck && i < rMarkList.GetMarkCount(); ++i )
+ {
+ SdrMark* pMark = rMarkList.GetMark(i);
+ bCheck = dynamic_cast<OUnoObject*>(pMark->GetMarkedSdrObj()) != nullptr || dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj()) != nullptr;
+ if ( bCheck )
+ aNewRect.Union(pMark->GetMarkedSdrObj()->GetLastBoundRect());
+ }
+
+ switch(pHdl->GetKind())
+ {
+ case SdrHdlKind::Left:
+ case SdrHdlKind::UpperLeft:
+ case SdrHdlKind::LowerLeft:
+ case SdrHdlKind::Upper:
+ aNewRect.AdjustLeft(nX );
+ aNewRect.AdjustTop(nY );
+ break;
+ case SdrHdlKind::UpperRight:
+ case SdrHdlKind::Right:
+ case SdrHdlKind::LowerRight:
+ case SdrHdlKind::Lower:
+ aNewRect.setWidth(aNewRect.getWidth() + nX);
+ aNewRect.setHeight(aNewRect.getHeight() + nY);
+ break;
+ default:
+ break;
+ }
+ if ( !(bCheck && isOver(aNewRect,*rReportSection.getPage(),rView)) )
+ rView.MovAction(aEndPoint);
+ rView.EndDragObj();
+
+ // restore snap
+ if ( !bWasNoSnap )
+ const_cast<SdrDragStat&>(rDragStat).SetNoSnap( bWasNoSnap );
+ if ( bWasSnapEnabled )
+ rView.SetSnapEnabled( bWasSnapEnabled );
+ }
+
+ // make moved handle visible
+ const tools::Rectangle aVisRect( aEndPoint - Point( DEFAUL_MOVE_SIZE, DEFAUL_MOVE_SIZE ), Size( 200, 200 ) );
+ rView.MakeVisible( aVisRect, rReportSection);
+ }
+ }
+ rView.AdjustMarkHdl();
+ }
+ }
+}
+
+void OViewsWindow::stopScrollTimer()
+{
+ ::std::for_each(m_aSections.begin(),m_aSections.end(),
+ [] (const TSectionsMap::value_type& sectionPtr) {
+ sectionPtr->getReportSection().stopScrollTimer();
+ });
+}
+
+void OViewsWindow::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const
+{
+ sal_uInt16 i = 0;
+ for (const auto& rxSection : m_aSections)
+ {
+ if ( rxSection->getStartMarker().isCollapsed() )
+ _rCollapsedPositions.push_back(i);
+ ++i;
+ }
+}
+
+void OViewsWindow::collapseSections(const uno::Sequence< beans::PropertyValue>& _aCollapsedSections)
+{
+ for (const beans::PropertyValue& rSection : _aCollapsedSections)
+ {
+ sal_uInt16 nPos = sal_uInt16(-1);
+ if ( (rSection.Value >>= nPos) && nPos < m_aSections.size() )
+ {
+ m_aSections[nPos]->setCollapsed(true);
+ }
+ }
+}
+
+void OViewsWindow::zoom(const Fraction& _aZoom)
+{
+ const MapMode& aMapMode = GetMapMode();
+
+ Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH));
+ if ( _aZoom < aMapMode.GetScaleX() )
+ aStartWidth *= aMapMode.GetScaleX();
+ else
+ aStartWidth *= _aZoom;
+
+ setZoomFactor(_aZoom,*this);
+
+ for (const auto& rxSection : m_aSections)
+ {
+ rxSection->zoom(_aZoom);
+ }
+
+ Resize();
+
+ Size aOut = GetOutputSizePixel();
+ aOut.setWidth( tools::Long(aStartWidth) );
+ aOut = PixelToLogic(aOut);
+
+ tools::Rectangle aRect(PixelToLogic(Point(0,0)),aOut);
+ Invalidate(aRect, InvalidateFlags::NoChildren);
+}
+
+void OViewsWindow::scrollChildren(const Point& _aThumbPos)
+{
+ const Point aPos(PixelToLogic(_aThumbPos));
+ {
+ MapMode aMapMode = GetMapMode();
+ const Point aOld = aMapMode.GetOrigin();
+ aMapMode.SetOrigin(m_pParent->GetMapMode().GetOrigin());
+
+ const Point aPosY(m_pParent->PixelToLogic(_aThumbPos,aMapMode));
+
+ aMapMode.SetOrigin( Point(aOld.X() , - aPosY.Y()));
+ SetMapMode( aMapMode );
+ Scroll(0, -( aOld.Y() + aPosY.Y()),ScrollFlags::Children);
+ }
+
+ for (const auto& rxSection : m_aSections)
+ {
+ rxSection->scrollChildren(aPos.X());
+ }
+}
+
+void OViewsWindow::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const
+{
+ for (const auto& rxSection : m_aSections)
+ {
+ rxSection->getReportSection().fillControlModelSelection(_rSelection);
+ }
+}
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/dlgedclip.cxx b/reportdesign/source/ui/report/dlgedclip.cxx
new file mode 100644
index 000000000..1f36563fe
--- /dev/null
+++ b/reportdesign/source/ui/report/dlgedclip.cxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <dlgedclip.hxx>
+#include <osl/diagnose.h>
+#include <sot/exchange.hxx>
+
+namespace rptui
+{
+
+using namespace ::com::sun::star;
+
+
+// OReportExchange
+
+
+OReportExchange::OReportExchange(const TSectionElements& _rCopyElements )
+: m_aCopyElements(_rCopyElements)
+{
+}
+
+SotClipboardFormatId OReportExchange::getDescriptorFormatId()
+{
+ static SotClipboardFormatId s_nFormat = static_cast<SotClipboardFormatId>(-1);
+ if (static_cast<SotClipboardFormatId>(-1) == s_nFormat)
+ {
+ s_nFormat = SotExchange::RegisterFormatName("application/x-openoffice;windows_formatname=\"report.ReportObjectsTransfer\"");
+ OSL_ENSURE(static_cast<SotClipboardFormatId>(-1) != s_nFormat, "OReportExchange::getDescriptorFormatId: bad exchange id!");
+ }
+ return s_nFormat;
+}
+
+void OReportExchange::AddSupportedFormats()
+{
+ AddFormat(getDescriptorFormatId());
+}
+
+bool OReportExchange::GetData( const datatransfer::DataFlavor& _rFlavor, const OUString& /*rDestDoc*/ )
+{
+ const SotClipboardFormatId nFormatId = SotExchange::GetFormat(_rFlavor);
+ return (nFormatId == getDescriptorFormatId()) && SetAny( uno::Any(m_aCopyElements) );
+}
+
+bool OReportExchange::canExtract(const DataFlavorExVector& _rFlavor)
+{
+ return IsFormatSupported(_rFlavor,getDescriptorFormatId());
+}
+
+OReportExchange::TSectionElements OReportExchange::extractCopies(const TransferableDataHelper& _rData)
+{
+ SotClipboardFormatId nKnownFormatId = getDescriptorFormatId();
+ if ( _rData.HasFormat( nKnownFormatId ) )
+ {
+ // extract the any from the transferable
+ datatransfer::DataFlavor aFlavor;
+ bool bSuccess =
+ SotExchange::GetFormatDataFlavor(nKnownFormatId, aFlavor);
+ OSL_ENSURE(bSuccess, "OReportExchange::extractCopies: invalid data format (no flavor)!");
+
+ uno::Any aDescriptor = _rData.GetAny(aFlavor, OUString());
+
+ TSectionElements aCopies;
+ bSuccess = aDescriptor >>= aCopies;
+ OSL_ENSURE(bSuccess, "OReportExchange::extractCopies: invalid clipboard format!");
+
+ // build the real descriptor
+ return aCopies;
+ }
+
+ return TSectionElements();
+}
+
+} // rptui
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/dlgedfac.cxx b/reportdesign/source/ui/report/dlgedfac.cxx
new file mode 100644
index 000000000..7429d5517
--- /dev/null
+++ b/reportdesign/source/ui/report/dlgedfac.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <dlgedfac.hxx>
+#include <strings.hxx>
+#include <RptObject.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <osl/diagnose.h>
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+
+
+DlgEdFactory::DlgEdFactory()
+{
+ SdrObjFactory::InsertMakeObjectHdl( LINK(this, DlgEdFactory, MakeObject) );
+}
+
+
+DlgEdFactory::~DlgEdFactory() COVERITY_NOEXCEPT_FALSE
+{
+ SdrObjFactory::RemoveMakeObjectHdl( LINK(this, DlgEdFactory, MakeObject) );
+}
+
+
+IMPL_STATIC_LINK(
+ DlgEdFactory, MakeObject, SdrObjCreatorParams, aParams, SdrObject* )
+{
+ SdrObject* pNewObj = nullptr;
+
+ if ( aParams.nInventor == SdrInventor::ReportDesign )
+ {
+ switch( aParams.nObjIdentifier )
+ {
+ case SdrObjKind::ReportDesignFixedText:
+ pNewObj = new OUnoObject(aParams.rSdrModel, SERVICE_FIXEDTEXT
+ ,OUString("com.sun.star.form.component.FixedText")
+ ,SdrObjKind::ReportDesignFixedText);
+ break;
+ case SdrObjKind::ReportDesignImageControl:
+ pNewObj = new OUnoObject(aParams.rSdrModel, SERVICE_IMAGECONTROL
+ ,OUString("com.sun.star.form.component.DatabaseImageControl")
+ ,SdrObjKind::ReportDesignImageControl);
+ break;
+ case SdrObjKind::ReportDesignFormattedField:
+ pNewObj = new OUnoObject(aParams.rSdrModel, SERVICE_FORMATTEDFIELD
+ ,OUString("com.sun.star.form.component.FormattedField")
+ ,SdrObjKind::ReportDesignFormattedField);
+ break;
+ case SdrObjKind::ReportDesignVerticalFixedLine:
+ case SdrObjKind::ReportDesignHorizontalFixedLine:
+ {
+ OUnoObject* pObj = new OUnoObject(aParams.rSdrModel, SERVICE_FIXEDLINE
+ ,OUString("com.sun.star.awt.UnoControlFixedLineModel")
+ ,aParams.nObjIdentifier);
+ pNewObj = pObj;
+ if ( aParams.nObjIdentifier == SdrObjKind::ReportDesignHorizontalFixedLine )
+ {
+ uno::Reference<beans::XPropertySet> xProp = pObj->getAwtComponent();
+ xProp->setPropertyValue( PROPERTY_ORIENTATION, uno::Any(sal_Int32(0)) );
+ }
+ }
+ break;
+ case SdrObjKind::CustomShape:
+ pNewObj = new OCustomShape(aParams.rSdrModel, SERVICE_SHAPE);
+ break;
+ case SdrObjKind::ReportDesignSubReport:
+ pNewObj = new OOle2Obj(aParams.rSdrModel, SERVICE_REPORTDEFINITION, SdrObjKind::ReportDesignSubReport);
+ break;
+ case SdrObjKind::OLE2:
+ pNewObj = new OOle2Obj(aParams.rSdrModel, "com.sun.star.chart2.ChartDocument", SdrObjKind::OLE2);
+ break;
+ default:
+ OSL_FAIL("Unknown object id");
+ break;
+ }
+ }
+ return pNewObj;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/dlgedfunc.cxx b/reportdesign/source/ui/report/dlgedfunc.cxx
new file mode 100644
index 000000000..8a84093cd
--- /dev/null
+++ b/reportdesign/source/ui/report/dlgedfunc.cxx
@@ -0,0 +1,894 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <vcl/scrbar.hxx>
+#include <vcl/seleng.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <svx/svdview.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svddrgmt.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/svxids.hrc>
+#include <svx/svditer.hxx>
+
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <dlgedfunc.hxx>
+#include <ReportSection.hxx>
+#include <DesignView.hxx>
+#include <ReportController.hxx>
+#include <SectionView.hxx>
+#include <ViewsWindow.hxx>
+#include <ReportWindow.hxx>
+#include <RptObject.hxx>
+#include <ScrollHelper.hxx>
+#include <UITools.hxx>
+
+#include <strings.hxx>
+#include <UndoEnv.hxx>
+#include <RptModel.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <tools/diagnose_ex.h>
+
+#define DEFAUL_MOVE_SIZE 100
+namespace rptui
+{
+using namespace ::com::sun::star;
+
+
+IMPL_LINK_NOARG( DlgEdFunc, ScrollTimeout, Timer *, void )
+{
+ ForceScroll( m_pParent->PixelToLogic( m_pParent->GetPointerPosPixel() ) );
+}
+
+
+void DlgEdFunc::ForceScroll( const Point& rPos )
+{
+ aScrollTimer.Stop();
+
+ OReportWindow* pReportWindow = m_pParent->getSectionWindow()->getViewsWindow()->getView();
+ OScrollWindowHelper* pScrollWindow = pReportWindow->getScrollWindow();
+
+ Size aOut = pReportWindow->GetOutputSizePixel();
+ Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH));
+ aStartWidth *= m_pParent->GetMapMode().GetScaleX();
+
+ aOut.AdjustWidth( -static_cast<tools::Long>(aStartWidth) );
+ aOut.setHeight( m_pParent->GetOutputSizePixel().Height() );
+
+ Point aPos = pScrollWindow->getThumbPos();
+ aPos.setX( aPos.X() * 0.5 );
+ aPos.setY( aPos.Y() * 0.5 );
+ tools::Rectangle aOutRect( aPos, aOut );
+ aOutRect = m_pParent->PixelToLogic( aOutRect );
+ tools::Rectangle aWorkArea(Point(), pScrollWindow->getTotalSize());
+ aWorkArea.AdjustRight( -static_cast<tools::Long>(aStartWidth) );
+ aWorkArea = pScrollWindow->PixelToLogic( aWorkArea );
+ if( !aOutRect.Contains( rPos ) && aWorkArea.Contains( rPos ) )
+ {
+ ScrollBar& rHScroll = pScrollWindow->GetHScroll();
+ ScrollBar& rVScroll = pScrollWindow->GetVScroll();
+ ScrollType eH = ScrollType::LineDown,eV = ScrollType::LineDown;
+ if( rPos.X() < aOutRect.Left() )
+ eH = ScrollType::LineUp;
+ else if( rPos.X() <= aOutRect.Right() )
+ eH = ScrollType::DontKnow;
+
+ if( rPos.Y() < aOutRect.Top() )
+ eV = ScrollType::LineUp;
+ else if( rPos.Y() <= aOutRect.Bottom() )
+ eV = ScrollType::DontKnow;
+
+ rHScroll.DoScrollAction(eH);
+ rVScroll.DoScrollAction(eV);
+ }
+
+ aScrollTimer.Start();
+}
+
+DlgEdFunc::DlgEdFunc( OReportSection* _pParent )
+ : m_pParent(_pParent)
+ , m_rView(_pParent->getSectionView())
+ , aScrollTimer("reportdesign DlgEdFunc aScrollTimer")
+ , m_pOverlappingObj(nullptr)
+ , m_nOverlappedControlColor(0)
+ , m_nOldColor(0)
+ , m_bSelectionMode(false)
+ , m_bUiActive(false)
+ , m_bShowPropertyBrowser(false)
+{
+ aScrollTimer.SetInvokeHandler( LINK( this, DlgEdFunc, ScrollTimeout ) );
+ m_rView.SetActualWin( m_pParent->GetOutDev() );
+ aScrollTimer.SetTimeout( SELENG_AUTOREPEAT_INTERVAL );
+}
+
+void DlgEdFunc::setOverlappedControlColor(Color _nColor)
+{
+ m_nOverlappedControlColor = _nColor;
+}
+
+static Color lcl_setColorOfObject(const uno::Reference< uno::XInterface >& _xObj, Color _nColorTRGB)
+{
+ Color nBackColor;
+ try
+ {
+ uno::Reference<report::XReportComponent> xComponent(_xObj, uno::UNO_QUERY_THROW);
+ uno::Reference< beans::XPropertySet > xProp(xComponent, uno::UNO_QUERY_THROW);
+ uno::Any aAny = xProp->getPropertyValue(PROPERTY_CONTROLBACKGROUND);
+ if (aAny.hasValue())
+ {
+ aAny >>= nBackColor;
+ // try to set background color at the ReportComponent
+ uno::Any aBlackColorAny(_nColorTRGB);
+ xProp->setPropertyValue(PROPERTY_CONTROLBACKGROUND, aBlackColorAny);
+ }
+ }
+ catch(uno::Exception&)
+ {
+ }
+ return nBackColor;
+}
+
+DlgEdFunc::~DlgEdFunc()
+{
+ unColorizeOverlappedObj();
+ aScrollTimer.Stop();
+}
+
+
+bool DlgEdFunc::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ m_aMDPos = m_pParent->PixelToLogic( rMEvt.GetPosPixel() );
+ m_pParent->GrabFocus();
+ bool bHandled = false;
+ if ( rMEvt.IsLeft() )
+ {
+ if ( rMEvt.GetClicks() > 1 )
+ {
+ // show property browser
+ uno::Sequence<beans::PropertyValue> aArgs( comphelper::InitPropertySequence({
+ { "ShowProperties", uno::Any(true) }
+ }));
+ m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->getController().executeUnChecked(SID_SHOW_PROPERTYBROWSER,aArgs);
+ m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->UpdatePropertyBrowserDelayed(m_rView);
+ // TODO character in shapes
+ // SdrViewEvent aVEvt;
+ // m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
+ // if ( aVEvt.mpRootObj && aVEvt.pRootObj->ISA(SdrTextObj) )
+ // SetInEditMode(static_cast<SdrTextObj *>(aVEvt.mpRootObj),rMEvt, sal_False);
+ bHandled = true;
+ }
+ else
+ {
+ SdrHdl* pHdl = m_rView.PickHandle(m_aMDPos);
+
+ // if selected object was hit, drag object
+ if ( pHdl!=nullptr || m_rView.IsMarkedHit(m_aMDPos) )
+ {
+ bHandled = true;
+ m_pParent->CaptureMouse();
+ m_pParent->getSectionWindow()->getViewsWindow()->BegDragObj(m_aMDPos, pHdl,&m_rView);
+ }
+ }
+ }
+ else if ( rMEvt.IsRight() && !rMEvt.IsLeft() && rMEvt.GetClicks() == 1 ) // mark object when context menu was selected
+ {
+ SdrPageView* pPV = m_rView.GetSdrPageView();
+ SdrViewEvent aVEvt;
+ if ( m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt) != SdrHitKind::MarkedObject && !rMEvt.IsShift() )
+ m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr);
+ if ( aVEvt.mpRootObj )
+ m_rView.MarkObj(aVEvt.mpRootObj, pPV);
+ else
+ m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr);
+
+ bHandled = true;
+ }
+ else if( !rMEvt.IsLeft() )
+ bHandled = true;
+ if ( !bHandled )
+ m_pParent->CaptureMouse();
+ return bHandled;
+}
+
+
+bool DlgEdFunc::MouseButtonUp( const MouseEvent& /*rMEvt*/ )
+{
+ m_pParent->getSectionWindow()->getViewsWindow()->stopScrollTimer();
+ return false;
+}
+
+void DlgEdFunc::checkTwoClicks(const MouseEvent& rMEvt)
+{
+ deactivateOle();
+
+ const sal_uInt16 nClicks = rMEvt.GetClicks();
+ if ( !(nClicks == 2 && rMEvt.IsLeft()) )
+ return;
+
+ if ( m_rView.AreObjectsMarked() )
+ {
+ const SdrMarkList& rMarkList = m_rView.GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ const SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+ activateOle(pObj);
+ }
+ }
+}
+
+void DlgEdFunc::stopScrollTimer()
+{
+ unColorizeOverlappedObj();
+ aScrollTimer.Stop();
+ if ( m_pParent->IsMouseCaptured() )
+ m_pParent->ReleaseMouse();
+}
+
+
+bool DlgEdFunc::MouseMove( const MouseEvent& /*rMEvt*/ )
+{
+ return false;
+}
+
+bool DlgEdFunc::handleKeyEvent(const KeyEvent& _rEvent)
+{
+ bool bReturn = false;
+
+ if ( !m_bUiActive )
+ {
+ const vcl::KeyCode& rCode = _rEvent.GetKeyCode();
+ sal_uInt16 nCode = rCode.GetCode();
+
+ switch ( nCode )
+ {
+ case KEY_ESCAPE:
+ {
+ if ( m_pParent->getSectionWindow()->getViewsWindow()->IsAction() )
+ {
+ m_pParent->getSectionWindow()->getViewsWindow()->BrkAction();
+ bReturn = true;
+ }
+ else if ( m_rView.IsTextEdit() )
+ {
+ m_rView.SdrEndTextEdit();
+ bReturn = true;
+ }
+ else if ( m_rView.AreObjectsMarked() )
+ {
+ const SdrHdlList& rHdlList = m_rView.GetHdlList();
+ SdrHdl* pHdl = rHdlList.GetFocusHdl();
+ if ( pHdl )
+ const_cast<SdrHdlList&>(rHdlList).ResetFocusHdl();
+ else
+ m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr);
+
+ deactivateOle(true);
+ bReturn = false;
+ }
+ else
+ {
+ deactivateOle(true);
+ }
+ }
+ break;
+ case KEY_TAB:
+ {
+ if ( !rCode.IsMod1() && !rCode.IsMod2() )
+ {
+ // mark next object
+ if ( !m_rView.MarkNextObj( !rCode.IsShift() ) )
+ {
+ // if no next object, mark first/last
+ m_rView.UnmarkAllObj();
+ m_rView.MarkNextObj( !rCode.IsShift() );
+ }
+
+ if ( m_rView.AreObjectsMarked() )
+ m_rView.MakeVisible( m_rView.GetAllMarkedRect(), *m_pParent);
+
+ bReturn = true;
+ }
+ else if ( rCode.IsMod1() && rCode.IsMod2())
+ {
+ // selected handle
+ const SdrHdlList& rHdlList = m_rView.GetHdlList();
+ const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl( !rCode.IsShift() );
+
+ // guarantee visibility of focused handle
+ SdrHdl* pHdl = rHdlList.GetFocusHdl();
+ if ( pHdl )
+ {
+ Point aHdlPosition( pHdl->GetPos() );
+ tools::Rectangle aVisRect( aHdlPosition - Point( DEFAUL_MOVE_SIZE, DEFAUL_MOVE_SIZE ), Size( 200, 200 ) );
+ m_rView.MakeVisible( aVisRect, *m_pParent);
+ }
+
+ bReturn = true;
+ }
+ }
+ break;
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ {
+ m_pParent->getSectionWindow()->getViewsWindow()->handleKey(rCode);
+ bReturn = true;
+ }
+ break;
+ case KEY_RETURN:
+ if ( !rCode.IsMod1() )
+ {
+ const SdrMarkList& rMarkList = m_rView.GetMarkedObjectList();
+ if ( rMarkList.GetMarkCount() == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ activateOle(pObj);
+ }
+ }
+ break;
+ case KEY_DELETE:
+ if ( !rCode.IsMod1() && !rCode.IsMod2() )
+ {
+ bReturn = true;
+ break;
+ }
+ [[fallthrough]];
+ default:
+ {
+ bReturn = m_rView.KeyInput(_rEvent, m_pParent);
+ }
+ break;
+ }
+ }
+
+ if ( bReturn && m_pParent->IsMouseCaptured() )
+ m_pParent->ReleaseMouse();
+
+ return bReturn;
+}
+
+void DlgEdFunc::activateOle(SdrObject* _pObj)
+{
+ if ( !_pObj )
+ return;
+
+ const SdrObjKind nSdrObjKind = _pObj->GetObjIdentifier();
+
+ // OLE: activate
+
+ if (nSdrObjKind != SdrObjKind::OLE2)
+ return;
+
+ SdrOle2Obj* pOleObj = dynamic_cast<SdrOle2Obj*>(_pObj);
+ if (!(pOleObj && pOleObj->GetObjRef().is()))
+ return;
+
+ if (m_rView.IsTextEdit())
+ {
+ m_rView.SdrEndTextEdit();
+ }
+
+ pOleObj->AddOwnLightClient();
+ pOleObj->SetWindow(VCLUnoHelper::GetInterface(m_pParent));
+ try
+ {
+ pOleObj->GetObjRef()->changeState( embed::EmbedStates::UI_ACTIVE );
+ m_bUiActive = true;
+ OReportController& rController = m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->getController();
+ m_bShowPropertyBrowser = rController.isCommandChecked(SID_SHOW_PROPERTYBROWSER);
+ if ( m_bShowPropertyBrowser )
+ rController.executeChecked(SID_SHOW_PROPERTYBROWSER,uno::Sequence< beans::PropertyValue >());
+ }
+ catch( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ }
+}
+
+void DlgEdFunc::deactivateOle(bool _bSelect)
+{
+ OLEObjCache& rObjCache = GetSdrGlobalData().GetOLEObjCache();
+ OReportController& rController = m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->getController();
+ const size_t nCount = rObjCache.size();
+ for(size_t i = 0 ; i < nCount;++i)
+ {
+ SdrOle2Obj* pObj = rObjCache[i];
+ if ( m_pParent->getPage() == pObj->getSdrPageFromSdrObject() )
+ {
+ uno::Reference< embed::XEmbeddedObject > xObj = pObj->GetObjRef();
+ if ( xObj.is() && xObj->getCurrentState() == embed::EmbedStates::UI_ACTIVE )
+ {
+ xObj->changeState( embed::EmbedStates::RUNNING );
+ m_bUiActive = false;
+ if ( m_bShowPropertyBrowser )
+ {
+ rController.executeChecked(SID_SHOW_PROPERTYBROWSER,uno::Sequence< beans::PropertyValue >());
+ }
+
+ if ( _bSelect )
+ {
+ SdrPageView* pPV = m_rView.GetSdrPageView();
+ m_rView.MarkObj(pObj, pPV);
+ }
+ }
+ }
+ }
+}
+
+void DlgEdFunc::colorizeOverlappedObject(SdrObject* _pOverlappedObj)
+{
+ OObjectBase* pObj = dynamic_cast<OObjectBase*>(_pOverlappedObj);
+ if ( !pObj )
+ return;
+
+ const uno::Reference<report::XReportComponent>& xComponent = pObj->getReportComponent();
+ if (xComponent.is() && xComponent != m_xOverlappingObj)
+ {
+ OReportModel& rRptModel(static_cast< OReportModel& >(_pOverlappedObj->getSdrModelFromSdrObject()));
+ OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv());
+
+ // uncolorize an old object, if there is one
+ unColorizeOverlappedObj();
+
+ m_nOldColor = lcl_setColorOfObject(xComponent, m_nOverlappedControlColor);
+ m_xOverlappingObj = xComponent;
+ m_pOverlappingObj = _pOverlappedObj;
+ }
+}
+
+void DlgEdFunc::unColorizeOverlappedObj()
+{
+ // uncolorize an old object, if there is one
+ if (m_xOverlappingObj.is())
+ {
+ OReportModel& rRptModel(static_cast< OReportModel& >(m_pOverlappingObj->getSdrModelFromSdrObject()));
+ OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv());
+
+ lcl_setColorOfObject(m_xOverlappingObj, m_nOldColor);
+ m_xOverlappingObj = nullptr;
+ m_pOverlappingObj = nullptr;
+ }
+}
+
+bool DlgEdFunc::isOverlapping(const MouseEvent& rMEvt)
+{
+ SdrViewEvent aVEvt;
+ bool bOverlapping = m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONUP, aVEvt) != SdrHitKind::NONE;
+ if (bOverlapping && aVEvt.mpObj)
+ {
+ colorizeOverlappedObject(aVEvt.mpObj);
+ }
+ else
+ {
+ unColorizeOverlappedObj();
+ }
+
+ return bOverlapping;
+}
+
+void DlgEdFunc::checkMovementAllowed(const MouseEvent& rMEvt)
+{
+ if ( m_pParent->getSectionWindow()->getViewsWindow()->IsDragObj() )
+ {
+ if ( isRectangleHit(rMEvt) )
+ {
+ // there is another component under use, break action
+ m_pParent->getSectionWindow()->getViewsWindow()->BrkAction();
+ }
+ // object was dragged
+ Point aPnt( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) );
+ if (m_bSelectionMode)
+ {
+ m_pParent->getSectionWindow()->getViewsWindow()->EndAction();
+ }
+ else
+ {
+ bool bControlKeyPressed = rMEvt.IsMod1();
+ // Don't allow points smaller 0
+ if (bControlKeyPressed && (aPnt.Y() < 0))
+ {
+ aPnt.setY( 0 );
+ }
+ if (m_rView.IsDragResize())
+ {
+ // we resize the object don't resize to above sections
+ if ( aPnt.Y() < 0 )
+ {
+ aPnt.setY( 0 );
+ }
+ }
+ m_pParent->getSectionWindow()->getViewsWindow()->EndDragObj( bControlKeyPressed, &m_rView, aPnt );
+ }
+ m_pParent->getSectionWindow()->getViewsWindow()->ForceMarkedToAnotherPage();
+ m_pParent->Invalidate(InvalidateFlags::Children);
+ }
+ else
+ m_pParent->getSectionWindow()->getViewsWindow()->EndAction();
+}
+
+bool DlgEdFunc::isOnlyCustomShapeMarked() const
+{
+ bool bReturn = true;
+ const SdrMarkList& rMarkList = m_rView.GetMarkedObjectList();
+ for (size_t i = 0; i < rMarkList.GetMarkCount(); ++i )
+ {
+ SdrMark* pMark = rMarkList.GetMark(i);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+ if (pObj->GetObjIdentifier() != SdrObjKind::CustomShape)
+ {
+ // we found an object in the marked objects, which is not a custom shape.
+ bReturn = false;
+ break;
+ }
+ }
+ return bReturn;
+}
+
+bool DlgEdFunc::isRectangleHit(const MouseEvent& rMEvt)
+{
+ if (isOnlyCustomShapeMarked())
+ {
+ return false;
+ }
+
+ SdrViewEvent aVEvt;
+ const SdrHitKind eHit = m_rView.PickAnything(rMEvt, SdrMouseEventKind::MOVE, aVEvt);
+ bool bIsSetPoint = (eHit == SdrHitKind::UnmarkedObject);
+ if ( !bIsSetPoint )
+ {
+ // no drag rect, we have to check every single select rect
+ const SdrDragStat& rDragStat = m_rView.GetDragStat();
+ if (rDragStat.GetDragMethod() != nullptr)
+ {
+ SdrObjListIter aIter(m_pParent->getPage(),SdrIterMode::DeepNoGroups);
+ // loop through all marked objects and check if there new rect overlapps an old one.
+ for (;;)
+ {
+ SdrObject* pObjIter = aIter.Next();
+ if( !pObjIter || bIsSetPoint)
+ break;
+ if ( m_rView.IsObjMarked(pObjIter)
+ && (dynamic_cast<OUnoObject*>(pObjIter) != nullptr || dynamic_cast<OOle2Obj*>(pObjIter) != nullptr) )
+ {
+ tools::Rectangle aNewRect = pObjIter->GetLastBoundRect();
+ tools::Long nDx = rDragStat.IsHorFixed() ? 0 : rDragStat.GetDX();
+ tools::Long nDy = rDragStat.IsVerFixed() ? 0 : rDragStat.GetDY();
+ if ( (nDx + aNewRect.Left()) < 0 )
+ nDx = -aNewRect.Left();
+ if ( (nDy + aNewRect.Top()) < 0 )
+ nDy = -aNewRect.Top();
+
+ if ( rDragStat.GetDragMethod()->getMoveOnly() )
+ aNewRect.Move(nDx,nDy);
+ else
+ ::ResizeRect(aNewRect,rDragStat.GetRef1(),rDragStat.GetXFact(),rDragStat.GetYFact());
+
+
+ SdrObject* pObjOverlapped = isOver(aNewRect,*m_pParent->getPage(),m_rView,false,pObjIter, ISOVER_IGNORE_CUSTOMSHAPES);
+ bIsSetPoint = pObjOverlapped != nullptr;
+ if (pObjOverlapped && !m_bSelectionMode)
+ {
+ colorizeOverlappedObject(pObjOverlapped);
+ }
+ }
+ }
+ }
+ }
+ else if (aVEvt.mpObj && (aVEvt.mpObj->GetObjIdentifier() != SdrObjKind::CustomShape) && !m_bSelectionMode)
+ {
+ colorizeOverlappedObject(aVEvt.mpObj);
+ }
+ else
+ bIsSetPoint = false;
+ return bIsSetPoint;
+}
+
+bool DlgEdFunc::setMovementPointer(const MouseEvent& rMEvt)
+{
+ bool bIsSetPoint = isRectangleHit(rMEvt);
+ if ( bIsSetPoint )
+ m_pParent->SetPointer( PointerStyle::NotAllowed );
+ else
+ {
+ bool bCtrlKey = rMEvt.IsMod1();
+ if (bCtrlKey)
+ {
+ m_pParent->SetPointer( PointerStyle::MoveDataLink );
+ bIsSetPoint = true;
+ }
+ }
+ return bIsSetPoint;
+}
+
+
+DlgEdFuncInsert::DlgEdFuncInsert( OReportSection* _pParent ) :
+ DlgEdFunc( _pParent )
+{
+ m_rView.SetCreateMode();
+}
+
+
+DlgEdFuncInsert::~DlgEdFuncInsert()
+{
+ m_rView.SetEditMode();
+}
+
+
+bool DlgEdFuncInsert::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( DlgEdFunc::MouseButtonDown(rMEvt) )
+ return true;
+
+ SdrViewEvent aVEvt;
+ SdrObjKind nId = m_rView.GetCurrentObjIdentifier();
+
+ const SdrHitKind eHit = m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
+
+ if (eHit == SdrHitKind::UnmarkedObject && nId != SdrObjKind::CustomShape)
+ {
+ // there is an object under the mouse cursor, but not a customshape
+ m_pParent->getSectionWindow()->getViewsWindow()->BrkAction();
+ return false;
+ }
+
+ // if no action, create object
+ if (!m_pParent->getSectionWindow()->getViewsWindow()->IsAction())
+ {
+ deactivateOle(true);
+ if ( m_pParent->getSectionWindow()->getViewsWindow()->HasSelection() )
+ m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(&m_rView);
+ m_rView.BegCreateObj(m_aMDPos);
+ m_pParent->getSectionWindow()->getViewsWindow()->createDefault();
+ }
+
+ return true;
+}
+
+
+bool DlgEdFuncInsert::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( DlgEdFunc::MouseButtonUp( rMEvt ) )
+ return true;
+
+ const Point aPos( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) );
+ const sal_uInt16 nHitLog = sal_uInt16 ( m_pParent->PixelToLogic(Size(3,0)).Width() );
+
+ bool bReturn = true;
+ // object creation active?
+ if ( m_rView.IsCreateObj() )
+ {
+ if ( isOver(m_rView.GetCreateObj(),*m_pParent->getPage(),m_rView) )
+ {
+ m_pParent->getSectionWindow()->getViewsWindow()->BrkAction();
+ // BrkAction disables the create mode
+ m_rView.SetCreateMode();
+ return true;
+ }
+
+ m_rView.EndCreateObj(SdrCreateCmd::ForceEnd);
+
+ if ( !m_rView.AreObjectsMarked() )
+ {
+ m_rView.MarkObj(aPos, nHitLog);
+ }
+
+ bReturn = m_rView.AreObjectsMarked();
+ if ( bReturn )
+ {
+ OReportController& rController = m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->getController();
+ const SdrMarkList& rMarkList = m_rView.GetMarkedObjectList();
+ for (size_t i = 0; i < rMarkList.GetMarkCount(); ++i )
+ {
+ SdrMark* pMark = rMarkList.GetMark(i);
+ OOle2Obj* pObj = dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj());
+ if ( pObj && !pObj->IsEmpty() )
+ {
+ pObj->initializeChart(rController.getModel());
+ }
+ }
+ }
+ }
+ else
+ checkMovementAllowed(rMEvt);
+
+ if ( !m_rView.AreObjectsMarked() &&
+ std::abs(m_aMDPos.X() - aPos.X()) < nHitLog &&
+ std::abs(m_aMDPos.Y() - aPos.Y()) < nHitLog &&
+ !rMEvt.IsShift() && !rMEvt.IsMod2() )
+ {
+ SdrPageView* pPV = m_rView.GetSdrPageView();
+ SdrViewEvent aVEvt;
+ m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
+ m_rView.MarkObj(aVEvt.mpRootObj, pPV);
+ }
+ checkTwoClicks(rMEvt);
+ m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->UpdatePropertyBrowserDelayed(m_rView);
+ return bReturn;
+}
+
+
+bool DlgEdFuncInsert::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( DlgEdFunc::MouseMove(rMEvt ) )
+ return true;
+ Point aPos( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) );
+
+ if ( m_rView.IsCreateObj() )
+ {
+ m_rView.SetOrtho(SdrObjCustomShape::doConstructOrthogonal(m_rView.getReportSection()->getSectionWindow()->getViewsWindow()->getShapeType()) ? !rMEvt.IsShift() : rMEvt.IsShift());
+ m_rView.SetAngleSnapEnabled(rMEvt.IsShift());
+ }
+
+ bool bIsSetPoint = false;
+ if ( m_rView.IsAction() )
+ {
+ if ( m_rView.IsDragResize() )
+ {
+ // we resize the object don't resize to above sections
+ if ( aPos.Y() < 0 )
+ {
+ aPos.setY( 0 );
+ }
+ }
+ bIsSetPoint = setMovementPointer(rMEvt);
+ ForceScroll(aPos);
+ m_pParent->getSectionWindow()->getViewsWindow()->MovAction(aPos,&m_rView, false);
+ }
+
+ if ( !bIsSetPoint )
+ m_pParent->SetPointer( m_rView.GetPreferredPointer( aPos, m_pParent->GetOutDev()) );
+
+ return true;
+}
+
+
+DlgEdFuncSelect::DlgEdFuncSelect( OReportSection* _pParent ) :
+ DlgEdFunc( _pParent )
+{
+}
+
+
+DlgEdFuncSelect::~DlgEdFuncSelect()
+{
+}
+
+
+bool DlgEdFuncSelect::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ m_bSelectionMode = false;
+ if ( DlgEdFunc::MouseButtonDown(rMEvt) )
+ return true;
+
+ SdrViewEvent aVEvt;
+ const SdrHitKind eHit = m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
+ if( eHit == SdrHitKind::UnmarkedObject )
+ {
+ // if not multi selection, unmark all
+ if ( !rMEvt.IsShift() )
+ m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr);
+
+ if ( m_rView.MarkObj(m_aMDPos) && rMEvt.IsLeft() )
+ {
+ // drag object
+ m_pParent->getSectionWindow()->getViewsWindow()->BegDragObj(m_aMDPos, m_rView.PickHandle(m_aMDPos), &m_rView);
+ }
+ else
+ {
+ // select object
+ m_pParent->getSectionWindow()->getViewsWindow()->BegMarkObj(m_aMDPos,&m_rView);
+ }
+ }
+ else
+ {
+ if( !rMEvt.IsShift() )
+ m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr);
+
+ if ( rMEvt.GetClicks() == 1 )
+ {
+ m_bSelectionMode = true;
+ m_pParent->getSectionWindow()->getViewsWindow()->BegMarkObj( m_aMDPos ,&m_rView);
+ }
+ else
+ {
+ m_rView.SdrBeginTextEdit( aVEvt.mpRootObj,m_rView.GetSdrPageView(),m_pParent );
+ }
+ }
+
+ return true;
+}
+
+
+bool DlgEdFuncSelect::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( DlgEdFunc::MouseButtonUp( rMEvt ) )
+ return true;
+
+ // get view from parent
+ const Point aPnt( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) );
+
+ if ( rMEvt.IsLeft() ) // left mousebutton pressed
+ checkMovementAllowed(rMEvt);
+
+ m_pParent->getSectionWindow()->getViewsWindow()->EndAction();
+ checkTwoClicks(rMEvt);
+
+ m_pParent->SetPointer( m_rView.GetPreferredPointer( aPnt, m_pParent->GetOutDev() ) );
+
+ if ( !m_bUiActive )
+ m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->UpdatePropertyBrowserDelayed(m_rView);
+ m_bSelectionMode = false;
+ return true;
+}
+
+
+bool DlgEdFuncSelect::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( DlgEdFunc::MouseMove(rMEvt ) )
+ return true;
+
+ Point aPnt( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) );
+ bool bIsSetPoint = false;
+
+ if ( m_rView.IsAction() ) // Drag Mode
+ {
+ bIsSetPoint = setMovementPointer(rMEvt);
+ ForceScroll(aPnt);
+ if (m_rView.GetDragMethod()==nullptr)
+ {
+ // create a selection
+ m_pParent->getSectionWindow()->getViewsWindow()->MovAction(aPnt, &m_rView, false);
+ }
+ else
+ {
+ if ( m_rView.IsDragResize() )
+ {
+ // we resize the object don't resize to above sections
+ if ( aPnt.Y() < 0 )
+ {
+ aPnt.setY( 0 );
+ }
+ }
+ // drag or resize an object
+ bool bControlKey = rMEvt.IsMod1();
+ m_pParent->getSectionWindow()->getViewsWindow()->MovAction(aPnt, &m_rView, bControlKey);
+ }
+ }
+
+ if ( !bIsSetPoint )
+ {
+ m_pParent->SetPointer( m_rView.GetPreferredPointer( aPnt, m_pParent->GetOutDev() ) );
+
+ // restore color
+ unColorizeOverlappedObj();
+ }
+
+ return true;
+}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/report/propbrw.cxx b/reportdesign/source/ui/report/propbrw.cxx
new file mode 100644
index 000000000..4254dcf3e
--- /dev/null
+++ b/reportdesign/source/ui/report/propbrw.cxx
@@ -0,0 +1,528 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <memory>
+#include <propbrw.hxx>
+#include <RptObject.hxx>
+#include <ReportController.hxx>
+#include <cppuhelper/component_context.hxx>
+#include <strings.hrc>
+#include <rptui_slotid.hrc>
+#include <tools/diagnose_ex.h>
+#include <com/sun/star/awt/XLayoutConstrains.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/Frame.hpp>
+#include <com/sun/star/inspection/ObjectInspector.hpp>
+#include <com/sun/star/inspection/DefaultHelpProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/report/inspection/DefaultComponentInspectorModel.hpp>
+#include <vcl/stdtext.hxx>
+#include <vcl/weld.hxx>
+#include <svx/svditer.hxx>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <comphelper/namecontainer.hxx>
+#include <comphelper/types.hxx>
+#include <comphelper/sequence.hxx>
+#include <core_resource.hxx>
+#include <SectionView.hxx>
+#include <ReportSection.hxx>
+#include <strings.hxx>
+#include <DesignView.hxx>
+#include <ViewsWindow.hxx>
+#include <UITools.hxx>
+#include <unotools/confignode.hxx>
+
+namespace rptui
+{
+#define STD_WIN_SIZE_X 300
+#define STD_WIN_SIZE_Y 350
+
+using namespace ::com::sun::star;
+using namespace uno;
+using namespace lang;
+using namespace frame;
+using namespace beans;
+using namespace container;
+using namespace ::comphelper;
+
+
+namespace
+{
+ bool lcl_shouldEnableHelpSection( const Reference< XComponentContext >& _rxContext )
+ {
+ ::utl::OConfigurationTreeRoot aConfiguration(
+ ::utl::OConfigurationTreeRoot::createWithComponentContext(
+ _rxContext, "/org.openoffice.Office.ReportDesign/PropertyBrowser/" ) );
+
+ bool bEnabled = false;
+ OSL_VERIFY( aConfiguration.getNodeValue( "DirectHelp" ) >>= bEnabled );
+ return bEnabled;
+ }
+}
+
+
+// PropBrw
+
+
+PropBrw::PropBrw(const Reference< XComponentContext >& _xORB, vcl::Window* pParent, ODesignView* _pDesignView)
+ : DockingWindow(pParent,WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_3DLOOK))
+ , m_xContentArea(VclPtr<VclVBox>::Create(this))
+ , m_xORB(_xORB)
+ , m_pDesignView(_pDesignView)
+ , m_pView( nullptr )
+ , m_bInitialStateChange(true)
+{
+
+ Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y);
+ SetOutputSizePixel(aPropWinSize);
+
+ // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under"
+ // transparent children of the widget
+ m_xContentArea->SetControlBackground(m_xContentArea->GetSettings().GetStyleSettings().GetWindowColor());
+ m_xContentArea->SetBackground(m_xContentArea->GetControlBackground());
+ m_xContentArea->SetStyle(m_xContentArea->GetStyle() & ~WB_CLIPCHILDREN);
+ m_xContentArea->Show();
+
+ try
+ {
+ // create a frame wrapper for myself
+ m_xMeAsFrame = Frame::create( m_xORB );
+ m_xMeAsFrame->initialize(VCLUnoHelper::GetInterface(m_xContentArea));
+ m_xMeAsFrame->setName("report property browser"); // change name!
+ }
+ catch (Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ OSL_FAIL("PropBrw::PropBrw: could not create/initialize my frame!");
+ m_xMeAsFrame.clear();
+ }
+
+ if (m_xMeAsFrame.is())
+ {
+ try
+ {
+ ::cppu::ContextEntry_Init aHandlerContextInfo[] =
+ {
+ ::cppu::ContextEntry_Init( "ContextDocument", Any( m_pDesignView->getController().getModel() )),
+ ::cppu::ContextEntry_Init( "DialogParentWindow", Any( VCLUnoHelper::GetInterface ( this ) )),
+ ::cppu::ContextEntry_Init( "ActiveConnection", Any( m_pDesignView->getController().getConnection() ) ),
+ };
+ m_xInspectorContext.set(
+ ::cppu::createComponentContext( aHandlerContextInfo, SAL_N_ELEMENTS( aHandlerContextInfo ),
+ m_xORB ) );
+ // create a property browser controller
+ bool bEnableHelpSection = lcl_shouldEnableHelpSection( m_xORB );
+ Reference< inspection::XObjectInspectorModel> xInspectorModel( bEnableHelpSection
+ ? report::inspection::DefaultComponentInspectorModel::createWithHelpSection( m_xInspectorContext, 3, 8 )
+ : report::inspection::DefaultComponentInspectorModel::createDefault( m_xInspectorContext ) );
+
+ m_xBrowserController = inspection::ObjectInspector::createWithModel(m_xInspectorContext, xInspectorModel);
+ if ( !m_xBrowserController.is() )
+ {
+ ShowServiceNotAvailableError(pParent ? pParent->GetFrameWeld() : nullptr, u"com.sun.star.inspection.ObjectInspector", true);
+ }
+ else
+ {
+ m_xBrowserController->attachFrame( Reference<XFrame>(m_xMeAsFrame, UNO_QUERY_THROW));
+ if ( bEnableHelpSection )
+ {
+ uno::Reference< inspection::XObjectInspector > xInspector( m_xBrowserController, uno::UNO_SET_THROW );
+ uno::Reference< inspection::XObjectInspectorUI > xInspectorUI( xInspector->getInspectorUI() );
+ inspection::DefaultHelpProvider::create( m_xInspectorContext, xInspectorUI );
+ }
+ }
+ }
+ catch (Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("reportdesign");
+ OSL_FAIL("PropBrw::PropBrw: could not create/initialize the browser controller!");
+ try
+ {
+ ::comphelper::disposeComponent(m_xBrowserController);
+ }
+ catch(Exception&) { }
+ m_xBrowserController.clear();
+ }
+ }
+
+ VclContainer::setLayoutAllocation(*m_xContentArea, Point(0, 0), aPropWinSize);
+ m_xContentArea->Show();
+
+ ::rptui::notifySystemWindow(pParent,this,::comphelper::mem_fun(&TaskPaneList::AddWindow));
+}
+
+
+PropBrw::~PropBrw()
+{
+ disposeOnce();
+}
+
+void PropBrw::dispose()
+{
+ if (m_xBrowserController.is())
+ implDetachController();
+
+ try
+ {
+ uno::Reference<container::XNameContainer> xName(m_xInspectorContext,uno::UNO_QUERY);
+ if ( xName.is() )
+ {
+ const OUString pProps[] = { OUString( "ContextDocument" )
+ , OUString( "DialogParentWindow" )
+ , OUString( "ActiveConnection" )};
+ for (const auto & i : pProps)
+ xName->removeByName(i);
+ }
+ }
+ catch(Exception&)
+ {}
+
+ ::rptui::notifySystemWindow(this,this,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
+ m_pDesignView.clear();
+ m_xContentArea.disposeAndClear();
+ DockingWindow::dispose();
+}
+
+void PropBrw::setCurrentPage(const OUString& _sLastActivePage)
+{
+ m_sLastActivePage = _sLastActivePage;
+}
+
+
+void PropBrw::implDetachController()
+{
+ m_sLastActivePage = getCurrentPage();
+ implSetNewObject( );
+
+ if ( m_xMeAsFrame.is() )
+ m_xMeAsFrame->setComponent( nullptr, nullptr );
+
+ if ( m_xBrowserController.is() )
+ m_xBrowserController->attachFrame( nullptr );
+
+ m_xMeAsFrame.clear();
+ m_xBrowserController.clear();
+}
+
+OUString PropBrw::getCurrentPage() const
+{
+ OUString sCurrentPage;
+ try
+ {
+ if ( m_xBrowserController.is() )
+ {
+ OSL_VERIFY( m_xBrowserController->getViewData() >>= sCurrentPage );
+ }
+
+ if ( sCurrentPage.isEmpty() )
+ sCurrentPage = m_sLastActivePage;
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::getCurrentPage: caught an exception while retrieving the current page!" );
+ }
+ return sCurrentPage;
+}
+
+bool PropBrw::Close()
+{
+ m_xLastSection.clear();
+ // suspend the controller (it is allowed to veto)
+ if ( m_xMeAsFrame.is() )
+ {
+ try
+ {
+ Reference< XController > xController( m_xMeAsFrame->getController() );
+ if ( xController.is() && !xController->suspend( true ) )
+ return false;
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::Close: caught an exception while asking the controller!" );
+ }
+ }
+ implDetachController();
+
+ m_pDesignView->getController().executeUnChecked(SID_PROPERTYBROWSER_LAST_PAGE,uno::Sequence< beans::PropertyValue>());
+
+ return true;
+}
+
+uno::Sequence< Reference<uno::XInterface> > PropBrw::CreateCompPropSet(const SdrMarkList& _rMarkList)
+{
+ const size_t nMarkCount = _rMarkList.GetMarkCount();
+ ::std::vector< uno::Reference< uno::XInterface> > aSets;
+ aSets.reserve(nMarkCount);
+
+ for(size_t i=0; i<nMarkCount; ++i)
+ {
+ SdrObject* pCurrent = _rMarkList.GetMark(i)->GetMarkedSdrObj();
+
+ ::std::unique_ptr<SdrObjListIter> pGroupIterator;
+ if (pCurrent->IsGroupObject())
+ {
+ pGroupIterator.reset(new SdrObjListIter(pCurrent->GetSubList()));
+ pCurrent = pGroupIterator->IsMore() ? pGroupIterator->Next() : nullptr;
+ }
+
+ while (pCurrent)
+ {
+ OObjectBase* pObj = dynamic_cast<OObjectBase*>(pCurrent);
+ if ( pObj )
+ aSets.push_back(CreateComponentPair(pObj));
+
+ // next element
+ pCurrent = pGroupIterator && pGroupIterator->IsMore() ? pGroupIterator->Next() : nullptr;
+ }
+ }
+ return uno::Sequence< Reference<uno::XInterface> >(aSets.data(), aSets.size());
+}
+
+void PropBrw::implSetNewObject( const uno::Sequence< Reference<uno::XInterface> >& _aObjects )
+{
+ if ( m_xBrowserController.is() )
+ {
+ try
+ {
+ m_xBrowserController->inspect(uno::Sequence< Reference<uno::XInterface> >());
+ m_xBrowserController->inspect(_aObjects);
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
+ }
+ }
+ SetText( GetHeadlineName(_aObjects) );
+}
+
+
+OUString PropBrw::GetHeadlineName( const uno::Sequence< Reference<uno::XInterface> >& _aObjects )
+{
+ OUString aName;
+ if ( !_aObjects.hasElements() )
+ {
+ aName = RptResId(RID_STR_BRWTITLE_NO_PROPERTIES);
+ }
+ else if ( _aObjects.getLength() == 1 ) // single selection
+ {
+ aName = RptResId(RID_STR_BRWTITLE_PROPERTIES);
+
+ uno::Reference< container::XNameContainer > xNameCont(_aObjects[0],uno::UNO_QUERY);
+ Reference< lang::XServiceInfo > xServiceInfo( xNameCont->getByName("ReportComponent"), UNO_QUERY );
+ if ( xServiceInfo.is() )
+ {
+ TranslateId pResId;
+ if ( xServiceInfo->supportsService( SERVICE_FIXEDTEXT ) )
+ {
+ pResId = RID_STR_PROPTITLE_FIXEDTEXT;
+ }
+ else if ( xServiceInfo->supportsService( SERVICE_IMAGECONTROL ) )
+ {
+ pResId = RID_STR_PROPTITLE_IMAGECONTROL;
+ }
+ else if ( xServiceInfo->supportsService( SERVICE_FORMATTEDFIELD ) )
+ {
+ pResId = RID_STR_PROPTITLE_FORMATTED;
+ }
+ else if ( xServiceInfo->supportsService( SERVICE_SHAPE ) )
+ {
+ pResId = RID_STR_PROPTITLE_SHAPE;
+ }
+ else if ( xServiceInfo->supportsService( SERVICE_REPORTDEFINITION ) )
+ {
+ pResId = RID_STR_PROPTITLE_REPORT;
+ }
+ else if ( xServiceInfo->supportsService( SERVICE_SECTION ) )
+ {
+ pResId = RID_STR_PROPTITLE_SECTION;
+ }
+ else if ( xServiceInfo->supportsService( SERVICE_FUNCTION ) )
+ {
+ pResId = RID_STR_PROPTITLE_FUNCTION;
+ }
+ else if ( xServiceInfo->supportsService( SERVICE_GROUP ) )
+ {
+ pResId = RID_STR_PROPTITLE_GROUP;
+ }
+ else if ( xServiceInfo->supportsService( SERVICE_FIXEDLINE ) )
+ {
+ pResId = RID_STR_PROPTITLE_FIXEDLINE;
+ }
+ else
+ {
+ OSL_FAIL("Unknown service name!");
+ aName += RID_STR_CLASS_FORMATTEDFIELD;
+ return aName;
+ }
+
+ aName += RptResId(pResId);
+ }
+ }
+ else // multiselection
+ {
+ aName = RptResId(RID_STR_BRWTITLE_PROPERTIES)
+ + RptResId(RID_STR_BRWTITLE_MULTISELECT);
+ }
+
+ return aName;
+}
+
+uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(OObjectBase* _pObj)
+{
+ _pObj->initializeOle();
+ return CreateComponentPair(_pObj->getAwtComponent(),_pObj->getReportComponent());
+}
+
+uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(const uno::Reference< uno::XInterface>& _xFormComponent
+ ,const uno::Reference< uno::XInterface>& _xReportComponent)
+{
+ uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get());
+ xNameCont->insertByName("FormComponent",uno::Any(_xFormComponent));
+ xNameCont->insertByName("ReportComponent",uno::Any(_xReportComponent));
+ xNameCont->insertByName("RowSet",uno::Any(uno::Reference< uno::XInterface>(m_pDesignView->getController().getRowSet())));
+
+ return xNameCont;
+}
+
+::Size PropBrw::getMinimumSize() const
+{
+ ::Size aSize;
+ Reference< awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY );
+ if( xLayoutConstrains.is() )
+ {
+ awt::Size aMinSize = xLayoutConstrains->getMinimumSize();
+ aMinSize.Height += 4;
+ aMinSize.Width += 4;
+ aSize.setHeight( aMinSize.Height );
+ aSize.setWidth( aMinSize.Width );
+ }
+ return aSize;
+}
+
+void PropBrw::Update( OSectionView* pNewView )
+{
+ try
+ {
+ if ( m_pView )
+ {
+ EndListening( *(m_pView->GetModel()) );
+ m_pView = nullptr;
+ }
+
+ // set focus on initialization
+ if ( m_bInitialStateChange )
+ {
+ // if we're just newly created, we want to have the focus
+ PostUserEvent( LINK( this, PropBrw, OnAsyncGetFocus ), nullptr, true );
+ m_bInitialStateChange = false;
+ // and additionally, we want to show the page which was active during
+ // our previous incarnation
+ if ( !m_sLastActivePage.isEmpty() && m_xBrowserController.is() )
+ {
+ try
+ {
+ m_xBrowserController->restoreViewData( Any( m_sLastActivePage ) );
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" );
+ }
+ }
+ }
+
+ if ( !pNewView )
+ return;
+ else
+ m_pView = pNewView;
+
+ uno::Sequence< Reference<uno::XInterface> > aMarkedObjects;
+ OViewsWindow* pViews = m_pView->getReportSection()->getSectionWindow()->getViewsWindow();
+ const sal_uInt16 nSectionCount = pViews->getSectionCount();
+ for (sal_uInt16 i = 0; i < nSectionCount; ++i)
+ {
+ OSectionWindow* pSectionWindow = pViews->getSectionWindow(i);
+ if ( pSectionWindow )
+ {
+ const SdrMarkList& rMarkList = pSectionWindow->getReportSection().getSectionView().GetMarkedObjectList();
+ aMarkedObjects = ::comphelper::concatSequences(aMarkedObjects,CreateCompPropSet( rMarkList ));
+ }
+ }
+
+ if ( aMarkedObjects.hasElements() ) // multiple selection
+ {
+ m_xLastSection.clear();
+ implSetNewObject( aMarkedObjects );
+ }
+ else if ( m_xLastSection != m_pView->getReportSection()->getSection() )
+ {
+ uno::Reference< uno::XInterface> xTemp(m_pView->getReportSection()->getSection());
+ m_xLastSection = xTemp;
+ uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get() );
+ xNameCont->insertByName("ReportComponent",uno::Any(xTemp));
+ xTemp = xNameCont;
+
+ implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) );
+ }
+
+ StartListening( *(m_pView->GetModel()) );
+ }
+ catch ( Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update" );
+ }
+}
+
+void PropBrw::Update( const uno::Reference< uno::XInterface>& _xReportComponent)
+{
+ if ( m_xLastSection == _xReportComponent )
+ return;
+
+ m_xLastSection = _xReportComponent;
+ try
+ {
+ if ( m_pView )
+ {
+ EndListening( *(m_pView->GetModel()) );
+ m_pView = nullptr;
+ }
+
+ uno::Reference< uno::XInterface> xTemp(CreateComponentPair(_xReportComponent,_xReportComponent));
+ implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) );
+ }
+ catch ( Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update: Exception occurred!" );
+ }
+}
+
+IMPL_LINK_NOARG( PropBrw, OnAsyncGetFocus, void*, void )
+{
+ m_xContentArea->GrabFocus();
+}
+
+void PropBrw::LoseFocus()
+{
+ DockingWindow::LoseFocus();
+ if (m_pDesignView)
+ m_pDesignView->getController().InvalidateAll();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */