diff options
Diffstat (limited to 'sc/source/ui/miscdlgs/dataproviderdlg.cxx')
-rw-r--r-- | sc/source/ui/miscdlgs/dataproviderdlg.cxx | 1122 |
1 files changed, 1122 insertions, 0 deletions
diff --git a/sc/source/ui/miscdlgs/dataproviderdlg.cxx b/sc/source/ui/miscdlgs/dataproviderdlg.cxx new file mode 100644 index 0000000000..16a6c44664 --- /dev/null +++ b/sc/source/ui/miscdlgs/dataproviderdlg.cxx @@ -0,0 +1,1122 @@ +/* -*- 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/. + */ + +#include <dataproviderdlg.hxx> + +#include <document.hxx> +#include <dataprovider.hxx> +#include <datatransformation.hxx> +#include <datamapper.hxx> +#include <dbdata.hxx> + +#include <comphelper/string.hxx> +#include <sal/log.hxx> +#include <sfx2/filedlghelper.hxx> +#include <unotools/charclass.hxx> +#include <utility> +#include <vcl/svapp.hxx> + +class ScDataTransformationBaseControl +{ +protected: + std::unique_ptr<weld::Builder> mxBuilder; + std::unique_ptr<weld::Container> mxGrid; + weld::Container* mpContainer; + + sal_uInt32 mnIndex; + +public: + ScDataTransformationBaseControl(weld::Container* pParent, const OUString& rUIFile, sal_uInt32 nIndex); + virtual ~ScDataTransformationBaseControl(); + + void updateIndex(sal_uInt32 nIndex) { mnIndex = nIndex; } + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() = 0; + + static SCROW getLastRow(const ScDocument& rDoc); + static SCCOL getLastCol(const ScDocument& rDoc); +}; + +SCROW ScDataTransformationBaseControl::getLastRow(const ScDocument& rDoc) +{ + SCROW nEndRow = rDoc.MaxRow(); + return rDoc.GetLastDataRow(0, 0, 0, nEndRow); +} + +SCCOL ScDataTransformationBaseControl::getLastCol(const ScDocument& rDoc) +{ + for (SCCOL nCol = 1; nCol <= rDoc.MaxCol(); ++nCol) + { + if (rDoc.GetCellType(nCol, 0, 0) == CELLTYPE_NONE) + { + return static_cast<SCCOL>(nCol - 1 ); + } + } + return rDoc.MaxCol(); +} + +ScDataTransformationBaseControl::ScDataTransformationBaseControl(weld::Container* pParent, const OUString& rUIFile, sal_uInt32 nIndex) + : mxBuilder(Application::CreateBuilder(pParent, rUIFile)) + , mxGrid(mxBuilder->weld_container("grid")) + , mpContainer(pParent) + , mnIndex(nIndex) +{ +} + +ScDataTransformationBaseControl::~ScDataTransformationBaseControl() +{ + mpContainer->move(mxGrid.get(), nullptr); +} + +namespace { + +struct MenuData +{ + const char* aTransformationName; + std::function<void(ScDataProviderDlg*)> maCallback; +}; + +MenuData aTransformationData[] = { + { "Delete Column", &ScDataProviderDlg::deleteColumn }, + { "Delete Row", &ScDataProviderDlg::deleteRowTransformation}, + { "Swap Rows", &ScDataProviderDlg::swapRowsTransformation}, + { "Split Column", &ScDataProviderDlg::splitColumn }, + { "Merge Columns", &ScDataProviderDlg::mergeColumns }, + { "Text Transformation", &ScDataProviderDlg::textTransformation }, + { "Sort Columns", &ScDataProviderDlg::sortTransformation }, + { "Aggregate Functions", &ScDataProviderDlg::aggregateFunction}, + { "Number Transformations", &ScDataProviderDlg::numberTransformation }, + { "Replace Null Transformations", &ScDataProviderDlg::replaceNullTransformation }, + { "Date & Time Transformations", &ScDataProviderDlg::dateTimeTransformation }, + { "Find Replace Transformation", &ScDataProviderDlg::findReplaceTransformation} +}; + +class ScDeleteColumnTransformationControl : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxColumnNums; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScDeleteColumnTransformationControl(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 aIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScDeleteColumnTransformationControl::ScDeleteColumnTransformationControl( + const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/deletecolumnentry.ui", nIndex) + , mxColumnNums(mxBuilder->weld_entry("ed_columns")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this,ScDeleteColumnTransformationControl, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScDeleteColumnTransformationControl::getTransformation() +{ + OUString aColumnString = mxColumnNums->get_text(); + std::vector<OUString> aSplitColumns = comphelper::string::split(aColumnString, ';'); + std::set<SCCOL> ColNums; + for (const auto& rColStr : aSplitColumns) + { + sal_Int32 nCol = rColStr.toInt32(); + if (nCol <= 0) + continue; + + if (nCol > mpDoc->MaxCol()) + continue; + + // translate from 1-based column notations to internal Calc one + ColNums.insert(nCol - 1); + } + + return std::make_shared<sc::ColumnRemoveTransformation>(std::move(ColNums)); +} + +class ScSplitColumnTransformationControl : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxSeparator; + std::unique_ptr<weld::Entry> mxNumColumns; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScSplitColumnTransformationControl(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScSplitColumnTransformationControl::ScSplitColumnTransformationControl( + const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, + std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/splitcolumnentry.ui", nIndex) + , mxSeparator(mxBuilder->weld_entry("ed_separator")) + , mxNumColumns(mxBuilder->weld_entry("num_cols")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this,ScSplitColumnTransformationControl, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScSplitColumnTransformationControl::getTransformation() +{ + OUString aSeparator = mxSeparator->get_text(); + sal_Unicode cSeparator = aSeparator.isEmpty() ? ',' : aSeparator[0]; + OUString aColStr = mxNumColumns->get_text(); + SCCOL mnCol = -1; + sal_Int32 nCol = aColStr.toInt32(); + if (nCol > 0 && nCol <= mpDoc->MaxCol()) + mnCol = nCol - 1; + return std::make_shared<sc::SplitColumnTransformation>(mnCol, cSeparator); +} + +class ScMergeColumnTransformationControl : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxSeparator; + std::unique_ptr<weld::Entry> mxEdColumns; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScMergeColumnTransformationControl(const ScDocument *pDoc, weld::Container* pParent, SCCOL nStartCol, SCCOL nEndCol, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScMergeColumnTransformationControl::ScMergeColumnTransformationControl( + const ScDocument* pDoc, weld::Container* pParent, SCCOL nStartCol, SCCOL nEndCol, sal_uInt32 nIndex, + std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/mergecolumnentry.ui", nIndex) + , mxSeparator(mxBuilder->weld_entry("ed_separator")) + , mxEdColumns(mxBuilder->weld_entry("ed_columns")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this,ScMergeColumnTransformationControl, DeleteHdl)); + + OUStringBuffer aBuffer; + + // map from zero based to one based column numbers + aBuffer.append(static_cast<sal_Int32>(nStartCol + 1)); + for ( SCCOL nCol = nStartCol + 1; nCol <= nEndCol; ++nCol) + { + aBuffer.append(";" + OUString::number(nCol + 1)); + } + + mxEdColumns->set_text(aBuffer.makeStringAndClear()); +} + +std::shared_ptr<sc::DataTransformation> ScMergeColumnTransformationControl::getTransformation() +{ + OUString aColumnString = mxEdColumns->get_text(); + std::vector<OUString> aSplitColumns = comphelper::string::split(aColumnString, ';'); + std::set<SCCOL> aMergedColumns; + for (const auto& rColStr : aSplitColumns) + { + sal_Int32 nCol = rColStr.toInt32(); + if (nCol <= 0) + continue; + + if (nCol > mpDoc->MaxCol()) + continue; + + // translate from 1-based column notations to internal Calc one + aMergedColumns.insert(nCol - 1); + } + return std::make_shared<sc::MergeColumnTransformation>(std::move(aMergedColumns), mxSeparator->get_text()); +} + +class ScSortTransformationControl : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::ComboBox> mxType; + std::unique_ptr<weld::Entry> mxEdColumns; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScSortTransformationControl(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScSortTransformationControl::ScSortTransformationControl( + const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/sorttransformationentry.ui", nIndex) + , mxType(mxBuilder->weld_combo_box("ed_ascending")) + , mxEdColumns(mxBuilder->weld_entry("ed_columns")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this,ScSortTransformationControl, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScSortTransformationControl::getTransformation() +{ + OUString aColStr = mxEdColumns->get_text(); + bool aIsAscending = mxType->get_active(); + SCCOL aColumn = 0; + sal_Int32 nCol = aColStr.toInt32(); + if (nCol > 0 && nCol <= mpDoc->MaxCol()) + aColumn = nCol - 1; // translate from 1-based column notations to internal Calc one + + ScSortParam aSortParam; + aSortParam.nRow1=0; + aSortParam.nRow2=getLastRow(*mpDoc); + aSortParam.nCol1=0; + aSortParam.nCol2=getLastCol(*mpDoc); + aSortParam.maKeyState[0].bDoSort = true; + aSortParam.maKeyState[0].nField = aColumn; + aSortParam.maKeyState[0].bAscending = aIsAscending; + return std::make_shared<sc::SortTransformation>(aSortParam); +} + +class ScColumnTextTransformation : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxColumnNums; + std::unique_ptr<weld::ComboBox> mxType; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScColumnTextTransformation(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScColumnTextTransformation::ScColumnTextTransformation( + const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/texttransformationentry.ui", nIndex) + , mxColumnNums(mxBuilder->weld_entry("ed_columns")) + , mxType(mxBuilder->weld_combo_box("ed_lst")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this,ScColumnTextTransformation, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScColumnTextTransformation::getTransformation() +{ + OUString aColumnString = mxColumnNums->get_text(); + std::vector<OUString> aSplitColumns = comphelper::string::split(aColumnString, ';'); + std::set<SCCOL> aColumns; + for (const auto& rColStr : aSplitColumns) + { + sal_Int32 nCol = rColStr.toInt32(); + if (nCol <= 0) + continue; + + if (nCol > mpDoc->MaxCol()) + continue; + + // translate from 1-based column notations to internal Calc one + aColumns.insert(nCol - 1); + } + + sal_Int32 nPos = mxType->get_active(); + switch (nPos) + { + case 0: + return std::make_shared<sc::TextTransformation>(std::move(aColumns),sc::TEXT_TRANSFORM_TYPE::TO_LOWER); + case 1: + return std::make_shared<sc::TextTransformation>(std::move(aColumns),sc::TEXT_TRANSFORM_TYPE::TO_UPPER); + case 2: + return std::make_shared<sc::TextTransformation>(std::move(aColumns),sc::TEXT_TRANSFORM_TYPE::CAPITALIZE); + case 3: + return std::make_shared<sc::TextTransformation>(std::move(aColumns),sc::TEXT_TRANSFORM_TYPE::TRIM); + default: + assert(false); + } + + return nullptr; +} + +class ScAggregateFunction : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxColumnNums; + std::unique_ptr<weld::ComboBox> mxType; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScAggregateFunction(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScAggregateFunction::ScAggregateFunction(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, + std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/aggregatefunctionentry.ui", nIndex) + , mxColumnNums(mxBuilder->weld_entry("ed_columns")) + , mxType(mxBuilder->weld_combo_box("ed_lst")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this,ScAggregateFunction, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScAggregateFunction::getTransformation() +{ + OUString aColumnString = mxColumnNums->get_text(); + sal_Int32 nPos = mxType->get_active(); + std::vector<OUString> aSplitColumns = comphelper::string::split(aColumnString, ';'); + std::set<SCCOL> aColumns; + for (const auto& rColStr : aSplitColumns) + { + sal_Int32 nCol = rColStr.toInt32(); + if (nCol <= 0) + continue; + + if (nCol > mpDoc->MaxCol()) + continue; + + // translate from 1-based column notations to internal Calc one + aColumns.insert(nCol - 1); + } + switch (nPos) + { + case 0: + return std::make_shared<sc::AggregateFunction>(std::move(aColumns),sc::AGGREGATE_FUNCTION::SUM); + case 1: + return std::make_shared<sc::AggregateFunction>(std::move(aColumns),sc::AGGREGATE_FUNCTION::AVERAGE); + case 2: + return std::make_shared<sc::AggregateFunction>(std::move(aColumns),sc::AGGREGATE_FUNCTION::MIN); + case 3: + return std::make_shared<sc::AggregateFunction>(std::move(aColumns),sc::AGGREGATE_FUNCTION::MAX); + default: + assert(false); + } + + return nullptr; +} + +class ScNumberTransformation : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxColumnNums; + std::unique_ptr<weld::ComboBox> mxType; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScNumberTransformation(const ScDocument *pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScNumberTransformation::ScNumberTransformation( + const ScDocument *pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/numbertransformationentry.ui", nIndex) + , mxColumnNums(mxBuilder->weld_entry("ed_columns")) + , mxType(mxBuilder->weld_combo_box("ed_lst")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this,ScNumberTransformation, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScNumberTransformation::getTransformation() +{ + OUString aColumnString = mxColumnNums->get_text(); + sal_Int32 nPos = mxType->get_active(); + std::vector<OUString> aSplitColumns = comphelper::string::split(aColumnString, ';'); + std::set<SCCOL> aColumns; + for (const auto& rColStr : aSplitColumns) + { + sal_Int32 nCol = rColStr.toInt32(); + if (nCol <= 0) + continue; + + if (nCol > mpDoc->MaxCol()) + continue; + + // translate from 1-based column notations to internal Calc one + aColumns.insert(nCol - 1); + } + switch (nPos) + { + case 0: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::SIGN); + case 1: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::ROUND); + case 2: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::ROUND_UP); + case 3: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::ROUND_DOWN); + case 4: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::ABSOLUTE); + case 5: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::LOG_E); + case 6: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::LOG_10); + case 7: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::CUBE); + case 8: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::SQUARE); + case 9: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::SQUARE_ROOT); + case 10: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::EXPONENT); + case 11: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::IS_EVEN); + case 12: + return std::make_shared<sc::NumberTransformation>(std::move(aColumns),sc::NUMBER_TRANSFORM_TYPE::IS_ODD); + default: + assert(false); + } + + return nullptr; +} + +class ScReplaceNullTransformation : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxColumnNums; + std::unique_ptr<weld::Entry> mxReplaceString; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument *mpDoc; + +public: + + ScReplaceNullTransformation(const ScDocument *pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScReplaceNullTransformation::ScReplaceNullTransformation(const ScDocument *pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent,"modules/scalc/ui/replacenulltransformationentry.ui", nIndex) + , mxColumnNums(mxBuilder->weld_entry("ed_columns")) + , mxReplaceString(mxBuilder->weld_entry("ed_str")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this,ScReplaceNullTransformation, DeleteHdl)); +} + + +std::shared_ptr<sc::DataTransformation> ScReplaceNullTransformation::getTransformation() +{ + OUString aColumnString = mxColumnNums->get_text(); + OUString aReplaceWithString = mxReplaceString->get_text(); + std::vector<OUString> aSplitColumns = comphelper::string::split(aColumnString, ';'); + std::set<SCCOL> aColumns; + for (const auto& rColStr : aSplitColumns) + { + sal_Int32 nCol = rColStr.toInt32(); + if (nCol <= 0) + continue; + + if (nCol > mpDoc->MaxCol()) + continue; + + // translate from 1-based column notations to internal Calc one + aColumns.insert(nCol - 1); + } + + return std::make_shared<sc::ReplaceNullTransformation>(std::move(aColumns),aReplaceWithString); +} + +class ScDateTimeTransformation : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxColumnNums; + std::unique_ptr<weld::ComboBox> mxType; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + + ScDateTimeTransformation(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScDateTimeTransformation::ScDateTimeTransformation(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent,"modules/scalc/ui/datetimetransformationentry.ui", nIndex) + , mxColumnNums(mxBuilder->weld_entry("ed_columns")) + , mxType(mxBuilder->weld_combo_box("ed_lst")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this,ScDateTimeTransformation, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScDateTimeTransformation::getTransformation() +{ + OUString aColumnString = mxColumnNums->get_text(); + sal_Int32 nPos = mxType->get_active(); + std::vector<OUString> aSplitColumns = comphelper::string::split(aColumnString, ';'); + std::set<SCCOL> aColumns; + for (const auto& rColStr : aSplitColumns) + { + sal_Int32 nCol = rColStr.toInt32(); + if (nCol <= 0) + continue; + + if (nCol > mpDoc->MaxCol()) + continue; + + // translate from 1-based column notations to internal Calc one + aColumns.insert(nCol - 1); + } + switch (nPos) + { + case 0: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::DATE_STRING); + case 1: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::YEAR); + case 2: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::START_OF_YEAR); + case 3: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::END_OF_YEAR); + case 4: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::MONTH); + case 5: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::MONTH_NAME); + case 6: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::START_OF_MONTH); + case 7: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::END_OF_MONTH); + case 8: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::DAY); + case 9: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_WEEK); + case 10: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_YEAR); + case 11: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::QUARTER); + case 12: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::START_OF_QUARTER); + case 13: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::END_OF_QUARTER); + case 14: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::HOUR); + case 15: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::MINUTE); + case 16: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::SECOND); + case 17: + return std::make_shared<sc::DateTimeTransformation>(std::move(aColumns),sc::DATETIME_TRANSFORMATION_TYPE::TIME); + default: + assert(false); + } + + return nullptr; +} + +class ScFindReplaceTransformation : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxFindString; + std::unique_ptr<weld::Entry> mxReplaceString; + std::unique_ptr<weld::Entry> mxEdColumns; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScFindReplaceTransformation(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScFindReplaceTransformation::ScFindReplaceTransformation( + const ScDocument *pDoc, weld::Container* pParent, sal_uInt32 nIndex, + std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/findreplaceentry.ui", nIndex) + , mxFindString(mxBuilder->weld_entry("ed_find")) + , mxReplaceString(mxBuilder->weld_entry("ed_replace")) + , mxEdColumns(mxBuilder->weld_entry("ed_columns")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this, ScFindReplaceTransformation, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScFindReplaceTransformation::getTransformation() +{ + OUString aColStr = mxEdColumns->get_text(); + SCCOL aColumn = -1; + sal_Int32 nCol = aColStr.toInt32(); + if (nCol > 0 && nCol <= mpDoc->MaxCol()) + aColumn = nCol - 1; + return std::make_shared<sc::FindReplaceTransformation>(aColumn, mxFindString->get_text(), mxReplaceString->get_text()); +} + +class ScDeleteRowTransformation : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxFindString; + std::unique_ptr<weld::Entry> mxEdColumns; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScDeleteRowTransformation(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScDeleteRowTransformation::ScDeleteRowTransformation( + const ScDocument *pDoc, weld::Container* pParent, sal_uInt32 nIndex, + std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/deleterowentry.ui", nIndex) + , mxFindString(mxBuilder->weld_entry("ed_find")) + , mxEdColumns(mxBuilder->weld_entry("ed_columns")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this, ScDeleteRowTransformation, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScDeleteRowTransformation::getTransformation() +{ + OUString aColStr = mxEdColumns->get_text(); + SCCOL aColumn = -1; + sal_Int32 nCol = aColStr.toInt32(); + if (nCol > 0 && nCol <= mpDoc->MaxCol()) + aColumn = nCol - 1; + return std::make_shared<sc::DeleteRowTransformation>(aColumn, mxFindString->get_text()); +} + +class ScSwapRowsTransformation : public ScDataTransformationBaseControl +{ +private: + std::unique_ptr<weld::Entry> mxRow; + std::unique_ptr<weld::Entry> nxRow; + std::unique_ptr<weld::Button> mxDelete; + std::function<void(sal_uInt32&)> maDeleteTransformation; + const ScDocument* mpDoc; + +public: + ScSwapRowsTransformation(const ScDocument* pDoc, weld::Container* pParent, sal_uInt32 nIndex, std::function<void(sal_uInt32&)> aDeleteTransformation); + + virtual std::shared_ptr<sc::DataTransformation> getTransformation() override; + DECL_LINK(DeleteHdl, weld::Button&, void); +}; + +ScSwapRowsTransformation::ScSwapRowsTransformation( + const ScDocument *pDoc, weld::Container* pParent, sal_uInt32 nIndex, + std::function<void(sal_uInt32&)> aDeleteTransformation) + : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/swaprowsentry.ui", nIndex) + , mxRow(mxBuilder->weld_entry("ed_row1")) + , nxRow(mxBuilder->weld_entry("ed_row2")) + , mxDelete(mxBuilder->weld_button("ed_delete")) + , maDeleteTransformation(std::move(aDeleteTransformation)) + , mpDoc(pDoc) +{ + mxDelete->connect_clicked(LINK(this, ScSwapRowsTransformation, DeleteHdl)); +} + +std::shared_ptr<sc::DataTransformation> ScSwapRowsTransformation::getTransformation() +{ + OUString aRowStr = mxRow->get_text(); + OUString bRowStr = nxRow->get_text(); + SCROW aRow = -1; + SCROW bRow = -1; + sal_Int32 mRow = aRowStr.toInt32(); + sal_Int32 nRow = bRowStr.toInt32(); + if (mRow > 0 && mRow <= mpDoc->MaxRow()) + aRow = mRow - 1; + if (nRow > 0 && nRow <= mpDoc->MaxRow()) + bRow = nRow - 1; + return std::make_shared<sc::SwapRowsTransformation>(aRow, bRow); +} + +} + +ScDataProviderDlg::ScDataProviderDlg(weld::Window* pParent, std::shared_ptr<ScDocument> pDoc, + const ScDocument* pDocument) + : GenericDialogController(pParent, "modules/scalc/ui/dataproviderdlg.ui", "dataproviderdlg") + , mxDoc(std::move(pDoc)) + , mxBox(m_xBuilder->weld_container("data_table")) + , m_xTableParent(mxBox->CreateChildFrame()) + , mxTable(VclPtr<ScDataTableView>::Create(m_xTableParent, mxDoc)) + , mxDBRanges(m_xBuilder->weld_combo_box("select_db_range")) + , mxOKBtn(m_xBuilder->weld_button("okay")) + , mxCancelBtn(m_xBuilder->weld_button("cancel")) + , mxAddTransformationBtn(m_xBuilder->weld_button("add_transformation")) + , mxScroll(m_xBuilder->weld_scrolled_window("scroll")) + , mxTransformationList(m_xBuilder->weld_container("transformation_ctrl")) + , mxTransformationBox(m_xBuilder->weld_combo_box("transformation_box")) + , mxProviderList(m_xBuilder->weld_combo_box("provider_lst")) + , mxEditURL(m_xBuilder->weld_entry("ed_url")) + , mxEditID(m_xBuilder->weld_entry("ed_id")) + , mxApplyBtn(m_xBuilder->weld_button("apply")) + , mxBrowseBtn(m_xBuilder->weld_button("browse")) + , maIdle("ScDataProviderDlg maIdle") + , mnIndex(0) +{ + Size aPrefSize = mxTable->GetOptimalSize(); + mxBox->set_size_request(aPrefSize.Width(), aPrefSize.Height()); + mxTable->Show(); + + ScDBCollection* pDBCollection = pDocument->GetDBCollection(); + auto& rNamedDBs = pDBCollection->getNamedDBs(); + for (auto& rNamedDB : rNamedDBs) + { + mxDBRanges->append_text(rNamedDB->GetName()); + } + + for (const auto& i : aTransformationData) + { + mxTransformationBox->append_text(OUString::createFromAscii(i.aTransformationName)); + } + + pDBData = new ScDBData("data", 0, 0, 0, mxDoc->MaxCol(), mxDoc->MaxRow()); + bool bSuccess = mxDoc->GetDBCollection()->getNamedDBs().insert(std::unique_ptr<ScDBData>(pDBData)); + SAL_WARN_IF(!bSuccess, "sc", "temporary warning"); + + auto aDataProvider = sc::DataProviderFactory::getDataProviders(); + for (const auto& rDataProvider : aDataProvider) + { + mxProviderList->append_text(rDataProvider); + } + + mxOKBtn->connect_clicked(LINK(this, ScDataProviderDlg, ApplyQuitHdl)); + mxCancelBtn->connect_clicked(LINK(this, ScDataProviderDlg, CancelQuitHdl)); + mxAddTransformationBtn->connect_clicked(LINK(this, ScDataProviderDlg, TransformationListHdl)); + mxApplyBtn->connect_clicked(LINK(this, ScDataProviderDlg, ApplyBtnHdl)); + mxBrowseBtn->connect_clicked(LINK(this, ScDataProviderDlg, BrowseBtnHdl)); + mxTransformationBox->connect_changed(LINK(this, ScDataProviderDlg, TransformationSelectHdl)); + mxProviderList->connect_changed(LINK(this, ScDataProviderDlg, ProviderSelectHdl)); + mxEditID->connect_changed(LINK(this, ScDataProviderDlg, IDEditHdl)); + mxEditURL->connect_changed(LINK(this, ScDataProviderDlg, URLEditHdl)); + + msApplyTooltip = mxApplyBtn->get_tooltip_text(); + msAddTransformationToolTip = mxAddTransformationBtn->get_tooltip_text(); + mxAddTransformationBtn->set_sensitive(false); + mxAddTransformationBtn->set_tooltip_text(OUString()); + isValid(); + + maIdle.SetPriority( TaskPriority::LOWEST ); + maIdle.SetInvokeHandler( LINK( this, ScDataProviderDlg, ScrollToEnd) ); +} + +ScDataProviderDlg::~ScDataProviderDlg() +{ + mxTable.disposeAndClear(); + m_xTableParent->dispose(); + m_xTableParent.clear(); +} + +IMPL_LINK_NOARG(ScDataProviderDlg, ScrollToEnd, Timer*, void) +{ + mxScroll->vadjustment_set_value(mxScroll->vadjustment_get_upper()); +} + +IMPL_LINK_NOARG(ScDataProviderDlg, ApplyQuitHdl, weld::Button&, void) +{ + m_xDialog->response(RET_OK); +} + +IMPL_LINK_NOARG(ScDataProviderDlg, CancelQuitHdl, weld::Button&, void) +{ + m_xDialog->response(RET_CANCEL); +} + +IMPL_LINK_NOARG(ScDataProviderDlg, TransformationListHdl, weld::Button&, void) +{ + OUString transformation_string = mxTransformationBox->get_active_text(); + for (auto& i: aTransformationData) + { + if (transformation_string == OUString::createFromAscii(i.aTransformationName)) + { + i.maCallback(this); + maIdle.Start(); + return; + } + } +} + +IMPL_LINK_NOARG(ScDataProviderDlg, ProviderSelectHdl, weld::ComboBox&, void) +{ + isValid(); +} + +IMPL_LINK_NOARG(ScDataProviderDlg, IDEditHdl, weld::Entry&, void) +{ + isValid(); +} + +IMPL_LINK_NOARG(ScDataProviderDlg, URLEditHdl, weld::Entry&, void) +{ + isValid(); +} + +IMPL_LINK_NOARG(ScDataProviderDlg, ApplyBtnHdl, weld::Button&, void) +{ + updateApplyBtn(true); + import(*mxDoc, true); +} + +IMPL_LINK_NOARG(ScDataProviderDlg, BrowseBtnHdl, weld::Button&, void) +{ + sfx2::FileDialogHelper aFileDialog(0, FileDialogFlags::NONE, m_xDialog.get()); + aFileDialog.SetContext(sfx2::FileDialogHelper::CalcDataProvider); + if (aFileDialog.Execute() != ERRCODE_NONE) + return; + + mxEditURL->set_text(aFileDialog.GetPath()); + isValid(); +} + +IMPL_LINK_NOARG(ScDataProviderDlg, TransformationSelectHdl, weld::ComboBox&, void) +{ + mxAddTransformationBtn->set_sensitive(true); + mxAddTransformationBtn->set_tooltip_text(msAddTransformationToolTip); +} + +sc::ExternalDataSource ScDataProviderDlg::getDataSource(ScDocument* pDoc) +{ + sc::ExternalDataSource aSource(mxEditURL->get_text(), mxProviderList->get_active_text(), pDoc); + + OUString aID = mxEditID->get_text(); + aSource.setID(aID); + return aSource; +} + +void ScDataProviderDlg::isValid() +{ + bool bValid = !mxProviderList->get_active_text().isEmpty(); + bValid &= !mxEditURL->get_text().isEmpty(); + updateApplyBtn(bValid); +} + +void ScDataProviderDlg::updateApplyBtn(bool bValidConfig) +{ + if (!bValidConfig) + { + mxApplyBtn->set_sensitive(false); + mxApplyBtn->set_tooltip_text(OUString()); + return; + } + + mxApplyBtn->set_sensitive(true); + mxApplyBtn->set_tooltip_text(msApplyTooltip); +} + +void ScDataProviderDlg::deleteColumn() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScDeleteColumnTransformationControl>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::splitColumn() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScSplitColumnTransformationControl>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::mergeColumns() +{ + SCCOL nStartCol = -1; + SCCOL nEndCol = -1; + mxTable->getColRange(nStartCol, nEndCol); + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScMergeColumnTransformationControl>(mxDoc.get(), mxTransformationList.get(), nStartCol, nEndCol, mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::textTransformation() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScColumnTextTransformation>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::sortTransformation() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScSortTransformationControl>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::aggregateFunction() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScAggregateFunction>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::numberTransformation() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScNumberTransformation>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::replaceNullTransformation() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScReplaceNullTransformation>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::dateTimeTransformation() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScDateTimeTransformation>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::findReplaceTransformation() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList, this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScFindReplaceTransformation>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::deleteRowTransformation() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList, this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScDeleteRowTransformation>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +void ScDataProviderDlg::swapRowsTransformation() +{ + std::function<void(sal_uInt32&)> adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList, this, std::placeholders::_1); + maControls.emplace_back(std::make_unique<ScSwapRowsTransformation>(mxDoc.get(), mxTransformationList.get(), mnIndex++, adeleteTransformation)); +} + +namespace { + +bool hasDBName(const OUString& rName, ScDBCollection* pDBCollection) +{ + if (pDBCollection->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(rName))) + return true; + + return false; +} + +} + +void ScDataProviderDlg::import(ScDocument& rDoc, bool bInternal) +{ + sc::ExternalDataSource aSource = getDataSource(&rDoc); + + for (size_t i = 0; i < maControls.size(); ++i) + { + ScDataTransformationBaseControl* pTransformationCtrl = maControls[i].get(); + aSource.AddDataTransformation(pTransformationCtrl->getTransformation()); + } + if (bInternal) + aSource.setDBData(pDBData->GetName()); + else + { + aSource.setDBData(mxDBRanges->get_active_text()); + if (!hasDBName(aSource.getDBName(), rDoc.GetDBCollection())) + return; + rDoc.GetExternalDataMapper().insertDataSource(aSource); + } + aSource.refresh(&rDoc, true); + mxTable->Invalidate(); +} + +void ScDataProviderDlg::deletefromList(sal_uInt32 nIndex) +{ + auto itr = maControls.erase(maControls.begin() + nIndex); + while (itr != maControls.end()) + { + (*itr)->updateIndex(nIndex++); + ++itr; + } + --mnIndex; +} + +IMPL_LINK_NOARG(ScDeleteColumnTransformationControl, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScSplitColumnTransformationControl, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScMergeColumnTransformationControl, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScNumberTransformation, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScAggregateFunction, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScSortTransformationControl, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScColumnTextTransformation, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScReplaceNullTransformation, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScDateTimeTransformation, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScFindReplaceTransformation, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScDeleteRowTransformation, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} + +IMPL_LINK_NOARG(ScSwapRowsTransformation, DeleteHdl, weld::Button&, void) +{ + maDeleteTransformation(mnIndex); +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |