1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
21 #include <com/sun/star/beans/XPropertySet.hpp>
22 #include <com/sun/star/container/XNameAccess.hpp>
23 #include <com/sun/star/frame/XModel.hpp>
25 #include <futempl.hxx>
27 #include <svx/svxids.hrc>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/dispatch.hxx>
30 #include <editeng/eeitem.hxx>
31 #include <sfx2/request.hxx>
32 #include <sfx2/sfxdlg.hxx>
33 #include <editeng/numitem.hxx>
34 #include <svx/svdopage.hxx>
35 #include <editeng/colritem.hxx>
36 #include <editeng/brushitem.hxx>
37 #include <svx/svditer.hxx>
38 #include <svx/sdr/properties/properties.hxx>
39 #include <svl/intitem.hxx>
41 #include <sfx2/viewfrm.hxx>
42 #include <svx/xlndsit.hxx>
43 #include <svx/xlnstit.hxx>
44 #include <svx/xlnedit.hxx>
45 #include <svx/xbtmpit.hxx>
46 #include <svx/xflgrit.hxx>
47 #include <svx/xflftrit.hxx>
48 #include <svx/xflhtit.hxx>
49 #include <o3tl/string_view.hxx>
51 #include <stlsheet.hxx>
53 #include <stlpool.hxx>
56 #include <drawdoc.hxx>
57 #include <DrawDocShell.hxx>
58 #include <DrawViewShell.hxx>
59 #include <ViewShell.hxx>
61 #include <strings.hrc>
62 #include <prlayout.hxx>
63 #include <sdresid.hxx>
64 #include <OutlineView.hxx>
65 #include <sdabstdlg.hxx>
68 using namespace com::sun::star::uno
;
69 using namespace com::sun::star::container
;
70 using namespace com::sun::star::beans
;
71 using namespace com::sun::star::style
;
77 FuTemplate::FuTemplate (
83 : FuPoor( pViewSh
, pWin
, pView
, pDoc
, rReq
)
87 rtl::Reference
<FuPoor
> FuTemplate::Create( ViewShell
* pViewSh
, ::sd::Window
* pWin
, ::sd::View
* pView
, SdDrawDocument
* pDoc
, SfxRequest
& rReq
)
89 rtl::Reference
<FuPoor
> xFunc( new FuTemplate( pViewSh
, pWin
, pView
, pDoc
, rReq
) );
90 xFunc
->DoExecute(rReq
);
94 void FuTemplate::DoExecute( SfxRequest
& rReq
)
96 const SfxItemSet
* pArgs
= rReq
.GetArgs();
97 sal_uInt16 nSId
= rReq
.GetSlot();
99 // get StyleSheet parameter
100 SfxStyleSheetBasePool
* pSSPool
= mpDoc
->GetDocSh()->GetStyleSheetPool();
101 SfxStyleSheetBase
* pStyleSheet
= nullptr;
103 const SfxPoolItem
* pItem
;
104 SfxStyleFamily nFamily
= SfxStyleFamily(USHRT_MAX
);
105 if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState( SID_STYLE_FAMILY
,
108 nFamily
= static_cast<SfxStyleFamily
>( pArgs
->Get( SID_STYLE_FAMILY
).GetValue());
110 else if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState( SID_STYLE_FAMILYNAME
,
113 OUString sFamily
= pArgs
->Get( SID_STYLE_FAMILYNAME
).GetValue();
114 if (sFamily
== "graphics")
115 nFamily
= SfxStyleFamily::Para
;
117 nFamily
= SfxStyleFamily::Pseudo
;
121 sal_uInt16 nRetMask
= static_cast<sal_uInt16
>(SfxStyleSearchBits::All
);
125 case SID_STYLE_APPLY
:
127 case SID_STYLE_DELETE
:
130 case SID_STYLE_FAMILY
:
131 case SID_STYLE_NEW_BY_EXAMPLE
:
133 const SfxStringItem
* pNameItem
= rReq
.GetArg
<SfxStringItem
>(SID_APPLY_STYLE
);
134 const SfxStringItem
* pFamilyItem
= rReq
.GetArg
<SfxStringItem
>(SID_STYLE_FAMILYNAME
);
135 if ( pFamilyItem
&& pNameItem
)
139 Reference
< XStyleFamiliesSupplier
> xModel(mpDoc
->GetDocSh()->GetModel(), UNO_QUERY_THROW
);
140 Reference
< XNameAccess
> xCont( xModel
->getStyleFamilies() );
141 Reference
< XNameAccess
> xStyles( xCont
->getByName(pFamilyItem
->GetValue()), UNO_QUERY_THROW
);
142 Reference
< XPropertySet
> xInfo( xStyles
->getByName( pNameItem
->GetValue() ), UNO_QUERY_THROW
);
145 xInfo
->getPropertyValue( u
"DisplayName"_ustr
) >>= aUIName
;
146 if ( !aUIName
.isEmpty() )
147 rReq
.AppendItem( SfxStringItem( nSId
, aUIName
) );
154 if (pArgs
&& pArgs
->GetItemState(nSId
) == SfxItemState::SET
)
155 aStyleName
= static_cast<const SfxStringItem
&>( pArgs
->Get( nSId
) ).GetValue();
163 SfxStyleSheetBase
*p
= pSSPool
->Find(aStyleName
, nFamily
);
169 pStyleSheet
= &pSSPool
->Make( aStyleName
, nFamily
, SfxStyleSearchBits::UserDefined
);
171 if (pArgs
&& pArgs
->GetItemState(SID_STYLE_REFERENCE
) == SfxItemState::SET
)
173 OUString
aParentName( pArgs
->Get(SID_STYLE_REFERENCE
).GetValue());
174 pStyleSheet
->SetParent(aParentName
);
178 pStyleSheet
->SetParent(SdResId(STR_STANDARD_STYLESHEET_NAME
));
183 case SID_STYLE_NEW_BY_EXAMPLE
:
185 // at the moment, the dialog to enter the name of the template is still opened
186 SfxStyleSheetBase
*p
= pSSPool
->Find(aStyleName
, nFamily
);
192 pStyleSheet
= &pSSPool
->Make( aStyleName
, nFamily
, SfxStyleSearchBits::UserDefined
);
193 pStyleSheet
->SetParent(SdResId(STR_STANDARD_STYLESHEET_NAME
));
198 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
201 case SID_STYLE_DELETE
:
202 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
205 pSSPool
->Remove( pStyleSheet
);
206 nRetMask
= sal_uInt16(true);
211 nRetMask
= sal_uInt16(false);
217 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
218 pStyleSheet
->SetHidden( nSId
== SID_STYLE_HIDE
);
219 nRetMask
= sal_uInt16(true);
222 case SID_STYLE_APPLY
:
223 // apply the template to the document
224 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
226 // do not set presentation styles, they will be set implicit
227 if ( pStyleSheet
&& pStyleSheet
->GetFamily() != SfxStyleFamily::Pseudo
)
229 SfxStyleSheet
* pOldStyleSheet
= mpView
->GetStyleSheet();
232 if( // if the object had no style sheet, allow all
235 // allow if old and new style sheet has same family
236 pStyleSheet
->GetFamily() == pOldStyleSheet
->GetFamily() ||
238 // allow if old was background objects and new is graphics
239 (pStyleSheet
->GetFamily() == SfxStyleFamily::Para
&& pOldStyleSheet
->GetHelpId( aStr
) == HID_PSEUDOSHEET_BACKGROUNDOBJECTS
) ||
241 // allow if old was presentation and we are a drawing document
242 (pOldStyleSheet
->GetFamily() == SfxStyleFamily::Page
&& mpDoc
->GetDocumentType() == DocumentType::Draw
) )
244 mpView
->SetStyleSheet( static_cast<SfxStyleSheet
*>(pStyleSheet
));
246 mpViewShell
->GetViewFrame()->GetBindings().Invalidate( SID_STYLE_FAMILY2
);
251 case SID_STYLE_WATERCAN
:
253 if (SdModule
* mod
= SdModule::get(); !mod
->GetWaterCan())
255 if (pArgs
&& pArgs
->GetItemState( nSId
) == SfxItemState::SET
)
257 aStyleName
= static_cast<const SfxStringItem
&>( pArgs
->Get( nSId
) ).GetValue();
258 mod
->SetWaterCan(true);
259 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
261 // no presentation object templates, they are only allowed implicitly
262 if( pStyleSheet
&& pStyleSheet
->GetFamily() != SfxStyleFamily::Pseudo
)
264 static_cast<SdStyleSheetPool
*>( pSSPool
)->SetActualStyleSheet( pStyleSheet
);
266 // we switch explicitly into selection mode
267 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute( SID_OBJECT_SELECT
,
268 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
272 mod
->SetWaterCan(false);
276 mod
->SetWaterCan(false);
277 // we have to re-enable to tools-bar
278 mpViewShell
->Invalidate();
292 PresentationObjects ePO
= PresentationObjects::Outline_1
;
296 ScopedVclPtr
<SfxAbstractTabDialog
> pStdDlg
;
297 ScopedVclPtr
<SfxAbstractTabDialog
> pPresDlg
;
298 SdAbstractDialogFactory
* pFact
= SdAbstractDialogFactory::Create();
300 SfxStyleFamily eFamily
= pStyleSheet
->GetFamily();
302 if (eFamily
== SfxStyleFamily::Para
)
304 pStdDlg
.disposeAndReset(pFact
? pFact
->CreateSdTabTemplateDlg(mpViewShell
->GetFrameWeld(), mpDoc
->GetDocSh(), *pStyleSheet
, mpDoc
, mpView
) : nullptr);
306 else if (eFamily
== SfxStyleFamily::Pseudo
)
308 OUString
aName(pStyleSheet
->GetName());
309 bool bBackground
= false;
310 bool bOldDocInOtherLanguage
= false;
312 if (aName
== SdResId(STR_PSEUDOSHEET_TITLE
))
314 ePO
= PresentationObjects::Title
;
316 else if (aName
== SdResId(STR_PSEUDOSHEET_SUBTITLE
))
318 ePO
= PresentationObjects::Subtitle
;
321 SdResId(STR_PSEUDOSHEET_BACKGROUND
))
324 ePO
= PresentationObjects::Background
;
327 SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS
))
329 ePO
= PresentationObjects::BackgroundObjects
;
332 SdResId(STR_PSEUDOSHEET_NOTES
))
334 ePO
= PresentationObjects::Notes
;
336 else if(aName
.indexOf(SdResId(STR_PSEUDOSHEET_OUTLINE
)) != -1)
338 OUString
aOutlineStr(SdResId(STR_PSEUDOSHEET_OUTLINE
));
339 // determine number, mind the blank between name and number
340 std::u16string_view
aNumStr(aName
.subView(aOutlineStr
.getLength() + 1));
341 sal_uInt16 nLevel
= static_cast<sal_uInt16
>(o3tl::toInt32(aNumStr
));
344 case 1: ePO
= PresentationObjects::Outline_1
; break;
345 case 2: ePO
= PresentationObjects::Outline_2
; break;
346 case 3: ePO
= PresentationObjects::Outline_3
; break;
347 case 4: ePO
= PresentationObjects::Outline_4
; break;
348 case 5: ePO
= PresentationObjects::Outline_5
; break;
349 case 6: ePO
= PresentationObjects::Outline_6
; break;
350 case 7: ePO
= PresentationObjects::Outline_7
; break;
351 case 8: ePO
= PresentationObjects::Outline_8
; break;
352 case 9: ePO
= PresentationObjects::Outline_9
; break;
357 OSL_FAIL("StyleSheet from older version with different language");
358 bOldDocInOtherLanguage
= true;
361 if( !bOldDocInOtherLanguage
)
363 pPresDlg
.disposeAndReset(pFact
? pFact
->CreateSdPresLayoutTemplateDlg(mpDocSh
, mpViewShell
->GetFrameWeld(), bBackground
, *pStyleSheet
, ePO
, pSSPool
) : nullptr);
367 sal_uInt16 nResult
= RET_CANCEL
;
368 const SfxItemSet
* pOutSet
= nullptr;
371 nResult
= pStdDlg
->Execute();
372 pOutSet
= pStdDlg
->GetOutputItemSet();
376 nResult
= pPresDlg
->Execute();
377 pOutSet
= pPresDlg
->GetOutputItemSet();
384 nRetMask
= static_cast<sal_uInt16
>(pStyleSheet
->GetMask());
386 if (eFamily
== SfxStyleFamily::Pseudo
)
388 SfxItemSet
aTempSet(*pOutSet
);
389 /* Extract SvxBrushItem out of set and insert SvxColorItem */
390 const SvxBrushItem
* pBrushItem
= aTempSet
.GetItem
<SvxBrushItem
>( SID_ATTR_BRUSH_CHAR
);
394 SvxColorItem
aBackColorItem(pBrushItem
->GetColor(), EE_CHAR_BKGCOLOR
);
395 aTempSet
.ClearItem( EE_CHAR_BKGCOLOR
);
396 aTempSet
.Put( aBackColorItem
);
398 static_cast<SdStyleSheet
*>(pStyleSheet
)->AdjustToFontHeight(aTempSet
);
400 /* Special treatment: reset the INVALIDS to
401 NULL-Pointer (otherwise INVALIDs or pointer point
402 to DefaultItems in the template; both would
403 prevent the attribute inheritance) */
404 aTempSet
.ClearInvalidItems();
406 // EE_PARA_NUMBULLET item is only valid in first outline template
407 if( (ePO
>= PresentationObjects::Outline_2
) && (ePO
<= PresentationObjects::Outline_9
) )
409 const SvxNumBulletItem
* pBulletItem
= nullptr;
410 if (aTempSet
.GetItemState(EE_PARA_NUMBULLET
, true, &pBulletItem
) == SfxItemState::SET
)
412 SvxNumRule
aRule(pBulletItem
->GetNumRule());
414 OUString
sStyleName(SdResId(STR_PSEUDOSHEET_OUTLINE
) + " 1");
415 SfxStyleSheetBase
* pFirstStyleSheet
= pSSPool
->Find( sStyleName
, SfxStyleFamily::Pseudo
);
419 pFirstStyleSheet
->GetItemSet().Put( SvxNumBulletItem( aRule
, EE_PARA_NUMBULLET
));
420 SdStyleSheet
* pRealSheet
= static_cast<SdStyleSheet
*>(pFirstStyleSheet
)->GetRealStyleSheet();
421 pRealSheet
->Broadcast(SfxHint(SfxHintId::DataChanged
));
424 aTempSet
.ClearItem( EE_PARA_NUMBULLET
);
428 pStyleSheet
->GetItemSet().Put(aTempSet
);
429 SdStyleSheet::BroadcastSdStyleSheetChange(pStyleSheet
, ePO
, pSSPool
);
432 SfxItemSet
& rAttr
= pStyleSheet
->GetItemSet();
434 sdr::properties::CleanupFillProperties( rAttr
);
436 // check for unique names of named items for xml
437 const SfxPoolItem
* pOldItem
= nullptr;
438 if( rAttr
.GetItemState( XATTR_FILLBITMAP
, true, &pOldItem
) == SfxItemState::SET
)
440 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XFillBitmapItem
*>(pOldItem
)->checkForUniqueItem( *mpDoc
);
443 rAttr
.Put( std::move(pNewItem
) );
446 if( rAttr
.GetItemState( XATTR_LINEDASH
, true, &pOldItem
) == SfxItemState::SET
)
448 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XLineDashItem
*>(pOldItem
)->checkForUniqueItem( *mpDoc
);
451 rAttr
.Put( std::move(pNewItem
) );
454 if( rAttr
.GetItemState( XATTR_LINESTART
, true, &pOldItem
) == SfxItemState::SET
)
456 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XLineStartItem
*>(pOldItem
)->checkForUniqueItem( *mpDoc
);
459 rAttr
.Put( std::move(pNewItem
) );
462 if( rAttr
.GetItemState( XATTR_LINEEND
, true, &pOldItem
) == SfxItemState::SET
)
464 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XLineEndItem
*>(pOldItem
)->checkForUniqueItem( *mpDoc
);
467 rAttr
.Put( std::move(pNewItem
) );
470 if( rAttr
.GetItemState( XATTR_FILLGRADIENT
, true, &pOldItem
) == SfxItemState::SET
)
472 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XFillGradientItem
*>(pOldItem
)->checkForUniqueItem( *mpDoc
);
475 rAttr
.Put( std::move(pNewItem
) );
478 if( rAttr
.GetItemState( XATTR_FILLFLOATTRANSPARENCE
, true, &pOldItem
) == SfxItemState::SET
)
480 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XFillFloatTransparenceItem
*>(pOldItem
)->checkForUniqueItem( *mpDoc
);
483 rAttr
.Put( std::move(pNewItem
) );
486 if( rAttr
.GetItemState( XATTR_FILLHATCH
, true, &pOldItem
) == SfxItemState::SET
)
488 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XFillHatchItem
*>(pOldItem
)->checkForUniqueItem( *mpDoc
);
491 rAttr
.Put( std::move(pNewItem
) );
495 static_cast<SfxStyleSheet
*>( pStyleSheet
)->Broadcast( SfxHint( SfxHintId::DataChanged
) );
497 DrawViewShell
* pDrawViewShell
= dynamic_cast< DrawViewShell
* >( mpViewShell
);
500 PageKind ePageKind
= pDrawViewShell
->GetPageKind();
501 if( ePageKind
== PageKind::Notes
|| ePageKind
== PageKind::Handout
)
503 SdPage
* pPage
= mpViewShell
->GetActualPage();
505 if(pDrawViewShell
->GetEditMode() == EditMode::MasterPage
)
507 pPage
= static_cast<SdPage
*>((&(pPage
->TRG_GetMasterPage())));
512 SdrObjListIter
aIter( pPage
);
513 while( aIter
.IsMore() )
515 SdrObject
* pObj
= aIter
.Next();
516 if( dynamic_cast< const SdrPageObj
*>( pObj
) != nullptr )
519 pObj
->ActionChanged();
520 // pObj->SendRepaintBroadcast();
527 if( mpDoc
->GetOnlineSpell() )
529 if( SfxItemState::SET
== rAttr
.GetItemState(EE_CHAR_LANGUAGE
, false ) ||
530 SfxItemState::SET
== rAttr
.GetItemState(EE_CHAR_LANGUAGE_CJK
, false ) ||
531 SfxItemState::SET
== rAttr
.GetItemState(EE_CHAR_LANGUAGE_CTL
, false ) )
533 mpDoc
->StopOnlineSpelling();
534 mpDoc
->StartOnlineSpelling();
544 if( nSId
== SID_STYLE_NEW
)
545 pSSPool
->Remove( pStyleSheet
);
553 case SID_STYLE_NEW_BY_EXAMPLE
:
557 nRetMask
= static_cast<sal_uInt16
>(pStyleSheet
->GetMask());
558 SfxItemSet
aCoreSet( mpDoc
->GetPool() );
559 mpView
->GetAttributes( aCoreSet
, true );
561 // if the object had a template, this becomes parent of the new template
562 SfxStyleSheet
* pOldStyle
= mpView
->GetStyleSheet();
564 // if pOldStyle == pStyleSheet -> recursion
565 if( pOldStyle
!= pStyleSheet
)
569 pStyleSheet
->SetParent(pOldStyle
->GetName());
572 SfxItemSet
* pStyleSet
= &pStyleSheet
->GetItemSet();
573 pStyleSet
->Put(aCoreSet
);
575 /* apply template (but not when somebody is editing a text.
576 To do this, the edit engine had to be capable to use
577 templates on a character level. */
578 if (!mpView
->GetTextEditObject())
580 mpView
->SetStyleSheet( static_cast<SfxStyleSheet
*>(pStyleSheet
));
583 static_cast<SfxStyleSheet
*>( pStyleSheet
)->Broadcast( SfxHint( SfxHintId::DataChanged
) );
586 mpViewShell
->GetViewFrame()->GetBindings().Invalidate( SID_STYLE_FAMILY2
);
592 case SID_STYLE_UPDATE_BY_EXAMPLE
:
594 const SdrMarkList
& rMarkList
= mpView
->GetMarkedObjectList();
595 if ((rMarkList
.GetMarkCount() != 0 && rMarkList
.GetMarkCount() == 1) ||
596 dynamic_cast< const OutlineView
*>( mpView
) != nullptr)
598 pStyleSheet
= mpView
->GetStyleSheet();
602 nRetMask
= static_cast<sal_uInt16
>(pStyleSheet
->GetMask());
603 SfxItemSet
aCoreSet( mpDoc
->GetPool() );
604 mpView
->GetAttributes( aCoreSet
);
606 SfxItemSet
* pStyleSet
= &pStyleSheet
->GetItemSet();
607 pStyleSet
->Put( aCoreSet
);
609 mpView
->SetStyleSheet( static_cast<SfxStyleSheet
*>(pStyleSheet
));
611 static_cast<SfxStyleSheet
*>( pStyleSheet
)->Broadcast( SfxHint( SfxHintId::DataChanged
) );
613 mpViewShell
->GetViewFrame()->GetBindings().Invalidate( SID_STYLE_FAMILY2
);
620 if( nRetMask
!= static_cast<sal_uInt16
>(SfxStyleSearchBits::All
) )
621 rReq
.SetReturnValue( SfxUInt16Item( nSId
, nRetMask
) );
624 void FuTemplate::Activate()
628 void FuTemplate::Deactivate()
632 } // end of namespace sd
634 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */