summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--formula/source/ui/dlg/formula.cxx21
-rw-r--r--formula/source/ui/dlg/funcutl.cxx180
-rw-r--r--include/formula/IControlReferenceHandler.hxx4
-rw-r--r--include/formula/formula.hxx4
-rw-r--r--include/formula/funcutl.hxx102
-rw-r--r--include/sfx2/basedlgs.hxx3
-rw-r--r--include/vcl/weld.hxx5
-rw-r--r--reportdesign/source/ui/dlg/Formula.cxx9
-rw-r--r--reportdesign/source/ui/inc/Formula.hxx2
-rw-r--r--sc/inc/scmod.hxx5
-rw-r--r--sc/source/ui/StatisticsDialogs/CorrelationDialog.cxx10
-rw-r--r--sc/source/ui/StatisticsDialogs/MatrixComparisonGenerator.cxx71
-rw-r--r--sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx277
-rw-r--r--sc/source/ui/app/scmod.cxx112
-rw-r--r--sc/source/ui/formdlg/formula.cxx16
-rw-r--r--sc/source/ui/inc/ChildWindowWrapper.hxx61
-rw-r--r--sc/source/ui/inc/CorrelationDialog.hxx6
-rw-r--r--sc/source/ui/inc/IAnyRefDialog.hxx1
-rw-r--r--sc/source/ui/inc/MatrixComparisonGenerator.hxx18
-rw-r--r--sc/source/ui/inc/StatisticsInputOutputDialog.hxx72
-rw-r--r--sc/source/ui/inc/anyrefdg.hxx88
-rw-r--r--sc/source/ui/inc/formula.hxx3
-rw-r--r--sc/source/ui/inc/reffact.hxx2
-rw-r--r--sc/source/ui/inc/tabvwsh.hxx4
-rw-r--r--sc/source/ui/inc/validate.hxx5
-rw-r--r--sc/source/ui/miscdlgs/anyrefdg.cxx235
-rw-r--r--sc/source/ui/view/tabvwshc.cxx45
-rw-r--r--sc/uiconfig/scalc/ui/correlationdialog.ui19
-rw-r--r--solenv/sanitizers/ui/modules/scalc.suppr2
-rw-r--r--vcl/source/app/salvtables.cxx94
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx109
31 files changed, 1498 insertions, 87 deletions
diff --git a/formula/source/ui/dlg/formula.cxx b/formula/source/ui/dlg/formula.cxx
index 68120f6bbd51..e7c5fede138d 100644
--- a/formula/source/ui/dlg/formula.cxx
+++ b/formula/source/ui/dlg/formula.cxx
@@ -77,6 +77,8 @@ class FormulaDlg_Impl
public:
::std::pair<RefButton*, RefEdit*>
RefInputStartBefore( RefEdit* pEdit, RefButton* pButton );
+ static ::std::pair<WeldRefButton*, WeldRefEdit*>
+ RefInputStartBefore( WeldRefEdit* pEdit, WeldRefButton* pButton );
void RefInputStartAfter();
void RefInputDoneAfter( bool bForced );
bool CalcValue( const OUString& rStrExp, OUString& rStrResult, bool bForceMatrixFormula = false );
@@ -1522,6 +1524,15 @@ void FormulaDlg_Impl::UpdateSelection()
return aPair;
}
+::std::pair<WeldRefButton*, WeldRefEdit*> FormulaDlg_Impl::RefInputStartBefore( WeldRefEdit* pEdit, WeldRefButton* pButton )
+{
+ assert(!pEdit && !pButton);
+ ::std::pair<WeldRefButton*, WeldRefEdit*> aPair;
+ aPair.first = pButton;
+ aPair.second = pEdit;
+ return aPair;
+}
+
void FormulaDlg_Impl::RefInputStartAfter()
{
m_pRefBtn->SetEndImage();
@@ -1779,6 +1790,11 @@ void FormulaModalDialog::Update()
return m_pImpl->RefInputStartBefore( pEdit, pButton );
}
+::std::pair<WeldRefButton*, WeldRefEdit*> FormulaModalDialog::RefInputStartBefore( WeldRefEdit* pEdit, WeldRefButton* pButton )
+{
+ return formula::FormulaDlg_Impl::RefInputStartBefore(pEdit, pButton);
+}
+
void FormulaModalDialog::RefInputStartAfter()
{
m_pImpl->RefInputStartAfter();
@@ -1868,6 +1884,11 @@ void FormulaDlg::DoEnter()
return m_pImpl->RefInputStartBefore( pEdit, pButton );
}
+::std::pair<WeldRefButton*, WeldRefEdit*> FormulaDlg::RefInputStartBefore( WeldRefEdit* pEdit, WeldRefButton* pButton )
+{
+ return formula::FormulaDlg_Impl::RefInputStartBefore(pEdit, pButton);
+}
+
void FormulaDlg::RefInputStartAfter()
{
m_pImpl->RefInputStartAfter();
diff --git a/formula/source/ui/dlg/funcutl.cxx b/formula/source/ui/dlg/funcutl.cxx
index 9499992b6b7e..47c3d408d63e 100644
--- a/formula/source/ui/dlg/funcutl.cxx
+++ b/formula/source/ui/dlg/funcutl.cxx
@@ -517,6 +517,112 @@ IMPL_LINK_NOARG(RefEdit, UpdateHdl, Timer *, void)
pAnyRefDlg->ShowReference( GetText() );
}
+// class RefEdit
+
+WeldRefEdit::WeldRefEdit(std::unique_ptr<weld::Entry> xControl)
+ : xEntry(std::move(xControl))
+ , aIdle("formula RefEdit Idle")
+ , pAnyRefDlg(nullptr)
+ , pLabelWidget(nullptr)
+{
+ xEntry->connect_focus_in(LINK(this, WeldRefEdit, GetFocus));
+ xEntry->connect_focus_out(LINK(this, WeldRefEdit, LoseFocus));
+ xEntry->connect_key_press(LINK(this, WeldRefEdit, KeyInput));
+ xEntry->connect_changed(LINK(this, WeldRefEdit, Modify));
+ aIdle.SetInvokeHandler( LINK( this, WeldRefEdit, UpdateHdl ) );
+}
+
+WeldRefEdit::~WeldRefEdit()
+{
+ aIdle.ClearInvokeHandler();
+ aIdle.Stop();
+}
+
+void WeldRefEdit::SetRefString( const OUString& rStr )
+{
+ // Prevent unwanted side effects by setting only a differing string.
+ // See commit message for reasons.
+ if (xEntry->get_text() != rStr)
+ xEntry->set_text(rStr);
+}
+
+void WeldRefEdit::SetRefValid(bool bValid)
+{
+ xEntry->set_error(!bValid);
+}
+
+void WeldRefEdit::SetText(const OUString& rStr)
+{
+ xEntry->set_text(rStr);
+ UpdateHdl( &aIdle );
+}
+
+void WeldRefEdit::StartUpdateData()
+{
+ aIdle.Start();
+}
+
+void WeldRefEdit::SetReferences(IControlReferenceHandler* pDlg, weld::Label* pLabel)
+{
+ pAnyRefDlg = pDlg;
+ pLabelWidget = pLabel;
+
+ if( pDlg )
+ {
+ aIdle.SetInvokeHandler(LINK(this, WeldRefEdit, UpdateHdl));
+ }
+ else
+ {
+ aIdle.ClearInvokeHandler();
+ aIdle.Stop();
+ }
+}
+
+IMPL_LINK_NOARG(WeldRefEdit, Modify, weld::Entry&, void)
+{
+ maModifyHdl.Call(*this);
+ if (pAnyRefDlg)
+ pAnyRefDlg->HideReference();
+}
+
+IMPL_LINK(WeldRefEdit, KeyInput, const KeyEvent&, rKEvt, bool)
+{
+ const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ if (pAnyRefDlg && !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_F2)
+ {
+ pAnyRefDlg->ReleaseFocus( this );
+ return true;
+ }
+
+ switch (rKeyCode.GetCode())
+ {
+ case KEY_RETURN:
+ case KEY_ESCAPE:
+ return maActivateHdl.Call(*GetWidget());
+ }
+
+ return false;
+}
+
+IMPL_LINK_NOARG(WeldRefEdit, GetFocus, weld::Widget&, void)
+{
+ maGetFocusHdl.Call(*this);
+ StartUpdateData();
+}
+
+IMPL_LINK_NOARG(WeldRefEdit, LoseFocus, weld::Widget&, void)
+{
+ maLoseFocusHdl.Call(*this);
+ if( pAnyRefDlg )
+ pAnyRefDlg->HideReference();
+}
+
+IMPL_LINK_NOARG(WeldRefEdit, UpdateHdl, Timer *, void)
+{
+ if( pAnyRefDlg )
+ pAnyRefDlg->ShowReference(xEntry->get_text());
+}
+
//class RefButton
RefButton::RefButton( vcl::Window* _pParent, WinBits nStyle ) :
ImageButton(_pParent, nStyle),
@@ -590,6 +696,80 @@ void RefButton::LoseFocus()
pRefEdit->Modify();
}
+//class RefButton
+WeldRefButton::WeldRefButton(std::unique_ptr<weld::Button> xControl)
+ : xButton(std::move(xControl))
+ , pAnyRefDlg( nullptr )
+ , pRefEdit( nullptr )
+{
+ xButton->connect_focus_in(LINK(this, WeldRefButton, GetFocus));
+ xButton->connect_focus_out(LINK(this, WeldRefButton, LoseFocus));
+ xButton->connect_key_press(LINK(this, WeldRefButton, KeyInput));
+ xButton->connect_clicked(LINK(this, WeldRefButton, Click));
+ SetStartImage();
+}
+
+WeldRefButton::~WeldRefButton()
+{
+}
+
+void WeldRefButton::SetStartImage()
+{
+ xButton->set_from_icon_name(RID_BMP_REFBTN1);
+ xButton->set_tooltip_text(ForResId(RID_STR_SHRINK));
+}
+
+void WeldRefButton::SetEndImage()
+{
+ xButton->set_from_icon_name(RID_BMP_REFBTN2);
+ xButton->set_tooltip_text(ForResId(RID_STR_EXPAND));
+}
+
+void WeldRefButton::SetReferences( IControlReferenceHandler* pDlg, WeldRefEdit* pEdit )
+{
+ pAnyRefDlg = pDlg;
+ pRefEdit = pEdit;
+}
+
+IMPL_LINK_NOARG(WeldRefButton, Click, weld::Button&, void)
+{
+ if( pAnyRefDlg )
+ pAnyRefDlg->ToggleCollapsed( pRefEdit, this );
+}
+
+IMPL_LINK(WeldRefButton, KeyInput, const KeyEvent&, rKEvt, bool)
+{
+ const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ if (pAnyRefDlg && !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_F2)
+ {
+ pAnyRefDlg->ReleaseFocus( pRefEdit );
+ return true;
+ }
+
+ switch (rKeyCode.GetCode())
+ {
+ case KEY_RETURN:
+ case KEY_ESCAPE:
+ return maActivateHdl.Call(*GetWidget());
+ }
+
+ return false;
+}
+
+IMPL_LINK_NOARG(WeldRefButton, GetFocus, weld::Widget&, void)
+{
+ maGetFocusHdl.Call(*this);
+ if (pRefEdit)
+ pRefEdit->StartUpdateData();
+}
+
+IMPL_LINK_NOARG(WeldRefButton, LoseFocus, weld::Widget&, void)
+{
+ maLoseFocusHdl.Call(*this);
+ if (pRefEdit)
+ pRefEdit->DoModify();
+}
+
} // formula
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/IControlReferenceHandler.hxx b/include/formula/IControlReferenceHandler.hxx
index e1096c47ae38..f73a7618d346 100644
--- a/include/formula/IControlReferenceHandler.hxx
+++ b/include/formula/IControlReferenceHandler.hxx
@@ -26,14 +26,18 @@
namespace formula
{
class RefEdit;
+ class WeldRefEdit;
class RefButton;
+ class WeldRefButton;
class FORMULA_DLLPUBLIC SAL_NO_VTABLE IControlReferenceHandler
{
public:
virtual void ShowReference(const OUString& _sRef) = 0;
virtual void HideReference( bool bDoneRefMode = true ) = 0;
virtual void ReleaseFocus( RefEdit* pEdit ) = 0;
+ virtual void ReleaseFocus( WeldRefEdit* pEdit ) = 0;
virtual void ToggleCollapsed( RefEdit* pEdit, RefButton* pButton ) = 0;
+ virtual void ToggleCollapsed( WeldRefEdit* pEdit, WeldRefButton* pButton ) = 0;
protected:
~IControlReferenceHandler() {}
diff --git a/include/formula/formula.hxx b/include/formula/formula.hxx
index 201a598891e4..defd1ecfd1a8 100644
--- a/include/formula/formula.hxx
+++ b/include/formula/formula.hxx
@@ -56,7 +56,9 @@ class FormulaDlg_Impl;
class IControlReferenceHandler;
class FormulaHelper;
class RefEdit;
+class WeldRefEdit;
class RefButton;
+class WeldRefButton;
class FormEditData;
class FORMULA_DLLPUBLIC FormulaModalDialog : public ModalDialog, public formula::IFormulaEditorHelper
@@ -76,6 +78,7 @@ protected:
virtual bool PreNotify( NotifyEvent& rNEvt ) override;
::std::pair<RefButton*,RefEdit*> RefInputStartBefore( RefEdit* pEdit, RefButton* pButton );
+ static ::std::pair<WeldRefButton*,WeldRefEdit*> RefInputStartBefore( WeldRefEdit* pEdit, WeldRefButton* pButton );
void RefInputStartAfter();
void RefInputDoneAfter();
@@ -110,6 +113,7 @@ protected:
virtual bool PreNotify( NotifyEvent& rNEvt ) override;
::std::pair<RefButton*,RefEdit*> RefInputStartBefore( RefEdit* pEdit, RefButton* pButton );
+ static ::std::pair<WeldRefButton*,WeldRefEdit*> RefInputStartBefore( WeldRefEdit* pEdit, WeldRefButton* pButton );
void RefInputStartAfter();
void RefInputDoneAfter( bool bForced );
diff --git a/include/formula/funcutl.hxx b/include/formula/funcutl.hxx
index 0a4c25d1236c..5a6c095db77e 100644
--- a/include/formula/funcutl.hxx
+++ b/include/formula/funcutl.hxx
@@ -28,6 +28,7 @@
#include <vcl/edit.hxx>
#include <vcl/idle.hxx>
#include <vcl/image.hxx>
+#include <vcl/weld.hxx>
#include <vcl/vclptr.hxx>
class KeyEvent;
@@ -83,6 +84,74 @@ public:
}
};
+class FORMULA_DLLPUBLIC WeldRefEdit
+{
+private:
+ std::unique_ptr<weld::Entry> xEntry;
+ Idle aIdle;
+ IControlReferenceHandler* pAnyRefDlg; // parent dialog
+ weld::Label* pLabelWidget;
+ Link<WeldRefEdit&,void> maGetFocusHdl;
+ Link<WeldRefEdit&,void> maLoseFocusHdl;
+ Link<WeldRefEdit&,void> maModifyHdl;
+ Link<weld::Widget&,bool> maActivateHdl;
+
+ DECL_LINK( UpdateHdl, Timer*, void );
+
+protected:
+ DECL_LINK(KeyInput, const KeyEvent&, bool);
+ DECL_LINK(GetFocus, weld::Widget&, void);
+ DECL_LINK(LoseFocus, weld::Widget&, void);
+ DECL_LINK(Modify, weld::Entry&, void);
+
+public:
+ WeldRefEdit(std::unique_ptr<weld::Entry> xControl);
+ weld::Widget* GetWidget() const { return xEntry.get(); }
+ ~WeldRefEdit();
+
+ void SetRefString( const OUString& rStr );
+
+ /**
+ * Flag reference valid or invalid, which in turn changes the visual
+ * appearance of the control accordingly.
+ */
+ void SetRefValid(bool bValid);
+
+ void SetText(const OUString& rStr);
+ OUString GetText() const
+ {
+ return xEntry->get_text();
+ }
+
+ void StartUpdateData();
+
+ void SetReferences( IControlReferenceHandler* pDlg, weld::Label *pLabelWidget );
+
+ void DoModify()
+ {
+ Modify(*xEntry);
+ }
+
+ void GrabFocus()
+ {
+ xEntry->grab_focus();
+ }
+
+ void SelectAll()
+ {
+ xEntry->select_region(0, -1);
+ }
+
+ weld::Label* GetLabelWidgetForShrinkMode()
+ {
+ return pLabelWidget;
+ }
+
+ void SetGetFocusHdl(const Link<WeldRefEdit&,void>& rLink) { maGetFocusHdl = rLink; }
+ void SetLoseFocusHdl(const Link<WeldRefEdit&,void>& rLink) { maLoseFocusHdl = rLink; }
+ void SetModifyHdl(const Link<WeldRefEdit&,void>& rLink) { maModifyHdl = rLink; }
+ void SetActivateHdl(const Link<weld::Widget&,bool>& rLink) { maActivateHdl = rLink; }
+};
class FORMULA_DLLPUBLIC RefButton : public ImageButton
{
@@ -113,6 +182,39 @@ public:
}
};
+class FORMULA_DLLPUBLIC WeldRefButton
+{
+private:
+ std::unique_ptr<weld::Button> xButton;
+ IControlReferenceHandler* pAnyRefDlg; // parent dialog
+ WeldRefEdit* pRefEdit; // associated Edit-Control
+ Link<WeldRefButton&,void> maGetFocusHdl;
+ Link<WeldRefButton&,void> maLoseFocusHdl;
+ Link<weld::Widget&,bool> maActivateHdl;
+
+protected:
+ DECL_LINK(Click, weld::Button&, void);
+ DECL_LINK(KeyInput, const KeyEvent&, bool);
+ DECL_LINK(GetFocus, weld::Widget&, void);
+ DECL_LINK(LoseFocus, weld::Widget&, void);
+
+public:
+ WeldRefButton(std::unique_ptr<weld::Button> xControl);
+ weld::Widget* GetWidget() const { return xButton.get(); }
+ ~WeldRefButton();
+ void SetReferences(IControlReferenceHandler* pDlg, WeldRefEdit* pEdit);
+ void SetStartImage();
+ void SetEndImage();
+ void DoRef()
+ {
+ Click(*xButton);
+ }
+ void SetGetFocusHdl(const Link<WeldRefButton&,void>& rLink) { maGetFocusHdl = rLink; }
+ void SetLoseFocusHdl(const Link<WeldRefButton&,void>& rLink) { maLoseFocusHdl = rLink; }
+ void SetActivateHdl(const Link<weld::Widget&,bool>& rLink) { maActivateHdl = rLink; }
+};
+
+
} // formula
#endif // INCLUDED_FORMULA_FUNCUTL_HXX
diff --git a/include/sfx2/basedlgs.hxx b/include/sfx2/basedlgs.hxx
index 7a29b9f1bd02..6706010c6c51 100644
--- a/include/sfx2/basedlgs.hxx
+++ b/include/sfx2/basedlgs.hxx
@@ -139,9 +139,10 @@ class SFX2_DLLPUBLIC SfxModelessDialogController : public SfxDialogController
protected:
SfxModelessDialogController(SfxBindings*, SfxChildWindow* pChildWin,
weld::Window* pParent, const OUString& rUIXMLDescription, const OString& rID);
- virtual ~SfxModelessDialogController() override;
public:
+ virtual ~SfxModelessDialogController() override;
+
void Initialize (SfxChildWinInfo const * pInfo);
bool IsClosing() const;
virtual void Close() override;
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 3b2fea407aec..2a7511b419fc 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -383,6 +383,11 @@ public:
virtual Button* get_widget_for_response(int response) = 0;
virtual Container* weld_content_area() = 0;
+ // shrink the dialog down to shown just these widgets
+ virtual void collapse(weld::Widget* pEdit, weld::Widget* pButton) = 0;
+ // undo previous dialog collapse
+ virtual void undo_collapse() = 0;
+
virtual void SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink)
= 0;
};
diff --git a/reportdesign/source/ui/dlg/Formula.cxx b/reportdesign/source/ui/dlg/Formula.cxx
index 3e3d5f03206f..ac91552c351d 100644
--- a/reportdesign/source/ui/dlg/Formula.cxx
+++ b/reportdesign/source/ui/dlg/Formula.cxx
@@ -201,6 +201,10 @@ void FormulaDialog::ReleaseFocus( RefEdit* /*pEdit*/)
{
}
+void FormulaDialog::ReleaseFocus( WeldRefEdit* /*pEdit*/)
+{
+}
+
void FormulaDialog::ToggleCollapsed( RefEdit* _pEdit, RefButton* _pButton)
{
::std::pair<RefButton*,RefEdit*> aPair = RefInputStartBefore( _pEdit, _pButton );
@@ -228,6 +232,11 @@ void FormulaDialog::ToggleCollapsed( RefEdit* _pEdit, RefButton* _pButton)
}
+void FormulaDialog::ToggleCollapsed( WeldRefEdit* /*_pEdit*/, WeldRefButton* /*_pButton*/)
+{
+ assert(false);
+}
+
IMPL_LINK( FormulaDialog, OnClickHdl, OAddFieldWindow& ,_rAddFieldDlg, void)
{
const uno::Sequence< beans::PropertyValue > aArgs = _rAddFieldDlg.getSelectedFieldDescriptors();
diff --git a/reportdesign/source/ui/inc/Formula.hxx b/reportdesign/source/ui/inc/Formula.hxx
index 68c20917af4f..e28438325329 100644
--- a/reportdesign/source/ui/inc/Formula.hxx
+++ b/reportdesign/source/ui/inc/Formula.hxx
@@ -101,7 +101,9 @@ public:
virtual void ShowReference(const OUString& _sRef) override;
virtual void HideReference( bool bDoneRefMode = true ) override;
virtual void ReleaseFocus( formula::RefEdit* pEdit ) override;
+ virtual void ReleaseFocus( formula::WeldRefEdit* pEdit ) override;
virtual void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton ) override;
+ virtual void ToggleCollapsed( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton ) override;
};
diff --git a/sc/inc/scmod.hxx b/sc/inc/scmod.hxx
index 883da0ba9be6..2a3fbc04b748 100644
--- a/sc/inc/scmod.hxx
+++ b/sc/inc/scmod.hxx
@@ -75,6 +75,7 @@ class ScSelectionTransferObj;
class ScFormEditData;
class ScMarkData;
struct ScDragData;
+class SfxModelessDialogController;
class ScModule: public SfxModule, public SfxListener, public utl::ConfigurationListener
{
@@ -108,6 +109,7 @@ class ScModule: public SfxModule, public SfxListener, public utl::ConfigurationL
bool m_bIsInSharedDocSaving:1;
std::map<sal_uInt16, std::vector<VclPtr<vcl::Window> > > m_mapRefWindow;
+ std::map<sal_uInt16, std::vector<SfxModelessDialogController*>> m_mapRefController;
css::uno::Reference< ooo::vba::XSinkCaller > mxAutomationApplicationEventsCaller;
@@ -250,6 +252,9 @@ public:
SC_DLLPUBLIC void UnregisterRefWindow( sal_uInt16 nSlotId, vcl::Window *pWnd );
SC_DLLPUBLIC vcl::Window * Find1RefWindow( sal_uInt16 nSlotId, vcl::Window *pWndAncestor );
+ SC_DLLPUBLIC void RegisterRefController( sal_uInt16 nSlotId, SfxModelessDialogController *pWnd );
+ SC_DLLPUBLIC void UnregisterRefController( sal_uInt16 nSlotId, SfxModelessDialogController *pWnd );
+
SC_DLLPUBLIC void RegisterAutomationApplicationEventsCaller(css::uno::Reference< ooo::vba::XSinkCaller > const& xCaller);
SC_DLLPUBLIC void CallAutomationApplicationEventSinks(const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments);
};
diff --git a/sc/source/ui/StatisticsDialogs/CorrelationDialog.cxx b/sc/source/ui/StatisticsDialogs/CorrelationDialog.cxx
index c7a8a7be932e..d1463f608b3d 100644
--- a/sc/source/ui/StatisticsDialogs/CorrelationDialog.cxx
+++ b/sc/source/ui/StatisticsDialogs/CorrelationDialog.cxx
@@ -15,15 +15,15 @@
ScCorrelationDialog::ScCorrelationDialog(
SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
- vcl::Window* pParent, ScViewData* pViewData ) :
- ScMatrixComparisonGenerator(
+ weld::Window* pParent, ScViewData* pViewData ) :
+ ScMatrixComparisonGeneratorController(
pSfxBindings, pChildWindow, pParent, pViewData,
- "CorrelationDialog", "modules/scalc/ui/correlationdialog.ui" )
+ "modules/scalc/ui/correlationdialog.ui", "CorrelationDialog")
{}
-bool ScCorrelationDialog::Close()
+void ScCorrelationDialog::Close()
{
- return DoClose( ScCorrelationDialogWrapper::GetChildWindowId() );
+ DoClose(ScCorrelationDialogWrapper::GetChildWindowId());
}
const OUString ScCorrelationDialog::getLabel()
diff --git a/sc/source/ui/StatisticsDialogs/MatrixComparisonGenerator.cxx b/sc/source/ui/StatisticsDialogs/MatrixComparisonGenerator.cxx
index d5aa05933f24..487602fe8a1a 100644
--- a/sc/source/ui/StatisticsDialogs/MatrixComparisonGenerator.cxx
+++ b/sc/source/ui/StatisticsDialogs/MatrixComparisonGenerator.cxx
@@ -109,4 +109,75 @@ ScRange ScMatrixComparisonGenerator::ApplyOutput(ScDocShell* pDocShell)
return ScRange(output.mMinimumAddress, output.mMaximumAddress);
}
+ScMatrixComparisonGeneratorController::ScMatrixComparisonGeneratorController(
+ SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
+ weld::Window* pParent, ScViewData* pViewData,
+ const OUString& rUiXmlDescription,
+ const OString& rID)
+ : ScStatisticsInputOutputDialogController(pSfxBindings, pChildWindow, pParent, pViewData, rUiXmlDescription, rID)
+{}
+
+ScMatrixComparisonGeneratorController::~ScMatrixComparisonGeneratorController()
+{}
+
+const char* ScMatrixComparisonGeneratorController::GetUndoNameId()
+{
+ return STR_CORRELATION_UNDO_NAME;
+}
+
+ScRange ScMatrixComparisonGeneratorController::ApplyOutput(ScDocShell* pDocShell)
+{
+ AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument,
+ formula::FormulaGrammar::mergeToGrammar( formula::FormulaGrammar::GRAM_ENGLISH, mAddressDetails.eConv));
+ FormulaTemplate aTemplate(mDocument);
+
+ SCTAB inTab = mInputRange.aStart.Tab();
+
+ ScRangeList aRangeList = (mGroupedBy == BY_COLUMN) ?
+ MakeColumnRangeList(inTab, mInputRange.aStart, mInputRange.aEnd) :
+ MakeRowRangeList(inTab, mInputRange.aStart, mInputRange.aEnd);
+
+ // labels
+ output.writeString(getLabel());
+ output.nextColumn();
+
+ const OUString strWildcardNumber("%NUMBER%");
+
+ // write labels to columns
+ for (size_t i = 0; i < aRangeList.size(); i++)
+ {
+ if (mGroupedBy == BY_COLUMN)
+ aTemplate.setTemplate(ScResId(STR_COLUMN_LABEL_TEMPLATE));
+ else
+ aTemplate.setTemplate(ScResId(STR_ROW_LABEL_TEMPLATE));
+
+ aTemplate.applyNumber(strWildcardNumber, i + 1);
+ output.writeString(aTemplate.getTemplate());
+ output.nextColumn();
+ }
+
+ // write labels to rows
+ output.resetColumn();
+ output.nextRow();
+ for (size_t i = 0; i < aRangeList.size(); i++)
+ {
+ if (mGroupedBy == BY_COLUMN)
+ aTemplate.setTemplate(ScResId(STR_COLUMN_LABEL_TEMPLATE));
+ else
+ aTemplate.setTemplate(ScResId(STR_ROW_LABEL_TEMPLATE));
+
+ aTemplate.applyNumber(strWildcardNumber, i + 1);
+ output.writeString(aTemplate.getTemplate());
+ output.nextRow();
+ }
+
+ // write correlation formulas
+ output.reset();
+ output.push(1, 1);
+
+ lclWriteCorrelationFormulas(output, aTemplate, aRangeList, getTemplate());
+
+ return ScRange(output.mMinimumAddress, output.mMaximumAddress);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx b/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx
index 8d630ebc7e63..a55e34092edc 100644
--- a/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx
+++ b/sc/source/ui/StatisticsDialogs/StatisticsInputOutputDialog.cxx
@@ -296,4 +296,281 @@ void ScStatisticsInputOutputDialog::ValidateDialogInput()
mpButtonOk->Disable();
}
+ScRangeList ScStatisticsInputOutputDialogController::MakeColumnRangeList(SCTAB aTab, ScAddress const & aStart, ScAddress const & aEnd)
+{
+ ScRangeList aRangeList;
+ for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++)
+ {
+ ScRange aColumnRange (
+ ScAddress(inCol, aStart.Row(), aTab),
+ ScAddress(inCol, aEnd.Row(), aTab) );
+
+ aRangeList.push_back(aColumnRange);
+ }
+ return aRangeList;
+}
+
+ScRangeList ScStatisticsInputOutputDialogController::MakeRowRangeList(SCTAB aTab, ScAddress const & aStart, ScAddress const & aEnd)
+{
+ ScRangeList aRangeList;
+ for (SCROW inRow = aStart.Row(); inRow <= aEnd.Row(); inRow++)
+ {
+ ScRange aRowRange (
+ ScAddress(aStart.Col(), inRow, aTab),
+ ScAddress(aEnd.Col(), inRow, aTab) );
+
+ aRangeList.push_back(aRowRange);
+ }
+ return aRangeList;
+}
+
+ScStatisticsInputOutputDialogController::ScStatisticsInputOutputDialogController(
+ SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
+ weld::Window* pParent, ScViewData* pViewData, const OUString& rUIXMLDescription, const OString& rID)
+ : ScAnyRefDlgController(pSfxBindings, pChildWindow, pParent, rUIXMLDescription, rID)
+ , mxInputRangeLabel(m_xBuilder->weld_label("input-range-label"))
+ , mxInputRangeEdit(new formula::WeldRefEdit(m_xBuilder->weld_entry("input-range-edit")))
+ , mxInputRangeButton(new formula::WeldRefButton(m_xBuilder->weld_button("input-range-button")))
+ , mxOutputRangeLabel(m_xBuilder->weld_label("output-range-label"))
+ , mxOutputRangeEdit(new formula::WeldRefEdit(m_xBuilder->weld_entry("output-range-edit")))
+ , mxOutputRangeButton(new formula::WeldRefButton(m_xBuilder->weld_button("output-range-button")))
+ , mxGroupByColumnsRadio(m_xBuilder->weld_radio_button("groupedby-columns-radio"))
+ , mxGroupByRowsRadio(m_xBuilder->weld_radio_button("groupedby-rows-radio"))
+ , mViewData(pViewData)
+ , mDocument(pViewData->GetDocument())
+ , mInputRange(ScAddress::INITIALIZE_INVALID)
+ , mAddressDetails(mDocument->GetAddressConvention(), 0, 0)
+ , mOutputAddress(ScAddress::INITIALIZE_INVALID)
+ , mGroupedBy(BY_COLUMN)
+ , mxButtonOk(m_xBuilder->weld_button("ok"))
+ , mpActiveEdit(nullptr)
+ , mCurrentAddress(pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo())
+ , mDialogLostFocus(false)
+{
+ mxInputRangeEdit->SetReferences(this, mxInputRangeLabel.get());
+ mxInputRangeButton->SetReferences(this, mxInputRangeEdit.get());
+
+ mxOutputRangeEdit->SetReferences(this, mxOutputRangeLabel.get());
+ mxOutputRangeButton->SetReferences(this, mxOutputRangeEdit.get());
+
+ Init();
+ GetRangeFromSelection();
+}
+
+ScStatisticsInputOutputDialogController::~ScStatisticsInputOutputDialogController()
+{
+}
+
+void ScStatisticsInputOutputDialogController::Init()
+{
+ mxButtonOk->connect_clicked( LINK( this, ScStatisticsInputOutputDialogController, OkClicked ) );
+ mxButtonOk->set_sensitive(false);
+
+ Link<formula::WeldRefEdit&,void> aEditLink = LINK( this, ScStatisticsInputOutputDialogController, GetEditFocusHandler );
+ mxInputRangeEdit->SetGetFocusHdl( aEditLink );
+ mxOutputRangeEdit->SetGetFocusHdl( aEditLink );
+ Link<formula::WeldRefButton&,void> aButtonLink = LINK( this, ScStatisticsInputOutputDialogController, GetButtonFocusHandler );
+ mxInputRangeButton->SetGetFocusHdl( aButtonLink );
+ mxOutputRangeButton->SetGetFocusHdl( aButtonLink );
+
+ aEditLink = LINK( this, ScStatisticsInputOutputDialogController, LoseEditFocusHandler );
+ mxInputRangeEdit->SetLoseFocusHdl( aEditLink );
+ mxOutputRangeEdit->SetLoseFocusHdl( aEditLink );
+ aButtonLink = LINK( this, ScStatisticsInputOutputDialogController, LoseButtonFocusHandler );
+ mxInputRangeButton->SetLoseFocusHdl( aButtonLink );
+ mxOutputRangeButton->SetLoseFocusHdl( aButtonLink );
+
+ Link<formula::WeldRefEdit&,void> aLink2 = LINK( this, ScStatisticsInputOutputDialogController, RefInputModifyHandler);
+ mxInputRangeEdit->SetModifyHdl( aLink2);
+ mxOutputRangeEdit->SetModifyHdl( aLink2);
+
+ mxOutputRangeEdit->GrabFocus();
+
+ mxGroupByColumnsRadio->connect_toggled( LINK( this, ScStatisticsInputOutputDialogController, GroupByChanged ) );
+ mxGroupByRowsRadio->connect_toggled( LINK( this, ScStatisticsInputOutputDialogController, GroupByChanged ) );
+
+ mxGroupByColumnsRadio->set_active(true);
+ mxGroupByRowsRadio->set_active(false);
+}
+
+void ScStatisticsInputOutputDialogController::GetRangeFromSelection()
+{
+ mViewData->GetSimpleArea(mInputRange);
+ OUString aCurrentString(mInputRange.Format(ScRefFlags::RANGE_ABS_3D, mDocument, mAddressDetails));
+ mxInputRangeEdit->SetText(aCurrentString);
+}
+
+void ScStatisticsInputOutputDialogController::SetActive()
+{
+ if ( mDialogLostFocus )
+ {
+ mDialogLostFocus = false;
+ if( mpActiveEdit )
+ mpActiveEdit->GrabFocus();
+ }
+ else
+ {
+ m_xDialog->grab_focus();
+ }
+ RefInputDone();
+}
+
+void ScStatisticsInputOutputDialogController::SetReference( const ScRange& rReferenceRange, ScDocument* pDocument )
+{
+ if ( mpActiveEdit )
+ {
+ if ( rReferenceRange.aStart != rReferenceRange.aEnd )
+ RefInputStart( mpActiveEdit );
+
+ OUString aReferenceString;
+
+ if (mpActiveEdit == mxInputRangeEdit.get())
+ {
+ mInputRange = rReferenceRange;
+ aReferenceString = mInputRange.Format(ScRefFlags::RANGE_ABS_3D, pDocument, mAddressDetails);
+ mxInputRangeEdit->SetRefString( aReferenceString );
+ }
+ else if (mpActiveEdit == mxOutputRangeEdit.get())
+ {
+ mOutputAddress = rReferenceRange.aStart;
+
+ ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
+ ScRefFlags::ADDR_ABS :
+ ScRefFlags::ADDR_ABS_3D;
+ aReferenceString = mOutputAddress.Format(nFormat, pDocument, pDocument->GetAddressConvention());
+ mxOutputRangeEdit->SetRefString( aReferenceString );
+ }
+ }
+
+ ValidateDialogInput();
+}
+
+IMPL_LINK_NOARG( ScStatisticsInputOutputDialogController, OkClicked, weld::Button&, void )
+{
+ CalculateInputAndWriteToOutput();
+ response(RET_OK);
+}
+
+IMPL_LINK(ScStatisticsInputOutputDialogController, GetEditFocusHandler, formula::WeldRefEdit&, rCtrl, void)
+{
+ mpActiveEdit = nullptr;
+
+ if (&rCtrl == mxInputRangeEdit.get())
+ mpActiveEdit = mxInputRangeEdit.get();
+ if (&rCtrl == mxOutputRangeEdit.get())
+ mpActiveEdit = mxOutputRangeEdit.get();
+
+ if (mpActiveEdit)
+ mpActiveEdit->SelectAll();
+}
+
+IMPL_LINK(ScStatisticsInputOutputDialogController, GetButtonFocusHandler, formula::WeldRefButton&, rCtrl, void)
+{
+ mpActiveEdit = nullptr;
+
+ if (&rCtrl == mxInputRangeButton.get())
+ mpActiveEdit = mxInputRangeEdit.get();
+ else if (&rCtrl == mxOutputRangeButton.get())
+ mpActiveEdit = mxOutputRangeEdit.get();
+
+ if (mpActiveEdit)
+ mpActiveEdit->SelectAll();
+}
+
+IMPL_LINK_NOARG(ScStatisticsInputOutputDialogController, LoseEditFocusHandler, formula::WeldRefEdit&, void)
+{
+ mDialogLostFocus = !m_xDialog->has_toplevel_focus();
+}
+
+IMPL_LINK_NOARG(ScStatisticsInputOutputDialogController, LoseButtonFocusHandler, formula::WeldRefButton&, void)
+{
+ mDialogLostFocus = !m_xDialog->has_toplevel_focus();
+}
+
+IMPL_LINK_NOARG( ScStatisticsInputOutputDialogController, GroupByChanged, weld::ToggleButton&, void )
+{
+ if (mxGroupByColumnsRadio->get_active())
+ mGroupedBy = BY_COLUMN;
+ else if (mxGroupByRowsRadio->get_active())
+ mGroupedBy = BY_ROW;
+
+ ValidateDialogInput();
+}
+
+IMPL_LINK_NOARG( ScStatisticsInputOutputDialogController, RefInputModifyHandler, formula::WeldRefEdit&, void )
+{
+ if ( mpActiveEdit )
+ {
+ if (mpActiveEdit == mxInputRangeEdit.get())
+ {
+ ScRangeList aRangeList;
+ bool bValid = ParseWithNames( aRangeList, mxInputRangeEdit->GetText(), mDocument);
+ const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
+ if (pRange)
+ {
+ mInputRange = *pRange;
+ // Highlight the resulting range.
+ mxInputRangeEdit->StartUpdateData();
+ }
+ else
+ {
+ mInputRange = ScRange( ScAddress::INITIALIZE_INVALID);
+ }
+ }
+ else if (mpActiveEdit == mxOutputRangeEdit.get())
+ {
+ ScRangeList aRangeList;
+ bool bValid = ParseWithNames( aRangeList, mxOutputRangeEdit->GetText(), mDocument);
+ const ScRange* pRange = (bValid && aRangeList.size() == 1) ? &aRangeList[0] : nullptr;
+ if (pRange)
+ {
+ mOutputAddress = pRange->aStart;
+
+ // Crop output range to top left address for Edit field.
+ if (pRange->aStart != pRange->aEnd)
+ {
+ ScRefFlags nFormat = ( mOutputAddress.Tab() == mCurrentAddress.Tab() ) ?
+ ScRefFlags::ADDR_ABS :
+ ScRefFlags::ADDR_ABS_3D;
+ OUString aReferenceString = mOutputAddress.Format(nFormat, mDocument, mDocument->GetAddressConvention());
+ mxOutputRangeEdit->SetRefString( aReferenceString );
+ }
+
+ // Highlight the resulting range.
+ mxOutputRangeEdit->StartUpdateData();
+ }
+ else
+ {
+ mOutputAddress = ScAddress( ScAddress::INITIALIZE_INVALID);
+ }
+ }
+ }
+
+ ValidateDialogInput();
+}
+
+void ScStatisticsInputOutputDialogController::CalculateInputAndWriteToOutput()
+{
+ OUString aUndo(ScResId(GetUndoNameId()));
+ ScDocShell* pDocShell = mViewData->GetDocShell();
+ SfxUndoManager* pUndoManager = pDocShell->GetUndoManager();
+ pUndoManager->EnterListAction( aUndo, aUndo, 0, mViewData->GetViewShell()->GetViewShellId() );
+
+ ScRange aOutputRange = ApplyOutput(pDocShell);
+
+ pUndoManager->LeaveListAction();
+ pDocShell->PostPaint( aOutputRange, PaintPartFlags::Grid );
+}
+
+bool ScStatisticsInputOutputDialogController::InputRangesValid()
+{
+ return mInputRange.IsValid() && mOutputAddress.IsValid();
+}
+
+void ScStatisticsInputOutputDialogController::ValidateDialogInput()
+{
+ // Enable OK button if all inputs are ok.
+ mxButtonOk->set_sensitive(InputRangesValid());
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index dcae91f597b8..7235c02076fb 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -1567,10 +1567,20 @@ bool ScModule::IsModalMode(SfxObjectShell* pDocSh)
SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( m_nCurRefDlgId );
if ( pChildWnd )
{
- IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
- assert(pRefDlg);
- bIsModal = pChildWnd->IsVisible() && pRefDlg &&
- !( pRefDlg->IsRefInputMode() && pRefDlg->IsDocAllowed(pDocSh) );
+ if (pChildWnd->GetWindow())
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ assert(pRefDlg);
+ bIsModal = pChildWnd->IsVisible() && pRefDlg &&
+ !( pRefDlg->IsRefInputMode() && pRefDlg->IsDocAllowed(pDocSh) );
+ }
+ if (pChildWnd->GetController())
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
+ assert(pRefDlg);
+ bIsModal = pChildWnd->IsVisible() && pRefDlg &&
+ !( pRefDlg->IsRefInputMode() && pRefDlg->IsDocAllowed(pDocSh) );
+ }
}
}
else if (pDocSh)
@@ -1642,9 +1652,18 @@ bool ScModule::IsFormulaMode()
SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( m_nCurRefDlgId );
if ( pChildWnd )
{
- IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
- assert(pRefDlg);
- bIsFormula = pChildWnd->IsVisible() && pRefDlg && pRefDlg->IsRefInputMode();
+ if (pChildWnd->GetWindow())
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ assert(pRefDlg);
+ bIsFormula = pChildWnd->IsVisible() && pRefDlg && pRefDlg->IsRefInputMode();
+ }
+ if (pChildWnd->GetController())
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
+ assert(pRefDlg);
+ bIsFormula = pChildWnd->IsVisible() && pRefDlg && pRefDlg->IsRefInputMode();
+ }
}
}
else
@@ -1694,14 +1713,29 @@ void ScModule::SetReference( const ScRange& rRef, ScDocument* pDoc,
aNew.aEnd.SetTab(nEndTab);
}
- IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
- assert(pRefDlg);
- if(pRefDlg)
+ if (pChildWnd->GetWindow())
{
- // hide the (color) selection now instead of later from LoseFocus,
- // don't abort the ref input that causes this call (bDoneRefMode = sal_False)
- pRefDlg->HideReference( false );
- pRefDlg->SetReference( aNew, pDoc );
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ assert(pRefDlg);
+ if(pRefDlg)
+ {
+ // hide the (color) selection now instead of later from LoseFocus,
+ // don't abort the ref input that causes this call (bDoneRefMode = sal_False)
+ pRefDlg->HideReference( false );
+ pRefDlg->SetReference( aNew, pDoc );
+ }
+ }
+ if (pChildWnd->GetController())
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
+ assert(pRefDlg);
+ if(pRefDlg)
+ {
+ // hide the (color) selection now instead of later from LoseFocus,
+ // don't abort the ref input that causes this call (bDoneRefMode = sal_False)
+ pRefDlg->HideReference( false );
+ pRefDlg->SetReference( aNew, pDoc );
+ }
}
}
}
@@ -1760,11 +1794,23 @@ void ScModule::EndReference()
OSL_ENSURE( pChildWnd, "NoChildWin" );
if ( pChildWnd )
{
- IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
- assert(pRefDlg);
- if(pRefDlg)
+ if (pChildWnd->GetWindow())
{
- pRefDlg->SetActive();
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ assert(pRefDlg);
+ if(pRefDlg)
+ {
+ pRefDlg->SetActive();
+ }
+ }
+ if (pChildWnd->GetController())
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
+ assert(pRefDlg);
+ if(pRefDlg)
+ {
+ pRefDlg->SetActive();
+ }
}
}
}
@@ -2161,6 +2207,36 @@ void ScModule::UnregisterRefWindow( sal_uInt16 nSlotId, vcl::Window *pWnd )
m_mapRefWindow.erase( nSlotId );
}
+void ScModule::RegisterRefController( sal_uInt16 nSlotId, SfxModelessDialogController *pWnd )
+{
+ std::vector<SfxModelessDialogController*> & rlRefWindow = m_mapRefController[nSlotId];
+
+ if( std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd ) == rlRefWindow.end() )
+ {
+ rlRefWindow.emplace_back(pWnd );
+ }
+}
+
+void ScModule::UnregisterRefController( sal_uInt16 nSlotId, SfxModelessDialogController *pWnd )
+{
+ auto iSlot = m_mapRefController.find( nSlotId );
+
+ if( iSlot == m_mapRefController.end() )
+ return;
+
+ std::vector<SfxModelessDialogController* > & rlRefWindow = iSlot->second;
+
+ auto i = std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd );
+
+ if( i == rlRefWindow.end() )
+ return;
+
+ rlRefWindow.erase( i );
+
+ if( rlRefWindow.empty() )
+ m_mapRefController.erase( nSlotId );
+}
+
vcl::Window * ScModule::Find1RefWindow( sal_uInt16 nSlotId, vcl::Window *pWndAncestor )
{
if (!pWndAncestor)
diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx
index 56d96a456ea9..4dd504d7d809 100644
--- a/sc/source/ui/formdlg/formula.cxx
+++ b/sc/source/ui/formdlg/formula.cxx
@@ -393,6 +393,14 @@ void ScFormulaDlg::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* p
RefInputStartAfter();
}
+void ScFormulaDlg::RefInputStart( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton )
+{
+ pEdit->SelectAll();
+ ::std::pair<formula::WeldRefButton*,formula::WeldRefEdit*> aPair = RefInputStartBefore( pEdit, pButton );
+ m_aHelper.RefInputStart( aPair.second, aPair.first);
+ RefInputStartAfter();
+}
+
void ScFormulaDlg::RefInputDone( bool bForced )
{
m_aHelper.RefInputDone( bForced );
@@ -531,10 +539,18 @@ void ScFormulaDlg::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton*
{
m_aHelper.ToggleCollapsed(pEdit,pButton);
}
+void ScFormulaDlg::ToggleCollapsed( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton)
+{
+ m_aHelper.ToggleCollapsed(pEdit,pButton);
+}
void ScFormulaDlg::ReleaseFocus( formula::RefEdit* pEdit)
{
m_aHelper.ReleaseFocus(pEdit);
}
+void ScFormulaDlg::ReleaseFocus( formula::WeldRefEdit* pEdit)
+{
+ m_aHelper.ReleaseFocus(pEdit);
+}
void ScFormulaDlg::dispatch(bool _bOK, bool _bMatrixChecked)
{
SfxBoolItem aRetItem( SID_DLG_RETOK, _bOK );
diff --git a/sc/source/ui/inc/ChildWindowWrapper.hxx b/sc/source/ui/inc/ChildWindowWrapper.hxx
index 60382774de03..1ad232a7b91b 100644
--- a/sc/source/ui/inc/ChildWindowWrapper.hxx
+++ b/sc/source/ui/inc/ChildWindowWrapper.hxx
@@ -88,6 +88,67 @@ private:
}
};
+template <sal_Int16 WindowID>
+class ChildControllerWrapper : public SfxChildWindow
+{
+public:
+ ChildControllerWrapper(vcl::Window* pParentP, sal_uInt16 nId,
+ SfxBindings* pBindings, const SfxChildWinInfo* pInfo)
+ : SfxChildWindow(pParentP, nId)
+ {
+ ScTabViewShell* pViewShell = getTabViewShell( pBindings );
+ if (!pViewShell)
+ pViewShell = dynamic_cast< ScTabViewShell *>( SfxViewShell::Current() );
+ OSL_ENSURE(pViewShell, "Missing view shell!");
+
+ if (pViewShell)
+ SetController(pViewShell->CreateRefDialogController(pBindings, this, pInfo, pParentP->GetFrameWeld(), WindowID));
+
+ if (pViewShell && !GetController())
+ pViewShell->GetViewFrame()->SetChildWindow( nId, false );
+ }
+
+ static std::unique_ptr<SfxChildWindow> CreateImpl(
+ vcl::Window *pParent, sal_uInt16 nId,
+ SfxBindings *pBindings, SfxChildWinInfo* pInfo )
+ {
+ return std::make_unique<ChildControllerWrapper>(pParent, nId, pBindings, pInfo);
+ }
+
+ static void RegisterChildWindow (
+ bool bVisible = false,
+ SfxModule* pModule = nullptr,
+ SfxChildWindowFlags nFlags = SfxChildWindowFlags::NONE)
+ {
+ auto pFactory = std::make_unique<SfxChildWinFactory>(ChildControllerWrapper::CreateImpl, WindowID, CHILDWIN_NOPOS );
+ pFactory->aInfo.nFlags |= nFlags;
+ pFactory->aInfo.bVisible = bVisible;
+ SfxChildWindow::RegisterChildWindow(pModule, std::move(pFactory));
+ }
+
+ static sal_uInt16 GetChildWindowId()
+ {
+ return WindowID;
+ }
+
+private:
+ static ScTabViewShell* getTabViewShell( const SfxBindings *pBindings )
+ {
+ if( !pBindings )
+ return nullptr;
+ SfxDispatcher* pDispacher = pBindings ->GetDispatcher();
+ if( !pDispacher )
+ return nullptr;
+ SfxViewFrame* pFrame = pDispacher->GetFrame();
+ if( !pFrame )
+ return nullptr;
+ SfxViewShell* pViewShell = pFrame->GetViewShell();
+ if( !pViewShell )
+ return nullptr;
+ return dynamic_cast<ScTabViewShell*>( pViewShell );
+ }
+};
+
#endif // INCLUDED_SC_SOURCE_UI_INC_CHILDWINDOWWRAPPER_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/CorrelationDialog.hxx b/sc/source/ui/inc/CorrelationDialog.hxx
index ee2f433ed35d..2a98da43881f 100644
--- a/sc/source/ui/inc/CorrelationDialog.hxx
+++ b/sc/source/ui/inc/CorrelationDialog.hxx
@@ -13,14 +13,14 @@
#include "MatrixComparisonGenerator.hxx"
-class ScCorrelationDialog : public ScMatrixComparisonGenerator
+class ScCorrelationDialog : public ScMatrixComparisonGeneratorController
{
public:
ScCorrelationDialog(
SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
- vcl::Window* pParent, ScViewData* pViewData);
+ weld::Window* pParent, ScViewData* pViewData);
- virtual bool Close() override;
+ virtual void Close() override;
protected:
virtual const OUString getLabel() override;
diff --git a/sc/source/ui/inc/IAnyRefDialog.hxx b/sc/source/ui/inc/IAnyRefDialog.hxx
index 0e4f81f41572..486322936ba8 100644
--- a/sc/source/ui/inc/IAnyRefDialog.hxx
+++ b/sc/source/ui/inc/IAnyRefDialog.hxx
@@ -36,6 +36,7 @@ public:
virtual void SetReference( const ScRange& rRef, ScDocument* pDoc ) = 0;
virtual void RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton = nullptr ) = 0;
+ virtual void RefInputStart( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton = nullptr ) = 0;
virtual void RefInputDone( bool bForced = false ) = 0;
virtual bool IsTableLocked() const = 0;
virtual bool IsRefInputMode() const = 0;
diff --git a/sc/source/ui/inc/MatrixComparisonGenerator.hxx b/sc/source/ui/inc/MatrixComparisonGenerator.hxx
index cce103291a51..0923042120e6 100644
--- a/sc/source/ui/inc/MatrixComparisonGenerator.hxx
+++ b/sc/source/ui/inc/MatrixComparisonGenerator.hxx
@@ -34,6 +34,24 @@ protected:
virtual const OUString getTemplate() = 0;
};
+class ScMatrixComparisonGeneratorController : public ScStatisticsInputOutputDialogController
+{
+public:
+ ScMatrixComparisonGeneratorController(
+ SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
+ weld::Window* pParent, ScViewData* pViewData,
+ const OUString& rUiXmlDescription, const OString& rID);
+
+ virtual ~ScMatrixComparisonGeneratorController() override;
+
+protected:
+ virtual const char* GetUndoNameId() override;
+ virtual ScRange ApplyOutput(ScDocShell* pDocShell) override;
+
+ virtual const OUString getLabel() = 0;
+ virtual const OUString getTemplate() = 0;
+};
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/StatisticsInputOutputDialog.hxx b/sc/source/ui/inc/StatisticsInputOutputDialog.hxx
index b63ccd35c78e..6a18855851a4 100644
--- a/sc/source/ui/inc/StatisticsInputOutputDialog.hxx
+++ b/sc/source/ui/inc/StatisticsInputOutputDialog.hxx
@@ -86,6 +86,78 @@ private:
DECL_LINK( RefInputModifyHandler, Edit&, void );
};
+class ScStatisticsInputOutputDialogController : public ScAnyRefDlgController
+{
+public:
+ enum GroupedBy {
+ BY_COLUMN,
+ BY_ROW
+ };
+
+ ScStatisticsInputOutputDialogController(
+ SfxBindings* pB, SfxChildWindow* pCW,
+ weld::Window* pParent, ScViewData* pViewData,
+ const OUString& rUIXMLDescription,
+ const OString& rID);
+
+ virtual ~ScStatisticsInputOutputDialogController() override;
+
+ virtual void SetReference( const ScRange& rRef, ScDocument* pDoc ) override;
+ virtual void SetActive() override;
+
+protected:
+ void CalculateInputAndWriteToOutput();
+
+ virtual ScRange ApplyOutput(ScDocShell* pDocShell) = 0;
+ virtual const char* GetUndoNameId() = 0;
+ virtual bool InputRangesValid();
+ void ValidateDialogInput();
+
+ // Widgets
+ std::unique_ptr<weld::Label> mxInputRangeLabel;
+ std::unique_ptr<formula::WeldRefEdit> mxInputRangeEdit;
+ std::unique_ptr<formula::WeldRefButton> mxInputRangeButton;
+
+ std::unique_ptr<weld::Label> mxOutputRangeLabel;
+ std::unique_ptr<formula::WeldRefEdit> mxOutputRangeEdit;
+ std::unique_ptr<formula::WeldRefButton> mxOutputRangeButton;
+
+ std::unique_ptr<weld::RadioButton> mxGroupByColumnsRadio;
+ std::unique_ptr<weld::RadioButton> mxGroupByRowsRadio;
+
+ // Data
+ ScViewData* const mViewData;
+ ScDocument* const mDocument;
+
+ ScRange mInputRange;
+ ScAddress::Details const mAddressDetails;
+ ScAddress mOutputAddress;
+ GroupedBy mGroupedBy;
+
+ static ScRangeList MakeColumnRangeList(SCTAB aTab, ScAddress const & aStart, ScAddress const & aEnd);
+ static ScRangeList MakeRowRangeList(SCTAB aTab, ScAddress const & aStart, ScAddress const & aEnd);
+
+private:
+ // Widgets
+ std::unique_ptr<weld::Button> mxButtonOk;
+
+ formula::WeldRefEdit* mpActiveEdit;
+ ScAddress const mCurrentAddress;
+ bool mDialogLostFocus;
+
+ void Init();
+ void GetRangeFromSelection();
+
+ DECL_LINK( GroupByChanged, weld::ToggleButton&, void );
+ DECL_LINK( OkClicked, weld::Button&, void );
+ DECL_LINK( GetEditFocusHandler, formula::WeldRefEdit&, void );
+ DECL_LINK( GetButtonFocusHandler, formula::WeldRefButton&, void );
+ DECL_LINK( LoseEditFocusHandler, formula::WeldRefEdit&, void );
+ DECL_LINK( LoseButtonFocusHandler, formula::WeldRefButton&, void );
+ DECL_LINK( RefInputModifyHandler, formula::WeldRefEdit&, void );
+};
+
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/anyrefdg.hxx b/sc/source/ui/inc/anyrefdg.hxx
index 069bc2650ee5..3a5726123654 100644
--- a/sc/source/ui/inc/anyrefdg.hxx
+++ b/sc/source/ui/inc/anyrefdg.hxx
@@ -40,7 +40,10 @@ class ScFormulaReferenceHelper
::std::unique_ptr<ScCompiler> m_pRefComp;
VclPtr<formula::RefEdit> m_pRefEdit; // active input field
VclPtr<formula::RefButton> m_pRefBtn; // associated button
+ formula::WeldRefEdit* m_pWeldRefEdit; // active input field
+ formula::WeldRefButton* m_pWeldRefBtn; // associated button
VclPtr<vcl::Window> m_pWindow;
+ weld::Dialog* m_pDialog;
SfxBindings* const m_pBindings;
::std::unique_ptr<Accelerator>
m_pAccel; // for Enter/Escape
@@ -63,6 +66,7 @@ class ScFormulaReferenceHelper
bool m_bAccInserted;
DECL_LINK( AccelSelectHdl, Accelerator&, void );
+ DECL_LINK( ActivateHdl, weld::Widget&, bool );
public:
ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindings* _pBindings);
@@ -76,12 +80,16 @@ public:
void ShowReference(const OUString& rStr);
void ReleaseFocus( formula::RefEdit* pEdit );
+ void ReleaseFocus( formula::WeldRefEdit* pEdit );
void HideReference( bool bDoneRefMode = true );
void RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton );
+ void RefInputStart( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton );
void RefInputDone( bool bForced );
void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton );
+ void ToggleCollapsed( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton );
- void SetWindow(vcl::Window* _pWindow) { m_pWindow = _pWindow; }
+ void SetWindow(vcl::Window* _pWindow) { m_pWindow = _pWindow; }
+ void SetDialog(weld::Dialog* pDialog) { m_pDialog = pDialog; }
void DoClose( sal_uInt16 nId );
void SetDispatcherLock( bool bLock );
static void EnableSpreadsheets( bool bFlag = true );
@@ -91,13 +99,14 @@ public:
public:
static bool CanInputStart( const formula::RefEdit *pEdit ){ return !!pEdit; }
- bool CanInputDone( bool bForced ){ return m_pRefEdit && (bForced || !m_pRefBtn); }
+ bool CanInputDone( bool bForced ){ return (m_pRefEdit || m_pWeldRefEdit) && (bForced || !(m_pRefBtn || m_pWeldRefBtn)); }
};
class SC_DLLPUBLIC ScRefHandler :
public IAnyRefDialog
{
VclPtr<vcl::Window> m_rWindow;
+ weld::DialogController* m_pController;
bool m_bInRefMode;
public:
@@ -118,12 +127,14 @@ protected:
void SetDispatcherLock( bool bLock );
virtual void RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton = nullptr ) override;
+ virtual void RefInputStart( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton = nullptr ) override;
virtual void RefInputDone( bool bForced = false ) override;
bool ParseWithNames( ScRangeList& rRanges, const OUString& rStr, const ScDocument* pDoc );
public:
ScRefHandler( vcl::Window &rWindow, SfxBindings* pB, bool bBindRef );
+ ScRefHandler( SfxModelessDialogController &rController, SfxBindings* pB, bool bBindRef );
virtual ~ScRefHandler() override;
virtual void SetReference( const ScRange& rRef, ScDocument* pDoc ) override = 0;
@@ -137,7 +148,9 @@ public:
virtual void HideReference( bool bDoneRefMode = true ) override;
virtual void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton ) override;
+ virtual void ToggleCollapsed( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton ) override;
virtual void ReleaseFocus( formula::RefEdit* pEdit ) override;
+ virtual void ReleaseFocus( formula::WeldRefEdit* pEdit ) override;
virtual void ViewShellChanged() override;
void SwitchToDocument();
@@ -228,6 +241,77 @@ struct ScAnyRefDlg : ::ScRefHdlrImpl< ScAnyRefDlg, SfxModelessDialog>
}
};
+template< class TWindow, bool bBindRef = true >
+class ScRefHdlrControllerImplBase: public TWindow, public ScRefHandler
+{
+private:
+ template<class TBindings, class TChildWindow, class TParentWindow >
+ ScRefHdlrControllerImplBase( TBindings* pB, TChildWindow* pCW,
+ TParentWindow* pParent, const OUString& rUIXMLDescription, const OString& rID );
+
+ template<class TParentWindow, class TArg>
+ ScRefHdlrControllerImplBase(TParentWindow* pParent, const OUString& rUIXMLDescription, const OString& rID, const TArg &rArg, SfxBindings *pB);
+
+ virtual ~ScRefHdlrControllerImplBase() override;
+
+ template<class, class, bool> friend struct ScRefHdlrControllerImpl;
+};
+
+template<class TWindow, bool bBindRef >
+ScRefHdlrControllerImplBase<TWindow,bBindRef>::~ScRefHdlrControllerImplBase(){}
+
+template<class TWindow, bool bBindRef>
+template<class TBindings, class TChildWindow, class TParentWindow>
+ScRefHdlrControllerImplBase<TWindow, bBindRef>::ScRefHdlrControllerImplBase(TBindings* pB, TChildWindow* pCW,
+ TParentWindow* pParent, const OUString& rUIXMLDescription, const OString& rID)
+ : TWindow(pB, pCW, pParent, rUIXMLDescription, rID)
+ , ScRefHandler( *static_cast<TWindow*>(this), pB, bBindRef )
+{
+}
+
+template<class TWindow, bool bBindRef >
+template<class TParentWindow, class TArg>
+ScRefHdlrControllerImplBase<TWindow,bBindRef>::ScRefHdlrControllerImplBase(TParentWindow* pParent, const OUString& rUIXMLDescription, const OString& rID,
+ const TArg &rArg, SfxBindings *pB)
+ : TWindow(pParent, rUIXMLDescription, rID, rArg)
+ , ScRefHandler( *static_cast<TWindow*>(this), pB, bBindRef )
+{
+}
+
+template<class TDerived, class TBase, bool bBindRef = true>
+struct ScRefHdlrControllerImpl: ScRefHdlrControllerImplBase< TBase, bBindRef >
+{
+ enum { UNKNOWN_SLOTID = 0U, SLOTID = UNKNOWN_SLOTID };
+
+ template<class T1, class T2, class T3, class T4>
+ ScRefHdlrControllerImpl( const T1 & rt1, const T2 & rt2, const T3& rt3, const T4& rt4 )
+ : ScRefHdlrControllerImplBase<TBase, bBindRef >(rt1, rt2, rt3, rt4)
+ {
+ SC_MOD()->RegisterRefController( static_cast<sal_uInt16>( TDerived::SLOTID ), this );
+ }
+
+ template<class T1, class T2, class T3, class T4, class T5>
+ ScRefHdlrControllerImpl( const T1 & rt1, const T2 & rt2, const T3& rt3, const T4& rt4, const T5& rt5 )
+ : ScRefHdlrControllerImplBase<TBase, bBindRef >(rt1, rt2, rt3, rt4, rt5)
+ {
+ SC_MOD()->RegisterRefController( static_cast<sal_uInt16>( TDerived::SLOTID ), this );
+ }
+
+ ~ScRefHdlrControllerImpl()
+ {
+ SC_MOD()->UnregisterRefController( static_cast<sal_uInt16>( TDerived::SLOTID ), this );
+ }
+};
+
+struct ScAnyRefDlgController : ::ScRefHdlrControllerImpl<ScAnyRefDlgController, SfxModelessDialogController>
+{
+ template<class T1, class T2, class T3, class T4, class T5>
+ ScAnyRefDlgController( const T1 & rt1, const T2 & rt2, const T3& rt3, const T4& rt4, const T5& rt5 )
+ : ScRefHdlrControllerImpl<ScAnyRefDlgController, SfxModelessDialogController>(rt1, rt2, rt3, rt4, rt5)
+ {
+ }
+};
+
inline bool ScRefHandler::CanInputStart( const formula::RefEdit *pEdit )
{
return ScFormulaReferenceHelper::CanInputStart( pEdit );
diff --git a/sc/source/ui/inc/formula.hxx b/sc/source/ui/inc/formula.hxx
index a40b55ecb9e1..97737e7c4af9 100644
--- a/sc/source/ui/inc/formula.hxx
+++ b/sc/source/ui/inc/formula.hxx
@@ -83,7 +83,9 @@ public:
virtual void SetReference( const ScRange& rRef, ScDocument* pD ) override;
virtual void ReleaseFocus( formula::RefEdit* pEdit ) override;
+ virtual void ReleaseFocus( formula::WeldRefEdit* pEdit ) override;
virtual void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton ) override;
+ virtual void ToggleCollapsed( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton ) override;
virtual void RefInputDone( bool bForced = false ) override;
virtual bool IsTableLocked() const override;
virtual bool IsRefInputMode() const override;
@@ -95,6 +97,7 @@ public:
private:
virtual void RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton = nullptr ) override;
+ virtual void RefInputStart( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton = nullptr ) override;
static void SaveLRUEntry(const ScFuncDesc* pFuncDesc);
static bool IsInputHdl(const ScInputHandler* pHdl);
diff --git a/sc/source/ui/inc/reffact.hxx b/sc/source/ui/inc/reffact.hxx
index a49f80c0de97..28c42f089a38 100644
--- a/sc/source/ui/inc/reffact.hxx
+++ b/sc/source/ui/inc/reffact.hxx
@@ -79,7 +79,7 @@ private:
};
class ScCorrelationDialogWrapper :
- public ChildWindowWrapper<SID_CORRELATION_DIALOG>
+ public ChildControllerWrapper<SID_CORRELATION_DIALOG>
{
private:
ScCorrelationDialogWrapper() = delete;
diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx
index d60cb0e388e0..f2a260030206 100644
--- a/sc/source/ui/inc/tabvwsh.hxx
+++ b/sc/source/ui/inc/tabvwsh.hxx
@@ -328,6 +328,10 @@ public:
const SfxChildWinInfo* pInfo,
vcl::Window* pParent, sal_uInt16 nSlotId );
+ std::unique_ptr<SfxModelessDialogController> CreateRefDialogController(SfxBindings* pB, SfxChildWindow* pCW,
+ const SfxChildWinInfo* pInfo,
+ weld::Window* pParent, sal_uInt16 nSlotId);
+
void UpdateOleZoom();
virtual const FmFormShell* GetFormShell() const override { return pFormShell.get(); }
diff --git a/sc/source/ui/inc/validate.hxx b/sc/source/ui/inc/validate.hxx
index 62b4388272e1..c29d8b6c7335 100644
--- a/sc/source/ui/inc/validate.hxx
+++ b/sc/source/ui/inc/validate.hxx
@@ -228,6 +228,11 @@ public:
ScValidationDlgBase::RefInputStart( pEdit, pButton );
}
+ virtual void RefInputStart( formula::WeldRefEdit* /*pEdit*/, formula::WeldRefButton* /*pButton*/ = nullptr ) override
+ {
+ assert(false);
+ }
+
virtual void RefInputDone( bool bForced = false ) override
{
if( !CanInputDone( bForced ) )
diff --git a/sc/source/ui/miscdlgs/anyrefdg.cxx b/sc/source/ui/miscdlgs/anyrefdg.cxx
index b108d4487acd..29c05945b30c 100644
--- a/sc/source/ui/miscdlgs/anyrefdg.cxx
+++ b/sc/source/ui/miscdlgs/anyrefdg.cxx
@@ -47,7 +47,10 @@ ScFormulaReferenceHelper::ScFormulaReferenceHelper(IAnyRefDialog* _pDlg,SfxBindi
: m_pDlg(_pDlg)
, m_pRefEdit (nullptr)
, m_pRefBtn (nullptr)
+ , m_pWeldRefEdit (nullptr)
+ , m_pWeldRefBtn (nullptr)
, m_pWindow(nullptr)
+ , m_pDialog(nullptr)
, m_pBindings(_pBindings)
, m_nOldBorderWidth (0)
, m_nRefTab(0)
@@ -85,6 +88,7 @@ void ScFormulaReferenceHelper::dispose()
m_pOldEditParent.clear();
m_pWindow.clear();
+ m_pDialog = nullptr;
m_pRefBtn.clear();
m_pRefEdit.clear();
}
@@ -321,6 +325,39 @@ void ScFormulaReferenceHelper::ReleaseFocus( formula::RefEdit* pEdit )
}
}
+void ScFormulaReferenceHelper::ReleaseFocus( formula::WeldRefEdit* pEdit )
+{
+ if( !m_pWeldRefEdit && pEdit )
+ {
+ m_pDlg->RefInputStart( pEdit );
+ }
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if( pViewShell )
+ {
+ pViewShell->ActiveGrabFocus();
+ if( m_pWeldRefEdit )
+ {
+ const ScViewData& rViewData = pViewShell->GetViewData();
+ ScDocument* pDoc = rViewData.GetDocument();
+ ScRangeList aRangeList;
+ if( ParseWithNames( aRangeList, m_pWeldRefEdit->GetText(), pDoc ) )
+ {
+ if ( !aRangeList.empty() )
+ {
+ const ScRange & rRange = aRangeList.front();
+ pViewShell->SetTabNo( rRange.aStart.Tab() );
+ pViewShell->MoveCursorAbs( rRange.aStart.Col(),
+ rRange.aStart.Row(), SC_FOLLOW_JUMP, false, false );
+ pViewShell->MoveCursorAbs( rRange.aEnd.Col(),
+ rRange.aEnd.Row(), SC_FOLLOW_JUMP, true, false );
+ m_pDlg->SetReference( rRange, pDoc );
+ }
+ }
+ }
+ }
+}
+
void ScFormulaReferenceHelper::Init()
{
ScViewData* pViewData=ScDocShell::GetViewData(); //! use pScViewShell?
@@ -353,6 +390,14 @@ IMPL_LINK( ScFormulaReferenceHelper, AccelSelectHdl, Accelerator&, rSelAccel, vo
}
}
+IMPL_LINK_NOARG(ScFormulaReferenceHelper, ActivateHdl, weld::Widget&, bool)
+{
+ if (m_pWeldRefEdit)
+ m_pWeldRefEdit->GrabFocus();
+ m_pDlg->RefInputDone(true);
+ return true;
+}
+
void ScFormulaReferenceHelper::RefInputDone( bool bForced )
{
if ( CanInputDone( bForced ) )
@@ -363,62 +408,86 @@ void ScFormulaReferenceHelper::RefInputDone( bool bForced )
m_bAccInserted = false;
}
- //get rid of all this junk when we can
- if (!m_bOldDlgLayoutEnabled)
+ if (m_pDialog)
{
- m_pWindow->SetOutputSizePixel(m_aOldDialogSize);
+ // Adjust window title
+ m_pDialog->set_title(m_sOldDialogText);
- // restore the parent of the edit field
- m_pRefEdit->SetParent(m_pOldEditParent);
+ if (m_pWeldRefEdit)
+ m_pWeldRefEdit->SetActivateHdl(Link<weld::Widget&, bool>());
- // the window is at the old size again
- m_pWindow->SetOutputSizePixel(m_aOldDialogSize);
-
- // set button parent
- if( m_pRefBtn )
+ // set button image
+ if (m_pWeldRefBtn)
{
- m_pRefBtn->SetParent(m_pWindow);
+ m_pWeldRefBtn->SetActivateHdl(Link<weld::Widget&, bool>());
+ m_pWeldRefBtn->SetStartImage();
}
+
+ m_pDialog->undo_collapse();
+
+ m_pWeldRefEdit = nullptr;
+ m_pWeldRefBtn = nullptr;
}
- if (!m_bOldEditParentLayoutEnabled)
+ if (m_pWindow)
{
- // set pEditCell to old position
- m_pRefEdit->SetPosSizePixel(m_aOldEditPos, m_aOldEditSize);
+ //get rid of all this junk when we can
+ if (!m_bOldDlgLayoutEnabled)
+ {
+ m_pWindow->SetOutputSizePixel(m_aOldDialogSize);
- // set button position
- if( m_pRefBtn )
+ // restore the parent of the edit field
+ m_pRefEdit->SetParent(m_pOldEditParent);
+
+ // the window is at the old size again
+ m_pWindow->SetOutputSizePixel(m_aOldDialogSize);
+
+ // set button parent
+ if( m_pRefBtn )
+ {
+ m_pRefBtn->SetParent(m_pWindow);
+ }
+ }
+
+ if (!m_bOldEditParentLayoutEnabled)
{
- m_pRefBtn->SetPosPixel( m_aOldButtonPos );
+ // set pEditCell to old position
+ m_pRefEdit->SetPosSizePixel(m_aOldEditPos, m_aOldEditSize);
+
+ // set button position
+ if( m_pRefBtn )
+ {
+ m_pRefBtn->SetPosPixel( m_aOldButtonPos );
+ }
}
- }
- // Adjust window title
- m_pWindow->SetText(m_sOldDialogText);
+ // Adjust window title
+ m_pWindow->SetText(m_sOldDialogText);
- // set button image
- if( m_pRefBtn )
- m_pRefBtn->SetStartImage();
+ // set button image
+ if( m_pRefBtn )
+ m_pRefBtn->SetStartImage();
- // All others: Show();
- for (VclPtr<vcl::Window> const & pWindow : m_aHiddenWidgets)
- {
- pWindow->Show();
- }
- m_aHiddenWidgets.clear();
+ // All others: Show();
+ for (VclPtr<vcl::Window> const & pWindow : m_aHiddenWidgets)
+ {
+ pWindow->Show();
+ }
+ m_aHiddenWidgets.clear();
- if (m_bOldDlgLayoutEnabled)
- {
- m_pRefEdit->set_width_request(m_nOldEditWidthReq);
- Dialog* pResizeDialog = m_pRefEdit->GetParentDialog();
- pResizeDialog->set_border_width(m_nOldBorderWidth);
- if (vcl::Window *pActionArea = pResizeDialog->get_action_area())
- pActionArea->Show();
- pResizeDialog->setOptimalLayoutSize();
- }
+ if (m_bOldDlgLayoutEnabled)
+ {
+ m_pRefEdit->set_width_request(m_nOldEditWidthReq);
+ Dialog* pResizeDialog = m_pRefEdit->GetParentDialog();
+ pResizeDialog->set_border_width(m_nOldBorderWidth);
+ if (vcl::Window *pActionArea = pResizeDialog->get_action_area())
+ pActionArea->Show();
+ pResizeDialog->setOptimalLayoutSize();
+ }
- m_pRefEdit = nullptr;
- m_pRefBtn = nullptr;
+ m_pRefEdit = nullptr;
+ m_pRefBtn = nullptr;
+ }
}
}
@@ -591,6 +660,37 @@ void ScFormulaReferenceHelper::RefInputStart( formula::RefEdit* pEdit, formula::
}
}
+void ScFormulaReferenceHelper::RefInputStart( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton )
+{
+ if (!m_pWeldRefEdit)
+ {
+ m_pWeldRefEdit = pEdit;
+ m_pWeldRefBtn = pButton;
+
+ // Save and adjust window title
+ m_sOldDialogText = m_pDialog->get_title();
+ if (weld::Label *pLabel = m_pWeldRefEdit->GetLabelWidgetForShrinkMode())
+ {
+ const OUString sLabel = pLabel->get_label();
+ if (!sLabel.isEmpty())
+ {
+ const OUString sNewDialogText = m_sOldDialogText + ": " + comphelper::string::stripEnd(sLabel, ':');
+ m_pDialog->set_title(pLabel->strip_mnemonic(sNewDialogText));
+ }
+ }
+
+ m_pDialog->collapse(pEdit->GetWidget(), pButton ? pButton->GetWidget() : nullptr);
+
+ // set button image
+ if (pButton)
+ pButton->SetEndImage();
+
+ m_pWeldRefEdit->SetActivateHdl(LINK(this, ScFormulaReferenceHelper, ActivateHdl));
+ if (m_pWeldRefBtn)
+ m_pWeldRefBtn->SetActivateHdl(LINK(this, ScFormulaReferenceHelper, ActivateHdl));
+ }
+}
+
void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
{
if( pEdit )
@@ -611,6 +711,26 @@ void ScFormulaReferenceHelper::ToggleCollapsed( formula::RefEdit* pEdit, formula
}
}
+void ScFormulaReferenceHelper::ToggleCollapsed( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton )
+{
+ if( pEdit )
+ {
+ if( m_pWeldRefEdit == pEdit ) // is this the active ref edit field?
+ {
+ m_pWeldRefEdit->GrabFocus(); // before RefInputDone()
+ m_pDlg->RefInputDone( true ); // finish ref input
+ }
+ else
+ {
+ m_pDlg->RefInputDone( true ); // another active ref edit?
+ m_pDlg->RefInputStart( pEdit, pButton ); // start ref input
+ // pRefEdit might differ from pEdit after RefInputStart() (i.e. ScFormulaDlg)
+ if( m_pWeldRefEdit )
+ m_pWeldRefEdit->GrabFocus();
+ }
+ }
+}
+
void ScFormulaReferenceHelper::DoClose( sal_uInt16 nId )
{
SfxApplication* pSfxApp = SfxGetpApp();
@@ -747,11 +867,9 @@ static void lcl_HideAllReferences()
}
}
-//The class of ScAnyRefDlg is rewritten by PengYunQuan for Validity Cell Range Picker
-// class ScRefHandler
-
ScRefHandler::ScRefHandler( vcl::Window &rWindow, SfxBindings* pB, bool bBindRef ):
m_rWindow( &rWindow ),
+ m_pController( nullptr ),
m_bInRefMode( false ),
m_aHelper(this,pB),
m_pMyBindings( pB )
@@ -761,6 +879,17 @@ ScRefHandler::ScRefHandler( vcl::Window &rWindow, SfxBindings* pB, bool bBindRef
if( bBindRef ) EnterRefMode();
}
+ScRefHandler::ScRefHandler(SfxModelessDialogController& rController, SfxBindings* pB, bool bBindRef)
+ : m_pController(&rController)
+ , m_bInRefMode(false)
+ , m_aHelper(this, pB)
+ , m_pMyBindings(pB)
+{
+ m_aHelper.SetDialog(rController.getDialog());
+
+ if( bBindRef ) EnterRefMode();
+}
+
bool ScRefHandler::EnterRefMode()
{
if( m_bInRefMode ) return false;
@@ -819,6 +948,7 @@ ScRefHandler::~ScRefHandler()
void ScRefHandler::disposeRefHandler()
{
m_rWindow.clear();
+ m_pController = nullptr;
LeaveRefMode();
m_aHelper.dispose();
}
@@ -831,6 +961,8 @@ bool ScRefHandler::LeaveRefMode()
if( Dialog *pDlg = dynamic_cast<Dialog*>( m_rWindow.get() ) )
pDlg->SetModalInputMode(false);
+ if (m_pController)
+ m_pController->getDialog()->set_modal(false);
SetDispatcherLock( false ); //! here and in DoClose ?
ScTabViewShell* pScViewShell = ScTabViewShell::GetActiveViewShell();
@@ -885,6 +1017,8 @@ bool ScRefHandler::IsDocAllowed(SfxObjectShell* pDocSh) const // pDocSh may be
bool ScRefHandler::IsRefInputMode() const
{
+ if (m_pController)
+ return m_pController->getDialog()->get_visible();
return m_rWindow->IsVisible(); // references can only be input to visible windows
}
@@ -924,11 +1058,21 @@ void ScRefHandler::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* p
m_aHelper.RefInputStart( pEdit, pButton );
}
+void ScRefHandler::RefInputStart( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton )
+{
+ m_aHelper.RefInputStart( pEdit, pButton );
+}
+
void ScRefHandler::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton )
{
m_aHelper.ToggleCollapsed( pEdit, pButton );
}
+void ScRefHandler::ToggleCollapsed( formula::WeldRefEdit* pEdit, formula::WeldRefButton* pButton )
+{
+ m_aHelper.ToggleCollapsed( pEdit, pButton );
+}
+
bool ScRefHandler::ParseWithNames( ScRangeList& rRanges, const OUString& rStr, const ScDocument* pDoc )
{
return m_aHelper.ParseWithNames( rRanges, rStr, pDoc );
@@ -949,6 +1093,11 @@ void ScRefHandler::ReleaseFocus( formula::RefEdit* pEdit )
m_aHelper.ReleaseFocus( pEdit );
}
+void ScRefHandler::ReleaseFocus( formula::WeldRefEdit* pEdit )
+{
+ m_aHelper.ReleaseFocus( pEdit );
+}
+
void ScRefHandler::RefInputDone( bool bForced )
{
m_aHelper.RefInputDone( bForced );
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index 649af1829361..c826234e3da0 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -348,12 +348,6 @@ VclPtr<SfxModelessDialog> ScTabViewShell::CreateRefDialog(
}
break;
- case SID_CORRELATION_DIALOG:
- {
- pResult = VclPtr<ScCorrelationDialog>::Create( pB, pCW, pParent, &GetViewData() );
- }
- break;
-
case SID_COVARIANCE_DIALOG:
{
pResult = VclPtr<ScCovarianceDialog>::Create( pB, pCW, pParent, &GetViewData() );
@@ -512,6 +506,45 @@ VclPtr<SfxModelessDialog> ScTabViewShell::CreateRefDialog(
return pResult;
}
+std::unique_ptr<SfxModelessDialogController> ScTabViewShell::CreateRefDialogController(
+ SfxBindings* pB, SfxChildWindow* pCW,
+ const SfxChildWinInfo* pInfo,
+ weld::Window* pParent, sal_uInt16 nSlotId)
+{
+ // only open dialog when called through ScModule::SetRefDialog,
+ // so that it does not re appear for instance after a crash (#42341#).
+
+ if ( SC_MOD()->GetCurRefDlgId() != nSlotId )
+ return nullptr;
+
+ if ( nCurRefDlgId != nSlotId )
+ {
+ // the dialog has been opened in a different view
+ // -> lock the dispatcher for this view (modal mode)
+
+ GetViewData().GetDispatcher().Lock( true ); // lock is reset when closing dialog
+ return nullptr;
+ }
+
+ std::unique_ptr<SfxModelessDialogController> xResult;
+
+ if(pCW)
+ pCW->SetHideNotDelete(true);
+
+ switch( nSlotId )
+ {
+ case SID_CORRELATION_DIALOG:
+ {
+ xResult.reset(new ScCorrelationDialog(pB, pCW, pParent, &GetViewData()));
+ }
+ break;
+ }
+
+ if (xResult)
+ xResult->Initialize( pInfo );
+ return xResult;
+}
+
int ScTabViewShell::getPart() const
{
return GetViewData().GetTabNo();
diff --git a/sc/uiconfig/scalc/ui/correlationdialog.ui b/sc/uiconfig/scalc/ui/correlationdialog.ui
index 378875bec5ec..7fff92fa924d 100644
--- a/sc/uiconfig/scalc/ui/correlationdialog.ui
+++ b/sc/uiconfig/scalc/ui/correlationdialog.ui
@@ -1,14 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.18.3 -->
+<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
<requires lib="gtk+" version="3.18"/>
- <requires lib="LibreOffice" version="1.0"/>
<object class="GtkDialog" id="CorrelationDialog">
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="title" translatable="yes" context="correlationdialog|CorrelationDialog">Correlation</property>
<property name="resizable">False</property>
<property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
@@ -96,10 +98,10 @@
<object class="GtkLabel" id="input-range-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes" context="correlationdialog|input-range-label">Input range:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">input-range-edit</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -110,10 +112,10 @@
<object class="GtkLabel" id="output-range-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes" context="correlationdialog|output-range-label">Results to:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">output-range-edit</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -121,7 +123,7 @@
</packing>
</child>
<child>
- <object class="foruilo-RefEdit" id="input-range-edit">
+ <object class="GtkEntry" id="input-range-edit">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
@@ -134,7 +136,7 @@
</packing>
</child>
<child>
- <object class="foruilo-RefEdit" id="output-range-edit">
+ <object class="GtkEntry" id="output-range-edit">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
@@ -147,7 +149,7 @@
</packing>
</child>
<child>
- <object class="foruilo-RefButton" id="input-range-button">
+ <object class="GtkButton" id="input-range-button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@@ -158,7 +160,7 @@
</packing>
</child>
<child>
- <object class="foruilo-RefButton" id="output-range-button">
+ <object class="GtkButton" id="output-range-button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@@ -266,6 +268,7 @@
</child>
<action-widgets>
<action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
<action-widget response="-11">help</action-widget>
</action-widgets>
</object>
diff --git a/solenv/sanitizers/ui/modules/scalc.suppr b/solenv/sanitizers/ui/modules/scalc.suppr
index f15bbf423067..c3ae37462c58 100644
--- a/solenv/sanitizers/ui/modules/scalc.suppr
+++ b/solenv/sanitizers/ui/modules/scalc.suppr
@@ -31,6 +31,8 @@ sc/uiconfig/scalc/ui/conflictsdialog.ui://GtkLabel[@id='label1'] orphan-label
sc/uiconfig/scalc/ui/conflictsdialog.ui://svtlo-SvSimpleTableContainer[@id='container:border'] no-labelled-by
sc/uiconfig/scalc/ui/consolidatedialog.ui://foruilo-RefEdit[@id='eddataarea'] no-labelled-by
sc/uiconfig/scalc/ui/consolidatedialog.ui://foruilo-RefEdit[@id='eddestarea'] no-labelled-by
+sc/uiconfig/scalc/ui/correlationdialog.ui://GtkButton[@id='input-range-button'] button-no-label
+sc/uiconfig/scalc/ui/correlationdialog.ui://GtkButton[@id='output-range-button'] button-no-label
sc/uiconfig/scalc/ui/dapiservicedialog.ui://GtkLabel[@id='label2'] orphan-label
sc/uiconfig/scalc/ui/dapiservicedialog.ui://GtkLabel[@id='label3'] orphan-label
sc/uiconfig/scalc/ui/dapiservicedialog.ui://GtkLabel[@id='label4'] orphan-label
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 0926dac611fb..74716b18aa35 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -1016,15 +1016,48 @@ IMPL_LINK_NOARG(SalInstanceWindow, HelpHdl, vcl::Window&, bool)
return false;
}
+typedef std::set<VclPtr<vcl::Window> > winset;
+
+namespace
+{
+ void hideUnless(const vcl::Window *pTop, const winset& rVisibleWidgets,
+ std::vector<VclPtr<vcl::Window> > &rWasVisibleWidgets)
+ {
+ for (vcl::Window* pChild = pTop->GetWindow(GetWindowType::FirstChild); pChild;
+ pChild = pChild->GetWindow(GetWindowType::Next))
+ {
+ if (!pChild->IsVisible())
+ continue;
+ if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
+ {
+ rWasVisibleWidgets.emplace_back(pChild);
+ pChild->Hide();
+ }
+ else if (isContainerWindow(pChild))
+ {
+ hideUnless(pChild, rVisibleWidgets, rWasVisibleWidgets);
+ }
+ }
+ }
+}
+
class SalInstanceDialog : public SalInstanceWindow, public virtual weld::Dialog
{
private:
VclPtr<::Dialog> m_xDialog;
+ // for calc ref dialog that shrink to range selection widgets and resize back
+ VclPtr<vcl::Window> m_xRefEdit;
+ std::vector<VclPtr<vcl::Window> > m_aHiddenWidgets; // vector of hidden Controls
+ long m_nOldEditWidthReq; // Original width request of the input field
+ sal_Int32 m_nOldBorderWidth; // border width for expanded dialog
+
public:
SalInstanceDialog(::Dialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
: SalInstanceWindow(pDialog, pBuilder, bTakeOwnership)
, m_xDialog(pDialog)
+ , m_nOldEditWidthReq(0)
+ , m_nOldBorderWidth(0)
{
}
@@ -1044,6 +1077,67 @@ public:
return m_xDialog->StartExecuteAsync(aCtx);
}
+ virtual void collapse(weld::Widget* pEdit, weld::Widget* pButton) override
+ {
+ SalInstanceWidget* pVclEdit = dynamic_cast<SalInstanceWidget*>(pEdit);
+ SalInstanceWidget* pVclButton = dynamic_cast<SalInstanceWidget*>(pButton);
+
+ vcl::Window* pRefEdit = pVclEdit->getWidget();
+ vcl::Window* pRefBtn = pVclButton ? pVclButton->getWidget() : nullptr;
+
+ auto nOldEditWidth = pRefEdit->GetSizePixel().Width();
+ m_nOldEditWidthReq = pRefEdit->get_width_request();
+
+ //We want just pRefBtn and pRefEdit to be shown
+ //mark widgets we want to be visible, starting with pRefEdit
+ //and all its direct parents.
+ winset aVisibleWidgets;
+ vcl::Window *pContentArea = m_xDialog->get_content_area();
+ for (vcl::Window *pCandidate = pRefEdit;
+ pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
+ pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
+ {
+ aVisibleWidgets.insert(pCandidate);
+ }
+ //same again with pRefBtn, except stop if there's a
+ //shared parent in the existing widgets
+ for (vcl::Window *pCandidate = pRefBtn;
+ pCandidate && (pCandidate != pContentArea && pCandidate->IsVisible());
+ pCandidate = pCandidate->GetWindow(GetWindowType::RealParent))
+ {
+ if (aVisibleWidgets.insert(pCandidate).second)
+ break;
+ }
+
+ //hide everything except the aVisibleWidgets
+ hideUnless(pContentArea, aVisibleWidgets, m_aHiddenWidgets);
+
+ pRefEdit->set_width_request(nOldEditWidth);
+ m_nOldBorderWidth = m_xDialog->get_border_width();
+ m_xDialog->set_border_width(0);
+ if (vcl::Window *pActionArea = m_xDialog->get_action_area())
+ pActionArea->Hide();
+ m_xDialog->setOptimalLayoutSize();
+ m_xRefEdit = pRefEdit;
+ }
+
+ virtual void undo_collapse() override
+ {
+ // All others: Show();
+ for (VclPtr<vcl::Window> const & pWindow : m_aHiddenWidgets)
+ {
+ pWindow->Show();
+ }
+ m_aHiddenWidgets.clear();
+
+ m_xRefEdit->set_width_request(m_nOldEditWidthReq);
+ m_xRefEdit.clear();
+ m_xDialog->set_border_width(m_nOldBorderWidth);
+ if (vcl::Window *pActionArea = m_xDialog->get_action_area())
+ pActionArea->Show();
+ m_xDialog->setOptimalLayoutSize();
+ }
+
virtual void SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink) override
{
m_xDialog->SetInstallLOKNotifierHdl(rLink);
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 7f294bae8c21..f7d138f5f538 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -2761,6 +2761,34 @@ struct DialogRunner
}
};
+typedef std::set<GtkWidget*> winset;
+
+namespace
+{
+ void hideUnless(GtkContainer *pTop, const winset& rVisibleWidgets,
+ std::vector<GtkWidget*> &rWasVisibleWidgets)
+ {
+ GList* pChildren = gtk_container_get_children(pTop);
+ for (GList* pEntry = g_list_first(pChildren); pEntry; pEntry = g_list_next(pEntry))
+ {
+ GtkWidget* pChild = static_cast<GtkWidget*>(pEntry->data);
+ if (!gtk_widget_get_visible(pChild))
+ continue;
+ if (rVisibleWidgets.find(pChild) == rVisibleWidgets.end())
+ {
+ g_object_ref(pChild);
+ rWasVisibleWidgets.emplace_back(pChild);
+ gtk_widget_hide(pChild);
+ }
+ else if (GTK_IS_CONTAINER(pChild))
+ {
+ hideUnless(GTK_CONTAINER(pChild), rVisibleWidgets, rWasVisibleWidgets);
+ }
+ }
+ g_list_free(pChildren);
+ }
+}
+
class GtkInstanceDialog : public GtkInstanceWindow, public virtual weld::Dialog
{
private:
@@ -2773,6 +2801,13 @@ private:
gulong m_nCloseSignalId;
gulong m_nResponseSignalId;
+ // for calc ref dialog that shrink to range selection widgets and resize back
+ GtkWidget* m_pRefEdit;
+ std::vector<GtkWidget*> m_aHiddenWidgets; // vector of hidden Controls
+ int m_nOldEditWidth; // Original width of the input field
+ int m_nOldEditWidthReq; // Original width request of the input field
+ int m_nOldBorderWidth; // border width for expanded dialog
+
static void signalClose(GtkWidget*, gpointer widget)
{
GtkInstanceDialog* pThis = static_cast<GtkInstanceDialog*>(widget);
@@ -2828,6 +2863,10 @@ public:
, m_aDialogRun(pDialog)
, m_nCloseSignalId(g_signal_connect(m_pDialog, "close", G_CALLBACK(signalClose), this))
, m_nResponseSignalId(0)
+ , m_pRefEdit(nullptr)
+ , m_nOldEditWidth(0)
+ , m_nOldEditWidthReq(0)
+ , m_nOldBorderWidth(0)
{
}
@@ -2948,6 +2987,69 @@ public:
return new GtkInstanceContainer(GTK_CONTAINER(gtk_dialog_get_content_area(m_pDialog)), m_pBuilder, false);
}
+ virtual void collapse(weld::Widget* pEdit, weld::Widget* pButton) override
+ {
+ GtkInstanceWidget* pVclEdit = dynamic_cast<GtkInstanceWidget*>(pEdit);
+ GtkInstanceWidget* pVclButton = dynamic_cast<GtkInstanceWidget*>(pButton);
+
+ GtkWidget* pRefEdit = pVclEdit->getWidget();
+ GtkWidget* pRefBtn = pVclButton ? pVclButton->getWidget() : nullptr;
+
+ m_nOldEditWidth = gtk_widget_get_allocated_width(pRefEdit);
+
+ gtk_widget_get_size_request(pRefEdit, &m_nOldEditWidthReq, nullptr);
+
+ //We want just pRefBtn and pRefEdit to be shown
+ //mark widgets we want to be visible, starting with pRefEdit
+ //and all its direct parents.
+ winset aVisibleWidgets;
+ GtkWidget *pContentArea = gtk_dialog_get_content_area(m_pDialog);
+ for (GtkWidget *pCandidate = pRefEdit;
+ pCandidate && pCandidate != pContentArea && gtk_widget_get_visible(pCandidate);
+ pCandidate = gtk_widget_get_parent(pCandidate))
+ {
+ aVisibleWidgets.insert(pCandidate);
+ }
+ //same again with pRefBtn, except stop if there's a
+ //shared parent in the existing widgets
+ for (GtkWidget *pCandidate = pRefBtn;
+ pCandidate && pCandidate != pContentArea && gtk_widget_get_visible(pCandidate);
+ pCandidate = gtk_widget_get_parent(pCandidate))
+ {
+ if (aVisibleWidgets.insert(pCandidate).second)
+ break;
+ }
+
+ //hide everything except the aVisibleWidgets
+ hideUnless(GTK_CONTAINER(pContentArea), aVisibleWidgets, m_aHiddenWidgets);
+
+ gtk_widget_set_size_request(pRefEdit, m_nOldEditWidth, -1);
+ m_nOldBorderWidth = gtk_container_get_border_width(GTK_CONTAINER(m_pDialog));
+ gtk_container_set_border_width(GTK_CONTAINER(m_pDialog), 0);
+ if (GtkWidget* pActionArea = gtk_dialog_get_action_area(m_pDialog))
+ gtk_widget_hide(pActionArea);
+ resize_to_request();
+ m_pRefEdit = pRefEdit;
+ }
+
+ virtual void undo_collapse() override
+ {
+ // All others: Show();
+ for (GtkWidget* pWindow : m_aHiddenWidgets)
+ {
+ gtk_widget_show(pWindow);
+ g_object_unref(pWindow);
+ }
+ m_aHiddenWidgets.clear();
+
+ gtk_widget_set_size_request(m_pRefEdit, m_nOldEditWidthReq, -1);
+ m_pRefEdit = nullptr;
+ gtk_container_set_border_width(GTK_CONTAINER(m_pDialog), m_nOldBorderWidth);
+ if (GtkWidget* pActionArea = gtk_dialog_get_action_area(m_pDialog))
+ gtk_widget_show(pActionArea);
+ resize_to_request();
+ }
+
virtual void SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>&) override
{
//not implemented for the gtk variant
@@ -2955,6 +3057,13 @@ public:
virtual ~GtkInstanceDialog() override
{
+ if (!m_aHiddenWidgets.empty())
+ {
+ for (GtkWidget* pWindow : m_aHiddenWidgets)
+ g_object_unref(pWindow);
+ m_aHiddenWidgets.clear();
+ }
+
g_signal_handler_disconnect(m_pDialog, m_nCloseSignalId);
if (m_nResponseSignalId)
g_signal_handler_disconnect(m_pDialog, m_nResponseSignalId);