summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorPierre-Eric Pelloux-Prayer <pierre-eric@lanedo.com>2013-10-16 10:07:08 +0200
committerCaolán McNamara <caolanm@redhat.com>2013-10-29 13:50:33 +0000
commiteb42610c43b1011cde0af8b03d20ec70e4e789b5 (patch)
tree95aad299b12741b2c8f911ff7b9d642086361b65 /sw
parent38b8e742872b2cbdba93f4d1b84c8f09b5ab38ff (diff)
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@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/swabstdlg.hxx3
-rw-r--r--sw/source/ui/dialog/swdlgfact.cxx5
-rw-r--r--sw/source/ui/dialog/swdlgfact.hxx1
-rw-r--r--sw/source/ui/wrtsh/wrtsh2.cxx38
4 files changed, 44 insertions, 3 deletions
diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx
index 32d1d37f0b15..e1f5d7c60aea 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 bfd44dddbf40..e337589c65f1 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 fc80b86a4af8..09d59637ffcf 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 0e034e8174df..56046475210d 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();