[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