sw/inc/swabstdlg.hxx | 3 ++- sw/source/ui/dialog/swdlgfact.cxx | 5 +++++ sw/source/ui/dialog/swdlgfact.hxx | 1 + sw/source/ui/wrtsh/wrtsh2.cxx | 38 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 44 insertions(+), 3 deletions(-)
New commits: commit eb42610c43b1011cde0af8b03d20ec70e4e789b5 Author: Pierre-Eric Pelloux-Prayer <pierre-e...@lanedo.com> Date: Wed Oct 16 10:07:08 2013 +0200 sw: clone InputField dialog on input-field removal Setup a listener on RES_FIELD_DELETED event, and cancel dialog if a field is deleted. Add Cancellable capability to Input dialog too. Fixes a crasher that occurs when fields are removed (e.g: by an extension) while the InputField dialog is running. Change-Id: I9e132a109cba3127b934a3baecbf445a2bde1377 Reviewed-on: https://gerrit.libreoffice.org/6261 Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx index 32d1d37..e1f5d7c 100644 --- a/sw/inc/swabstdlg.hxx +++ b/sw/inc/swabstdlg.hxx @@ -99,12 +99,13 @@ public: virtual OUString GetCurrShortName() const = 0; }; -class AbstractFldInputDlg : public VclAbstractDialog +class AbstractFldInputDlg : public VclAbstractTerminatedDialog { public: //from class SalFrame virtual void SetWindowState( const OString & rStr ) = 0; virtual OString GetWindowState( sal_uLong nMask = WINDOWSTATE_MASK_ALL ) const = 0; + virtual void EndDialog(long ) = 0; }; class AbstractInsFootNoteDlg : public VclAbstractDialog diff --git a/sw/source/ui/dialog/swdlgfact.cxx b/sw/source/ui/dialog/swdlgfact.cxx index bfd44dd..e337589 100644 --- a/sw/source/ui/dialog/swdlgfact.cxx +++ b/sw/source/ui/dialog/swdlgfact.cxx @@ -414,6 +414,11 @@ OString AbstractFldInputDlg_Impl::GetWindowState( sal_uLong nMask ) const return pDlg->GetWindowState( nMask ); } +void AbstractFldInputDlg_Impl::EndDialog(long n) +{ + pDlg->EndDialog(n); +} + OUString AbstractInsFootNoteDlg_Impl::GetFontName() { return pDlg->GetFontName(); diff --git a/sw/source/ui/dialog/swdlgfact.hxx b/sw/source/ui/dialog/swdlgfact.hxx index fc80b86..09d5963 100644 --- a/sw/source/ui/dialog/swdlgfact.hxx +++ b/sw/source/ui/dialog/swdlgfact.hxx @@ -245,6 +245,7 @@ class AbstractFldInputDlg_Impl : public AbstractFldInputDlg //from class SalFrame virtual void SetWindowState( const OString & rStr ) ; virtual OString GetWindowState( sal_uLong nMask = WINDOWSTATE_MASK_ALL ) const ; + virtual void EndDialog(long); }; class SwInsFootNoteDlg; diff --git a/sw/source/ui/wrtsh/wrtsh2.cxx b/sw/source/ui/wrtsh/wrtsh2.cxx index 0e034e8..5604647 100644 --- a/sw/source/ui/wrtsh/wrtsh2.cxx +++ b/sw/source/ui/wrtsh/wrtsh2.cxx @@ -124,8 +124,11 @@ void SwWrtShell::UpdateInputFlds( SwInputFieldList* pLst, sal_Bool bOnlyInSel ) else bCancel = StartInputFldDlg( pField, sal_True, 0, &aDlgPos); - // Otherwise update error at multi-selection: - pTmp->GetField( i )->GetTyp()->UpdateFlds(); + if (!bCancel) + { + // Otherwise update error at multi-selection: + pTmp->GetField( i )->GetTyp()->UpdateFlds(); + } } pTmp->PopCrsr(); } @@ -134,6 +137,28 @@ void SwWrtShell::UpdateInputFlds( SwInputFieldList* pLst, sal_Bool bOnlyInSel ) delete pTmp; } +// Listener class: will close InputField dialog if input field(s) +// is(are) deleted (for instance, by an extension) after the dialog shows up. +// Otherwise, the for loop in SwWrtShell::UpdateInputFlds will crash when doing: +// 'pTmp->GetField( i )->GetTyp()->UpdateFlds();' +// on a deleted field. +class FieldDeletionModify : public SwModify +{ + public: + FieldDeletionModify(AbstractFldInputDlg* pInputFieldDlg) : mpInputFieldDlg(pInputFieldDlg) {} + + void Modify( const SfxPoolItem* pOld, const SfxPoolItem *) + { + // Input fields have been deleted: better to close the dialog + if (pOld->Which() == RES_FIELD_DELETED) + { + mpInputFieldDlg->EndDialog(RET_CANCEL); + } + } + private: + AbstractFldInputDlg* mpInputFieldDlg; +}; + // Start input dialog for a specific field sal_Bool SwWrtShell::StartInputFldDlg( SwField* pFld, sal_Bool bNextButton, @@ -146,7 +171,16 @@ sal_Bool SwWrtShell::StartInputFldDlg( SwField* pFld, sal_Bool bNextButton, OSL_ENSURE(pDlg, "Dialogdiet fail!"); if(pWindowState && !pWindowState->isEmpty()) pDlg->SetWindowState(*pWindowState); + + // Register for possible input field deletion while dialog is open + FieldDeletionModify aModify(pDlg); + GetDoc()->GetUnoCallBack()->Add(&aModify); + sal_Bool bRet = RET_CANCEL == pDlg->Execute(); + + // Dialog closed, remove modification listener + GetDoc()->GetUnoCallBack()->Remove(&aModify); + if(pWindowState) *pWindowState = pDlg->GetWindowState();
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits