office-gobmx/sw/source/uibase/app/docst.cxx
László Németh a1dcbd1d1c tdf#48459 sw inline heading: add Inline Heading frame style
Add the new frame style Inline Heading with default variable
width and anchoring as character to support UX better
– and later, – interoperability.

Note: the previous commit (7a35f3dc74)
used the Formula style for inline headings.

Note: adjust check_styles.py unit test according to the extended
frame style list.

Follow-up to commit 7a35f3dc74
"tdf#48459 sw inline heading: apply it on the selected words".

Change-Id: I615a53803d755acfbabb77fe53b0e5b60fa9fcc0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175834
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
2024-11-01 08:50:54 +01:00

1772 lines
67 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <config_wasm_strip.h>
#include <memory>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <comphelper/flagguard.hxx>
#include <o3tl/any.hxx>
#include <sal/log.hxx>
#include <osl/diagnose.h>
#include <hintids.hxx>
#include <sfx2/styledlg.hxx>
#include <svl/whiter.hxx>
#include <sfx2/tplpitem.hxx>
#include <sfx2/request.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/newstyle.hxx>
#include <sfx2/printer.hxx>
#include <sfx2/viewfrm.hxx>
#include <svl/stritem.hxx>
#include <svl/ctloptions.hxx>
#include <sfx2/htmlmode.hxx>
#include <swmodule.hxx>
#include <fchrfmt.hxx>
#include <svx/xdef.hxx>
#include <SwStyleNameMapper.hxx>
#include <SwRewriter.hxx>
#include <numrule.hxx>
#include <swundo.hxx>
#include <svx/drawitem.hxx>
#include <utility>
#include <view.hxx>
#include <wrtsh.hxx>
#include <docsh.hxx>
#include <uitool.hxx>
#include <cmdid.h>
#include <viewopt.hxx>
#include <doc.hxx>
#include <drawdoc.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <IDocumentUndoRedo.hxx>
#include <IDocumentSettingAccess.hxx>
#include <IDocumentDeviceAccess.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <IDocumentState.hxx>
#include <frmfmt.hxx>
#include <charfmt.hxx>
#include <poolfmt.hxx>
#include <pagedesc.hxx>
#include <docstyle.hxx>
#include <uiitems.hxx>
#include <fmtcol.hxx>
#include <edtwin.hxx>
#include <unochart.hxx>
#include <swabstdlg.hxx>
#include <tblafmt.hxx>
#include <sfx2/watermarkitem.hxx>
#include <svl/grabbagitem.hxx>
#include <PostItMgr.hxx>
#include <AnnotationWin.hxx>
#include <SwUndoFmt.hxx>
#include <strings.hrc>
#include <AccessibilityCheck.hxx>
#include <docmodel/theme/Theme.hxx>
#include <svx/svdpage.hxx>
#include <officecfg/Office/Common.hxx>
#include <fmtfsize.hxx>
#include <svl/ptitem.hxx>
#include <editeng/sizeitem.hxx>
#include <editeng/ulspitem.hxx>
using namespace ::com::sun::star;
static OutlinerView* lcl_GetPostItOutlinerView(SwWrtShell& rShell)
{
SwPostItMgr* pPostItMgr = rShell.GetPostItMgr();
if (!pPostItMgr)
return nullptr;
sw::annotation::SwAnnotationWin* pWin = pPostItMgr->GetActiveSidebarWin();
if (!pWin)
return nullptr;
return pWin->GetOutlinerView();
}
void SwDocShell::StateStyleSheet(SfxItemSet& rSet, SwWrtShell* pSh)
{
SfxWhichIter aIter(rSet);
sal_uInt16 nWhich = aIter.FirstWhich();
SfxStyleFamily nActualFamily = SfxStyleFamily(USHRT_MAX);
SwWrtShell* pShell = pSh ? pSh : GetWrtShell();
if(!pShell)
{
while (nWhich)
{
rSet.DisableItem(nWhich);
nWhich = aIter.NextWhich();
}
return;
}
else
{
SfxViewFrame& rFrame = pShell->GetView().GetViewFrame();
std::unique_ptr<SfxUInt16Item> pFamilyItem;
rFrame.GetBindings().QueryState(SID_STYLE_FAMILY, pFamilyItem);
if (pFamilyItem)
{
nActualFamily = static_cast<SfxStyleFamily>(pFamilyItem->GetValue());
}
}
while (nWhich)
{
// determine current template to every family
OUString aName;
SwTableAutoFormat aTableAutoFormat(u"dummy"_ustr); // needed to check if can take a table auto format at current cursor position
switch (nWhich)
{
case SID_STYLE_APPLY:
{// here the template and its family are passed to the StyleBox
// so that this family is being showed
if(pShell->IsFrameSelected())
{
SwFrameFormat* pFormat = pShell->GetSelectedFrameFormat();
if( pFormat )
aName = pFormat->GetName();
}
else if (pShell->GetSelectionType() == SelectionType::PostIt)
{
OutlinerView *pOLV = lcl_GetPostItOutlinerView(*pShell);
if (SfxStyleSheetBase* pStyle = pOLV ? pOLV->GetStyleSheet() : nullptr)
aName = pStyle->GetName();
}
else
{
SwTextFormatColl* pColl = pShell->GetCurTextFormatColl();
if(pColl)
aName = pColl->GetName();
}
rSet.Put(SfxTemplateItem(nWhich, aName));
}
break;
case SID_STYLE_FAMILY1:
if( !pShell->IsFrameSelected() )
{
SwCharFormat* pFormat = pShell->GetCurCharFormat();
if(pFormat)
aName = pFormat->GetName();
else
aName = SwResId(STR_POOLCHR_STANDARD);
rSet.Put(SfxTemplateItem(nWhich, aName));
}
break;
case SID_STYLE_FAMILY2:
if(!pShell->IsFrameSelected())
{
OUString aProgName;
if (pShell->GetSelectionType() == SelectionType::PostIt)
{
OutlinerView *pOLV = lcl_GetPostItOutlinerView(*pShell);
if (SfxStyleSheetBase* pStyle = pOLV ? pOLV->GetStyleSheet() : nullptr)
{
aName = pStyle->GetName();
aProgName = SwStyleNameMapper::GetProgName(aName, SwGetPoolIdFromName::TxtColl);
}
}
else if (auto pColl = pShell->GetCurTextFormatColl())
{
aName = pColl->GetName();
sal_uInt16 nId = pColl->GetPoolFormatId();
SwStyleNameMapper::FillProgName(nId, aProgName);
}
SfxTemplateItem aItem(nWhich, aName, aProgName);
SfxStyleSearchBits nMask = SfxStyleSearchBits::Auto;
if (m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE))
nMask = SfxStyleSearchBits::SwHtml;
else
{
const FrameTypeFlags nSelection = pShell->GetFrameType(nullptr,true);
if(pShell->GetCurTOX())
nMask = SfxStyleSearchBits::SwIndex ;
else if(nSelection & FrameTypeFlags::HEADER ||
nSelection & FrameTypeFlags::FOOTER ||
nSelection & FrameTypeFlags::TABLE ||
nSelection & FrameTypeFlags::FLY_ANY ||
nSelection & FrameTypeFlags::FOOTNOTE ||
nSelection & FrameTypeFlags::FTNPAGE)
nMask = SfxStyleSearchBits::SwExtra;
else
nMask = SfxStyleSearchBits::SwText;
}
aItem.SetValue(nMask);
rSet.Put(aItem);
}
break;
case SID_STYLE_FAMILY3:
if (m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE))
rSet.DisableItem( nWhich );
else
{
SwFrameFormat* pFormat = pShell->GetSelectedFrameFormat();
if(pFormat && pShell->IsFrameSelected())
{
aName = pFormat->GetName();
rSet.Put(SfxTemplateItem(nWhich, aName));
}
}
break;
case SID_STYLE_FAMILY4:
{
if (m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) && !officecfg::Office::Common::Filter::HTML::Export::PrintLayout::get())
rSet.DisableItem( nWhich );
else
{
size_t n = pShell->GetCurPageDesc( false );
if( n < pShell->GetPageDescCnt() )
aName = pShell->GetPageDesc( n ).GetName();
rSet.Put(SfxTemplateItem(nWhich, aName));
}
}
break;
case SID_STYLE_FAMILY5:
{
const SwNumRule* pRule = pShell->GetNumRuleAtCurrCursorPos();
if( pRule )
aName = pRule->GetName();
rSet.Put(SfxTemplateItem(nWhich, aName));
}
break;
case SID_STYLE_FAMILY6:
{
const SwTableNode *pTableNd = pShell->IsCursorInTable();
if( pTableNd )
aName = pTableNd->GetTable().GetTableStyleName();
rSet.Put(SfxTemplateItem(nWhich, aName));
}
break;
case SID_STYLE_WATERCAN:
{
SwEditWin& rEdtWin = pShell->GetView().GetEditWin();
SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate();
rSet.Put(SfxBoolItem(nWhich, pApply && pApply->eType != SfxStyleFamily(0)));
}
break;
case SID_STYLE_UPDATE_BY_EXAMPLE:
if( pShell->IsFrameSelected()
? SfxStyleFamily::Frame != nActualFamily
: ( SfxStyleFamily::Frame == nActualFamily ||
SfxStyleFamily::Page == nActualFamily ||
(SfxStyleFamily::Pseudo == nActualFamily && !pShell->GetNumRuleAtCurrCursorPos()) ||
(SfxStyleFamily::Table == nActualFamily && !pShell->GetTableAutoFormat(aTableAutoFormat))) )
{
rSet.DisableItem( nWhich );
}
break;
case SID_STYLE_NEW_BY_EXAMPLE:
if( (pShell->IsFrameSelected()
? SfxStyleFamily::Frame != nActualFamily
: SfxStyleFamily::Frame == nActualFamily) ||
(SfxStyleFamily::Pseudo == nActualFamily && !pShell->GetNumRuleAtCurrCursorPos()) ||
(SfxStyleFamily::Table == nActualFamily && !pShell->GetTableAutoFormat(aTableAutoFormat)) )
{
rSet.DisableItem( nWhich );
}
break;
case SID_CLASSIFICATION_APPLY:
// Just trigger ClassificationCategoriesController::statusChanged().
rSet.InvalidateItem(nWhich);
break;
case SID_CLASSIFICATION_DIALOG:
rSet.InvalidateItem(nWhich);
break;
case SID_STYLE_EDIT:
break;
case SID_WATERMARK:
if (pSh)
{
SfxWatermarkItem aItem = pSh->GetWatermark();
rSet.Put(aItem);
}
break;
default:
OSL_FAIL("Invalid SlotId");
}
nWhich = aIter.NextWhich();
}
}
// evaluate StyleSheet-Requests
void SwDocShell::ExecStyleSheet( SfxRequest& rReq )
{
sal_uInt16 nSlot = rReq.GetSlot();
const SfxItemSet* pArgs = rReq.GetArgs();
const SfxPoolItem* pItem;
switch (nSlot)
{
case SID_STYLE_NEW:
if( pArgs && SfxItemState::SET == pArgs->GetItemState( SID_STYLE_FAMILY,
false, &pItem ))
{
const SfxStyleFamily nFamily = static_cast<SfxStyleFamily>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
OUString sName;
SfxStyleSearchBits nMask = SfxStyleSearchBits::Auto;
if( SfxItemState::SET == pArgs->GetItemState( SID_STYLE_NEW,
false, &pItem ))
sName = static_cast<const SfxStringItem*>(pItem)->GetValue();
if( SfxItemState::SET == pArgs->GetItemState( SID_STYLE_MASK,
false, &pItem ))
nMask = static_cast<SfxStyleSearchBits>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
OUString sParent;
if( SfxItemState::SET == pArgs->GetItemState( SID_STYLE_REFERENCE,
false, &pItem ))
sParent = static_cast<const SfxStringItem*>(pItem)->GetValue();
if (sName.isEmpty() && m_xBasePool)
sName = SfxStyleDialogController::GenerateUnusedName(*m_xBasePool, nFamily);
Edit(rReq.GetFrameWeld(), sName, sParent, nFamily, nMask, true, {}, nullptr, &rReq, nSlot);
}
break;
case SID_STYLE_APPLY:
if( !pArgs )
{
GetView()->GetViewFrame().GetDispatcher()->Execute(SID_STYLE_DESIGNER);
break;
}
else
{
// convert internal StyleName to DisplayName (slot implementation uses the latter)
const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(SID_APPLY_STYLE);
const SfxStringItem* pFamilyItem = rReq.GetArg<SfxStringItem>(SID_STYLE_FAMILYNAME);
if ( pFamilyItem && pNameItem )
{
uno::Reference< style::XStyleFamiliesSupplier > xModel(GetModel(), uno::UNO_QUERY);
try
{
uno::Reference< container::XNameAccess > xStyles;
uno::Reference< container::XNameAccess > xCont = xModel->getStyleFamilies();
xCont->getByName(pFamilyItem->GetValue()) >>= xStyles;
uno::Reference< beans::XPropertySet > xInfo;
xStyles->getByName( pNameItem->GetValue() ) >>= xInfo;
OUString aUIName;
xInfo->getPropertyValue(u"DisplayName"_ustr) >>= aUIName;
if ( !aUIName.isEmpty() )
rReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aUIName ) );
}
catch (const uno::Exception&)
{
}
}
}
[[fallthrough]];
case SID_STYLE_EDIT:
case SID_STYLE_FONT:
case SID_STYLE_DELETE:
case SID_STYLE_HIDE:
case SID_STYLE_SHOW:
case SID_STYLE_WATERCAN:
case SID_STYLE_FAMILY:
case SID_STYLE_UPDATE_BY_EXAMPLE:
case SID_STYLE_NEW_BY_EXAMPLE:
{
OUString aParam;
SfxStyleFamily nFamily = SfxStyleFamily::Para;
SfxStyleSearchBits nMask = SfxStyleSearchBits::Auto;
SwWrtShell* pActShell = nullptr;
if( !pArgs )
{
switch (nSlot)
{
case SID_STYLE_NEW_BY_EXAMPLE:
{
SfxStyleSheetBasePool& rPool = *GetStyleSheetPool();
SfxNewStyleDlg aDlg(GetView()->GetFrameWeld(), rPool, nFamily);
if (aDlg.run() == RET_OK)
{
aParam = aDlg.GetName();
rReq.AppendItem(SfxStringItem(nSlot, aParam));
}
}
break;
case SID_STYLE_UPDATE_BY_EXAMPLE:
case SID_STYLE_EDIT:
{
if (GetWrtShell()->GetSelectionType() == SelectionType::PostIt)
{
OutlinerView *pOLV = lcl_GetPostItOutlinerView(*GetWrtShell());
if (SfxStyleSheetBase* pStyle = pOLV ? pOLV->GetStyleSheet() : nullptr)
aParam = pStyle->GetName();
}
else if (auto pColl = GetWrtShell()->GetCurTextFormatColl())
aParam = pColl->GetName();
if (!aParam.isEmpty())
rReq.AppendItem(SfxStringItem(nSlot, aParam));
}
break;
}
}
else
{
SAL_WARN_IF( !pArgs->Count(), "sw.ui", "SfxBug ItemSet is empty" );
SwWrtShell* pShell = GetWrtShell();
if( SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem ))
aParam = static_cast<const SfxStringItem*>(pItem)->GetValue();
if( SfxItemState::SET == pArgs->GetItemState(SID_STYLE_FAMILY,
false, &pItem ))
nFamily = static_cast<SfxStyleFamily>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
if( SfxItemState::SET == pArgs->GetItemState(SID_STYLE_FAMILYNAME, false, &pItem ))
{
OUString aFamily = static_cast<const SfxStringItem*>(pItem)->GetValue();
if(aFamily == "CharacterStyles")
nFamily = SfxStyleFamily::Char;
else
if(aFamily == "ParagraphStyles")
nFamily = SfxStyleFamily::Para;
else
if(aFamily == "PageStyles")
nFamily = SfxStyleFamily::Page;
else
if(aFamily == "FrameStyles")
nFamily = SfxStyleFamily::Frame;
else
if(aFamily == "NumberingStyles")
nFamily = SfxStyleFamily::Pseudo;
else
if(aFamily == "TableStyles")
nFamily = SfxStyleFamily::Table;
}
if( SfxItemState::SET == pArgs->GetItemState(SID_STYLE_MASK,
false, &pItem ))
nMask = static_cast<SfxStyleSearchBits>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
if( const SwPtrItem* pShellItem = pArgs->GetItemIfSet(FN_PARAM_WRTSHELL, false ))
pActShell = pShell = static_cast<SwWrtShell*>(pShellItem->GetValue());
if( nSlot == SID_STYLE_UPDATE_BY_EXAMPLE && aParam.isEmpty() )
{
switch( nFamily )
{
case SfxStyleFamily::Para:
{
SwTextFormatColl* pColl = pShell->GetCurTextFormatColl();
if(pColl)
aParam = pColl->GetName();
}
break;
case SfxStyleFamily::Frame:
{
SwFrameFormat* pFrame = m_pWrtShell->GetSelectedFrameFormat();
if( pFrame )
aParam = pFrame->GetName();
}
break;
case SfxStyleFamily::Char:
{
SwCharFormat* pChar = m_pWrtShell->GetCurCharFormat();
if( pChar )
aParam = pChar->GetName();
}
break;
case SfxStyleFamily::Pseudo:
if(const SfxStringItem* pExName = pArgs->GetItemIfSet(SID_STYLE_UPD_BY_EX_NAME, false))
{
aParam = pExName->GetValue();
}
break;
case SfxStyleFamily::Table:
if(const SfxStringItem* pExName = pArgs->GetItemIfSet(SID_STYLE_UPD_BY_EX_NAME, false))
{
aParam = pExName->GetValue();
}
break;
default: break;
}
rReq.AppendItem(SfxStringItem(nSlot, aParam));
}
}
if (!aParam.isEmpty() || nSlot == SID_STYLE_WATERCAN )
{
sal_uInt16 nRet = 0xffff;
bool bReturns = false;
switch(nSlot)
{
case SID_STYLE_EDIT:
case SID_STYLE_FONT:
Edit(rReq.GetFrameWeld(), aParam, {}, nFamily, nMask, false, (nSlot == SID_STYLE_FONT) ? u"font"_ustr : OUString(), pActShell);
break;
case SID_STYLE_DELETE:
Delete(aParam, nFamily);
break;
case SID_STYLE_HIDE:
case SID_STYLE_SHOW:
Hide(aParam, nFamily, nSlot == SID_STYLE_HIDE);
break;
case SID_STYLE_APPLY:
// Shell-switch in ApplyStyles
nRet = static_cast<sal_uInt16>(ApplyStyles(aParam, nFamily, pActShell, rReq.GetModifier() ));
bReturns = true;
break;
case SID_STYLE_WATERCAN:
nRet = static_cast<sal_uInt16>(DoWaterCan(aParam, nFamily));
bReturns = true;
break;
case SID_STYLE_UPDATE_BY_EXAMPLE:
UpdateStyle(aParam, nFamily, pActShell);
break;
case SID_STYLE_NEW_BY_EXAMPLE:
MakeByExample(aParam, nFamily, nMask, pActShell);
break;
default:
OSL_FAIL("Invalid SlotId");
}
// Update formatting toolbar buttons status
if (GetWrtShell()->GetSelectionType() == SelectionType::PostIt)
GetView()->GetViewFrame().GetBindings().InvalidateAll(false);
if (bReturns)
{
if(rReq.IsAPI()) // Basic only gets TRUE or FALSE
rReq.SetReturnValue(SfxUInt16Item(nSlot, sal_uInt16(nRet !=0)));
else
rReq.SetReturnValue(SfxUInt16Item(nSlot, nRet));
}
rReq.Done();
}
break;
}
}
}
namespace {
class ApplyStyle
{
public:
ApplyStyle(SwDocShell &rDocSh, bool bNew,
rtl::Reference< SwDocStyleSheet > xTmp,
SfxStyleFamily nFamily, SfxAbstractApplyTabDialog *pDlg,
rtl::Reference< SfxStyleSheetBasePool > xBasePool,
bool bModified)
: m_pDlg(pDlg)
, m_rDocSh(rDocSh)
, m_bNew(bNew)
, m_xTmp(std::move(xTmp))
, m_nFamily(nFamily)
, m_xBasePool(std::move(xBasePool))
, m_bModified(bModified)
{
}
DECL_LINK( ApplyHdl, LinkParamNone*, void );
void apply()
{
ApplyHdl(nullptr);
}
VclPtr<SfxAbstractApplyTabDialog> m_pDlg;
// true if the document was initially modified before ApplyStyle was created
// or if ApplyStyle:::apply was called
bool DocIsModified() const
{
return m_bModified;
}
private:
SwDocShell &m_rDocSh;
bool m_bNew;
rtl::Reference< SwDocStyleSheet > m_xTmp;
SfxStyleFamily m_nFamily;
rtl::Reference< SfxStyleSheetBasePool > m_xBasePool;
bool m_bModified;
};
}
IMPL_LINK_NOARG(ApplyStyle, ApplyHdl, LinkParamNone*, void)
{
SwWrtShell* pWrtShell = m_rDocSh.GetWrtShell();
SwDoc* pDoc = m_rDocSh.GetDoc();
SwView* pView = m_rDocSh.GetView();
pWrtShell->StartAllAction();
if( SfxStyleFamily::Para == m_nFamily )
{
SfxItemSet aSet( *m_pDlg->GetOutputItemSet() );
::ConvertAttrGenToChar(aSet, m_xTmp->GetItemSet(), /*bIsPara=*/true);
::SfxToSwPageDescAttr( *pWrtShell, aSet );
// reset indent attributes at paragraph style, if a list style
// will be applied and no indent attributes will be applied.
m_xTmp->SetItemSet( aSet, false, true );
}
else
{
if(SfxStyleFamily::Page == m_nFamily || SfxStyleFamily::Frame == m_nFamily)
{
static const sal_uInt16 aInval[] = {
SID_IMAGE_ORIENTATION,
SID_ATTR_CHAR_FONT,
FN_INSERT_CTRL, FN_INSERT_OBJ_CTRL,
FN_TABLE_INSERT_COL_BEFORE,
FN_TABLE_INSERT_COL_AFTER, 0};
pView->GetViewFrame().GetBindings().Invalidate(aInval);
}
SfxItemSet aTmpSet( *m_pDlg->GetOutputItemSet() );
if( SfxStyleFamily::Char == m_nFamily )
{
::ConvertAttrGenToChar(aTmpSet, m_xTmp->GetItemSet());
}
m_xTmp->SetItemSet( aTmpSet, false );
if( SfxStyleFamily::Page == m_nFamily && SvtCTLOptions::IsCTLFontEnabled() )
{
const SfxPoolItem *pItem = nullptr;
if( aTmpSet.GetItemState( m_rDocSh.GetPool().GetTrueWhichIDFromSlotID( SID_ATTR_FRAMEDIRECTION, false ) , true, &pItem ) == SfxItemState::SET )
SwChartHelper::DoUpdateAllCharts( pDoc );
}
if (m_nFamily == SfxStyleFamily::Page)
{
if (const SfxGrabBagItem* pGrabBagItem = aTmpSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
{
bool bGutterAtTop{};
auto it = pGrabBagItem->GetGrabBag().find(u"GutterAtTop"_ustr);
if (it != pGrabBagItem->GetGrabBag().end())
{
it->second >>= bGutterAtTop;
}
bool bOldGutterAtTop
= pDoc->getIDocumentSettingAccess().get(DocumentSettingId::GUTTER_AT_TOP);
if (bOldGutterAtTop != bGutterAtTop)
{
pDoc->getIDocumentSettingAccess().set(DocumentSettingId::GUTTER_AT_TOP,
bGutterAtTop);
pWrtShell->InvalidateLayout(/*bSizeChanged=*/true);
}
}
}
if (m_nFamily == SfxStyleFamily::Frame)
{
if (const SfxBoolItem* pBoolItem = aTmpSet.GetItemIfSet(FN_KEEP_ASPECT_RATIO))
{
const SwViewOption* pVOpt = pWrtShell->GetViewOptions();
SwViewOption aUsrPref(*pVOpt);
aUsrPref.SetKeepRatio(pBoolItem->GetValue());
if (pBoolItem->GetValue() != pVOpt->IsKeepRatio())
{
SW_MOD()->ApplyUsrPref(aUsrPref, &pWrtShell->GetView());
}
}
}
}
if(m_bNew)
{
if(SfxStyleFamily::Frame == m_nFamily || SfxStyleFamily::Para == m_nFamily)
{
// clear FillStyle so that it works as a derived attribute
SfxItemSet aTmpSet(*m_pDlg->GetOutputItemSet());
aTmpSet.ClearItem(XATTR_FILLSTYLE);
m_xTmp->SetItemSet(aTmpSet, false);
}
}
if(SfxStyleFamily::Page == m_nFamily)
pView->InvalidateRulerPos();
if( !m_bNew )
m_xBasePool->Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetModified, *m_xTmp));
pDoc->getIDocumentState().SetModified();
if( !m_bModified )
{
pDoc->GetIDocumentUndoRedo().SetUndoNoResetModified();
m_bModified = true;
}
pWrtShell->EndAllAction();
}
namespace
{
/// Checks if there is an Endnote page style in use, and makes sure it has the same orientation
/// with the Default (Standard) page style.
void syncEndnoteOrientation(const uno::Reference< style::XStyleFamiliesSupplier >& xStyleFamSupp)
{
if (!xStyleFamSupp.is())
{
SAL_WARN("sw.ui", "Ref to XStyleFamiliesSupplier is null.");
return;
}
uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamSupp->getStyleFamilies();
if (!xStyleFamilies.is())
return;
uno::Reference<container::XNameAccess> xPageStyles(xStyleFamilies->getByName(u"PageStyles"_ustr),
uno::UNO_QUERY);
if (!xPageStyles.is())
return;
uno::Reference<css::style::XStyle> xEndnotePageStyle(xPageStyles->getByName(u"Endnote"_ustr),
uno::UNO_QUERY);
if (!xEndnotePageStyle.is())
return;
// Language-independent name of the "Default Style" is "Standard"
uno::Reference<css::style::XStyle> xDefaultPageStyle(xPageStyles->getByName(u"Standard"_ustr),
uno::UNO_QUERY);
if (!xDefaultPageStyle.is())
return;
if (xEndnotePageStyle->isUserDefined() || !xEndnotePageStyle->isInUse())
return;
uno::Reference<beans::XPropertySet> xEndnotePagePropSet(xPageStyles->getByName(u"Endnote"_ustr), uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xDefaultPagePropSet(xPageStyles->getByName(u"Standard"_ustr), uno::UNO_QUERY);
if (!xEndnotePagePropSet.is() || !xDefaultPagePropSet.is())
{
SAL_WARN("sw.ui", "xEndnotePagePropSet or xDefaultPagePropSet is null.");
return;
}
auto const bIsDefLandScape = *o3tl::doAccess<bool>(
xDefaultPagePropSet->getPropertyValue(u"IsLandscape"_ustr));
auto const bIsEndLandScape = *o3tl::doAccess<bool>(
xEndnotePagePropSet->getPropertyValue(u"IsLandscape"_ustr));
if (bIsDefLandScape == bIsEndLandScape)
return;
auto const nWidth = xEndnotePagePropSet->getPropertyValue(u"Width"_ustr);
auto const nHeight = xEndnotePagePropSet->getPropertyValue(u"Height"_ustr);
xEndnotePagePropSet->setPropertyValue(u"IsLandscape"_ustr, css::uno::toAny(bIsDefLandScape));
xEndnotePagePropSet->setPropertyValue(u"Width"_ustr, nHeight);
xEndnotePagePropSet->setPropertyValue(u"Height"_ustr, nWidth);
}
}
void SwDocShell::Edit(
weld::Window* pDialogParent,
const OUString &rName,
const OUString &rParent,
const SfxStyleFamily nFamily,
SfxStyleSearchBits nMask,
const bool bNew,
const OUString& sPage,
SwWrtShell* pActShell,
SfxRequest* pReq,
sal_uInt16 nSlot)
{
assert( GetWrtShell() );
const bool bBasic = pReq && pReq->IsAPI();
SfxStyleSheetBase *pStyle = nullptr;
bool bModified = m_xDoc->getIDocumentState().IsModified();
SwUndoId nNewStyleUndoId(SwUndoId::EMPTY);
if( bNew )
{
if (!bBasic)
{
// start undo action in order to get only one undo action for the
// UI new style + change style operations
m_pWrtShell->StartUndo();
}
if( SfxStyleSearchBits::All != nMask && SfxStyleSearchBits::AllVisible != nMask && SfxStyleSearchBits::Used != nMask )
nMask |= SfxStyleSearchBits::UserDefined;
else
nMask = SfxStyleSearchBits::UserDefined;
if (nFamily == SfxStyleFamily::Para || nFamily == SfxStyleFamily::Char
|| nFamily == SfxStyleFamily::Frame || nFamily == SfxStyleFamily::Pseudo)
{
// Do Make undo append after an OK return from the style dialog below
::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
pStyle = &m_xBasePool->Make( rName, nFamily, nMask );
}
else
{
pStyle = &m_xBasePool->Make( rName, nFamily, nMask );
}
// set the current one as Parent
SwDocStyleSheet* pDStyle = static_cast<SwDocStyleSheet*>(pStyle);
switch( nFamily )
{
case SfxStyleFamily::Para:
{
if(!rParent.isEmpty())
{
SwTextFormatColl* pColl = m_pWrtShell->FindTextFormatCollByName( rParent );
if(!pColl)
{
sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rParent, SwGetPoolIdFromName::TxtColl);
if(USHRT_MAX != nId)
pColl = m_pWrtShell->GetTextCollFromPool( nId );
}
pDStyle->GetCollection()->SetDerivedFrom( pColl );
pDStyle->PresetParent( rParent );
}
else
{
SwTextFormatColl* pColl = m_pWrtShell->GetCurTextFormatColl();
pDStyle->GetCollection()->SetDerivedFrom( pColl );
if( pColl )
pDStyle->PresetParent( pColl->GetName() );
}
}
break;
case SfxStyleFamily::Char:
{
if(!rParent.isEmpty())
{
SwCharFormat* pCFormat = m_pWrtShell->FindCharFormatByName(rParent);
if(!pCFormat)
{
sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rParent, SwGetPoolIdFromName::ChrFmt);
if(USHRT_MAX != nId)
pCFormat = m_pWrtShell->GetCharFormatFromPool( nId );
}
pDStyle->GetCharFormat()->SetDerivedFrom( pCFormat );
pDStyle->PresetParent( rParent );
}
else
{
SwCharFormat* pCFormat = m_pWrtShell->GetCurCharFormat();
pDStyle->GetCharFormat()->SetDerivedFrom( pCFormat );
if( pCFormat )
pDStyle->PresetParent( pCFormat->GetName() );
}
}
break;
case SfxStyleFamily::Frame :
{
if(!rParent.isEmpty())
{
SwFrameFormat* pFFormat = m_pWrtShell->GetDoc()->FindFrameFormatByName( rParent );
if(!pFFormat)
{
sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rParent, SwGetPoolIdFromName::FrmFmt);
if(USHRT_MAX != nId)
pFFormat = m_pWrtShell->GetFrameFormatFromPool( nId );
}
pDStyle->GetFrameFormat()->SetDerivedFrom( pFFormat );
pDStyle->PresetParent( rParent );
}
}
break;
default: break;
}
if (!bBasic)
{
//Get the undo id for the type of style that was created in order to re-use that comment for the grouped
//create style + change style operations
m_pWrtShell->GetLastUndoInfo(nullptr, &nNewStyleUndoId);
}
}
else
{
pStyle = m_xBasePool->Find( rName, nFamily );
SAL_WARN_IF( !pStyle, "sw.ui", "Style not found" );
}
if(!pStyle)
return;
// put dialogues together
rtl::Reference< SwDocStyleSheet > xTmp( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pStyle) ) );
if( SfxStyleFamily::Para == nFamily )
{
SfxItemSet& rSet = xTmp->GetItemSet();
::SwToSfxPageDescAttr( rSet );
// merge list level indent attributes into the item set if needed
xTmp->MergeIndentAttrsOfListStyle( rSet );
::ConvertAttrCharToGen(xTmp->GetItemSet(), /*bIsPara=*/true);
}
else if( SfxStyleFamily::Char == nFamily )
{
::ConvertAttrCharToGen(xTmp->GetItemSet());
}
if(SfxStyleFamily::Page == nFamily || SfxStyleFamily::Para == nFamily)
{
// create needed items for XPropertyList entries from the DrawModel so that
// the Area TabPage can access them
SfxItemSet& rSet = xTmp->GetItemSet();
const SwDrawModel* pDrawModel = GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
rSet.Put(SvxColorListItem(pDrawModel->GetColorList(), SID_COLOR_TABLE));
rSet.Put(SvxGradientListItem(pDrawModel->GetGradientList(), SID_GRADIENT_LIST));
rSet.Put(SvxHatchListItem(pDrawModel->GetHatchList(), SID_HATCH_LIST));
rSet.Put(SvxBitmapListItem(pDrawModel->GetBitmapList(), SID_BITMAP_LIST));
rSet.Put(SvxPatternListItem(pDrawModel->GetPatternList(), SID_PATTERN_LIST));
std::map<OUString, css::uno::Any> aGrabBagMap;
if (SfxGrabBagItem const* pItem = rSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
aGrabBagMap = pItem->GetGrabBag();
bool bGutterAtTop
= GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GUTTER_AT_TOP);
aGrabBagMap[u"GutterAtTop"_ustr] <<= bGutterAtTop;
rSet.Put(SfxGrabBagItem(SID_ATTR_CHAR_GRABBAG, std::move(aGrabBagMap)));
}
SwWrtShell* pCurrShell = pActShell ? pActShell : m_pWrtShell;
if (nFamily == SfxStyleFamily::Frame)
{
SfxItemSet& rSet = xTmp->GetItemSet();
const SwViewOption* pVOpt = pCurrShell->GetViewOptions();
rSet.Put(SfxBoolItem(FN_KEEP_ASPECT_RATIO, pVOpt->IsKeepRatio()));
}
if (!bBasic)
{
// prior to the dialog the HtmlMode at the DocShell is being sunk
sal_uInt16 nHtmlMode = ::GetHtmlMode(this);
// In HTML mode, we do not always have a printer. In order to show
// the correct page size in the Format - Page dialog, we have to
// get one here.
if( ( HTMLMODE_ON & nHtmlMode ) &&
!pCurrShell->getIDocumentDeviceAccess().getPrinter( false ) )
pCurrShell->InitPrt( pCurrShell->getIDocumentDeviceAccess().getPrinter( true ) );
PutItem(SfxUInt16Item(SID_HTML_MODE, nHtmlMode));
FieldUnit eMetric = ::GetDfltMetric(0 != (HTMLMODE_ON&nHtmlMode));
SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
if (!pDialogParent)
{
SAL_WARN("sw.ui", "no parent for dialog supplied, assuming document frame is good enough");
pDialogParent = GetView()->GetFrameWeld();
}
VclPtr<SfxAbstractApplyTabDialog> pDlg(pFact->CreateTemplateDialog(pDialogParent,
*xTmp, nFamily, sPage, pCurrShell, bNew));
auto pApplyStyleHelper = std::make_shared<ApplyStyle>(*this, bNew, xTmp, nFamily, pDlg.get(), m_xBasePool, bModified);
pDlg->SetApplyHdl(LINK(pApplyStyleHelper.get(), ApplyStyle, ApplyHdl));
std::shared_ptr<SfxRequest> pRequest;
if (pReq)
{
pRequest = std::make_shared<SfxRequest>(*pReq);
pReq->Ignore(); // the 'old' request is not relevant any more
}
bool bIsDefaultPage = nFamily == SfxStyleFamily::Page
&& rName == SwResId(STR_POOLPAGE_STANDARD)
&& pStyle->IsUsed()
&& !pStyle->IsUserDefined();
pDlg->StartExecuteAsync([bIsDefaultPage, bNew, nFamily, nSlot, nNewStyleUndoId,
pApplyStyleHelper=std::move(pApplyStyleHelper),
pRequest=std::move(pRequest), xTmp, this](sal_Int32 nResult){
if (RET_OK == nResult)
pApplyStyleHelper->apply();
if (bNew)
{
switch( nFamily )
{
case SfxStyleFamily::Para:
{
if(!xTmp->GetParent().isEmpty())
{
SwTextFormatColl* pColl = m_pWrtShell->FindTextFormatCollByName(xTmp->GetParent());
if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
{
GetDoc()->GetIDocumentUndoRedo().AppendUndo(
std::make_unique<SwUndoTextFormatCollCreate>(xTmp->GetCollection(), pColl, *GetDoc()));
}
}
}
break;
case SfxStyleFamily::Char:
{
if(!xTmp->GetParent().isEmpty())
{
SwCharFormat* pCFormat = m_pWrtShell->FindCharFormatByName(xTmp->GetParent());
if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
{
GetDoc()->GetIDocumentUndoRedo().AppendUndo(
std::make_unique<SwUndoCharFormatCreate>(xTmp->GetCharFormat(), pCFormat, *GetDoc()));
}
}
}
break;
case SfxStyleFamily::Frame:
{
if(!xTmp->GetParent().isEmpty())
{
SwFrameFormat* pFFormat = m_pWrtShell->GetDoc()->FindFrameFormatByName(xTmp->GetParent());
if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
{
GetDoc()->GetIDocumentUndoRedo().AppendUndo(
std::make_unique<SwUndoFrameFormatCreate>(xTmp->GetFrameFormat(), pFFormat, *GetDoc()));
}
}
}
break;
case SfxStyleFamily::Pseudo:
{
if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
{
GetDoc()->GetIDocumentUndoRedo().AppendUndo(
std::make_unique<SwUndoNumruleCreate>(xTmp->GetNumRule(),
*GetDoc()));
}
}
break;
default: break;
}
SwRewriter aRewriter;
aRewriter.AddRule(UndoArg1, xTmp->GetName());
//Group the create style and change style operations together under the
//one "create style" comment
m_pWrtShell->EndUndo(nNewStyleUndoId, &aRewriter);
}
bool bDocModified = pApplyStyleHelper->DocIsModified();
if (RET_OK != nResult)
{
if (bNew)
{
GetWrtShell()->Undo();
m_xDoc->GetIDocumentUndoRedo().ClearRedo();
}
if (!bDocModified)
m_xDoc->getIDocumentState().ResetModified();
}
// Update Watermark if new page style was created
if (nSlot == SID_STYLE_NEW && nFamily == SfxStyleFamily::Page)
{
SwWrtShell* pShell = GetWrtShell();
const SfxWatermarkItem aWatermark = pShell->GetWatermark();
pShell->SetWatermark(aWatermark);
}
pApplyStyleHelper->m_pDlg.disposeAndClear();
if (pRequest)
pRequest->Done();
if (bIsDefaultPage && bDocModified)
{
uno::Reference< style::XStyleFamiliesSupplier > xStyleFamSupp(GetModel(), uno::UNO_QUERY);
if (!xStyleFamSupp.is())
{
SAL_WARN("sw.ui", "Ref to XStyleFamiliesSupplier is null.");
return;
}
syncEndnoteOrientation(xStyleFamSupp);
}
});
}
else
{
// prior to the dialog the HtmlMode at the DocShell is being sunk
PutItem(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(this)));
GetWrtShell()->StartAllAction();
if( SfxStyleFamily::Para == nFamily )
{
::SfxToSwPageDescAttr( *GetWrtShell(), xTmp->GetItemSet() );
::ConvertAttrGenToChar(xTmp->GetItemSet(), xTmp->GetItemSet(), /*bIsPara=*/true);
}
else
{
::ConvertAttrGenToChar(xTmp->GetItemSet(), xTmp->GetItemSet());
}
if(SfxStyleFamily::Page == nFamily)
m_pView->InvalidateRulerPos();
m_xDoc->getIDocumentState().SetModified();
if( !bModified ) // Bug 57028
{
m_xDoc->GetIDocumentUndoRedo().SetUndoNoResetModified();
}
GetWrtShell()->EndAllAction();
}
}
void SwDocShell::Delete(const OUString &rName, SfxStyleFamily nFamily)
{
SfxStyleSheetBase *pStyle = m_xBasePool->Find(rName, nFamily);
if(pStyle)
{
assert( GetWrtShell() );
GetWrtShell()->StartAllAction();
m_xBasePool->Remove(pStyle);
GetWrtShell()->EndAllAction();
}
}
void SwDocShell::Hide(const OUString &rName, SfxStyleFamily nFamily, bool bHidden)
{
SfxStyleSheetBase *pStyle = m_xBasePool->Find(rName, nFamily);
if(pStyle)
{
assert( GetWrtShell() );
GetWrtShell()->StartAllAction();
rtl::Reference< SwDocStyleSheet > xTmp( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pStyle) ) );
xTmp->SetHidden( bHidden );
GetWrtShell()->EndAllAction();
}
}
#define MAX_CHAR_IN_INLINE_HEADING 75
bool SwDocShell::MakeInlineHeading(SwWrtShell *pSh, SwTextFormatColl* pColl, const sal_uInt16 nMode)
{
// insert an inline heading frame, if only MAX_CHAR_IN_INLINE_HEADING or less
// characters are selected beginning of a single paragraph, but not the full paragraph
// TODO extend it for multiple selections
if ( pSh->IsSelOnePara() && !pSh->IsSelFullPara() && pSh->IsSelStartPara() &&
GetView()->GetSelectionText().getLength() < MAX_CHAR_IN_INLINE_HEADING &&
0 < GetView()->GetSelectionText().getLength() )
{
SwTextFormatColl *pLocal = pColl? pColl: (*GetDoc()->GetTextFormatColls())[0];
// put inside a single Undo
SwRewriter aRewriter;
aRewriter.AddRule(UndoArg1, pLocal->GetName());
GetWrtShell()->StartUndo(SwUndoId::SETFMTCOLL, &aRewriter);
// anchor as character
SfxUInt16Item aAnchor(FN_INSERT_FRAME, static_cast<sal_uInt16>(1));
SvxSizeItem aSizeItem(FN_PARAM_2, Size(1, 1));
GetView()->GetViewFrame().GetDispatcher()->ExecuteList(FN_INSERT_FRAME,
SfxCallMode::SYNCHRON|SfxCallMode::RECORD, { &aAnchor, &aSizeItem });
if ( pSh->IsFrameSelected() )
{
// use the associated borderless frame style "Inline Heading"
SwDocStyleSheet* pStyle2 = static_cast<SwDocStyleSheet*>(
m_xBasePool->Find( "Inline Heading", SfxStyleFamily::Frame));
pSh->SetFrameFormat( pStyle2->GetFrameFormat() );
// select the text content of the frame, and apply the paragraph style
pSh->UnSelectFrame();
pSh->LeaveSelFrameMode();
pSh->MoveSection( GoCurrSection, fnSectionEnd );
pSh->SelAll();
pSh->SetTextFormatColl( pColl, true, (nMode & KEY_MOD1) ? SetAttrMode::REMOVE_ALL_ATTR : SetAttrMode::DEFAULT);
// zero the upper and lower margins of the paragraph (also an interoperability issue)
SfxItemSetFixed<RES_UL_SPACE, RES_UL_SPACE> aSet2(pSh->GetAttrPool());
pSh->GetCurAttr( aSet2 );
SvxULSpaceItem aUL( 0, 0, RES_UL_SPACE );
pSh->SetAttrItem( aUL );
// leave the inline heading frame
GetView()->GetViewFrame().GetDispatcher()->Execute(FN_ESCAPE, SfxCallMode::ASYNCHRON);
GetView()->GetViewFrame().GetDispatcher()->Execute(FN_ESCAPE, SfxCallMode::ASYNCHRON);
GetView()->GetViewFrame().GetDispatcher()->Execute(FN_ESCAPE, SfxCallMode::SYNCHRON);
GetWrtShell()->EndUndo();
return true;
}
}
return false;
}
// apply template
SfxStyleFamily SwDocShell::ApplyStyles(const OUString &rName, SfxStyleFamily nFamily,
SwWrtShell* pShell, const sal_uInt16 nMode )
{
SwDocStyleSheet* pStyle = static_cast<SwDocStyleSheet*>( m_xBasePool->Find( rName, nFamily ) );
SAL_WARN_IF( !pStyle, "sw.ui", "Style not found" );
if(!pStyle)
return SfxStyleFamily::None;
SwWrtShell *pSh = pShell ? pShell : GetWrtShell();
assert( pSh );
pSh->StartAllAction();
switch (nFamily)
{
case SfxStyleFamily::Char:
{
SwFormatCharFormat aFormat(pStyle->GetCharFormat());
SetAttrMode nFlags = (nMode & KEY_SHIFT) ?
SetAttrMode::DONTREPLACE : SetAttrMode::DEFAULT;
if (nMode & KEY_MOD1)
nFlags |= SetAttrMode::REMOVE_ALL_ATTR;
pSh->SetAttrItem( aFormat, nFlags );
break;
}
case SfxStyleFamily::Para:
{
if (OutlinerView *pOLV = lcl_GetPostItOutlinerView(*pSh))
pOLV->SetStyleSheet(rName);
else
{
// When outline-folding is enabled, MakeAllOutlineContentTemporarilyVisible makes
// application of a paragraph style that has an outline-level greater than the previous
// outline node become folded content of the previous outline node if the previous
// outline node's content is folded.
MakeAllOutlineContentTemporarilyVisible a(GetDoc());
// if the first 75 or less characters are selected, but not the full paragraph,
// create an inline heading from the selected text
SwTextFormatColl* pColl = pStyle->GetCollection();
if ( MakeInlineHeading( pSh, pColl, nMode ) )
break;
// #i62675#
// clear also list attributes at affected text nodes, if paragraph
// style has the list style attribute set.
pSh->SetTextFormatColl( pColl, true, (nMode & KEY_MOD1) ? SetAttrMode::REMOVE_ALL_ATTR : SetAttrMode::DEFAULT);
}
break;
}
case SfxStyleFamily::Frame:
{
if ( pSh->IsFrameSelected() )
pSh->SetFrameFormat( pStyle->GetFrameFormat() );
break;
}
case SfxStyleFamily::Page:
{
pSh->SetPageStyle(pStyle->GetPageDesc()->GetName());
break;
}
case SfxStyleFamily::Pseudo:
{
// reset indent attribute on applying list style
// continue list of list style
const SwNumRule* pNumRule = pStyle->GetNumRule();
if (pNumRule->GetName() == SwResId(STR_POOLNUMRULE_NOLIST))
{
if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
pViewFrm->GetDispatcher()->Execute(FN_NUM_BULLET_OFF);
break;
}
const OUString sListIdForStyle =pNumRule->GetDefaultListId();
pSh->SetCurNumRule( *pNumRule, false, sListIdForStyle, true );
break;
}
case SfxStyleFamily::Table:
{
pSh->SetTableStyle(pStyle->GetName());
break;
}
default:
OSL_FAIL("Unknown family");
}
pSh->EndAllAction();
return nFamily;
}
// start watering-can
SfxStyleFamily SwDocShell::DoWaterCan(const OUString &rName, SfxStyleFamily nFamily)
{
assert( GetWrtShell() );
SwEditWin& rEdtWin = m_pView->GetEditWin();
SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate();
bool bWaterCan = !(pApply && pApply->eType != SfxStyleFamily(0));
if( rName.isEmpty() )
bWaterCan = false;
SwApplyTemplate aTemplate;
aTemplate.eType = nFamily;
if(bWaterCan)
{
SwDocStyleSheet* pStyle =
static_cast<SwDocStyleSheet*>( m_xBasePool->Find(rName, nFamily) );
SAL_WARN_IF( !pStyle, "sw.ui", "Where's the StyleSheet" );
if(!pStyle) return nFamily;
switch(nFamily)
{
case SfxStyleFamily::Char:
aTemplate.aColl.pCharFormat = pStyle->GetCharFormat();
break;
case SfxStyleFamily::Para:
aTemplate.aColl.pTextColl = pStyle->GetCollection();
break;
case SfxStyleFamily::Frame:
aTemplate.aColl.pFrameFormat = pStyle->GetFrameFormat();
break;
case SfxStyleFamily::Page:
aTemplate.aColl.pPageDesc = const_cast<SwPageDesc*>(pStyle->GetPageDesc());
break;
case SfxStyleFamily::Pseudo:
aTemplate.aColl.pNumRule = const_cast<SwNumRule*>(pStyle->GetNumRule());
break;
default:
OSL_FAIL("Unknown family");
}
}
else
aTemplate.eType = SfxStyleFamily(0);
m_pView->GetEditWin().SetApplyTemplate(aTemplate);
return nFamily;
}
// update template
void SwDocShell::UpdateStyle(const OUString &rName, SfxStyleFamily nFamily, SwWrtShell* pShell)
{
SwWrtShell* pCurrWrtShell = pShell ? pShell : GetWrtShell();
assert( pCurrWrtShell );
SwDocStyleSheet* pStyle =
static_cast<SwDocStyleSheet*>( m_xBasePool->Find(rName, nFamily) );
if (!pStyle)
return;
switch(nFamily)
{
case SfxStyleFamily::Para:
{
SwTextFormatColl* pColl = pStyle->GetCollection();
if(pColl && !pColl->IsDefault())
{
GetWrtShell()->StartAllAction();
SwRewriter aRewriter;
aRewriter.AddRule(UndoArg1, pColl->GetName());
GetWrtShell()->StartUndo(SwUndoId::INSFMTATTR, &aRewriter);
GetWrtShell()->FillByEx(pColl);
// also apply template to remove hard set attributes
GetWrtShell()->SetTextFormatColl( pColl );
GetWrtShell()->EndUndo();
GetWrtShell()->EndAllAction();
}
break;
}
case SfxStyleFamily::Frame:
{
SwFrameFormat* pFrame = pStyle->GetFrameFormat();
if( pCurrWrtShell->IsFrameSelected() && pFrame && !pFrame->IsDefault() )
{
SfxItemSet aSet( GetPool(), aFrameFormatSetRange );
pCurrWrtShell->StartAllAction();
pCurrWrtShell->GetFlyFrameAttr( aSet );
// #i105535#
// no update of anchor attribute
aSet.ClearItem( RES_ANCHOR );
pFrame->SetFormatAttr( aSet );
// also apply template to remove hard set attributes
pCurrWrtShell->SetFrameFormat( pFrame, true );
pCurrWrtShell->EndAllAction();
}
}
break;
case SfxStyleFamily::Char:
{
SwCharFormat* pChar = pStyle->GetCharFormat();
if( pChar && !pChar->IsDefault() )
{
pCurrWrtShell->StartAllAction();
pCurrWrtShell->FillByEx(pChar);
// also apply template to remove hard set attributes
pCurrWrtShell->EndAllAction();
}
}
break;
case SfxStyleFamily::Pseudo:
{
const SwNumRule* pCurRule;
if( pStyle->GetNumRule() &&
nullptr != ( pCurRule = pCurrWrtShell->GetNumRuleAtCurrCursorPos() ))
{
SwNumRule aRule( *pCurRule );
// #i91400#
aRule.SetName( pStyle->GetNumRule()->GetName(),
pCurrWrtShell->GetDoc()->getIDocumentListsAccess() );
pCurrWrtShell->ChgNumRuleFormats( aRule );
}
}
break;
case SfxStyleFamily::Table:
{
if (SwFEShell* pFEShell = GetFEShell())
{
if(pFEShell->IsTableMode())
{
pFEShell->TableCursorToCursor();
}
}
SwTableAutoFormat aFormat(rName);
if (pCurrWrtShell->GetTableAutoFormat(aFormat))
{
pCurrWrtShell->StartAllAction();
pCurrWrtShell->GetDoc()->ChgTableStyle(rName, aFormat);
pCurrWrtShell->EndAllAction();
}
}
break;
default: break;
}
m_xDoc->BroadcastStyleOperation(rName, nFamily, SfxHintId::StyleSheetModified);
}
// NewByExample
void SwDocShell::MakeByExample( const OUString &rName, SfxStyleFamily nFamily,
SfxStyleSearchBits nMask, SwWrtShell* pShell )
{
SwWrtShell* pCurrWrtShell = pShell ? pShell : GetWrtShell();
SwDocStyleSheet* pStyle = static_cast<SwDocStyleSheet*>( m_xBasePool->Find(
rName, nFamily ) );
if(!pStyle)
{
// preserve the current mask of PI, then the new one is
// immediately merged with the viewable area
if( SfxStyleSearchBits::All == nMask || SfxStyleSearchBits::Used == nMask )
nMask = SfxStyleSearchBits::UserDefined;
else
nMask |= SfxStyleSearchBits::UserDefined;
if (nFamily == SfxStyleFamily::Para || nFamily == SfxStyleFamily::Char || nFamily == SfxStyleFamily::Frame)
{
// Prevent undo append from being done during paragraph, character, and frame style Make. Do it later
::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
pStyle = static_cast<SwDocStyleSheet*>(&m_xBasePool->Make(rName, nFamily, nMask));
}
else
{
pStyle = static_cast<SwDocStyleSheet*>(&m_xBasePool->Make(rName, nFamily, nMask));
}
}
switch(nFamily)
{
case SfxStyleFamily::Para:
{
SwTextFormatColl* pColl = pStyle->GetCollection();
if(pColl && !pColl->IsDefault())
{
pCurrWrtShell->StartAllAction();
pCurrWrtShell->FillByEx(pColl);
// also apply template to remove hard set attributes
SwTextFormatColl * pDerivedFrom = pCurrWrtShell->GetCurTextFormatColl();
pColl->SetDerivedFrom(pDerivedFrom);
// set the mask at the Collection:
sal_uInt16 nId = pColl->GetPoolFormatId() & 0x87ff;
switch( nMask & static_cast<SfxStyleSearchBits>(0x0fff) )
{
case SfxStyleSearchBits::SwText:
nId |= COLL_TEXT_BITS;
break;
case SfxStyleSearchBits::SwChapter:
nId |= COLL_DOC_BITS;
break;
case SfxStyleSearchBits::SwList:
nId |= COLL_LISTS_BITS;
break;
case SfxStyleSearchBits::SwIndex:
nId |= COLL_REGISTER_BITS;
break;
case SfxStyleSearchBits::SwExtra:
nId |= COLL_EXTRA_BITS;
break;
case SfxStyleSearchBits::SwHtml:
nId |= COLL_HTML_BITS;
break;
default: break;
}
pColl->SetPoolFormatId(nId);
if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
{
GetDoc()->GetIDocumentUndoRedo().AppendUndo(
std::make_unique<SwUndoTextFormatCollCreate>(pColl, pDerivedFrom, *GetDoc()));
}
pCurrWrtShell->SetTextFormatColl(pColl);
pCurrWrtShell->EndAllAction();
}
}
break;
case SfxStyleFamily::Frame:
{
SwFrameFormat* pFrame = pStyle->GetFrameFormat();
if(pCurrWrtShell->IsFrameSelected() && pFrame && !pFrame->IsDefault())
{
pCurrWrtShell->StartAllAction();
SfxItemSet aSet(GetPool(), aFrameFormatSetRange );
pCurrWrtShell->GetFlyFrameAttr( aSet );
aSet.ClearItem(RES_ANCHOR); // tdf#112574 no anchor in styles
SwFrameFormat* pFFormat = pCurrWrtShell->GetSelectedFrameFormat();
pFrame->SetDerivedFrom( pFFormat );
pFrame->SetFormatAttr( aSet );
if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
{
GetDoc()->GetIDocumentUndoRedo().AppendUndo(
std::make_unique<SwUndoFrameFormatCreate>(pFrame, pFFormat, *GetDoc()));
}
// also apply template to remove hard set attributes
pCurrWrtShell->SetFrameFormat(pFrame);
pCurrWrtShell->EndAllAction();
}
}
break;
case SfxStyleFamily::Char:
{
SwCharFormat* pChar = pStyle->GetCharFormat();
if(pChar && !pChar->IsDefault())
{
pCurrWrtShell->StartAllAction();
pCurrWrtShell->FillByEx( pChar );
SwCharFormat * pDerivedFrom = pCurrWrtShell->GetCurCharFormat();
pChar->SetDerivedFrom( pDerivedFrom );
SwFormatCharFormat aFormat( pChar );
if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
{
// Looks like sometimes pDerivedFrom can be null and this is not supported by redo code
// So use default format as a derived from in such situations
GetDoc()->GetIDocumentUndoRedo().AppendUndo(
std::make_unique<SwUndoCharFormatCreate>(
pChar, pDerivedFrom ? pDerivedFrom : GetDoc()->GetDfltCharFormat(),
*GetDoc()));
}
pCurrWrtShell->SetAttrItem(aFormat);
pCurrWrtShell->EndAllAction();
}
}
break;
case SfxStyleFamily::Page:
{
pCurrWrtShell->StartAllAction();
size_t nPgDsc = pCurrWrtShell->GetCurPageDesc();
SwPageDesc& rSrc = const_cast<SwPageDesc&>(pCurrWrtShell->GetPageDesc( nPgDsc ));
SwPageDesc& rDest = *const_cast<SwPageDesc*>(pStyle->GetPageDesc());
sal_uInt16 nPoolId = rDest.GetPoolFormatId();
sal_uInt16 nHId = rDest.GetPoolHelpId();
sal_uInt8 nHFId = rDest.GetPoolHlpFileId();
pCurrWrtShell->GetDoc()->CopyPageDesc( rSrc, rDest );
// PoolId must NEVER be copied!
rDest.SetPoolFormatId( nPoolId );
rDest.SetPoolHelpId( nHId );
rDest.SetPoolHlpFileId( nHFId );
// when Headers/Footers are created, there is no Undo anymore!
pCurrWrtShell->GetDoc()->GetIDocumentUndoRedo().DelAllUndoObj();
pCurrWrtShell->EndAllAction();
}
break;
case SfxStyleFamily::Pseudo:
{
const SwNumRule* pCurRule = pCurrWrtShell->GetNumRuleAtCurrCursorPos();
if (pCurRule)
{
pCurrWrtShell->StartAllAction();
SwNumRule aRule( *pCurRule );
OUString sOrigRule( aRule.GetName() );
// #i91400#
aRule.SetName( pStyle->GetNumRule()->GetName(),
pCurrWrtShell->GetDoc()->getIDocumentListsAccess() );
pCurrWrtShell->ChgNumRuleFormats( aRule );
pCurrWrtShell->ReplaceNumRule( sOrigRule, aRule.GetName() );
pCurrWrtShell->EndAllAction();
}
}
break;
case SfxStyleFamily::Table:
{
SwTableAutoFormat* pFormat = pStyle->GetTableFormat();
if (pCurrWrtShell->GetTableAutoFormat(*pFormat))
{
pCurrWrtShell->StartAllAction();
pCurrWrtShell->SetTableStyle(rName);
pCurrWrtShell->EndAllAction();
}
}
break;
default: break;
}
}
sfx::AccessibilityIssueCollection SwDocShell::runAccessibilityCheck()
{
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
sw::AccessibilityCheck aCheck(m_xDoc.get());
aCheck.check();
return aCheck.getIssueCollection();
#else
return sfx::AccessibilityIssueCollection();
#endif
}
std::set<Color> SwDocShell::GetDocColors()
{
return m_xDoc->GetDocColors();
}
std::shared_ptr<model::ColorSet> SwDocShell::GetThemeColors()
{
SdrModel* pModel = m_xDoc->getIDocumentDrawModelAccess().GetDrawModel();
if (!pModel)
return {};
auto const& pTheme = pModel->getTheme();
if (!pTheme)
return {};
return pTheme->getColorSet();
}
void SwDocShell::LoadStyles( SfxObjectShell& rSource )
{
LoadStyles_(rSource, false);
}
// bPreserveCurrentDocument determines whether SetFixFields() is called
// This call modifies the source document. This mustn't happen when the source
// is a document the user is working on.
// Calls of ::LoadStyles() normally use files especially loaded for the purpose
// of importing styles.
void SwDocShell::LoadStyles_( SfxObjectShell& rSource, bool bPreserveCurrentDocument )
{
/* [Description]
This method is called by SFx if Styles have to be reloaded from a
document-template. Existing Styles should be overwritten by that.
That's why the document has to be reformatted. Therefore applications
will usually override this method and call the baseclass' implementation
in their implementation.
*/
// When the source is our document, we do the checking ourselves
// (much quicker and doesn't use the crutch StxStylePool).
if( dynamic_cast<const SwDocShell*>( &rSource) != nullptr)
{
// in order for the Headers/Footers not to get the fixed content
// of the template, update all the Source's
// FixFields once.
if(!bPreserveCurrentDocument)
static_cast<SwDocShell&>(rSource).m_xDoc->getIDocumentFieldsAccess().SetFixFields(nullptr);
if (m_pWrtShell)
{
// rhbz#818557, fdo#58893: EndAllAction will call SelectShell(),
// which pushes a bunch of SfxShells that are not cleared
// (for unknown reasons) when closing the document, causing crash;
// setting g_bNoInterrupt appears to avoid the problem.
::comphelper::FlagRestorationGuard g(g_bNoInterrupt, true);
m_pWrtShell->StartAllAction();
m_xDoc->ReplaceStyles( *static_cast<SwDocShell&>(rSource).m_xDoc );
m_pWrtShell->EndAllAction();
}
else
{
bool bModified = m_xDoc->getIDocumentState().IsModified();
m_xDoc->ReplaceStyles( *static_cast<SwDocShell&>(rSource).m_xDoc );
if (!bModified && m_xDoc->getIDocumentState().IsModified() && !m_pView)
{
// the View is created later, but overwrites the Modify-Flag.
// Undo doesn't work anymore anyways.
m_xDoc->GetIDocumentUndoRedo().SetUndoNoResetModified();
}
}
}
else
SfxObjectShell::LoadStyles( rSource );
}
void SwDocShell::FormatPage(
weld::Window* pDialogParent,
const OUString& rPage,
const OUString& rPageId,
SwWrtShell& rActShell,
SfxRequest* pRequest)
{
Edit(pDialogParent, rPage, OUString(), SfxStyleFamily::Page, SfxStyleSearchBits::Auto, false, rPageId, &rActShell, pRequest);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */