editeng/source/editeng/impedit.hxx        |    1 
 editeng/source/editeng/impedit2.cxx       |  103 ++++++++++++++++--------------
 include/svx/svxids.hrc                    |    7 +-
 sw/source/uibase/docvw/AnnotationWin2.cxx |   30 +++++---
 sw/source/uibase/fldui/fldmgr.cxx         |    9 ++
 sw/source/uibase/inc/fldmgr.hxx           |    1 
 sw/source/uibase/wrtsh/wrtsh1.cxx         |   12 +++
 7 files changed, 102 insertions(+), 61 deletions(-)

New commits:
commit a3a59876a48688d39e9057bad4d6c7ebb440ecea
Author:     Michael Stahl <[email protected]>
AuthorDate: Fri Feb 14 14:11:10 2025 +0100
Commit:     Michael Stahl <[email protected]>
CommitDate: Fri Apr 4 13:06:48 2025 +0200

    editeng: factor out ImpEditEngine::UpdateSelection()
    
    Change-Id: Ia6f694a813ad30aadf159db0f75fb1a86e9663dd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181676
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins

diff --git a/editeng/source/editeng/impedit.hxx 
b/editeng/source/editeng/impedit.hxx
index 76dea3933b68..fc7d376af6dd 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -1007,6 +1007,7 @@ public:
 
     const SfxItemSet& GetEmptyItemSet() const;
 
+    bool                    UpdateSelection(EditSelection &);
     void                    UpdateSelections();
 
     void                EnableUndo( bool bEnable );
diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index 2e61efacd028..bc00e49613d0 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -3740,6 +3740,60 @@ sal_uInt32 ImpEditEngine::GetParaHeight(sal_Int32 
nParagraph) const
     return nHeight;
 }
 
+bool ImpEditEngine::UpdateSelection(EditSelection & rCurSel)
+{
+    bool bChanged = false;
+    for (const std::unique_ptr<DeletedNodeInfo> & aDeletedNode : 
maDeletedNodes)
+    {
+        const DeletedNodeInfo& rInf = *aDeletedNode;
+        if ((rCurSel.Min().GetNode() == rInf.GetNode()) ||
+            (rCurSel.Max().GetNode() == rInf.GetNode()))
+        {
+            // Use ParaPortions, as now also hidden paragraphs have to be
+            // taken into account!
+            sal_Int32 nPara = rInf.GetPosition();
+            if (!GetParaPortions().exists(nPara)) // Last paragraph
+            {
+                nPara = GetParaPortions().lastIndex();
+            }
+            assert(GetParaPortions().exists(nPara) && "Empty Document in 
UpdateSelections ?");
+            // Do not end up from a hidden paragraph:
+            sal_Int32 nCurrentPara = nPara;
+            sal_Int32 nLastParaIndex = GetParaPortions().lastIndex();
+            while (nPara <= nLastParaIndex && 
!GetParaPortions().getRef(nPara).IsVisible())
+                nPara++;
+            if (nPara > nLastParaIndex) // then also backwards ...
+            {
+                nPara = nCurrentPara;
+                while ( nPara && !GetParaPortions().getRef(nPara).IsVisible() )
+                    nPara--;
+            }
+            OSL_ENSURE(GetParaPortions().getRef(nPara).IsVisible(), "No 
visible paragraph found: UpdateSelections" );
+
+            ParaPortion& rParaPortion = GetParaPortions().getRef(nPara);
+            EditSelection aTmpSelection(EditPaM(rParaPortion.GetNode(), 0));
+            rCurSel = aTmpSelection;
+            bChanged=true;
+            break;  // for loop
+        }
+    }
+    if ( !bChanged )
+    {
+        // Check Index if node shrunk.
+        if (rCurSel.Min().GetIndex() > rCurSel.Min().GetNode()->Len())
+        {
+            rCurSel.Min().SetIndex(rCurSel.Min().GetNode()->Len());
+            bChanged = true;
+        }
+        if (rCurSel.Max().GetIndex() > rCurSel.Max().GetNode()->Len())
+        {
+            rCurSel.Max().SetIndex(rCurSel.Max().GetNode()->Len());
+            bChanged = true;
+        }
+    }
+    return bChanged;
+}
+
 void ImpEditEngine::UpdateSelections()
 {
     // Check whether one of the selections is at a deleted node...
@@ -3747,54 +3801,9 @@ void ImpEditEngine::UpdateSelections()
     for (EditView* pView : maEditViews)
     {
         EditSelection aCurSel( pView->getImpl().GetEditSelection() );
-        bool bChanged = false;
-        for (const std::unique_ptr<DeletedNodeInfo> & aDeletedNode : 
maDeletedNodes)
+        if (UpdateSelection(aCurSel))
         {
-            const DeletedNodeInfo& rInf = *aDeletedNode;
-            if ( ( aCurSel.Min().GetNode() == rInf.GetNode() ) ||
-                 ( aCurSel.Max().GetNode() == rInf.GetNode() ) )
-            {
-                // Use ParaPortions, as now also hidden paragraphs have to be
-                // taken into account!
-                sal_Int32 nPara = rInf.GetPosition();
-                if (!GetParaPortions().exists(nPara)) // Last paragraph
-                {
-                    nPara = GetParaPortions().lastIndex();
-                }
-                assert(GetParaPortions().exists(nPara) && "Empty Document in 
UpdateSelections ?");
-                // Do not end up from a hidden paragraph:
-                sal_Int32 nCurrentPara = nPara;
-                sal_Int32 nLastParaIndex = GetParaPortions().lastIndex();
-                while (nPara <= nLastParaIndex && 
!GetParaPortions().getRef(nPara).IsVisible())
-                    nPara++;
-                if (nPara > nLastParaIndex) // then also backwards ...
-                {
-                    nPara = nCurrentPara;
-                    while ( nPara && 
!GetParaPortions().getRef(nPara).IsVisible() )
-                        nPara--;
-                }
-                OSL_ENSURE(GetParaPortions().getRef(nPara).IsVisible(), "No 
visible paragraph found: UpdateSelections" );
-
-                ParaPortion& rParaPortion = GetParaPortions().getRef(nPara);
-                EditSelection aTmpSelection(EditPaM(rParaPortion.GetNode(), 
0));
-                pView->getImpl().SetEditSelection( aTmpSelection );
-                bChanged=true;
-                break;  // for loop
-            }
-        }
-        if ( !bChanged )
-        {
-            // Check Index if node shrunk.
-            if ( aCurSel.Min().GetIndex() > aCurSel.Min().GetNode()->Len() )
-            {
-                aCurSel.Min().SetIndex( aCurSel.Min().GetNode()->Len() );
-                pView->getImpl().SetEditSelection( aCurSel );
-            }
-            if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
-            {
-                aCurSel.Max().SetIndex( aCurSel.Max().GetNode()->Len() );
-                pView->getImpl().SetEditSelection( aCurSel );
-            }
+            pView->getImpl().SetEditSelection(aCurSel);
         }
     }
     maDeletedNodes.clear();
commit 46000e9db470c6d7735aac050dd5e944c79d9b38
Author:     Michael Stahl <[email protected]>
AuthorDate: Thu Apr 3 17:49:13 2025 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Fri Apr 4 13:06:38 2025 +0200

    svx,sw: when replying to comment, set parent ids immediately
    
    ... and not after insertion is already finished.
    
    This requires 3 new slots because SwWrtShell::InsertPostIt() takes a
    SfxRequest...
    
    Then SwInsertField_Data needs another different temporary representation.
    
    Open question is why does a comment need to have 3 different ids.
    
    Change-Id: Ie655c4f089240b8407c52288b2f96653299665c8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183686
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc
index 8b18de6306e8..4885e058c01a 100644
--- a/include/svx/svxids.hrc
+++ b/include/svx/svxids.hrc
@@ -1076,9 +1076,12 @@ class XFillGradientItem;
 #define SID_PROTECTSIZE                                 
TypedWhichId<SfxBoolItem>( SID_SVX_START + 1216 )
 #define SID_PROTECTPOS                                  
TypedWhichId<SfxBoolItem>( SID_SVX_START + 1217 )
 
-// IMPORTANT NOTE: adjust SID_SVX_FIRSTFREE, when adding new slot id
-#define SID_SVX_FIRSTFREE                               ( SID_SVX_START + 1217 
+ 1 )
+#define SID_ATTR_POSTIT_PARENTPARAID                    
TypedWhichId<SvxPostItIdItem>(SID_SVX_START + 1218)
+#define SID_ATTR_POSTIT_PARENTPOSTITID                  
TypedWhichId<SvxPostItIdItem>(SID_SVX_START + 1219)
+#define SID_ATTR_POSTIT_PARENTNAME                      
TypedWhichId<SfxStringItem>(SID_SVX_START + 1220)
 
+// IMPORTANT NOTE: adjust SID_SVX_FIRSTFREE, when adding new slot id
+#define SID_SVX_FIRSTFREE                               (SID_SVX_START + 1220 
+ 1)
 
 // Overflow check for slot IDs
 #if SID_SVX_FIRSTFREE > SID_SVX_END
diff --git a/sw/source/uibase/docvw/AnnotationWin2.cxx 
b/sw/source/uibase/docvw/AnnotationWin2.cxx
index 6bd5eeb72992..6b495bc6ec03 100644
--- a/sw/source/uibase/docvw/AnnotationWin2.cxx
+++ b/sw/source/uibase/docvw/AnnotationWin2.cxx
@@ -64,6 +64,8 @@
 #include <vcl/uitest/logger.hxx>
 #include <vcl/uitest/eventdescription.hxx>
 
+#include <svx/postattr.hxx>
+
 #include <edtwin.hxx>
 #include <view.hxx>
 #include <docsh.hxx>
@@ -1068,20 +1070,26 @@ void SwAnnotationWin::ExecuteCommand(sal_uInt16 nSlot)
             SwitchToFieldPos();
 
             SwDocShell* pShell = mrView.GetDocShell();
-            if (bReply)
+            if (!bReply)
+            {
+                // synchronous dispatch
+                mrView.GetViewFrame().GetDispatcher()->Execute(FN_POSTIT);
+            }
+            else
+            {
                 
pShell->GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+                SvxPostItIdItem parentParaId{SID_ATTR_POSTIT_PARENTPARAID};
+                parentParaId.SetValue(OUString::number(GetParaId()));
+                SvxPostItIdItem parentPostitId{SID_ATTR_POSTIT_PARENTPOSTITID};
+                
parentPostitId.SetValue(OUString::number(GetPostItField()->GetPostItId()));
+                this->GeneratePostItName();
+                SfxStringItem const parentName{SID_ATTR_POSTIT_PARENTNAME,
+                    GetPostItField()->GetName()};
+                // transport parent ids to SwWrtShell::InsertPostIt()
+                SfxPoolItem const* items[]{ &parentParaId, &parentPostitId, 
&parentName, nullptr };
+                mrView.GetViewFrame().GetDispatcher()->Execute(FN_POSTIT, 
SfxCallMode::SLOT, items);
 
-            // synchronous dispatch
-            mrView.GetViewFrame().GetDispatcher()->Execute(FN_POSTIT);
-
-            if (bReply)
-            {
-                // Get newly created SwPostItField and set its paraIdParent
                 auto pPostItField = mrMgr.GetLatestPostItField();
-                pPostItField->SetParentId(GetParaId());
-                
pPostItField->SetParentPostItId(GetPostItField()->GetPostItId());
-                this->GeneratePostItName();
-                pPostItField->SetParentName(GetPostItField()->GetName());
 
                 // In this case, force generating the associated window
                 // synchronously so we can bundle its use of the registered
diff --git a/sw/source/uibase/fldui/fldmgr.cxx 
b/sw/source/uibase/fldui/fldmgr.cxx
index cfef4e3e7bf5..cd738a47f710 100644
--- a/sw/source/uibase/fldui/fldmgr.cxx
+++ b/sw/source/uibase/fldui/fldmgr.cxx
@@ -902,7 +902,7 @@ bool SwFieldMgr::InsertField(
         {
             SvtUserOptions aUserOpt;
             SwPostItFieldType* pType = 
static_cast<SwPostItFieldType*>(pCurShell->GetFieldType(0, SwFieldIds::Postit));
-            pField.reset(
+            auto const pPostItField(
                 new SwPostItField(
                     pType,
                     rData.m_sPar1, // author
@@ -910,6 +910,13 @@ bool SwFieldMgr::InsertField(
                     aUserOpt.GetID(), // author's initials
                     OUString(), // name
                     DateTime(DateTime::SYSTEM) ));
+            if (rData.m_oParentId)
+            {
+                pPostItField->SetParentId(std::get<0>(*rData.m_oParentId));
+                
pPostItField->SetParentPostItId(std::get<1>(*rData.m_oParentId));
+                pPostItField->SetParentName(std::get<2>(*rData.m_oParentId));
+            }
+            pField.reset(pPostItField);
         }
         break;
         case SwFieldTypesEnum::Script:
diff --git a/sw/source/uibase/inc/fldmgr.hxx b/sw/source/uibase/inc/fldmgr.hxx
index 48d4500513c4..8f3409aa0694 100644
--- a/sw/source/uibase/inc/fldmgr.hxx
+++ b/sw/source/uibase/inc/fldmgr.hxx
@@ -83,6 +83,7 @@ struct SwInsertField_Data
     weld::Widget* m_pParent; // parent widget used for 
SwWrtShell::StartInputFieldDlg()
     /// Marks the PostIt field's annotation start/end if it differs from the 
cursor selection.
     std::optional<SwPaM> m_oAnnotationRange;
+    std::optional<std::tuple<sal_uInt32, sal_uInt32, OUString>> m_oParentId;
 
     SwInsertField_Data(SwFieldTypesEnum nType, sal_uInt16 nSub, OUString 
aPar1, OUString aPar2,
                     sal_uInt32 nFormatId, SwWrtShell* pShell = nullptr, 
sal_Unicode cSep = ' ', bool bIsAutoLanguage = true) :
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx 
b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 80d263fb4e69..0444700deff1 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -2325,6 +2325,18 @@ void SwWrtShell::InsertPostIt(SwFieldMgr& rFieldMgr, 
const SfxRequest& rReq)
 
         SwInsertField_Data aData(SwFieldTypesEnum::Postit, 0, sAuthor, sText, 
0);
 
+        {
+            SvxPostItIdItem const*const 
pParentParaIdItem{rReq.GetArg<SvxPostItIdItem>(SID_ATTR_POSTIT_PARENTPARAID)};
+            SvxPostItIdItem const*const 
pParentPostItIdItem{rReq.GetArg<SvxPostItIdItem>(SID_ATTR_POSTIT_PARENTPOSTITID)};
+            SfxStringItem const*const 
pParentNameItem{rReq.GetArg<SfxStringItem>(SID_ATTR_POSTIT_PARENTNAME)};
+            if (pParentParaIdItem && pParentPostItIdItem && pParentNameItem)
+            {
+                
aData.m_oParentId.emplace(pParentParaIdItem->GetValue().toUInt32(),
+                    pParentPostItIdItem->GetValue().toUInt32(),
+                    pParentNameItem->GetValue());
+            }
+        }
+
         if (IsSelFrameMode())
         {
             SwFlyFrame* pFly = GetSelectedFlyFrame();

Reply via email to