[Libreoffice-commits] core.git: sc/source sc/uiconfig sc/UIConfig_scalc.mk

Markus Mohrhard markus.mohrhard at googlemail.com
Fri Oct 13 23:49:23 UTC 2017


 sc/UIConfig_scalc.mk                      |    3 
 sc/source/ui/inc/dataproviderdlg.hxx      |   63 +--
 sc/source/ui/inc/datatableview.hxx        |   14 
 sc/source/ui/inc/hdrcont.hxx              |    2 
 sc/source/ui/miscdlgs/dataproviderdlg.cxx |  504 +++++++++++++++++++++++++-----
 sc/source/ui/miscdlgs/datatableview.cxx   |   41 +-
 sc/source/ui/view/cellsh2.cxx             |    6 
 sc/uiconfig/scalc/ui/dataproviderdlg.ui   |   40 ++
 sc/uiconfig/scalc/ui/dataproviderentry.ui |   88 +++++
 sc/uiconfig/scalc/ui/splitcolumnentry.ui  |   93 +++++
 10 files changed, 729 insertions(+), 125 deletions(-)

New commits:
commit 6250b856defa4d49469cb455c1eef53de02f623d
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Oct 8 17:48:15 2017 +0200

    implement new more user friendly data provider dlg
    
    This is still a work in progress.
    
    Change-Id: I1e68c86acc810eec068b1f184b2307c51d9b58df
    Reviewed-on: https://gerrit.libreoffice.org/43259
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk
index 4e03e316669c..845ede98034b 100644
--- a/sc/UIConfig_scalc.mk
+++ b/sc/UIConfig_scalc.mk
@@ -111,6 +111,8 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
 	sc/uiconfig/scalc/ui/dataform \
 	sc/uiconfig/scalc/ui/datastreams \
 	sc/uiconfig/scalc/ui/dataprovider \
+	sc/uiconfig/scalc/ui/dataproviderdlg \
+	sc/uiconfig/scalc/ui/dataproviderentry \
 	sc/uiconfig/scalc/ui/definedatabaserangedialog \
 	sc/uiconfig/scalc/ui/definename \
 	sc/uiconfig/scalc/ui/deletecells \
@@ -211,6 +213,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
 	sc/uiconfig/scalc/ui/sortkey \
 	sc/uiconfig/scalc/ui/sortoptionspage \
 	sc/uiconfig/scalc/ui/sortwarning \
+	sc/uiconfig/scalc/ui/splitcolumnentry \
 	sc/uiconfig/scalc/ui/subtotaldialog \
 	sc/uiconfig/scalc/ui/subtotaloptionspage \
 	sc/uiconfig/scalc/ui/subtotalgrppage \
diff --git a/sc/source/ui/inc/dataproviderdlg.hxx b/sc/source/ui/inc/dataproviderdlg.hxx
index ec519b4e9e35..5a45fb7cce39 100644
--- a/sc/source/ui/inc/dataproviderdlg.hxx
+++ b/sc/source/ui/inc/dataproviderdlg.hxx
@@ -16,51 +16,54 @@
 #include <vcl/dialog.hxx>
 #include <vcl/layout.hxx>
 #include <vcl/lstbox.hxx>
+#include <vcl/listctrl.hxx>
+#include <vcl/button.hxx>
 
-#include "address.hxx"
-#include "datamapper.hxx"
-#include "dataprovider.hxx"
+#include "datatableview.hxx"
 
-class ScDocShell;
-class SvtURLBox;
-class ScRange;
-class ComboBox;
+#include <memory>
 
-namespace sc {
+class ScDocument;
+class ScDataProviderBaseControl;
+class ScDBData;
 
-class DataProviderDlg : public ModalDialog
+class ScDataProviderDlg : public ModalDialog
 {
-    ScDocShell *mpDocShell;
+private:
 
-    VclPtr<SvtURLBox>      m_pCbUrl;
-    VclPtr<PushButton>     m_pBtnBrowse;
-    VclPtr<OKButton>       m_pBtnOk;
-    VclPtr<ListBox>        m_pCBData;
-    VclPtr<ListBox>        m_pCBProvider;
-    VclPtr<Edit>           m_pEdID;
+    std::shared_ptr<ScDocument> mpDoc;
+    VclPtr<ScDataTableView> mpTable;
+    VclPtr<ListControl> mpList;
+    VclPtr<MenuBar> mpBar;
+    VclPtr<ScDataProviderBaseControl> mpDataProviderCtrl;
 
-    DECL_LINK(UpdateClickHdl, Button*, void);
-    DECL_LINK(UpdateComboBoxHdl, ComboBox&, void);
-    DECL_LINK(BrowseHdl, Button*, void);
-    DECL_LINK(EditHdl, Edit&, void);
-    DECL_LINK(SelectHdl, ListBox&, void);
+    ScDBData* pDBData;
 
-    void UpdateEnable();
+    void InitMenu();
 
-    std::shared_ptr<ExternalDataSource> mpDataSource;
+    DECL_LINK( StartMenuHdl, Menu*, bool );
+    DECL_LINK( ColumnMenuHdl, Menu*, bool );
+    DECL_LINK( ImportHdl, Window*, void );
 
 public:
-    DataProviderDlg(ScDocShell *pDocShell, vcl::Window* pParent);
-    virtual ~DataProviderDlg() override;
+
+    ScDataProviderDlg(vcl::Window* pWindow, std::shared_ptr<ScDocument> pDoc);
+
+    virtual ~ScDataProviderDlg() override;
     virtual void dispose() override;
 
-    void Init();
+    virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
 
-    void StartImport();
-};
+    void applyAndQuit();
+    void cancelAndQuit();
 
-}
+    void deleteColumn();
+    void splitColumn();
+    void mergeColumns();
+
+    void import();
+};
 
-#endif // INCLUDED_SC_SOURCE_UI_INC_DATAPROVIDERDLG_HXX
+#endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/datatableview.hxx b/sc/source/ui/inc/datatableview.hxx
index 69c06cabe055..467309b7026e 100644
--- a/sc/source/ui/inc/datatableview.hxx
+++ b/sc/source/ui/inc/datatableview.hxx
@@ -35,9 +35,10 @@ class ScDataTableColView : public ScHeaderControl
 
 public:
 
-    ScDataTableColView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine);
+    ScDataTableColView(vcl::Window* pParent, SelectionEngine* pSelectionEngine);
 
     void SetPos(SCCOLROW nRow);
+    void Init(ScDocument* pDoc);
 
     virtual SCCOLROW GetPos() const override;
     virtual sal_uInt16 GetEntrySize(SCCOLROW nPos) const override;
@@ -54,9 +55,10 @@ class ScDataTableRowView : public ScHeaderControl
 
 public:
 
-    ScDataTableRowView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine);
+    ScDataTableRowView(vcl::Window* pParent, SelectionEngine* pSelectionEngine);
 
     void SetPos(SCCOLROW nRow);
+    void Init(ScDocument* pDoc);
 
     virtual SCCOLROW GetPos() const override;
     virtual sal_uInt16 GetEntrySize(SCCOLROW nPos) const override;
@@ -91,8 +93,14 @@ class SC_DLLPUBLIC ScDataTableView : public Control
 
     DECL_LINK( ScrollHdl, ScrollBar*, void );
 
+protected:
+
+    virtual Size GetOptimalSize() const override;
+
 public:
-    ScDataTableView(vcl::Window* pParent, std::shared_ptr<ScDocument> pDoc);
+    ScDataTableView(vcl::Window* pParent);
+
+    void Init(std::shared_ptr<ScDocument> pDoc);
 
     ~ScDataTableView() override;
 
diff --git a/sc/source/ui/inc/hdrcont.hxx b/sc/source/ui/inc/hdrcont.hxx
index 6410e2ce142c..b84981aa17a5 100644
--- a/sc/source/ui/inc/hdrcont.hxx
+++ b/sc/source/ui/inc/hdrcont.hxx
@@ -31,7 +31,7 @@
 
 class ScTabView;
 
-class ScHeaderControl : public vcl::Window
+class SC_DLLPUBLIC ScHeaderControl : public vcl::Window
 {
 private:
     SelectionEngine*    pSelEngine;
diff --git a/sc/source/ui/miscdlgs/dataproviderdlg.cxx b/sc/source/ui/miscdlgs/dataproviderdlg.cxx
index b049344eb536..23366fbea0fc 100644
--- a/sc/source/ui/miscdlgs/dataproviderdlg.cxx
+++ b/sc/source/ui/miscdlgs/dataproviderdlg.cxx
@@ -7,137 +7,479 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include <dataproviderdlg.hxx>
+#include "dataproviderdlg.hxx"
 
-#include <sfx2/filedlghelper.hxx>
-#include <svtools/inettbc.hxx>
-#include <vcl/layout.hxx>
-#include <address.hxx>
-#include <docsh.hxx>
-#include <dbdata.hxx>
-#include "datamapper.hxx"
+#include "document.hxx"
+#include "dataprovider.hxx"
+#include "datatransformation.hxx"
 
-namespace sc {
+#include <vcl/lstbox.hxx>
 
-DataProviderDlg::DataProviderDlg(ScDocShell *pDocShell, vcl::Window* pParent)
-    : ModalDialog(pParent, "DataProviderDialog", "modules/scalc/ui/dataprovider.ui")
-    , mpDocShell(pDocShell)
+constexpr int MENU_START = 0;
+constexpr int MENU_COLUMN = 1;
+
+class ScDataProviderBaseControl : public VclContainer,
+                                    public VclBuilderContainer
 {
-    get(m_pCbUrl, "url");
-    get(m_pBtnBrowse, "browse");
-    get(m_pBtnOk, "ok");
-    get(m_pCBData, "combobox_db");
-    get(m_pCBProvider, "combobox_provider");
-    get(m_pEdID, "edit_id");
+    VclPtr<VclContainer> maGrid;
+    VclPtr<ListBox> maProviderList;
+    VclPtr<Edit> maEditURL;
+    VclPtr<Edit> maEditID;
+    VclPtr<PushButton> mpApplyBtn;
+
+    bool mbDirty;
+    OUString maOldProvider;
+    OUString maURL;
+    OUString maID;
+
+    Link<Window*, void> 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);
 
-    m_pCbUrl->SetSelectHdl( LINK( this, DataProviderDlg, UpdateComboBoxHdl ) );
-    m_pCbUrl->SetModifyHdl(LINK(this, DataProviderDlg, EditHdl));
-    m_pBtnBrowse->SetClickHdl( LINK( this, DataProviderDlg, BrowseHdl ) );
-    m_pCBData->SetSelectHdl(LINK(this, DataProviderDlg, SelectHdl));
-    Init();
-    m_pCBData->Resize();
-    UpdateEnable();
+public:
+    ScDataProviderBaseControl(vcl::Window* pParent, const Link<Window*, void>& 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<Window*, void>& rImportCallback):
+    VclContainer(pParent, WB_CLIPCHILDREN | WB_BORDER),
+    mbDirty(false),
+    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<PushButton>::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(BitmapEx("sc/res/xml_element.png")));
+    mpApplyBtn->Show();
+    mpApplyBtn->SetClickHdl(LINK(this, ScDataProviderBaseControl, ApplyBtnHdl));
+    SetSizePixel(GetOptimalSize());
+    isValid();
 }
 
-DataProviderDlg::~DataProviderDlg()
+ScDataProviderBaseControl::~ScDataProviderBaseControl()
 {
     disposeOnce();
 }
 
-void DataProviderDlg::dispose()
+void ScDataProviderBaseControl::dispose()
 {
-    m_pCbUrl.clear();
-    m_pBtnBrowse.clear();
-    m_pBtnOk.clear();
-    m_pCBData.clear();
-    m_pCBProvider.clear();
-    m_pEdID.clear();
-    ModalDialog::dispose();
+    maEditID.clear();
+    maEditURL.clear();
+    maProviderList.clear();
+    mpApplyBtn.disposeAndClear();
+    maGrid.clear();
+    disposeBuilder();
+    VclContainer::dispose();
 }
 
-IMPL_LINK_NOARG(DataProviderDlg, BrowseHdl, Button*, void)
+Size ScDataProviderBaseControl::calculateRequisition() const
 {
-    sfx2::FileDialogHelper aFileDialog(0, FileDialogFlags::NONE, this);
-    if ( aFileDialog.Execute() != ERRCODE_NONE )
+    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();
+
+    if (bValid)
+    {
+        Color aColor = GetSettings().GetStyleSettings().GetDialogColor();
+        SetBackground(aColor);
+        maGrid->SetBackground(aColor);
+        Invalidate();
+        updateApplyBtn(true);
+    }
+    else
+    {
+        SetBackground(Wallpaper(COL_RED));
+        maGrid->SetBackground(Wallpaper(COL_RED));
+        Invalidate();
+        updateApplyBtn(false);
+    }
+}
+
+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->SetBackground(Wallpaper(COL_RED));
+        mpApplyBtn->SetQuickHelpText("");
         return;
+    }
 
-    m_pCbUrl->SetText( aFileDialog.GetPath() );
-    UpdateEnable();
+    if (mbDirty)
+    {
+        mpApplyBtn->Enable();
+        mpApplyBtn->SetBackground(Wallpaper(COL_YELLOW));
+        mpApplyBtn->SetQuickHelpText("Apply Changes");
+    }
+    else
+    {
+        mpApplyBtn->Disable();
+        mpApplyBtn->SetBackground(Wallpaper(COL_GREEN));
+        mpApplyBtn->SetQuickHelpText("Current Config Applied");
+    }
 }
 
-IMPL_LINK_NOARG(DataProviderDlg, UpdateClickHdl, Button*, void)
+IMPL_LINK_NOARG(ScDataProviderBaseControl, ProviderSelectHdl, ListBox&, void)
 {
-    UpdateEnable();
+    isValid();
+    mbDirty |= maOldProvider != maProviderList->GetSelectedEntry();
+    maOldProvider = maProviderList->GetSelectedEntry();
 }
 
-IMPL_LINK_NOARG(DataProviderDlg, UpdateComboBoxHdl, ComboBox&, void)
+IMPL_LINK_NOARG(ScDataProviderBaseControl, IDEditHdl, Edit&, void)
 {
-    UpdateEnable();
+    isValid();
+    mbDirty |= maEditID->GetText() != maID;
+    maID = maEditID->GetText();
 }
 
-IMPL_LINK_NOARG(DataProviderDlg, EditHdl, Edit&, void)
+IMPL_LINK_NOARG(ScDataProviderBaseControl, URLEditHdl, Edit&, void)
 {
-    UpdateEnable();
+    isValid();
+    mbDirty |= maEditURL->GetText() != maURL;
+    maURL = maEditURL->GetText();
 }
 
-IMPL_LINK_NOARG(DataProviderDlg, SelectHdl, ListBox&, void)
+IMPL_LINK_NOARG(ScDataProviderBaseControl, ApplyBtnHdl, Button*, void)
 {
-    UpdateEnable();
+    mbDirty = false;
+    updateApplyBtn(true);
+    maImportCallback.Call(this);
 }
 
-void DataProviderDlg::UpdateEnable()
+
+namespace {
+
+struct MenuData
+{
+    int nMenuID;
+    const char* aMenuName;
+    std::function<void(ScDataProviderDlg*)> 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 },
+};
+
+class ScDataTransformationBaseControl : public VclContainer,
+                                    public VclBuilderContainer
 {
-    bool bEmptyEntry = m_pCbUrl->GetURL().isEmpty() ||
-            m_pCBData->GetSelectedEntry().isEmpty() ||
-            m_pCBProvider->GetSelectedEntry().isEmpty();
-    m_pBtnOk->Enable(!bEmptyEntry);
-    setOptimalLayoutSize();
+    VclPtr<VclContainer> 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<sc::DataTransformation> 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());
 }
 
-void DataProviderDlg::Init()
+ScDataTransformationBaseControl::~ScDataTransformationBaseControl()
 {
-    ScDocument& rDoc = mpDocShell->GetDocument();
-    ScDBCollection::NamedDBs& rNamedDBs = rDoc.GetDBCollection()->getNamedDBs();
-    for (auto& itr : rNamedDBs)
+    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 ScSplitColumnTransformationControl : public ScDataTransformationBaseControl
+{
+private:
+    VclPtr<Edit> maSeparator;
+    VclPtr<NumericField> maNumColumns;
+
+public:
+    ScSplitColumnTransformationControl(vcl::Window* pParent);
+    ~ScSplitColumnTransformationControl() override;
+
+    virtual void dispose() override;
+
+    virtual std::shared_ptr<sc::DataTransformation> getTransformation() override;
+};
+
+ScSplitColumnTransformationControl::ScSplitColumnTransformationControl(vcl::Window* pParent):
+    ScDataTransformationBaseControl(pParent, "modules/scalc/ui/splitcolumnentry.ui")
+{
+    get(maSeparator, "ed_separator");
+    get(maNumColumns, "num_cols");
+}
+
+ScSplitColumnTransformationControl::~ScSplitColumnTransformationControl()
+{
+    disposeOnce();
+}
+
+void ScSplitColumnTransformationControl::dispose()
+{
+    maSeparator.clear();
+    maNumColumns.clear();
+
+    ScDataTransformationBaseControl::dispose();
+}
+
+std::shared_ptr<sc::DataTransformation> ScSplitColumnTransformationControl::getTransformation()
+{
+    return std::make_shared<sc::SplitColumnTransformation>(0, ',');
+}
+
+class ScMergeColumnTransformationControl : public ScDataTransformationBaseControl
+{
+private:
+
+public:
+    ScMergeColumnTransformationControl(vcl::Window* pParent);
+
+    virtual std::shared_ptr<sc::DataTransformation> getTransformation() override;
+};
+
+ScMergeColumnTransformationControl::ScMergeColumnTransformationControl(vcl::Window* pParent):
+    ScDataTransformationBaseControl(pParent, "modules/scalc/ui/mergecolumnentry.ui")
+{
+}
+
+std::shared_ptr<sc::DataTransformation> ScMergeColumnTransformationControl::getTransformation()
+{
+    return std::make_shared<sc::MergeColumnTransformation>(0, 1, ",");
+}
+
+}
+
+ScDataProviderDlg::ScDataProviderDlg(vcl::Window* pParent, std::shared_ptr<ScDocument> pDoc):
+    ModalDialog(pParent, "dataproviderdlg", "modules/scalc/ui/dataproviderdlg2.ui", true),
+    mpDoc(pDoc),
+    mpBar(VclPtr<MenuBar>::Create())
+{
+    get(mpTable, "data_table");
+    get(mpList, "operation_ctrl");
+    mpTable->Init(mpDoc);
+
+    mpDataProviderCtrl = VclPtr<ScDataProviderBaseControl>::Create(mpList, LINK(this, ScDataProviderDlg, ImportHdl));
+    mpList->addEntry(mpDataProviderCtrl);
+
+    pDBData = new ScDBData("data", 0, 0, 0, MAXCOL, MAXROW);
+    bool bSuccess = mpDoc->GetDBCollection()->getNamedDBs().insert(pDBData);
+    SAL_WARN_IF(!bSuccess, "sc", "temporary warning");
+
+    InitMenu();
+}
+
+ScDataProviderDlg::~ScDataProviderDlg()
+{
+    disposeOnce();
+}
+
+void ScDataProviderDlg::dispose()
+{
+    mpDataProviderCtrl.clear();
+    mpTable.clear();
+    mpList.clear();
+    mpBar.disposeAndClear();
+
+    ModalDialog::dispose();
+}
+
+void ScDataProviderDlg::InitMenu()
+{
+    mpBar->InsertItem(MENU_START, "Start");
+    VclPtrInstance<PopupMenu> pPopup;
+    for (auto& itrStartData : aStartData)
     {
-        OUString aName = itr->GetName();
-        m_pCBData->InsertEntry(aName);
+        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<PopupMenu> 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<FixedText> mpText = VclPtr<FixedText>::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);
+}
 
-    std::vector<OUString> aDataProviders = sc::DataProviderFactory::getDataProviders();
-    for (auto& itr : aDataProviders)
+IMPL_LINK(ScDataProviderDlg, StartMenuHdl, Menu*, pMenu, bool)
+{
+    for (auto& i: aStartData)
     {
-        m_pCBProvider->InsertEntry(itr);
+        if (i.nMenuID == pMenu->GetCurItemId())
+        {
+            i.maCallback(this);
+            return true;
+        }
     }
+    return true;
 }
 
-void DataProviderDlg::StartImport()
+IMPL_LINK(ScDataProviderDlg, ColumnMenuHdl, Menu*, pMenu, bool)
 {
-    OUString aURL = m_pCbUrl->GetText();
-    if (aURL.isEmpty())
-        return;
+    for (auto& i: aColumnData)
+    {
+        if (i.nMenuID == pMenu->GetCurItemId())
+        {
+            i.maCallback(this);
+            return true;
+        }
+    }
+    return true;
+}
 
-    OUString maDBDataName = m_pCBData->GetSelectedEntry();
-    if (maDBDataName.isEmpty())
-        return;
+IMPL_LINK(ScDataProviderDlg, ImportHdl, Window*, pCtrl, void)
+{
+    if (pCtrl == mpDataProviderCtrl.get())
+    {
+        import();
+    }
+}
 
-    OUString aProvider = m_pCBProvider->GetSelectedEntry();
-    if (aProvider.isEmpty())
-        return;
+void ScDataProviderDlg::applyAndQuit()
+{
+    EndDialog(RET_OK);
+}
 
-    ScDocument& rDoc = mpDocShell->GetDocument();
-    ScDBData* pDBData = rDoc.GetDBCollection()->getNamedDBs().findByUpperName(ScGlobal::pCharClass->uppercase(maDBDataName));
-    if (!pDBData)
-        return;
+void ScDataProviderDlg::cancelAndQuit()
+{
+    EndDialog(RET_CANCEL);
+}
 
-    OUString aID = m_pEdID->GetText();
+void ScDataProviderDlg::deleteColumn()
+{
+    VclPtr<FixedText> mpText = VclPtr<FixedText>::Create(mpList);
+    mpText->SetText("Delete Column");
+    mpText->SetSizePixel(Size(400, 20));
+    mpList->addEntry(mpText);
+}
 
-    ExternalDataSource aDataSource(aURL, aProvider, &mpDocShell->GetDocument());
-    aDataSource.setID(aID);
-    aDataSource.setDBData(pDBData);
-    mpDocShell->GetDocument().GetExternalDataMapper().insertDataSource(aDataSource);
+void ScDataProviderDlg::splitColumn()
+{
+    VclPtr<ScSplitColumnTransformationControl> pSplitColumnEntry = VclPtr<ScSplitColumnTransformationControl>::Create(mpList);
+    mpList->addEntry(pSplitColumnEntry);
 }
 
+void ScDataProviderDlg::mergeColumns()
+{
+    VclPtr<ScMergeColumnTransformationControl> pMergeColumnEntry = VclPtr<ScMergeColumnTransformationControl>::Create(mpList);
+    mpList->addEntry(pMergeColumnEntry);
+}
+
+void ScDataProviderDlg::import()
+{
+    sc::ExternalDataSource aSource = mpDataProviderCtrl->getDataSource(mpDoc.get());
+    std::vector<VclPtr<vcl::Window>> aListEntries = mpList->getEntries();
+    for (size_t i = 1; i < aListEntries.size(); ++i)
+    {
+        ScDataTransformationBaseControl* pTransformationCtrl = dynamic_cast<ScDataTransformationBaseControl*>(aListEntries[i].get());
+        if (!pTransformationCtrl)
+        {
+            SAL_WARN("sc", "all children except the provider should inherit from the base control");
+            continue;
+        }
+        aSource.AddDataTransformation(pTransformationCtrl->getTransformation());
+    }
+    aSource.setDBData(pDBData);
+    aSource.refresh(mpDoc.get(), true);
+    mpTable->Invalidate();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/miscdlgs/datatableview.cxx b/sc/source/ui/miscdlgs/datatableview.cxx
index fc0e68aa363a..00359e4340e5 100644
--- a/sc/source/ui/miscdlgs/datatableview.cxx
+++ b/sc/source/ui/miscdlgs/datatableview.cxx
@@ -25,6 +25,8 @@
 #include "fillinfo.hxx"
 #include "table.hxx"
 
+#include <vcl/builderfactory.hxx>
+
 constexpr double nPPTX = 0.06666;
 constexpr double nPPTY = 0.06666;
 
@@ -32,13 +34,18 @@ constexpr sal_uInt16 nRowHeaderWidth = 100;
 constexpr sal_uInt16 nColHeaderHeight = 20;
 constexpr sal_uInt16 nScrollBarSize = 10;
 
-ScDataTableColView::ScDataTableColView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine):
+ScDataTableColView::ScDataTableColView(vcl::Window* pParent, SelectionEngine* pSelectionEngine):
         ScHeaderControl(pParent, pSelectionEngine, 1024, false, nullptr),
-        mpDoc(pDoc),
+        mpDoc(nullptr),
         mnCol(0)
 {
 }
 
+void ScDataTableColView::Init(ScDocument* pDoc)
+{
+    mpDoc = pDoc;
+}
+
 void ScDataTableColView::SetPos(SCCOLROW nCol)
 {
     mnCol = nCol;
@@ -78,13 +85,18 @@ void ScDataTableColView::HideEntries(SCCOLROW nPos, SCCOLROW nEndPos)
 }
 
 
-ScDataTableRowView::ScDataTableRowView(vcl::Window* pParent, ScDocument* pDoc, SelectionEngine* pSelectionEngine):
+ScDataTableRowView::ScDataTableRowView(vcl::Window* pParent, SelectionEngine* pSelectionEngine):
         ScHeaderControl(pParent, pSelectionEngine, 1024, true, nullptr),
-        mpDoc(pDoc),
+        mpDoc(nullptr),
         mnRow(0)
 {
 }
 
+void ScDataTableRowView::Init(ScDocument* pDoc)
+{
+    mpDoc = pDoc;
+}
+
 void ScDataTableRowView::SetPos(SCCOLROW nRow)
 {
     mnRow = nRow;
@@ -123,12 +135,11 @@ void ScDataTableRowView::HideEntries(SCCOLROW nPos, SCCOLROW nEndPos)
     }
 }
 
-ScDataTableView::ScDataTableView(vcl::Window* pParent, std::shared_ptr<ScDocument> pDoc):
+ScDataTableView::ScDataTableView(vcl::Window* pParent):
     Control(pParent),
-    mpDoc(pDoc),
     mpSelectionEngine(new SelectionEngine(this)),
-    mpColView(VclPtr<ScDataTableColView>::Create(this, mpDoc.get(), mpSelectionEngine.get())),
-    mpRowView(VclPtr<ScDataTableRowView>::Create(this, mpDoc.get(), mpSelectionEngine.get())),
+    mpColView(VclPtr<ScDataTableColView>::Create(this, mpSelectionEngine.get())),
+    mpRowView(VclPtr<ScDataTableRowView>::Create(this, mpSelectionEngine.get())),
     mpVScroll(VclPtr<ScrollBar>::Create(this, WinBits(WB_VSCROLL | WB_DRAG))),
     mpHScroll(VclPtr<ScrollBar>::Create(this, WinBits(WB_HSCROLL | WB_DRAG))),
     mnFirstVisibleRow(0),
@@ -151,6 +162,15 @@ ScDataTableView::ScDataTableView(vcl::Window* pParent, std::shared_ptr<ScDocumen
     mpHScroll->Show();
 }
 
+void ScDataTableView::Init(std::shared_ptr<ScDocument> pDoc)
+{
+    mpDoc = pDoc;
+    mpColView->Init(mpDoc.get());
+    mpRowView->Init(mpDoc.get());
+}
+
+VCL_BUILDER_FACTORY(ScDataTableView)
+
 ScDataTableView::~ScDataTableView()
 {
     disposeOnce();
@@ -261,6 +281,11 @@ void ScDataTableView::Paint(vcl::RenderContext& rRenderContext, const tools::Rec
     Control::Paint(rRenderContext, rRectangle);
 }
 
+Size ScDataTableView::GetOptimalSize() const
+{
+    return Size(600, 200);
+}
+
 IMPL_LINK(ScDataTableView, ScrollHdl, ScrollBar*, pScrollBar, void)
 {
     if (pScrollBar == mpVScroll.get())
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index ff98bff748b2..6cc144191db4 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -783,10 +783,12 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
         break;
         case SID_DATA_PROVIDER:
         {
-            ScopedVclPtrInstance< sc::DataProviderDlg > aDialog( GetViewData()->GetDocShell(), pTabViewShell->GetDialogParent() );
+            std::shared_ptr<ScDocument> pDoc = std::make_shared<ScDocument>();
+            pDoc->InsertTab(0, "test");
+            ScopedVclPtrInstance< ScDataProviderDlg > aDialog( pTabViewShell->GetDialogParent(), pDoc);
             if (aDialog->Execute() == RET_OK)
             {
-                aDialog->StartImport();
+                // handle the import here
             }
         }
         break;
diff --git a/sc/uiconfig/scalc/ui/dataproviderdlg.ui b/sc/uiconfig/scalc/ui/dataproviderdlg.ui
new file mode 100644
index 000000000000..dc97cb8fa2ec
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/dataproviderdlg.ui
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface domain="sc">
+  <requires lib="gtk+" version="3.20"/>
+  <requires lib="LibreOffice" version="1.0"/>
+  <object class="GtkWindow" id="dataproviderdlg">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <child>
+          <object class="sclo-ScDataTableView" id="data_table">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <object class="GtkListBox" id="operation_ctrl">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/sc/uiconfig/scalc/ui/dataproviderentry.ui b/sc/uiconfig/scalc/ui/dataproviderentry.ui
new file mode 100644
index 000000000000..cd1cba78db66
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/dataproviderentry.ui
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface domain="sc">
+  <requires lib="gtk+" version="3.0"/>
+  <object class="GtkGrid" id="grid">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="border_width">6</property>
+    <property name="row_spacing">6</property>
+    <property name="column_spacing">12</property>
+    <child>
+      <object class="GtkComboBox" id="provider_lst">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="ed_url">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="ed_id">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">3</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes" context="dataproviderentry|url">URL:</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes" context="dataproviderentry|id">ID:</property>
+      </object>
+      <packing>
+        <property name="left_attach">2</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes" context="dataproviderentry|provider">Data Provider:</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+  </object>
+</interface>
diff --git a/sc/uiconfig/scalc/ui/splitcolumnentry.ui b/sc/uiconfig/scalc/ui/splitcolumnentry.ui
new file mode 100644
index 000000000000..f9f9248cb74c
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/splitcolumnentry.ui
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface domain="sc">
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkGrid" id="grid">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="border_width">6</property>
+    <property name="row_spacing">6</property>
+    <property name="column_spacing">12</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes" context="splitcolumnentry|name">Split Column Action</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkGrid" id="grid_details">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes" context="splitcolumnentry|separator">Separator:</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes" context="splitcolumnentry|max_num_columns">Maximum Number of Columns</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="ed_separator">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSpinButton" id="num_cols">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="input_purpose">digits</property>
+                <property name="climb_rate">1</property>
+                <property name="numeric">True</property>
+                <property name="value">-1</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+  </object>
+</interface>


More information about the Libreoffice-commits mailing list