/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include constexpr int MENU_START = 0; constexpr int MENU_COLUMN = 1; class ScDataProviderBaseControl : public VclContainer, public VclBuilderContainer { VclPtr maGrid; VclPtr maProviderList; VclPtr maEditURL; VclPtr maEditID; VclPtr mpApplyBtn; Link const maImportCallback; DECL_LINK(ProviderSelectHdl, ListBox&, void); DECL_LINK(IDEditHdl, Edit&, void); DECL_LINK(URLEditHdl, Edit&, void); DECL_LINK(ApplyBtnHdl, Button*, void); void updateApplyBtn(bool bValidConfig); public: ScDataProviderBaseControl(vcl::Window* pParent, const Link& rImportCallback); ~ScDataProviderBaseControl() override; virtual void dispose() override; virtual void setAllocation(const Size &rAllocation) override; virtual Size calculateRequisition() const override; void isValid(); sc::ExternalDataSource getDataSource(ScDocument* pDoc); }; ScDataProviderBaseControl::ScDataProviderBaseControl(vcl::Window* pParent, const Link& rImportCallback): VclContainer(pParent, WB_CLIPCHILDREN | WB_BORDER), maImportCallback(rImportCallback) { m_pUIBuilder.reset(new VclBuilder(this, getUIRootDir(), "modules/scalc/ui/dataproviderentry.ui")); get(maGrid, "grid"); get(maProviderList, "provider_lst"); get(maEditURL, "ed_url"); get(maEditID, "ed_id"); auto aDataProvider = sc::DataProviderFactory::getDataProviders(); for (auto& rDataProvider : aDataProvider) { maProviderList->InsertEntry(rDataProvider); } maProviderList->SetSelectHdl(LINK(this, ScDataProviderBaseControl, ProviderSelectHdl)); maEditID->SetModifyHdl(LINK(this, ScDataProviderBaseControl, IDEditHdl)); maEditURL->SetModifyHdl(LINK(this, ScDataProviderBaseControl, URLEditHdl)); mpApplyBtn = VclPtr::Create(maGrid, WB_FLATBUTTON); mpApplyBtn->set_grid_top_attach(1); mpApplyBtn->set_grid_left_attach(5); mpApplyBtn->SetQuickHelpText("Apply Changes"); mpApplyBtn->SetControlForeground(COL_GREEN); mpApplyBtn->SetControlBackground(COL_GREEN); mpApplyBtn->SetBackground(Wallpaper(COL_LIGHTGREEN)); mpApplyBtn->SetModeImage(Image(StockImage::Yes, "sc/res/xml_element.png")); mpApplyBtn->Show(); mpApplyBtn->SetClickHdl(LINK(this, ScDataProviderBaseControl, ApplyBtnHdl)); SetSizePixel(GetOptimalSize()); isValid(); } ScDataProviderBaseControl::~ScDataProviderBaseControl() { disposeOnce(); } void ScDataProviderBaseControl::dispose() { maEditID.clear(); maEditURL.clear(); maProviderList.clear(); mpApplyBtn.disposeAndClear(); maGrid.clear(); disposeBuilder(); VclContainer::dispose(); } Size ScDataProviderBaseControl::calculateRequisition() const { return getLayoutRequisition(*maGrid); } void ScDataProviderBaseControl::setAllocation(const Size &rAllocation) { setLayoutPosSize(*maGrid, Point(0, 0), rAllocation); } void ScDataProviderBaseControl::isValid() { bool bValid = !maProviderList->GetSelectedEntry().isEmpty(); bValid &= !maEditURL->GetText().isEmpty(); Invalidate(); updateApplyBtn(bValid); } sc::ExternalDataSource ScDataProviderBaseControl::getDataSource(ScDocument* pDoc) { OUString aURL = maEditURL->GetText(); OUString aProvider = maProviderList->GetSelectedEntry(); sc::ExternalDataSource aSource(aURL, aProvider, pDoc); OUString aID = maEditID->GetText(); aSource.setID(aID); return aSource; } void ScDataProviderBaseControl::updateApplyBtn(bool bValidConfig) { if (!bValidConfig) { mpApplyBtn->Disable(); mpApplyBtn->SetQuickHelpText(""); return; } else { mpApplyBtn->Enable(); mpApplyBtn->SetBackground(Wallpaper(COL_YELLOW)); mpApplyBtn->SetQuickHelpText("Apply Changes"); } } IMPL_LINK_NOARG(ScDataProviderBaseControl, ProviderSelectHdl, ListBox&, void) { isValid(); } IMPL_LINK_NOARG(ScDataProviderBaseControl, IDEditHdl, Edit&, void) { isValid(); } IMPL_LINK_NOARG(ScDataProviderBaseControl, URLEditHdl, Edit&, void) { isValid(); } IMPL_LINK_NOARG(ScDataProviderBaseControl, ApplyBtnHdl, Button*, void) { updateApplyBtn(true); maImportCallback.Call(this); } namespace { struct MenuData { int const nMenuID; const char* aMenuName; std::function const maCallback; }; MenuData aStartData[] = { { 0, "Apply & Quit", &ScDataProviderDlg::applyAndQuit }, { 1, "Cancel & Quit", &ScDataProviderDlg::cancelAndQuit } }; MenuData aColumnData[] = { { 0, "Delete Column", &ScDataProviderDlg::deleteColumn }, { 1, "Split Column", &ScDataProviderDlg::splitColumn }, { 2, "Merge Columns", &ScDataProviderDlg::mergeColumns }, { 3, "Text Transformation", &ScDataProviderDlg::textTransformation }, { 4, "Sort Columns", &ScDataProviderDlg::sortTransformation }, { 5, "Aggregate Functions", &ScDataProviderDlg::aggregateFunction}, { 6, "Number Transformations", &ScDataProviderDlg::numberTransformation }, { 7, "Replace Null Transformations", &ScDataProviderDlg::replaceNullTransformation }, { 8, "Date & Time Transformations", &ScDataProviderDlg::dateTimeTransformation } }; class ScDataTransformationBaseControl : public VclContainer, public VclBuilderContainer { VclPtr maGrid; public: ScDataTransformationBaseControl(vcl::Window* pParent, const OUString& rUIFile); ~ScDataTransformationBaseControl() override; virtual void dispose() override; virtual void setAllocation(const Size &rAllocation) override; virtual Size calculateRequisition() const override; virtual std::shared_ptr getTransformation() = 0; }; ScDataTransformationBaseControl::ScDataTransformationBaseControl(vcl::Window* pParent, const OUString& rUIFile): VclContainer(pParent, WB_BORDER | WB_CLIPCHILDREN) { m_pUIBuilder.reset(new VclBuilder(this, getUIRootDir(), rUIFile)); get(maGrid, "grid"); SetSizePixel(GetOptimalSize()); } ScDataTransformationBaseControl::~ScDataTransformationBaseControl() { disposeOnce(); } void ScDataTransformationBaseControl::dispose() { maGrid.clear(); VclContainer::dispose(); } Size ScDataTransformationBaseControl::calculateRequisition() const { return getLayoutRequisition(*maGrid); } void ScDataTransformationBaseControl::setAllocation(const Size &rAllocation) { setLayoutPosSize(*maGrid, Point(0, 0), rAllocation); } class ScDeleteColumnTransformationControl : public ScDataTransformationBaseControl { private: VclPtr maColumnNums; VclPtr maDelete; sal_uInt32 maIndex; std::function maDeleteTransformation; public: ScDeleteColumnTransformationControl(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation); ~ScDeleteColumnTransformationControl() override; virtual void dispose() override; virtual std::shared_ptr getTransformation() override; DECL_LINK(DeleteHdl, Button*, void); }; ScDeleteColumnTransformationControl::ScDeleteColumnTransformationControl( vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation) : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/deletecolumnentry.ui") , maIndex(aIndex) , maDeleteTransformation(std::move(aDeleteTransformation)) { get(maColumnNums, "ed_columns"); get(maDelete, "ed_delete"); maDelete->SetClickHdl(LINK(this,ScDeleteColumnTransformationControl, DeleteHdl)); } ScDeleteColumnTransformationControl::~ScDeleteColumnTransformationControl() { disposeOnce(); } void ScDeleteColumnTransformationControl::dispose() { maColumnNums.clear(); maDelete.clear(); ScDataTransformationBaseControl::dispose(); } std::shared_ptr ScDeleteColumnTransformationControl::getTransformation() { OUString aColumnString = maColumnNums->GetText(); std::vector aSplitColumns = comphelper::string::split(aColumnString, ';'); std::set ColNums; for (auto& rColStr : aSplitColumns) { sal_Int32 nCol = rColStr.toInt32(); if (nCol <= 0) continue; if (nCol > MAXCOL) continue; // translate from 1-based column notations to internal Calc one ColNums.insert(nCol - 1); } return std::make_shared(ColNums); } class ScSplitColumnTransformationControl : public ScDataTransformationBaseControl { private: VclPtr maSeparator; VclPtr maNumColumns; SCCOL mnCol; VclPtr maDelete; sal_uInt32 maIndex; std::function maDeleteTransformation; public: ScSplitColumnTransformationControl(vcl::Window* pParent, SCCOL nCol, sal_uInt32 aIndex, std::function aDeleteTransformation); ~ScSplitColumnTransformationControl() override; virtual void dispose() override; virtual std::shared_ptr getTransformation() override; DECL_LINK(DeleteHdl, Button*, void); }; ScSplitColumnTransformationControl::ScSplitColumnTransformationControl( vcl::Window* pParent, SCCOL nCol, sal_uInt32 aIndex, std::function aDeleteTransformation) : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/splitcolumnentry.ui") , mnCol(nCol) , maIndex(aIndex) , maDeleteTransformation(std::move(aDeleteTransformation)) { get(maSeparator, "ed_separator"); get(maNumColumns, "num_cols"); get(maDelete, "ed_delete"); maDelete->SetClickHdl(LINK(this,ScSplitColumnTransformationControl, DeleteHdl)); } ScSplitColumnTransformationControl::~ScSplitColumnTransformationControl() { disposeOnce(); } void ScSplitColumnTransformationControl::dispose() { maSeparator.clear(); maNumColumns.clear(); maDelete.clear(); ScDataTransformationBaseControl::dispose(); } std::shared_ptr ScSplitColumnTransformationControl::getTransformation() { OUString aSeparator = maSeparator->GetText(); sal_Unicode cSeparator = aSeparator.isEmpty() ? ',' : aSeparator[0]; return std::make_shared(mnCol, cSeparator); } class ScMergeColumnTransformationControl : public ScDataTransformationBaseControl { private: VclPtr mpSeparator; VclPtr mpEdColumns; VclPtr maDelete; sal_uInt32 maIndex; std::function maDeleteTransformation; public: ScMergeColumnTransformationControl(vcl::Window* pParent, SCCOL nStartCol, SCCOL nEndCol, sal_uInt32 aIndex, std::function aDeleteTransformation); ~ScMergeColumnTransformationControl() override; virtual void dispose() override; virtual std::shared_ptr getTransformation() override; DECL_LINK(DeleteHdl, Button*, void); }; ScMergeColumnTransformationControl::ScMergeColumnTransformationControl( vcl::Window* pParent, SCCOL nStartCol, SCCOL nEndCol, sal_uInt32 aIndex, std::function aDeleteTransformation) : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/mergecolumnentry.ui") , maIndex(aIndex) , maDeleteTransformation(std::move(aDeleteTransformation)) { get(mpSeparator, "ed_separator"); get(mpEdColumns, "ed_columns"); get(maDelete, "ed_delete"); maDelete->SetClickHdl(LINK(this,ScMergeColumnTransformationControl, DeleteHdl)); OUStringBuffer aBuffer; // map from zero based to one based column numbers aBuffer.append(OUString::number(nStartCol + 1)); for ( SCCOL nCol = nStartCol + 1; nCol <= nEndCol; ++nCol) { aBuffer.append(";").append(OUString::number(nCol + 1)); } mpEdColumns->SetText(aBuffer.makeStringAndClear()); } ScMergeColumnTransformationControl::~ScMergeColumnTransformationControl() { disposeOnce(); } void ScMergeColumnTransformationControl::dispose() { mpSeparator.clear(); mpEdColumns.clear(); maDelete.clear(); ScDataTransformationBaseControl::dispose(); } std::shared_ptr ScMergeColumnTransformationControl::getTransformation() { OUString aColumnString = mpEdColumns->GetText(); std::vector aSplitColumns = comphelper::string::split(aColumnString, ';'); std::set aMergedColumns; for (auto& rColStr : aSplitColumns) { sal_Int32 nCol = rColStr.toInt32(); if (nCol <= 0) continue; if (nCol > MAXCOL) continue; // translate from 1-based column notations to internal Calc one aMergedColumns.insert(nCol - 1); } return std::make_shared(aMergedColumns, mpSeparator->GetText()); } class ScSortTransformationControl : public ScDataTransformationBaseControl { private: VclPtr mpAscending; VclPtr mpEdColumns; VclPtr maDelete; sal_uInt32 maIndex; std::function maDeleteTransformation; public: ScSortTransformationControl(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation); ~ScSortTransformationControl() override; virtual void dispose() override; virtual std::shared_ptr getTransformation() override; DECL_LINK(DeleteHdl, Button*, void); }; ScSortTransformationControl::ScSortTransformationControl( vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation) : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/sorttransformationentry.ui") , maIndex(aIndex) , maDeleteTransformation(std::move(aDeleteTransformation)) { get(mpAscending, "ed_ascending"); get(mpEdColumns, "ed_columns"); get(maDelete, "ed_delete"); maDelete->SetClickHdl(LINK(this,ScSortTransformationControl, DeleteHdl)); } ScSortTransformationControl::~ScSortTransformationControl() { disposeOnce(); } void ScSortTransformationControl::dispose() { mpAscending.clear(); mpEdColumns.clear(); maDelete.clear(); ScDataTransformationBaseControl::dispose(); } std::shared_ptr ScSortTransformationControl::getTransformation() { OUString aColStr = mpEdColumns->GetText(); bool aIsAscending = mpAscending->IsChecked(); SCCOL aColumn = 0; sal_Int32 nCol = aColStr.toInt32(); if (nCol > 0 && nCol <= MAXCOL) aColumn = nCol - 1; // translate from 1-based column notations to internal Calc one ScSortParam aSortParam; ScSortKeyState aSortKey; aSortKey.bDoSort = true; aSortKey.nField = aColumn; aSortKey.bAscending = aIsAscending; aSortParam.maKeyState.push_back(aSortKey); return std::make_shared(aSortParam); } class ScColumnTextTransformation : public ScDataTransformationBaseControl { private: VclPtr maColumnNums; VclPtr maType; VclPtr maDelete; sal_uInt32 maIndex; std::function maDeleteTransformation; public: ScColumnTextTransformation(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation); ~ScColumnTextTransformation() override; virtual void dispose() override; virtual std::shared_ptr getTransformation() override; DECL_LINK(DeleteHdl, Button*, void); }; ScColumnTextTransformation::ScColumnTextTransformation( vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation) : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/texttransformationentry.ui") , maIndex(aIndex) , maDeleteTransformation(std::move(aDeleteTransformation)) { get(maColumnNums, "ed_columns"); get(maType, "ed_lst"); get(maDelete, "ed_delete"); maDelete->SetClickHdl(LINK(this,ScColumnTextTransformation, DeleteHdl)); } ScColumnTextTransformation::~ScColumnTextTransformation() { disposeOnce(); } void ScColumnTextTransformation::dispose() { maColumnNums.clear(); maType.clear(); maDelete.clear(); ScDataTransformationBaseControl::dispose(); } std::shared_ptr ScColumnTextTransformation::getTransformation() { OUString aColumnString = maColumnNums->GetText(); std::vector aSplitColumns = comphelper::string::split(aColumnString, ';'); std::set aColumns; for (auto& rColStr : aSplitColumns) { sal_Int32 nCol = rColStr.toInt32(); if (nCol <= 0) continue; if (nCol > MAXCOL) continue; // translate from 1-based column notations to internal Calc one aColumns.insert(nCol - 1); } sal_Int32 nPos = maType->GetSelectedEntryPos(); switch (nPos) { case 0: return std::make_shared(aColumns,sc::TEXT_TRANSFORM_TYPE::TO_LOWER); case 1: return std::make_shared(aColumns,sc::TEXT_TRANSFORM_TYPE::TO_UPPER); case 2: return std::make_shared(aColumns,sc::TEXT_TRANSFORM_TYPE::CAPITALIZE); case 3: return std::make_shared(aColumns,sc::TEXT_TRANSFORM_TYPE::TRIM); default: assert(false); } return nullptr; } class ScAggregateFunction : public ScDataTransformationBaseControl { private: VclPtr maColumnNums; VclPtr maType; VclPtr maDelete; sal_uInt32 maIndex; std::function maDeleteTransformation; public: ScAggregateFunction(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation); ~ScAggregateFunction() override; virtual void dispose() override; virtual std::shared_ptr getTransformation() override; DECL_LINK(DeleteHdl, Button*, void); }; ScAggregateFunction::ScAggregateFunction(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation) : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/aggregatefunctionentry.ui") , maIndex(aIndex) , maDeleteTransformation(std::move(aDeleteTransformation)) { get(maColumnNums, "ed_columns"); get(maType, "ed_lst"); get(maDelete, "ed_delete"); maDelete->SetClickHdl(LINK(this,ScAggregateFunction, DeleteHdl)); } ScAggregateFunction::~ScAggregateFunction() { disposeOnce(); } void ScAggregateFunction::dispose() { maColumnNums.clear(); maType.clear(); maDelete.clear(); ScDataTransformationBaseControl::dispose(); } std::shared_ptr ScAggregateFunction::getTransformation() { OUString aColumnString = maColumnNums->GetText(); sal_Int32 nPos = maType->GetSelectedEntryPos(); std::vector aSplitColumns = comphelper::string::split(aColumnString, ';'); std::set aColumns; for (auto& rColStr : aSplitColumns) { sal_Int32 nCol = rColStr.toInt32(); if (nCol <= 0) continue; if (nCol > MAXCOL) continue; // translate from 1-based column notations to internal Calc one aColumns.insert(nCol - 1); } switch (nPos) { case 0: return std::make_shared(aColumns,sc::AGGREGATE_FUNCTION::SUM); case 1: return std::make_shared(aColumns,sc::AGGREGATE_FUNCTION::AVERAGE); case 2: return std::make_shared(aColumns,sc::AGGREGATE_FUNCTION::MIN); case 3: return std::make_shared(aColumns,sc::AGGREGATE_FUNCTION::MAX); default: assert(false); } return nullptr; } class ScNumberTransformation : public ScDataTransformationBaseControl { private: VclPtr maColumnNums; VclPtr maType; VclPtr maDelete; sal_uInt32 maIndex; std::function maDeleteTransformation; public: ScNumberTransformation(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation); ~ScNumberTransformation() override; virtual void dispose() override; virtual std::shared_ptr getTransformation() override; DECL_LINK(DeleteHdl, Button*, void); }; ScNumberTransformation::ScNumberTransformation( vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation) : ScDataTransformationBaseControl(pParent, "modules/scalc/ui/numbertransformationentry.ui") , maIndex(aIndex) , maDeleteTransformation(std::move(aDeleteTransformation)) { get(maColumnNums, "ed_columns"); get(maType, "ed_lst"); get(maDelete, "ed_delete"); maDelete->SetClickHdl(LINK(this,ScNumberTransformation, DeleteHdl)); } ScNumberTransformation::~ScNumberTransformation() { disposeOnce(); } void ScNumberTransformation::dispose() { maColumnNums.clear(); maType.clear(); maDelete.clear(); ScDataTransformationBaseControl::dispose(); } std::shared_ptr ScNumberTransformation::getTransformation() { OUString aColumnString = maColumnNums->GetText(); sal_Int32 nPos = maType->GetSelectedEntryPos(); std::vector aSplitColumns = comphelper::string::split(aColumnString, ';'); std::set aColumns; for (auto& rColStr : aSplitColumns) { sal_Int32 nCol = rColStr.toInt32(); if (nCol <= 0) continue; if (nCol > MAXCOL) continue; // translate from 1-based column notations to internal Calc one aColumns.insert(nCol - 1); } switch (nPos) { case 0: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::SIGN); case 1: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::ROUND); case 2: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::ROUND_UP); case 3: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::ROUND_DOWN); case 4: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::ABSOLUTE); case 5: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::LOG_E); case 6: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::LOG_10); case 7: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::CUBE); case 8: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::SQUARE); case 9: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::SQUARE_ROOT); case 10: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::EXPONENT); case 11: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::IS_EVEN); case 12: return std::make_shared(aColumns,sc::NUMBER_TRANSFORM_TYPE::IS_ODD); default: assert(false); } return nullptr; } class ScReplaceNullTransformation : public ScDataTransformationBaseControl { private: VclPtr maColumnNums; VclPtr maReplaceString; VclPtr maDelete; sal_uInt32 maIndex; std::function maDeleteTransformation; public: ScReplaceNullTransformation(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation); ~ScReplaceNullTransformation() override; virtual void dispose() override; virtual std::shared_ptr getTransformation() override; DECL_LINK(DeleteHdl, Button*, void); }; ScReplaceNullTransformation::ScReplaceNullTransformation(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation): ScDataTransformationBaseControl(pParent,"modules/scalc/ui/replacenulltransformationentry.ui"), maIndex(aIndex), maDeleteTransformation(aDeleteTransformation) { get(maColumnNums, "ed_columns"); get(maReplaceString, "ed_str"); get(maDelete, "ed_delete"); maDelete->SetClickHdl(LINK(this,ScReplaceNullTransformation, DeleteHdl)); } ScReplaceNullTransformation::~ScReplaceNullTransformation() { disposeOnce(); } void ScReplaceNullTransformation::dispose() { maColumnNums.clear(); maReplaceString.clear(); maDelete.clear(); ScDataTransformationBaseControl::dispose(); } std::shared_ptr ScReplaceNullTransformation::getTransformation() { OUString aColumnString = maColumnNums->GetText(); OUString aReplaceWithString = maReplaceString->GetText(); std::vector aSplitColumns = comphelper::string::split(aColumnString, ';'); std::set aColumns; for (auto& rColStr : aSplitColumns) { sal_Int32 nCol = rColStr.toInt32(); if (nCol <= 0) continue; if (nCol > MAXCOL) continue; // translate from 1-based column notations to internal Calc one aColumns.insert(nCol - 1); } return std::make_shared(aColumns,aReplaceWithString); } class ScDateTimeTransformation : public ScDataTransformationBaseControl { private: VclPtr maColumnNums; VclPtr maType; VclPtr maDelete; sal_uInt32 maIndex; std::function maDeleteTransformation; public: ScDateTimeTransformation(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation); ~ScDateTimeTransformation() override; virtual void dispose() override; virtual std::shared_ptr getTransformation() override; DECL_LINK(DeleteHdl, Button*, void); }; ScDateTimeTransformation::ScDateTimeTransformation(vcl::Window* pParent, sal_uInt32 aIndex, std::function aDeleteTransformation): ScDataTransformationBaseControl(pParent,"modules/scalc/ui/datetimetransformationentry.ui"), maIndex(aIndex), maDeleteTransformation(aDeleteTransformation) { get(maColumnNums, "ed_columns"); get(maType, "ed_lst"); get(maDelete, "ed_delete"); maDelete->SetClickHdl(LINK(this,ScDateTimeTransformation, DeleteHdl)); } ScDateTimeTransformation::~ScDateTimeTransformation() { disposeOnce(); } void ScDateTimeTransformation::dispose() { maColumnNums.clear(); maType.clear(); maDelete.clear(); ScDataTransformationBaseControl::dispose(); } std::shared_ptr ScDateTimeTransformation::getTransformation() { OUString aColumnString = maColumnNums->GetText(); sal_Int32 nPos = maType->GetSelectedEntryPos(); std::vector aSplitColumns = comphelper::string::split(aColumnString, ';'); std::set aColumns; for (auto& rColStr : aSplitColumns) { sal_Int32 nCol = rColStr.toInt32(); if (nCol <= 0) continue; if (nCol > MAXCOL) continue; // translate from 1-based column notations to internal Calc one aColumns.insert(nCol - 1); } switch (nPos) { case 0: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::DATE_STRING); case 1: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::YEAR); case 2: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::START_OF_YEAR); case 3: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::END_OF_YEAR); case 4: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::MONTH); case 5: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::MONTH_NAME); case 6: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::START_OF_MONTH); case 7: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::END_OF_MONTH); case 8: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::DAY); case 9: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_WEEK); case 10: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::DAY_OF_YEAR); case 11: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::QUARTER); case 12: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::START_OF_QUARTER); case 13: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::END_OF_QUARTER); case 14: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::HOUR); case 15: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::MINUTE); case 16: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::SECOND); case 17: return std::make_shared(aColumns,sc::DATETIME_TRANSFORMATION_TYPE::TIME); default: assert(false); } return nullptr; } } ScDataProviderDlg::ScDataProviderDlg(vcl::Window* pParent, std::shared_ptr pDoc, const ScDocument* pDocument) : ModalDialog(pParent, "dataproviderdlg", "modules/scalc/ui/dataproviderdlg.ui", true) , mpDoc(std::move(pDoc)) , mpBar(VclPtr::Create()) { get(mpTable, "data_table"); get(mpList, "operation_ctrl"); get(mpDBRanges, "select_db_range"); mpTable->Init(mpDoc); mpIndex = 0; ScDBCollection* pDBCollection = pDocument->GetDBCollection(); auto& rNamedDBs = pDBCollection->getNamedDBs(); for (auto& rNamedDB : rNamedDBs) { mpDBRanges->InsertEntry(rNamedDB->GetName()); } mpDataProviderCtrl = VclPtr::Create(mpList, LINK(this, ScDataProviderDlg, ImportHdl)); mpList->addEntry(mpDataProviderCtrl); mpIndex++; pDBData = new ScDBData("data", 0, 0, 0, MAXCOL, MAXROW); bool bSuccess = mpDoc->GetDBCollection()->getNamedDBs().insert(std::unique_ptr(pDBData)); SAL_WARN_IF(!bSuccess, "sc", "temporary warning"); InitMenu(); } ScDataProviderDlg::~ScDataProviderDlg() { disposeOnce(); } void ScDataProviderDlg::dispose() { mpDataProviderCtrl.clear(); mpTable.clear(); mpList.clear(); mpDBRanges.clear(); mpBar.disposeAndClear(); ModalDialog::dispose(); } void ScDataProviderDlg::InitMenu() { mpBar->InsertItem(MENU_START, "Start"); VclPtrInstance pPopup; for (auto& itrStartData : aStartData) { pPopup->InsertItem(itrStartData.nMenuID, OUString::createFromAscii(itrStartData.aMenuName)); } mpBar->SetPopupMenu(MENU_START, pPopup); pPopup->SetSelectHdl(LINK(this, ScDataProviderDlg, StartMenuHdl)); mpBar->InsertItem(MENU_COLUMN, "Column"); VclPtrInstance pColumnMenu; for (auto& itrColumnData : aColumnData) { pColumnMenu->InsertItem(itrColumnData.nMenuID, OUString::createFromAscii(itrColumnData.aMenuName)); } pColumnMenu->SetSelectHdl(LINK(this, ScDataProviderDlg, ColumnMenuHdl)); mpBar->SetPopupMenu(MENU_COLUMN, pColumnMenu); SetMenuBar(mpBar.get()); } void ScDataProviderDlg::MouseButtonUp(const MouseEvent& rMEvt) { VclPtr mpText = VclPtr::Create(mpList); mpText->SetText("Some Text " + OUString::number(rMEvt.GetPosPixel().X()) + "x" + OUString::number(rMEvt.GetPosPixel().getY())); mpText->SetSizePixel(Size(400, 20)); mpList->addEntry(mpText); mpIndex++; } IMPL_LINK(ScDataProviderDlg, StartMenuHdl, Menu*, pMenu, bool) { for (auto& i: aStartData) { if (i.nMenuID == pMenu->GetCurItemId()) { i.maCallback(this); return true; } } return true; } IMPL_LINK(ScDataProviderDlg, ColumnMenuHdl, Menu*, pMenu, bool) { for (auto& i: aColumnData) { if (i.nMenuID == pMenu->GetCurItemId()) { i.maCallback(this); return true; } } return true; } IMPL_LINK(ScDataProviderDlg, ImportHdl, Window*, pCtrl, void) { if (pCtrl == mpDataProviderCtrl.get()) { import(mpDoc.get(), true); } } void ScDataProviderDlg::applyAndQuit() { EndDialog(RET_OK); } void ScDataProviderDlg::cancelAndQuit() { EndDialog(RET_CANCEL); } void ScDataProviderDlg::deleteColumn() { std::function adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); VclPtr pDeleteColumnEntry = VclPtr::Create(mpList, mpIndex++, adeleteTransformation); mpList->addEntry(pDeleteColumnEntry); } void ScDataProviderDlg::splitColumn() { SCCOL nStartCol = -1; SCCOL nEndCol = -1; mpTable->getColRange(nStartCol, nEndCol); std::function adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); VclPtr pSplitColumnEntry = VclPtr::Create(mpList, nStartCol, mpIndex++, adeleteTransformation); mpList->addEntry(pSplitColumnEntry); } void ScDataProviderDlg::mergeColumns() { SCCOL nStartCol = -1; SCCOL nEndCol = -1; mpTable->getColRange(nStartCol, nEndCol); std::function adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); VclPtr pMergeColumnEntry = VclPtr::Create(mpList, nStartCol, nEndCol, mpIndex++, adeleteTransformation); mpList->addEntry(pMergeColumnEntry); } void ScDataProviderDlg::textTransformation() { std::function adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); VclPtr pTextTransforamtionEntry = VclPtr::Create(mpList, mpIndex++, adeleteTransformation); mpList->addEntry(pTextTransforamtionEntry); } void ScDataProviderDlg::sortTransformation() { std::function adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); VclPtr pSortTransforamtionEntry = VclPtr::Create(mpList, mpIndex++, adeleteTransformation); mpList->addEntry(pSortTransforamtionEntry); } void ScDataProviderDlg::aggregateFunction() { std::function adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); VclPtr pAggregateFuntionEntry = VclPtr::Create(mpList, mpIndex++, adeleteTransformation); mpList->addEntry(pAggregateFuntionEntry); } void ScDataProviderDlg::numberTransformation() { std::function adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); VclPtr pNumberTransformationEntry = VclPtr::Create(mpList, mpIndex++, adeleteTransformation); mpList->addEntry(pNumberTransformationEntry); } void ScDataProviderDlg::replaceNullTransformation() { std::function adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); VclPtr pReplaceNullTransformationEntry = VclPtr::Create(mpList, mpIndex++, adeleteTransformation); mpList->addEntry(pReplaceNullTransformationEntry); } void ScDataProviderDlg::dateTimeTransformation() { std::function adeleteTransformation = std::bind(&ScDataProviderDlg::deletefromList,this, std::placeholders::_1); VclPtr pDateTimeTransformationEntry = VclPtr::Create(mpList, mpIndex++, adeleteTransformation); mpList->addEntry(pDateTimeTransformationEntry); } namespace { bool hasDBName(const OUString& rName, ScDBCollection* pDBCollection) { if (pDBCollection->getNamedDBs().findByUpperName(ScGlobal::pCharClass->uppercase(rName))) return true; return false; } } void ScDataProviderDlg::import(ScDocument* pDoc, bool bInternal) { sc::ExternalDataSource aSource = mpDataProviderCtrl->getDataSource(pDoc); std::vector> aListEntries = mpList->getEntries(); for (size_t i = 1; i < aListEntries.size(); ++i) { ScDataTransformationBaseControl* pTransformationCtrl = dynamic_cast(aListEntries[i].get()); if (!pTransformationCtrl) { SAL_WARN("sc", "all children except the provider should inherit from the base control"); continue; } aSource.AddDataTransformation(pTransformationCtrl->getTransformation()); } if (bInternal) aSource.setDBData(pDBData->GetName()); else { aSource.setDBData(mpDBRanges->GetSelectedEntry()); if (!hasDBName(aSource.getDBName(), pDoc->GetDBCollection())) return; pDoc->GetExternalDataMapper().insertDataSource(aSource); } aSource.refresh(pDoc, true); mpTable->Invalidate(); } void ScDataProviderDlg::deletefromList(sal_uInt32 nIndex) { mpList->deleteEntry(nIndex); } IMPL_LINK_NOARG(ScDeleteColumnTransformationControl, DeleteHdl, Button*, void) { maDeleteTransformation(maIndex); } IMPL_LINK_NOARG(ScSplitColumnTransformationControl, DeleteHdl, Button*, void) { maDeleteTransformation(maIndex); } IMPL_LINK_NOARG(ScMergeColumnTransformationControl, DeleteHdl, Button*, void) { maDeleteTransformation(maIndex); } IMPL_LINK_NOARG(ScNumberTransformation, DeleteHdl, Button*, void) { maDeleteTransformation(maIndex); } IMPL_LINK_NOARG(ScAggregateFunction, DeleteHdl, Button*, void) { maDeleteTransformation(maIndex); } IMPL_LINK_NOARG(ScSortTransformationControl, DeleteHdl, Button*, void) { maDeleteTransformation(maIndex); } IMPL_LINK_NOARG(ScColumnTextTransformation, DeleteHdl, Button*, void) { maDeleteTransformation(maIndex); } IMPL_LINK_NOARG(ScReplaceNullTransformation, DeleteHdl, Button*, void) { maDeleteTransformation(maIndex); } IMPL_LINK_NOARG(ScDateTimeTransformation, DeleteHdl, Button*, void) { maDeleteTransformation(maIndex); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */