[Libreoffice-commits] core.git: sw/inc sw/source
Pierre-Eric Pelloux-Prayer
pierre-eric at lanedo.com
Tue Oct 29 14:50:56 CET 2013
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-eric at 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 <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at 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();
More information about the Libreoffice-commits
mailing list