tdf#86395 tdf#104253 tdf#147658 tdf#135043 SwNavigator sort enhancement
Provides for sorting content members by order in document or
alphabetically. The option to sort comment and footnote content types
members alphabetically is not done by this patch.
Change-Id: If68c08bb0f1035b32cd1dad1d5bd08a340834b49
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131448
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
diff --git a/sw/source/uibase/inc/content.hxx b/sw/source/uibase/inc/content.hxx
index 0a4e180..2d6ac1a 100644
--- a/sw/source/uibase/inc/content.hxx
+++ b/sw/source/uibase/inc/content.hxx
@@ -183,6 +183,8 @@ class SwContentType final : public SwTypeNumber
bool m_bEdit: 1; // can this type be edited?
bool m_bDelete: 1; // can this type be deleted?
bool m_bAlphabeticSort = false;
static OUString RemoveNewline(const OUString&);
public:
SwContentType(SwWrtShell* pParent, ContentTypeId nType, sal_uInt8 nLevel );
@@ -206,6 +208,9 @@ public:
Invalidate();
}
bool GetSortType() const {return m_bAlphabeticSort;}
void SetSortType(bool bAlphabetic) {m_bAlphabeticSort = bAlphabetic;}
void Invalidate(); // only nMemberCount is read again
bool IsEditable() const {return m_bEdit;}
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index 6a4bf1d..7e18623 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -438,7 +438,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
if (nLevel >= m_nOutlineLevel || !m_pWrtShell->getIDocumentOutlineNodesAccess()->
isOutlineInLayout(i, *m_pWrtShell->GetLayout()))
continue;
tools::Long nYPos = getYPos(
tools::Long nYPos = m_bAlphabeticSort ? 0 : getYPos(
*m_pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineNode(i));
OUString aEntry(comphelper::string::stripStart(
m_pWrtShell->getIDocumentOutlineNodesAccess()->getOutlineText(
@@ -486,8 +486,11 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
continue;
}
tools::Long nYPos = 0;
if (SwTable* pTable = SwTable::FindTable(&rTableFormat))
nYPos = getYPos(*pTable->GetTableNode());
if (!m_bAlphabeticSort)
{
if (SwTable* pTable = SwTable::FindTable(&rTableFormat))
nYPos = getYPos(*pTable->GetTableNode());
}
auto pCnt = make_unique<SwContent>(this, rTableFormat.GetName(), nYPos);
if( !rTableFormat.GetInfo( aAskItem ) &&
!aAskItem.pObject ) // not visible
@@ -527,19 +530,18 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
const OUString sFrameName = pFrameFormat->GetName();
SwContent* pCnt;
tools::Long nYPos =
m_bAlphabeticSort ? 0 : pFrameFormat->FindLayoutRect(false, &aNullPt).Top();
if(ContentTypeId::GRAPHIC == m_nContentType)
{
OUString sLink;
m_pWrtShell->GetGrfNms( &sLink, nullptr, static_cast<const SwFlyFrameFormat*>( pFrameFormat));
pCnt = new SwGraphicContent(this, sFrameName,
INetURLObject::decode( sLink,
INetURLObject::DecodeMechanism::Unambiguous ),
pFrameFormat->FindLayoutRect(false, &aNullPt).Top());
pCnt = new SwGraphicContent(this, sFrameName, INetURLObject::decode(sLink,
INetURLObject::DecodeMechanism::Unambiguous), nYPos);
}
else
{
pCnt = new SwContent(this, sFrameName,
pFrameFormat->FindLayoutRect(false, &aNullPt).Top() );
pCnt = new SwContent(this, sFrameName, nYPos);
}
if( !pFrameFormat->GetInfo( aAskItem ) &&
!aAskItem.pObject ) // not visible
@@ -562,6 +564,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
break;
case ContentTypeId::BOOKMARK:
{
tools::Long nYPos = 0;
IDocumentMarkAccess* const pMarkAccess = m_pWrtShell->getIDocumentMarkAccess();
for(IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
ppBookmark != pMarkAccess->getBookmarksEnd();
@@ -571,7 +574,8 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
{
const OUString& rBkmName = (*ppBookmark)->GetName();
//nYPos from 0 -> text::Bookmarks will be sorted alphabetically
std::unique_ptr<SwContent> pCnt(new SwContent(this, rBkmName, 0));
auto pCnt(std::make_unique<SwContent>(this, rBkmName,
m_bAlphabeticSort ? 0 : nYPos++));
m_pMember->insert(std::move(pCnt));
}
}
@@ -617,7 +621,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
+ sSubType + sExpandField;
}
auto pCnt(std::make_unique<SwTextFieldContent>(this, sText, pFormatField,
pTextField->GetTextNode().GetIndex().get()));
m_bAlphabeticSort ? 0 : pTextField->GetTextNode().GetIndex().get()));
if (!pTextField->GetTextNode().getLayoutFrame(m_pWrtShell->GetLayout()))
pCnt->SetInvisible();
m_pMember->insert(std::move(pCnt));
@@ -681,7 +685,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
}
std::unique_ptr<SwContent> pCnt(new SwRegionContent(this, sSectionName,
nLevel, getYPos(*pNodeIndex)));
nLevel, m_bAlphabeticSort ? 0 : getYPos(*pNodeIndex)));
if( !pFormat->GetInfo( aAskItem ) &&
!aAskItem.pObject ) // not visible
pCnt->SetInvisible();
@@ -707,10 +711,11 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
std::vector<OUString> aRefMarks;
m_pWrtShell->GetRefMarks( &aRefMarks );
tools::Long nYPos = 0;
for (const auto& rRefMark : aRefMarks)
{
// References sorted alphabetically
m_pMember->insert(std::make_unique<SwContent>(this, rRefMark, 0));
m_pMember->insert(std::make_unique<SwContent>(this, rRefMark,
m_bAlphabeticSort ? 0 : nYPos++));
}
}
break;
@@ -719,6 +724,19 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
SwGetINetAttrs aArr;
m_pWrtShell->GetINetAttrs(aArr);
if (m_bAlphabeticSort)
{
for (auto& r : aArr)
{
auto pCnt(make_unique<SwURLFieldContent>(this, r.sText, INetURLObject::decode(
r.rINetAttr.GetINetFormat().GetValue(),
INetURLObject::DecodeMechanism::Unambiguous),
&r.rINetAttr, 0));
m_pMember->insert(std::move(pCnt));
}
break;
}
// use stable sort array to list hyperlinks in document order
std::vector<SwGetINetAttr*> aStableSortINetAttrsArray;
for (SwGetINetAttr& r : aArr)
@@ -752,7 +770,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
OUString sTOXNm( pBase->GetTOXName() );
SwContent* pCnt = new SwTOXBaseContent(
this, sTOXNm, nTox, *pBase);
this, sTOXNm, m_bAlphabeticSort ? 0 : nTox, *pBase);
if(pBase && !pBase->IsVisible())
pCnt->SetInvisible();
@@ -824,7 +842,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
tools::Long nYPos = LONG_MIN;
const bool bIsVisible = rIDDMA.IsVisibleLayerId(pTemp->GetLayer());
if (bIsVisible)
nYPos = pTemp->GetLogicRect().Top();
nYPos = m_bAlphabeticSort ? 0 : pTemp->GetLogicRect().Top();
auto pCnt(std::make_unique<SwContent>(this, pTemp->GetName(), nYPos));
if (!bIsVisible)
pCnt->SetInvisible();
@@ -1431,6 +1449,8 @@ IMPL_LINK(SwContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)
bool bRemoveFieldTracking = true;
bool bRemoveFootnoteTracking = true;
bool bRemoveSortEntry = true;
if (xEntry)
{
const SwContentType* pType;
@@ -1440,6 +1460,13 @@ IMPL_LINK(SwContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)
pType = weld::fromId<SwContent*>(
m_xTreeView->get_id(*xEntry))->GetParent();
const ContentTypeId nContentType = pType->GetType();
if (nContentType != ContentTypeId::FOOTNOTE && nContentType != ContentTypeId::POSTIT)
{
bRemoveSortEntry = false;
xPop->set_active("sort", pType->GetSortType());
}
OString aIdent;
switch (nContentType)
{
@@ -1734,6 +1761,9 @@ IMPL_LINK(SwContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)
if (bRemoveFootnoteTracking)
xPop->remove("footnotetracking");
if (bRemoveSortEntry)
xPop->remove("sort");
bool bSetSensitiveCollapseAllCategories = false;
if (!m_bIsRoot)
{
@@ -4180,6 +4210,20 @@ void SwContentTree::ExecuteContextMenuAction(const OString& rSelectedPopupEntry)
if (!m_xTreeView->get_selected(xFirst.get()))
return; // this shouldn't happen, but better to be safe than ...
if (rSelectedPopupEntry == "sort")
{
SwContentType* pCntType;
const OUString& rId(m_xTreeView->get_id(*xFirst));
if (lcl_IsContentType(*xFirst, *m_xTreeView))
pCntType = weld::fromId<SwContentType*>(rId);
else
pCntType = const_cast<SwContentType*>(weld::fromId<SwContent*>(rId)->GetParent());
pCntType->SetSortType(!pCntType->GetSortType());
pCntType->FillMemberList();
Display(true);
return;
}
auto nSelectedPopupEntry = rSelectedPopupEntry.toUInt32();
switch (nSelectedPopupEntry)
{
diff --git a/sw/uiconfig/swriter/ui/navigatorcontextmenu.ui b/sw/uiconfig/swriter/ui/navigatorcontextmenu.ui
index 5cda603..e393685 100644
--- a/sw/uiconfig/swriter/ui/navigatorcontextmenu.ui
+++ b/sw/uiconfig/swriter/ui/navigatorcontextmenu.ui
@@ -197,20 +197,6 @@
</object>
</child>
<child>
<object class="GtkMenuItem" id="1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="navigatorcontextmenu|STR_OUTLINE_LEVEL">Outline Level</property>
<property name="use-underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="outlinelevel">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="4">
<property name="visible">True</property>
<property name="can-focus">False</property>
@@ -329,12 +315,34 @@
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="sort">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="navigatorcontextmenu|STR_SORT_ALPHABETICALLY">Sort Alphabetically</property>
<property name="use-underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes" context="navigatorcontextmenu|STR_OUTLINE_LEVEL">Outline Level</property>
<property name="use-underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="outlinelevel">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="2">
<property name="visible">True</property>
<property name="can-focus">False</property>