sc/inc/drwlayer.hxx | 1 sc/inc/stlpool.hxx | 6 ++- sc/source/core/data/documen9.cxx | 8 ++++ sc/source/core/data/drwlayer.cxx | 18 ++++++++- sc/source/core/data/postit.cxx | 5 ++ sc/source/core/data/stlpool.cxx | 42 ++++++++++++++++++++-- sc/source/core/tool/stylehelper.cxx | 10 +++++ sc/source/ui/app/drwtrans.cxx | 22 ++++++++--- sc/source/ui/app/transobj.cxx | 6 +-- sc/source/ui/view/viewfun5.cxx | 12 ++---- sc/source/ui/view/viewfun7.cxx | 10 ++++- svx/source/sdr/properties/attributeproperties.cxx | 2 - svx/source/sdr/properties/graphicproperties.cxx | 1 svx/source/sdr/properties/oleproperties.cxx | 1 14 files changed, 119 insertions(+), 25 deletions(-)
New commits: commit 685a864cfc40227559ed55f6273fd118174e8e6e Author: Maxim Monastirsky <momonas...@gmail.com> AuthorDate: Sun Mar 26 22:23:52 2023 +0300 Commit: Maxim Monastirsky <momonas...@gmail.com> CommitDate: Thu Mar 30 22:43:23 2023 +0000 sc drawstyles: Clipboard support - Paste as Calc's own format (default in Calc, results with an OLE object elsewhere), should preserve style assignment. This can be in one of two ways: Either copy the shape itself, or a cell range that includes a shape. - Similarly, copying or moving a whole sheet to another document should also preserve the style. - Paste as drawing format (default in other apps, also default in Calc when copying shapes from other apps), should preserve the formatting as direct formatting. Pasting into Calc will also assign the default style to that shape. Change-Id: Icb951dad1a77ba9ced706c33c928980d1ec7f8ac Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149753 Tested-by: Jenkins Reviewed-by: Maxim Monastirsky <momonas...@gmail.com> diff --git a/sc/inc/stlpool.hxx b/sc/inc/stlpool.hxx index 51694a405202..131b82c749ef 100644 --- a/sc/inc/stlpool.hxx +++ b/sc/inc/stlpool.hxx @@ -45,8 +45,10 @@ public: void CreateStandardStyles(); void CopyStdStylesFrom( ScStyleSheetPool* pSrcPool ); - void CopyStyleFrom( ScStyleSheetPool* pSrcPool, - const OUString& rName, SfxStyleFamily eFamily ); + void CopyUsedGraphicStylesFrom( SfxStyleSheetBasePool* pSrcPool ); + void CopyStyleFrom( SfxStyleSheetBasePool* pSrcPool, + const OUString& rName, SfxStyleFamily eFamily, + bool bNewStyleHierarchy = false ); bool HasStandardStyles() const { return bHasStandardStyles; } diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx index 34c25c761db4..f63c1ee4d1f1 100644 --- a/sc/source/core/data/documen9.cxx +++ b/sc/source/core/data/documen9.cxx @@ -45,6 +45,7 @@ #include <rechead.hxx> #include <poolhelp.hxx> #include <docpool.hxx> +#include <stlpool.hxx> #include <editutil.hxx> #include <charthelper.hxx> #include <conditio.hxx> @@ -76,6 +77,12 @@ void ScDocument::TransferDrawPage(const ScDocument& rSrcDoc, SCTAB nSrcPos, SCTA SdrObject* pOldObject = aIter.Next(); while (pOldObject) { + // Copy style sheet + auto pStyleSheet = pOldObject->GetStyleSheet(); + if (pStyleSheet) + GetStyleSheetPool()->CopyStyleFrom(rSrcDoc.GetStyleSheetPool(), + pStyleSheet->GetName(), pStyleSheet->GetFamily(), true); + // Clone to target SdrModel rtl::Reference<SdrObject> pNewObject(pOldObject->CloneSdrObject(*mpDrawLayer)); pNewObject->NbcMove(Size(0,0)); diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 263c5698c15a..a3162055d386 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -385,8 +385,11 @@ SdrModel* ScDrawLayer::AllocModel() const { // Allocated model (for clipboard etc) must not have a pointer // to the original model's document, pass NULL as document: + auto pNewModel = std::make_unique<ScDrawLayer>(nullptr, aName); + auto pNewPool = static_cast<ScStyleSheetPool*>(pNewModel->GetStyleSheetPool()); + pNewPool->CopyUsedGraphicStylesFrom(GetStyleSheetPool()); - return new ScDrawLayer( nullptr, aName ); + return pNewModel.release(); } bool ScDrawLayer::ScAddPage( SCTAB nTab ) @@ -1930,6 +1933,12 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if (bObjectInArea && (pOldObject->GetLayer() != SC_LAYER_INTERN) && !IsNoteCaption(pOldObject)) { + // Copy style sheet + auto pStyleSheet = pOldObject->GetStyleSheet(); + if (pStyleSheet && !bSameDoc) + pDoc->GetStyleSheetPool()->CopyStyleFrom(pClipDoc->GetStyleSheetPool(), + pStyleSheet->GetName(), pStyleSheet->GetFamily(), true); + // Clone to target SdrModel rtl::Reference<SdrObject> pNewObject(pOldObject->CloneSdrObject(*this)); diff --git a/sc/source/core/data/stlpool.cxx b/sc/source/core/data/stlpool.cxx index e7f6d26aa0c7..6a450483d15e 100644 --- a/sc/source/core/data/stlpool.cxx +++ b/sc/source/core/data/stlpool.cxx @@ -125,8 +125,9 @@ void ScStyleSheetPool::Remove( SfxStyleSheetBase* pStyle ) } } -void ScStyleSheetPool::CopyStyleFrom( ScStyleSheetPool* pSrcPool, - const OUString& rName, SfxStyleFamily eFamily ) +void ScStyleSheetPool::CopyStyleFrom( SfxStyleSheetBasePool* pSrcPool, + const OUString& rName, SfxStyleFamily eFamily, + bool bNewStyleHierarchy ) { // this is the Dest-Pool @@ -136,8 +137,10 @@ void ScStyleSheetPool::CopyStyleFrom( ScStyleSheetPool* pSrcPool, const SfxItemSet& rSourceSet = pStyleSheet->GetItemSet(); SfxStyleSheetBase* pDestSheet = Find( rName, eFamily ); + if (pDestSheet && bNewStyleHierarchy) + return; if (!pDestSheet) - pDestSheet = &Make( rName, eFamily ); + pDestSheet = &Make( rName, eFamily, pStyleSheet->GetMask() ); SfxItemSet& rDestSet = pDestSheet->GetItemSet(); rDestSet.PutExtended( rSourceSet, SfxItemState::DONTCARE, SfxItemState::DEFAULT ); @@ -176,6 +179,38 @@ void ScStyleSheetPool::CopyStyleFrom( ScStyleSheetPool* pSrcPool, } } } + + const OUString aParentName = pStyleSheet->GetParent(); + if (!bNewStyleHierarchy || aParentName.isEmpty()) + return; + + CopyStyleFrom(pSrcPool, aParentName, eFamily, bNewStyleHierarchy); + pDestSheet->SetParent(aParentName); +} + +void ScStyleSheetPool::CopyUsedGraphicStylesFrom(SfxStyleSheetBasePool* pSrcPool) +{ + // this is the Dest-Pool + + std::vector<std::pair<SfxStyleSheetBase*, OUString>> aNewStyles; + + auto pSrcSheet = pSrcPool->First(SfxStyleFamily::Frame); + while (pSrcSheet) + { + if (pSrcSheet->IsUsed() && !Find(pSrcSheet->GetName(), pSrcSheet->GetFamily())) + { + auto pDestSheet = &Make(pSrcSheet->GetName(), pSrcSheet->GetFamily(), pSrcSheet->GetMask()); + aNewStyles.emplace_back(pDestSheet, pSrcSheet->GetParent()); + + SfxItemSet& rDestSet = pDestSheet->GetItemSet(); + rDestSet.Put(pSrcSheet->GetItemSet()); + } + + pSrcSheet = pSrcPool->Next(); + } + + for (const auto& style : aNewStyles) + style.first->SetParent(style.second); } // Standard templates @@ -185,6 +220,7 @@ void ScStyleSheetPool::CopyStdStylesFrom( ScStyleSheetPool* pSrcPool ) // Copy Default styles CopyStyleFrom( pSrcPool, ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para ); + CopyStyleFrom( pSrcPool, ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Frame ); CopyStyleFrom( pSrcPool, ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Page ); CopyStyleFrom( pSrcPool, ScResId(STR_STYLENAME_REPORT), SfxStyleFamily::Page ); } diff --git a/sc/source/ui/app/drwtrans.cxx b/sc/source/ui/app/drwtrans.cxx index 569fd6e0ab6a..8dae3e5f3374 100644 --- a/sc/source/ui/app/drwtrans.cxx +++ b/sc/source/ui/app/drwtrans.cxx @@ -54,6 +54,9 @@ #include <viewdata.hxx> #include <scmod.hxx> #include <dragdata.hxx> +#include <stlpool.hxx> +#include <scresid.hxx> +#include <globstr.hrc> #include <editeng/eeitem.hxx> @@ -358,7 +361,11 @@ bool ScDrawTransferObj::GetData( const css::datatransfer::DataFlavor& rFlavor, c } else if ( nFormat == SotClipboardFormatId::DRAWING ) { - bOK = SetObject( m_pModel.get(), SCDRAWTRANS_TYPE_DRAWMODEL, rFlavor ); + SdrView aView(*m_pModel); + SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel().GetPage(0)); + aView.MarkAllObj( pPv ); + auto pNewModel = aView.CreateMarkedObjModel(); + bOK = SetObject( pNewModel.get(), SCDRAWTRANS_TYPE_DRAWMODEL, rFlavor ); } else if ( nFormat == SotClipboardFormatId::BITMAP || nFormat == SotClipboardFormatId::PNG @@ -429,19 +436,20 @@ bool ScDrawTransferObj::WriteObject( tools::SvRef<SotTempStream>& rxOStm, void* case SCDRAWTRANS_TYPE_DRAWMODEL: { SdrModel* pDrawModel = static_cast<SdrModel*>(pUserObject); + pDrawModel->BurnInStyleSheetAttributes(); rxOStm->SetBufferSize( 0xff00 ); // for the changed pool defaults from drawing layer pool set those // attributes as hard attributes to preserve them for saving - const SfxItemPool& rItemPool = m_pModel->GetItemPool(); + const SfxItemPool& rItemPool = pDrawModel->GetItemPool(); const SvxFontHeightItem& rDefaultFontHeight = rItemPool.GetDefaultItem(EE_CHAR_FONTHEIGHT); // SW should have no MasterPages - OSL_ENSURE(0 == m_pModel->GetMasterPageCount(), "SW with MasterPages (!)"); + OSL_ENSURE(0 == pDrawModel->GetMasterPageCount(), "SW with MasterPages (!)"); - for(sal_uInt16 a(0); a < m_pModel->GetPageCount(); a++) + for(sal_uInt16 a(0); a < pDrawModel->GetPageCount(); a++) { - const SdrPage* pPage(m_pModel->GetPage(a)); + const SdrPage* pPage(pDrawModel->GetPage(a)); SdrObjListIter aIter(pPage, SdrIterMode::DeepNoGroups); while(aIter.IsMore()) @@ -677,6 +685,10 @@ void ScDrawTransferObj::InitDocShell() ScDocument& rDestDoc = pDocSh->GetDocument(); rDestDoc.InitDrawLayer( pDocSh ); + auto pPool = rDestDoc.GetStyleSheetPool(); + pPool->CopyStyleFrom(m_pModel->GetStyleSheetPool(), ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Frame); + pPool->CopyUsedGraphicStylesFrom(m_pModel->GetStyleSheetPool()); + SdrModel* pDestModel = rDestDoc.GetDrawLayer(); // #i71538# use complete SdrViews // SdrExchangeView aDestView( pDestModel ); diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx index d0fbd02fce43..138b0789370b 100644 --- a/sc/source/ui/app/transobj.cxx +++ b/sc/source/ui/app/transobj.cxx @@ -677,6 +677,9 @@ void ScTransferObj::InitDocShell(bool bLimitToPageSize) m_pDoc->GetName( m_aBlock.aStart.Tab(), aTabName ); rDestDoc.RenameTab( 0, aTabName ); + if (m_pDoc->GetDrawLayer() || m_pDoc->HasNotes()) + pDocSh->MakeDrawLayer(); + rDestDoc.CopyStdStylesFrom(*m_pDoc); SCCOL nStartX = m_aBlock.aStart.Col(); @@ -716,9 +719,6 @@ void ScTransferObj::InitDocShell(bool bLimitToPageSize) } } - if (m_pDoc->GetDrawLayer() || m_pDoc->HasNotes()) - pDocSh->MakeDrawLayer(); - // cell range is copied to the original position, but on the first sheet // -> bCutMode must be set // pDoc is always a Clipboard-document diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx index d1a6e5965fca..f57eca004edf 100644 --- a/sc/source/ui/view/viewfun5.cxx +++ b/sc/source/ui/view/viewfun5.cxx @@ -565,18 +565,15 @@ bool ScViewFunc::PasteDataFormat( SotClipboardFormatId nFormatId, MakeDrawLayer(); // before loading model, so 3D factory has been created ScDocShellRef aDragShellRef( new ScDocShell ); + aDragShellRef->MakeDrawLayer(); aDragShellRef->DoInitNew(); - std::unique_ptr<FmFormModel> pModel( - new FmFormModel( - nullptr, - aDragShellRef.get())); + ScDrawLayer* pModel = aDragShellRef->GetDocument().GetDrawLayer(); - pModel->GetItemPool().FreezeIdRanges(); xStm->Seek(0); css::uno::Reference< css::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) ); - SvxDrawingLayerImport( pModel.get(), xInputStream ); + SvxDrawingLayerImport( pModel, xInputStream ); // set everything to right layer: size_t nObjCount = 0; @@ -598,8 +595,7 @@ bool ScViewFunc::PasteDataFormat( SotClipboardFormatId nFormatId, nObjCount += pPage->GetObjCount(); // count group object only once } - PasteDraw(aPos, pModel.get(), (nObjCount > 1), u"A", u"B"); // grouped if more than 1 object - pModel.reset(); + PasteDraw(aPos, pModel, (nObjCount > 1), u"A", u"B"); // grouped if more than 1 object aDragShellRef->DoClose(); bRet = true; } diff --git a/sc/source/ui/view/viewfun7.cxx b/sc/source/ui/view/viewfun7.cxx index 76ede14b2fbe..f704256756fe 100644 --- a/sc/source/ui/view/viewfun7.cxx +++ b/sc/source/ui/view/viewfun7.cxx @@ -47,6 +47,7 @@ #include <docsh.hxx> #include <dragdata.hxx> #include <gridwin.hxx> +#include <stlpool.hxx> bool bPasteIsMove = false; @@ -213,10 +214,15 @@ void ScViewFunc::PasteDraw( const Point& rLogicPos, SdrModel* pModel, ScChartHelper::GetChartNames( aExcludedChartNames, pPage ); } - // #89247# Set flag for ScDocument::UpdateChartListeners() which is - // called during paste. if ( !bSameDocClipboard ) + { + auto pPool = static_cast<ScStyleSheetPool*>(pScDrawView->GetModel().GetStyleSheetPool()); + pPool->CopyUsedGraphicStylesFrom(pModel->GetStyleSheetPool()); + + // #89247# Set flag for ScDocument::UpdateChartListeners() which is + // called during paste. GetViewData().GetDocument().SetPastingDrawFromOtherDoc( true ); + } pScDrawView->Paste(*pModel, aPos, nullptr, nOptions); diff --git a/svx/source/sdr/properties/attributeproperties.cxx b/svx/source/sdr/properties/attributeproperties.cxx index 7f141b8f65b7..d4a001795360 100644 --- a/svx/source/sdr/properties/attributeproperties.cxx +++ b/svx/source/sdr/properties/attributeproperties.cxx @@ -195,7 +195,7 @@ namespace sdr::properties pTargetStyleSheet = dynamic_cast< SfxStyleSheet* >( pTargetStyleSheetPool->Find( rProps.GetStyleSheet()->GetName(), - SfxStyleFamily::All)); + rProps.GetStyleSheet()->GetFamily())); } } } commit cb3b8b0aaa9d53bd4b4a74d22b87d46e77835206 Author: Maxim Monastirsky <momonas...@gmail.com> AuthorDate: Wed Mar 22 22:10:21 2023 +0200 Commit: Maxim Monastirsky <momonas...@gmail.com> CommitDate: Thu Mar 30 22:43:09 2023 +0000 sc drawstyles: Add a default style and make use of it The style is empty, similar to the default cell style, thus fall backs to the pool defaults for everything. This ensures compatibility with existing documents, despite the fact that the default style is applied to all shapes upon import. In addition, people who will ignore styles and just continue to use DF, will have their spreadsheets look the same in older versions that don't support styles. For this reason I also opted to not set a dedicated style for images and OLE objects via SdrModel::SetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj, unlike Impress/Draw, and continue setting the "no fill and no line" override as DF. Change-Id: I11554044a1aaf386dc6c4acdbab798fc5a231adc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149359 Tested-by: Jenkins Reviewed-by: Maxim Monastirsky <momonas...@gmail.com> diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx index 55c1031d099a..c127f597bab2 100644 --- a/sc/inc/drwlayer.hxx +++ b/sc/inc/drwlayer.hxx @@ -118,6 +118,7 @@ public: virtual SdrModel* AllocModel() const override; virtual void SetChanged( bool bFlg = true ) override; + void CreateDefaultStyles(); bool HasObjects() const; bool ScAddPage( SCTAB nTab ); diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx index e6a6501c46e4..34c25c761db4 100644 --- a/sc/source/core/data/documen9.cxx +++ b/sc/source/core/data/documen9.cxx @@ -130,6 +130,7 @@ void ScDocument::InitDrawLayer( SfxObjectShell* pDocShell ) OSL_ENSURE(!pLocalPool->GetSecondaryPool(), "OOps, already a secondary pool set where the DrawingLayer ItemPool is to be placed (!)"); pLocalPool->SetSecondaryPool(&mpDrawLayer->GetItemPool()); } + mpDrawLayer->CreateDefaultStyles(); } // Drawing pages are accessed by table number, so they must also be present diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 359bf3b1e7be..263c5698c15a 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -343,6 +343,13 @@ ScDrawLayer::~ScDrawLayer() } } +void ScDrawLayer::CreateDefaultStyles() +{ + // Default + auto pSheet = &GetStyleSheetPool()->Make(ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Frame, SfxStyleSearchBits::ScStandard); + SetDefaultStyleSheet(static_cast<SfxStyleSheet*>(pSheet)); +} + void ScDrawLayer::UseHyphenator() { if (!bHyphenatorSet) diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx index f33ed9dd6b68..00aab1d52030 100644 --- a/sc/source/core/data/postit.cxx +++ b/sc/source/core/data/postit.cxx @@ -759,6 +759,11 @@ void ScPostIt::CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCapti } else { + // set default size, undoing sdr::TextProperties::SetStyleSheet's + // adjustment that use a wrong min height. + maNoteData.mxCaption->SetMergedItem(makeSdrTextMinFrameHeightItem(SC_NOTECAPTION_HEIGHT)); + maNoteData.mxCaption->SetMergedItem(makeSdrTextMinFrameWidthItem(SC_NOTECAPTION_WIDTH)); + maNoteData.mxCaption->NbcAdjustTextFrameWidthAndHeight(); // set default formatting and default position ScCaptionUtil::SetDefaultItems( *maNoteData.mxCaption, mrDoc, nullptr ); aCreator.AutoPlaceCaption(); diff --git a/sc/source/core/tool/stylehelper.cxx b/sc/source/core/tool/stylehelper.cxx index e9a920500e79..3adcfb4847bc 100644 --- a/sc/source/core/tool/stylehelper.cxx +++ b/sc/source/core/tool/stylehelper.cxx @@ -97,6 +97,16 @@ static const ScDisplayNameMap* lcl_GetStyleNameMap( SfxStyleFamily nType ) }; return aPageMap; } + else if ( nType == SfxStyleFamily::Frame ) + { + static ScDisplayNameMap const aGraphicMap[] + { + { ScResId( STR_STYLENAME_STANDARD ), OUString(SC_STYLE_PROG_STANDARD) }, + // last entry remains empty + { OUString(), OUString() }, + }; + return aGraphicMap; + } OSL_FAIL("invalid family"); return nullptr; } diff --git a/svx/source/sdr/properties/graphicproperties.cxx b/svx/source/sdr/properties/graphicproperties.cxx index be9b87800a0e..85509f79c6a7 100644 --- a/svx/source/sdr/properties/graphicproperties.cxx +++ b/svx/source/sdr/properties/graphicproperties.cxx @@ -49,6 +49,7 @@ namespace sdr::properties } else { + RectangleProperties::applyDefaultStyleSheetFromSdrModel(); SetMergedItem(XFillStyleItem(com::sun::star::drawing::FillStyle_NONE)); SetMergedItem(XLineStyleItem(com::sun::star::drawing::LineStyle_NONE)); } diff --git a/svx/source/sdr/properties/oleproperties.cxx b/svx/source/sdr/properties/oleproperties.cxx index 587ff1d3f880..da599428c97b 100644 --- a/svx/source/sdr/properties/oleproperties.cxx +++ b/svx/source/sdr/properties/oleproperties.cxx @@ -36,6 +36,7 @@ namespace sdr::properties } else { + RectangleProperties::applyDefaultStyleSheetFromSdrModel(); SetMergedItem(XFillStyleItem(com::sun::star::drawing::FillStyle_NONE)); SetMergedItem(XLineStyleItem(com::sun::star::drawing::LineStyle_NONE)); }