diff options
22 files changed, 170 insertions, 15 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index a7cbbb271b48..c5720c992ea5 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -3853,6 +3853,7 @@ static void doc_iniUnoCommands () u".uno:ReplyComment"_ustr, u".uno:ResolveComment"_ustr, u".uno:ResolveCommentThread"_ustr, + u".uno:PromoteComment"_ustr, u".uno:InsertRowsBefore"_ustr, u".uno:InsertRowsAfter"_ustr, u".uno:InsertColumnsBefore"_ustr, diff --git a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu index af3cff149c96..cb05dab650c7 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu @@ -6563,6 +6563,14 @@ bit 3 (0x8): #define UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON 8 <value>1</value> </prop> </node> + <node oor:name=".uno:PromoteComment" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Promote Comment To Root</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> <node oor:name=".uno:CellVertTop" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">Top</value> diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx index d0ebae89f73d..ec73bf047279 100644 --- a/sfx2/source/control/dispatch.cxx +++ b/sfx2/source/control/dispatch.cxx @@ -1532,6 +1532,7 @@ bool SfxDispatcher::IsCommandAllowedInLokReadOnlyViewMode (OUString commandName) u".uno:DeleteComment"_ustr, u".uno:DeleteAnnotation"_ustr, u".uno:EditAnnotation"_ustr, + u".uno:PromoteComment"_ustr, }; if (std::find(std::begin(allowedList), std::end(allowedList), commandName) != std::end(allowedList)) diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx index 3c9643eed181..30cf78a710f5 100644 --- a/sfx2/source/control/unoctitm.cxx +++ b/sfx2/source/control/unoctitm.cxx @@ -1219,6 +1219,7 @@ constexpr auto handlers = frozen::make_unordered_map<std::u16string_view, Payloa { u"DeleteAnnotation", EnabledPayload }, { u"ResolveAnnotation", EnabledPayload }, { u"ResolveAnnotationThread", EnabledPayload }, + { u"PromoteComment", EnabledPayload }, { u"InsertRowsBefore", EnabledPayload }, { u"InsertRowsAfter", EnabledPayload }, { u"InsertColumnsBefore", EnabledPayload }, diff --git a/sw/inc/AnnotationWin.hxx b/sw/inc/AnnotationWin.hxx index d5f31937409f..ec6a09cd8775 100644 --- a/sw/inc/AnnotationWin.hxx +++ b/sw/inc/AnnotationWin.hxx @@ -208,6 +208,9 @@ class SAL_DLLPUBLIC_RTTI SwAnnotationWin final : public InterimItemWindow virtual FactoryFunction GetUITestFactory() const override; + bool IsRootNote() const; + void SetAsRoot(); + private: virtual void LoseFocus() override; diff --git a/sw/inc/PostItMgr.hxx b/sw/inc/PostItMgr.hxx index 3461216894c4..05cc25baa032 100644 --- a/sw/inc/PostItMgr.hxx +++ b/sw/inc/PostItMgr.hxx @@ -171,6 +171,8 @@ class SAL_DLLPUBLIC_RTTI SwPostItMgr final : public SfxListener, void DeleteCommentThread(sal_uInt32 nPostItId); void ToggleResolved(sal_uInt32 nPostItId); void ToggleResolvedForThread(sal_uInt32 nPostItId); + void PromoteToRoot(sal_uInt32 nPostItId); + void MoveSubthreadToRoot(const sw::annotation::SwAnnotationWin* pNewRoot); sw::annotation::SwAnnotationWin* GetRemovedAnnotationWin(const SfxBroadcaster* pBroadcast); diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index 1e2cc3d10991..6a2406c0a32a 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -804,6 +804,7 @@ class SwUINumRuleItem; #define FN_RESOLVE_NOTE (FN_NOTES+9) #define FN_RESOLVE_NOTE_THREAD (FN_NOTES+10) #define FN_DELETE_COMMENT_THREAD (FN_NOTES+11) +#define FN_PROMOTE_COMMENT (FN_NOTES+12) // Region: Parameter #define FN_PARAM_MOVE_COUNT TypedWhichId<SfxInt32Item>(FN_PARAM+2) diff --git a/sw/sdi/_annotsh.sdi b/sw/sdi/_annotsh.sdi index 919dd0513aa5..0c26a55dd6d0 100644 --- a/sw/sdi/_annotsh.sdi +++ b/sw/sdi/_annotsh.sdi @@ -78,6 +78,12 @@ interface _Annotation StateMethod = GetNoteState ; ] + FN_PROMOTE_COMMENT + [ + ExecMethod = NoteExec ; + StateMethod = GetNoteState ; + ] + FN_POSTIT [ ExecMethod = NoteExec ; diff --git a/sw/sdi/_textsh.sdi b/sw/sdi/_textsh.sdi index 9f5e604ec297..8a37e74593e7 100644 --- a/sw/sdi/_textsh.sdi +++ b/sw/sdi/_textsh.sdi @@ -1115,6 +1115,11 @@ interface BaseText ExecMethod = ExecField ; StateMethod = StateField; ] + FN_PROMOTE_COMMENT + [ + ExecMethod = ExecField ; + StateMethod = StateField; + ] FN_REDLINE_COMMENT // status(play) [ ExecMethod = ExecField ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index ccbfb29dfb75..f1aad4a6d136 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -7851,6 +7851,23 @@ SfxStringItem HideAuthor FN_HIDE_NOTE_AUTHOR ( SfxStringItem Author FN_HIDE_NOTE GroupId = SfxGroupId::Edit; ] +SfxVoidItem PromoteComment FN_PROMOTE_COMMENT +(SvxPostItIdItem Id SID_ATTR_POSTIT_ID) +[ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = SfxGroupId::Edit; +] + SvxViewLayoutItem ViewLayout SID_ATTR_VIEWLAYOUT [ AutoUpdate = FALSE, diff --git a/sw/source/uibase/docvw/AnnotationMenuButton.cxx b/sw/source/uibase/docvw/AnnotationMenuButton.cxx index 345e57d4b084..5dbe5f07beae 100644 --- a/sw/source/uibase/docvw/AnnotationMenuButton.cxx +++ b/sw/source/uibase/docvw/AnnotationMenuButton.cxx @@ -55,6 +55,8 @@ IMPL_LINK(SwAnnotationWin, SelectHdl, const OUString&, rIdent, void) ExecuteCommand(FN_DELETE_ALL_NOTES); else if (rIdent == "formatall") ExecuteCommand(FN_FORMAT_ALL_NOTES); + else if (rIdent == "promote") + ExecuteCommand(FN_PROMOTE_COMMENT); if (bSwitchedFocus) UnsetActiveSidebarWin(); @@ -76,6 +78,7 @@ IMPL_LINK_NOARG(SwAnnotationWin, ToggleHdl, weld::Toggleable&, void) mxMenuButton->set_item_visible(u"resolvethread"_ustr, false); mxMenuButton->set_item_visible(u"unresolvethread"_ustr, false); mxMenuButton->set_item_visible(u"delete"_ustr, false ); + mxMenuButton->set_item_visible(u"promote"_ustr, false); } else { @@ -86,6 +89,7 @@ IMPL_LINK_NOARG(SwAnnotationWin, ToggleHdl, weld::Toggleable&, void) mxMenuButton->set_item_visible(u"resolvethread"_ustr, !IsThreadResolved()); mxMenuButton->set_item_visible(u"unresolvethread"_ustr, IsThreadResolved()); mxMenuButton->set_item_visible(u"delete"_ustr, !IsReadOnlyOrProtected()); + mxMenuButton->set_item_visible(u"promote"_ustr, !IsReadOnlyOrProtected() && !IsRootNote()); } mxMenuButton->set_item_visible(u"deletethread"_ustr, !bReadOnly); diff --git a/sw/source/uibase/docvw/AnnotationWin.cxx b/sw/source/uibase/docvw/AnnotationWin.cxx index 669db57b3bb8..46628b098527 100644 --- a/sw/source/uibase/docvw/AnnotationWin.cxx +++ b/sw/source/uibase/docvw/AnnotationWin.cxx @@ -307,6 +307,24 @@ bool SwAnnotationWin::IsThreadResolved() } } +bool SwAnnotationWin::IsRootNote() const +{ + return static_cast<SwPostItField*>(mpFormatField->GetField())->GetParentPostItId() == 0; +} + +void SwAnnotationWin::SetAsRoot() +{ + if (!IsRootNote()) + { + SwPostItField* pPostIt = static_cast<SwPostItField*>(mpFormatField->GetField()); + pPostIt->SetParentId(0); + pPostIt->SetParentPostItId(0); + pPostIt->SetParentName(""); + mrMgr.MoveSubthreadToRoot(this); + mpFormatField->Broadcast(SwFormatFieldHint(nullptr, SwFormatFieldHintWhich::CHANGED)); + } +} + void SwAnnotationWin::UpdateData() { if ( mpOutliner->IsModified() || mbResolvedStateUpdated ) diff --git a/sw/source/uibase/docvw/AnnotationWin2.cxx b/sw/source/uibase/docvw/AnnotationWin2.cxx index 437ee6baa220..306e4795a41f 100644 --- a/sw/source/uibase/docvw/AnnotationWin2.cxx +++ b/sw/source/uibase/docvw/AnnotationWin2.cxx @@ -1079,10 +1079,10 @@ void SwAnnotationWin::ExecuteCommand(sal_uInt16 nSlot) { // Get newly created SwPostItField and set its paraIdParent auto pPostItField = mrMgr.GetLatestPostItField(); - pPostItField->SetParentId(GetTopReplyNote()->GetParaId()); - pPostItField->SetParentPostItId(GetTopReplyNote()->GetPostItField()->GetPostItId()); + pPostItField->SetParentId(GetParaId()); + pPostItField->SetParentPostItId(GetPostItField()->GetPostItId()); this->GeneratePostItName(); - pPostItField->SetParentName(GetTopReplyNote()->GetPostItField()->GetName()); + pPostItField->SetParentName(GetPostItField()->GetName()); // In this case, force generating the associated window // synchronously so we can bundle its use of the registered @@ -1133,6 +1133,12 @@ void SwAnnotationWin::ExecuteCommand(sal_uInt16 nSlot) mrView.GetViewFrame().GetBindings().Execute( nSlot, aItems, SfxCallMode::ASYNCHRON ); } break; + case FN_PROMOTE_COMMENT: + SetAsRoot(); + DoResize(); + Invalidate(); + mrMgr.LayoutPostIts(); + break; default: mrView.GetViewFrame().GetBindings().Execute( nSlot ); break; diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx index 56abcb248cfd..c50ffd06485a 100644 --- a/sw/source/uibase/docvw/PostItMgr.cxx +++ b/sw/source/uibase/docvw/PostItMgr.cxx @@ -1735,6 +1735,62 @@ void SwPostItMgr::Delete() LayoutPostIts(); } +void SwPostItMgr::PromoteToRoot(sal_uInt32 nPostItId) +{ + mpWrtShell->StartAllAction(); + + SwRewriter aRewriter; + aRewriter.AddRule(UndoArg1, SwResId(STR_CONTENT_TYPE_SINGLE_POSTIT)); + + // We have no undo ID at the moment. + + IsPostitFieldWithPostitId aFilter(nPostItId); + FieldDocWatchingStack aStack(mvPostItFields, *mpView->GetDocShell(), aFilter); + const SwFormatField* pField = aStack.pop(); + // pField now contains our AnnotationWin object + if (pField) + { + SwAnnotationWin* pWin = GetSidebarWin(pField); + pWin->SetAsRoot(); + } + PrepareView(); + mpWrtShell->EndAllAction(); + mbLayout = true; + CalcRects(); + LayoutPostIts(); +} + +void SwPostItMgr::MoveSubthreadToRoot(const sw::annotation::SwAnnotationWin* pNewRoot) +{ + std::vector<std::unique_ptr<SwSidebarItem>>::iterator first, middle, last; + first = std::find_if(mvPostItFields.begin(), mvPostItFields.end(), + [&pNewRoot](const std::unique_ptr<SwSidebarItem>& pField) { + return pField->mpPostIt == pNewRoot; + }); + if (first == mvPostItFields.end()) + return; + std::set<int> aPostItIds; + aPostItIds.insert(pNewRoot->GetPostItField()->GetPostItId()); + middle = first + 1; + while (middle != mvPostItFields.end() + && aPostItIds.contains((*middle)->mpPostIt->GetPostItField()->GetParentPostItId())) + { + aPostItIds.insert((*middle)->mpPostIt->GetPostItField()->GetPostItId()); + ++middle; + } + if (middle == mvPostItFields.end()) + return; + last = middle; + while (last != mvPostItFields.end() + && (*last)->mpPostIt->GetPostItField()->GetParentPostItId() != 0) + ++last; + if (last == middle) + return; + std::rotate(first, middle, last); + CalcRects(); + LayoutPostIts(); +} + void SwPostItMgr::ExecuteFormatAllDialog(SwView& rView) { if (mvPostItFields.empty()) diff --git a/sw/source/uibase/shells/annotsh.cxx b/sw/source/uibase/shells/annotsh.cxx index a7e3afe845a0..6af5aa52fba5 100644 --- a/sw/source/uibase/shells/annotsh.cxx +++ b/sw/source/uibase/shells/annotsh.cxx @@ -1129,6 +1129,7 @@ void SwAnnotationShell::NoteExec(SfxRequest const &rReq) case FN_DELETE_COMMENT_THREAD: case FN_RESOLVE_NOTE: case FN_RESOLVE_NOTE_THREAD: + case FN_PROMOTE_COMMENT: if ( pPostItMgr->HasActiveSidebarWin() ) pPostItMgr->GetActiveSidebarWin()->ExecuteCommand(nSlot); break; @@ -1255,6 +1256,15 @@ void SwAnnotationShell::GetNoteState(SfxItemSet &rSet) } break; } + case FN_PROMOTE_COMMENT: + { + if (!pPostItMgr || !pPostItMgr->HasActiveAnnotationWin() + || pPostItMgr->GetActiveSidebarWin()->IsRootNote()) + { + rSet.DisableItem(nWhich); + } + break; + } default: rSet.InvalidateItem( nWhich ); break; diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index 653b4a93df2a..8365802163f1 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -518,18 +518,6 @@ void SwTextShell::ExecField(SfxRequest &rReq) sText = pTextItem->GetValue(); pMgr->RegisterAnswerText(sText); pWin->ExecuteCommand(nSlot); - - SwPostItField* pLatestPostItField = pMgr->GetLatestPostItField(); - if (pLatestPostItField) - { - // Set the parent postit id of the reply. - pLatestPostItField->SetParentPostItId(pIdItem->GetValue().toUInt32()); - - // If name of the replied comment is empty, we need to set a name in order to connect them in the xml file. - pWin->GeneratePostItName(); // Generates a name if the current name is empty. - - pLatestPostItField->SetParentName(pWin->GetPostItField()->GetName()); - } } } } @@ -561,6 +549,15 @@ void SwTextShell::ExecField(SfxRequest &rReq) } } break; + case FN_PROMOTE_COMMENT: + { + const SvxPostItIdItem* pIdItem = rReq.GetArg<SvxPostItIdItem>(SID_ATTR_POSTIT_ID); + if (pIdItem && !pIdItem->GetValue().isEmpty() && GetView().GetPostItMgr()) + { + GetView().GetPostItMgr()->PromoteToRoot(pIdItem->GetValue().toUInt32()); + } + break; + } case FN_REDLINE_COMMENT: { const SwRangeRedline *pRedline = rSh.GetCurrRedline(); diff --git a/sw/uiconfig/sglobal/menubar/menubar.xml b/sw/uiconfig/sglobal/menubar/menubar.xml index f1caab1bc1b4..13bd2a648fc9 100644 --- a/sw/uiconfig/sglobal/menubar/menubar.xml +++ b/sw/uiconfig/sglobal/menubar/menubar.xml @@ -146,6 +146,7 @@ <menu:menuitem menu:id=".uno:ReplyComment" menu:style="text"/> <menu:menuitem menu:id=".uno:ResolveComment" menu:style="text"/> <menu:menuitem menu:id=".uno:ResolveCommentThread" menu:style="text"/> + <menu:menuitem menu:id=".uno:PromoteComment" menu:syle="text"/> <menu:menuitem menu:id=".uno:DeleteComment" menu:style="text"/> <menu:menuitem menu:id=".uno:DeleteCommentThread" menu:style="text"/> <menu:menuitem menu:id=".uno:DeleteAuthor" menu:style="text"/> diff --git a/sw/uiconfig/sglobal/popupmenu/annotation.xml b/sw/uiconfig/sglobal/popupmenu/annotation.xml index 42c89cd7c8bc..91da8b30cbfc 100644 --- a/sw/uiconfig/sglobal/popupmenu/annotation.xml +++ b/sw/uiconfig/sglobal/popupmenu/annotation.xml @@ -21,6 +21,7 @@ <menu:menuitem menu:id=".uno:ReplyComment"/> <menu:menuitem menu:id=".uno:ResolveComment"/> <menu:menuitem menu:id=".uno:ResolveCommentThread"/> + <menu:menuitem menu:id=".uno:PromoteComment"/> <menu:menuseparator/> <menu:menuitem menu:id=".uno:DeleteComment"/> <menu:menuitem menu:id=".uno:DeleteCommentThread"/> diff --git a/sw/uiconfig/swriter/menubar/menubar.xml b/sw/uiconfig/swriter/menubar/menubar.xml index 5e8fe23f7107..ea5ef0f6b9cb 100644 --- a/sw/uiconfig/swriter/menubar/menubar.xml +++ b/sw/uiconfig/swriter/menubar/menubar.xml @@ -151,6 +151,7 @@ <menu:menuitem menu:id=".uno:ReplyComment" menu:style="text"/> <menu:menuitem menu:id=".uno:ResolveComment" menu:style="text"/> <menu:menuitem menu:id=".uno:ResolveCommentThread" menu:style="text"/> + <menu:menuitem menu:id=".uno:PromoteComment" menu:style="text"/> <menu:menuitem menu:id=".uno:DeleteComment" menu:style="text"/> <menu:menuitem menu:id=".uno:DeleteCommentThread" menu:style="text"/> <menu:menuitem menu:id=".uno:DeleteAuthor" menu:style="text"/> diff --git a/sw/uiconfig/swriter/popupmenu/annotation.xml b/sw/uiconfig/swriter/popupmenu/annotation.xml index acdc6551ea97..bda8f346e374 100644 --- a/sw/uiconfig/swriter/popupmenu/annotation.xml +++ b/sw/uiconfig/swriter/popupmenu/annotation.xml @@ -22,6 +22,7 @@ <menu:menuseparator/> <menu:menuitem menu:id=".uno:ResolveComment"/> <menu:menuitem menu:id=".uno:ResolveCommentThread"/> + <menu:menuitem menu:id=".uno:PromoteComment"/> <menu:menuitem menu:id=".uno:DeleteComment"/> <menu:menuitem menu:id=".uno:DeleteCommentThread"/> <menu:menuitem menu:id=".uno:DeleteAuthor"/> diff --git a/sw/uiconfig/swriter/ui/annotation.ui b/sw/uiconfig/swriter/ui/annotation.ui index fc0e4c39a1a2..31b3c90b8aed 100644 --- a/sw/uiconfig/swriter/ui/annotation.ui +++ b/sw/uiconfig/swriter/ui/annotation.ui @@ -58,6 +58,14 @@ </object> </child> <child> + <object class="GtkMenuItem" id="promote"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="annotationmenu|promote">Promote Comment</property> + <property name="use-underline">True</property> + </object> + </child> + <child> <object class="GtkMenuItem" id="delete"> <property name="visible">True</property> <property name="can-focus">False</property> diff --git a/sw/uiconfig/swriter/ui/notebookbar_groupedbar_full.ui b/sw/uiconfig/swriter/ui/notebookbar_groupedbar_full.ui index de0df8909927..59a3584f33a8 100644 --- a/sw/uiconfig/swriter/ui/notebookbar_groupedbar_full.ui +++ b/sw/uiconfig/swriter/ui/notebookbar_groupedbar_full.ui @@ -344,6 +344,13 @@ </object> </child> <child> + <object class="GtkMenuItem" id="MenuComments-PromoteComment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="action_name">.uno:PromoteComment</property> + </object> + </child> + <child> <object class="GtkMenuItem" id="MenuComments-DeleteAuthor"> <property name="visible">True</property> <property name="can_focus">False</property> |