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>
24 #include <futempl.hxx>
26 #include <svx/svxids.hrc>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <editeng/eeitem.hxx>
30 #include <sfx2/request.hxx>
31 #include <sfx2/sfxdlg.hxx>
32 #include <editeng/numitem.hxx>
33 #include <svx/svdopage.hxx>
34 #include <editeng/colritem.hxx>
35 #include <editeng/brushitem.hxx>
36 #include <svx/svditer.hxx>
37 #include <svx/sdr/properties/properties.hxx>
38 #include <svl/intitem.hxx>
40 #include <sfx2/viewfrm.hxx>
41 #include <svx/xlndsit.hxx>
42 #include <svx/xlnstit.hxx>
43 #include <svx/xlnedit.hxx>
44 #include <svx/xbtmpit.hxx>
45 #include <svx/xflgrit.hxx>
46 #include <svx/xflftrit.hxx>
47 #include <svx/xflhtit.hxx>
49 #include <stlsheet.hxx>
51 #include <stlpool.hxx>
54 #include <drawdoc.hxx>
55 #include <DrawDocShell.hxx>
56 #include <DrawViewShell.hxx>
57 #include <ViewShell.hxx>
59 #include <strings.hrc>
60 #include <prlayout.hxx>
61 #include <sdresid.hxx>
62 #include <OutlineView.hxx>
63 #include <sdabstdlg.hxx>
66 using namespace com::sun::star::uno
;
67 using namespace com::sun::star::container
;
68 using namespace com::sun::star::beans
;
69 using namespace com::sun::star::style
;
75 FuTemplate::FuTemplate (
81 : FuPoor( pViewSh
, pWin
, pView
, pDoc
, rReq
)
85 rtl::Reference
<FuPoor
> FuTemplate::Create( ViewShell
* pViewSh
, ::sd::Window
* pWin
, ::sd::View
* pView
, SdDrawDocument
* pDoc
, SfxRequest
& rReq
)
87 rtl::Reference
<FuPoor
> xFunc( new FuTemplate( pViewSh
, pWin
, pView
, pDoc
, rReq
) );
88 xFunc
->DoExecute(rReq
);
92 void FuTemplate::DoExecute( SfxRequest
& rReq
)
94 const SfxItemSet
* pArgs
= rReq
.GetArgs();
95 sal_uInt16 nSId
= rReq
.GetSlot();
97 // get StyleSheet parameter
98 SfxStyleSheetBasePool
* pSSPool
= mpDoc
->GetDocSh()->GetStyleSheetPool();
99 SfxStyleSheetBase
* pStyleSheet
= nullptr;
101 const SfxPoolItem
* pItem
;
102 SfxStyleFamily nFamily
= SfxStyleFamily(USHRT_MAX
);
103 if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState( SID_STYLE_FAMILY
,
106 nFamily
= static_cast<SfxStyleFamily
>( pArgs
->Get( SID_STYLE_FAMILY
).GetValue());
108 else if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState( SID_STYLE_FAMILYNAME
,
111 OUString sFamily
= pArgs
->Get( SID_STYLE_FAMILYNAME
).GetValue();
112 if (sFamily
== "graphics")
113 nFamily
= SfxStyleFamily::Para
;
115 nFamily
= SfxStyleFamily::Pseudo
;
119 sal_uInt16 nRetMask
= static_cast<sal_uInt16
>(SfxStyleSearchBits::All
);
123 case SID_STYLE_APPLY
:
125 case SID_STYLE_DELETE
:
128 case SID_STYLE_FAMILY
:
129 case SID_STYLE_NEW_BY_EXAMPLE
:
131 const SfxStringItem
* pNameItem
= rReq
.GetArg
<SfxStringItem
>(SID_APPLY_STYLE
);
132 const SfxStringItem
* pFamilyItem
= rReq
.GetArg
<SfxStringItem
>(SID_STYLE_FAMILYNAME
);
133 if ( pFamilyItem
&& pNameItem
)
137 Reference
< XStyleFamiliesSupplier
> xModel(mpDoc
->GetDocSh()->GetModel(), UNO_QUERY_THROW
);
138 Reference
< XNameAccess
> xCont( xModel
->getStyleFamilies() );
139 Reference
< XNameAccess
> xStyles( xCont
->getByName(pFamilyItem
->GetValue()), UNO_QUERY_THROW
);
140 Reference
< XPropertySet
> xInfo( xStyles
->getByName( pNameItem
->GetValue() ), UNO_QUERY_THROW
);
143 xInfo
->getPropertyValue( "DisplayName" ) >>= aUIName
;
144 if ( !aUIName
.isEmpty() )
145 rReq
.AppendItem( SfxStringItem( nSId
, aUIName
) );
152 if (pArgs
&& pArgs
->GetItemState(nSId
) == SfxItemState::SET
)
153 aStyleName
= static_cast<const SfxStringItem
&>( pArgs
->Get( nSId
) ).GetValue();
161 SfxStyleSheetBase
*p
= pSSPool
->Find(aStyleName
, nFamily
);
167 pStyleSheet
= &pSSPool
->Make( aStyleName
, nFamily
, SfxStyleSearchBits::UserDefined
);
169 if (pArgs
&& pArgs
->GetItemState(SID_STYLE_REFERENCE
) == SfxItemState::SET
)
171 OUString
aParentName( pArgs
->Get(SID_STYLE_REFERENCE
).GetValue());
172 pStyleSheet
->SetParent(aParentName
);
176 pStyleSheet
->SetParent(SdResId(STR_STANDARD_STYLESHEET_NAME
));
181 case SID_STYLE_NEW_BY_EXAMPLE
:
183 // at the moment, the dialog to enter the name of the template is still opened
184 SfxStyleSheetBase
*p
= pSSPool
->Find(aStyleName
, nFamily
);
190 pStyleSheet
= &pSSPool
->Make( aStyleName
, nFamily
, SfxStyleSearchBits::UserDefined
);
191 pStyleSheet
->SetParent(SdResId(STR_STANDARD_STYLESHEET_NAME
));
196 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
199 case SID_STYLE_DELETE
:
200 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
203 pSSPool
->Remove( pStyleSheet
);
204 nRetMask
= sal_uInt16(true);
209 nRetMask
= sal_uInt16(false);
215 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
216 pStyleSheet
->SetHidden( nSId
== SID_STYLE_HIDE
);
217 nRetMask
= sal_uInt16(true);
220 case SID_STYLE_APPLY
:
221 // apply the template to the document
222 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
224 // do not set presentation styles, they will be set implicit
225 if ( pStyleSheet
&& pStyleSheet
->GetFamily() != SfxStyleFamily::Pseudo
)
227 SfxStyleSheet
* pOldStyleSheet
= mpView
->GetStyleSheet();
230 if( // if the object had no style sheet, allow all
233 // allow if old and new style sheet has same family
234 pStyleSheet
->GetFamily() == pOldStyleSheet
->GetFamily() ||
236 // allow if old was background objects and new is graphics
237 (pStyleSheet
->GetFamily() == SfxStyleFamily::Para
&& pOldStyleSheet
->GetHelpId( aStr
) == HID_PSEUDOSHEET_BACKGROUNDOBJECTS
) ||
239 // allow if old was presentation and we are a drawing document
240 (pOldStyleSheet
->GetFamily() == SfxStyleFamily::Page
&& mpDoc
->GetDocumentType() == DocumentType::Draw
) )
242 mpView
->SetStyleSheet( static_cast<SfxStyleSheet
*>(pStyleSheet
));
244 mpViewShell
->GetViewFrame()->GetBindings().Invalidate( SID_STYLE_FAMILY2
);
249 case SID_STYLE_WATERCAN
:
251 if( !SD_MOD()->GetWaterCan() )
253 if (pArgs
&& pArgs
->GetItemState( nSId
) == SfxItemState::SET
)
255 aStyleName
= static_cast<const SfxStringItem
&>( pArgs
->Get( nSId
) ).GetValue();
256 SD_MOD()->SetWaterCan( true );
257 pStyleSheet
= pSSPool
->Find( aStyleName
, nFamily
);
259 // no presentation object templates, they are only allowed implicitly
260 if( pStyleSheet
&& pStyleSheet
->GetFamily() != SfxStyleFamily::Pseudo
)
262 static_cast<SdStyleSheetPool
*>( pSSPool
)->SetActualStyleSheet( pStyleSheet
);
264 // we switch explicitly into selection mode
265 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute( SID_OBJECT_SELECT
,
266 SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
270 SD_MOD()->SetWaterCan( false );
274 SD_MOD()->SetWaterCan( false );
275 // we have to re-enable to tools-bar
276 mpViewShell
->Invalidate();
290 PresentationObjects ePO
= PO_OUTLINE_1
;
294 ScopedVclPtr
<SfxAbstractTabDialog
> pStdDlg
;
295 ScopedVclPtr
<SfxAbstractTabDialog
> pPresDlg
;
296 SdAbstractDialogFactory
* pFact
= SdAbstractDialogFactory::Create();
297 bool bOldDocInOtherLanguage
= false;
299 SfxStyleFamily eFamily
= pStyleSheet
->GetFamily();
301 if (eFamily
== SfxStyleFamily::Para
)
303 pStdDlg
.disposeAndReset(pFact
? pFact
->CreateSdTabTemplateDlg(mpViewShell
->GetFrameWeld(), mpDoc
->GetDocSh(), *pStyleSheet
, mpDoc
, mpView
) : nullptr);
305 else if (eFamily
== SfxStyleFamily::Pseudo
)
307 OUString
aName(pStyleSheet
->GetName());
308 bool bBackground
= false;
310 if (aName
== SdResId(STR_PSEUDOSHEET_TITLE
))
314 else if (aName
== SdResId(STR_PSEUDOSHEET_SUBTITLE
))
319 SdResId(STR_PSEUDOSHEET_BACKGROUND
))
325 SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS
))
327 ePO
= PO_BACKGROUNDOBJECTS
;
330 SdResId(STR_PSEUDOSHEET_NOTES
))
334 else if(aName
.indexOf(SdResId(STR_PSEUDOSHEET_OUTLINE
)) != -1)
336 OUString
aOutlineStr(SdResId(STR_PSEUDOSHEET_OUTLINE
));
337 // determine number, mind the blank between name and number
338 OUString
aNumStr(aName
.copy(aOutlineStr
.getLength() + 1));
339 sal_uInt16 nLevel
= static_cast<sal_uInt16
>(aNumStr
.toInt32());
342 case 1: ePO
= PO_OUTLINE_1
; break;
343 case 2: ePO
= PO_OUTLINE_2
; break;
344 case 3: ePO
= PO_OUTLINE_3
; break;
345 case 4: ePO
= PO_OUTLINE_4
; break;
346 case 5: ePO
= PO_OUTLINE_5
; break;
347 case 6: ePO
= PO_OUTLINE_6
; break;
348 case 7: ePO
= PO_OUTLINE_7
; break;
349 case 8: ePO
= PO_OUTLINE_8
; break;
350 case 9: ePO
= PO_OUTLINE_9
; break;
355 OSL_FAIL("StyleSheet from older version with different language");
356 bOldDocInOtherLanguage
= true;
359 if( !bOldDocInOtherLanguage
)
361 pPresDlg
.disposeAndReset(pFact
? pFact
->CreateSdPresLayoutTemplateDlg(mpDocSh
, mpViewShell
->GetFrameWeld(), bBackground
, *pStyleSheet
, ePO
, pSSPool
) : nullptr);
365 sal_uInt16 nResult
= RET_CANCEL
;
366 const SfxItemSet
* pOutSet
= nullptr;
369 nResult
= pStdDlg
->Execute();
370 pOutSet
= pStdDlg
->GetOutputItemSet();
374 nResult
= pPresDlg
->Execute();
375 pOutSet
= pPresDlg
->GetOutputItemSet();
382 nRetMask
= static_cast<sal_uInt16
>(pStyleSheet
->GetMask());
384 if (eFamily
== SfxStyleFamily::Pseudo
)
386 SfxItemSet
aTempSet(*pOutSet
);
387 /* Extract SvxBrushItem out of set and insert SvxBackgroundColorItem */
388 const SvxBrushItem
* pBrushItem
= aTempSet
.GetItem
<SvxBrushItem
>( SID_ATTR_BRUSH_CHAR
);
392 SvxBackgroundColorItem
aBackColorItem(pBrushItem
->GetColor(), EE_CHAR_BKGCOLOR
);
393 aTempSet
.ClearItem( EE_CHAR_BKGCOLOR
);
394 aTempSet
.Put( aBackColorItem
);
396 static_cast<SdStyleSheet
*>(pStyleSheet
)->AdjustToFontHeight(aTempSet
);
398 /* Special treatment: reset the INVALIDS to
399 NULL-Pointer (otherwise INVALIDs or pointer point
400 to DefaultItems in the template; both would
401 prevent the attribute inheritance) */
402 aTempSet
.ClearInvalidItems();
404 // EE_PARA_NUMBULLET item is only valid in first outline template
405 if( (ePO
>= PO_OUTLINE_2
) && (ePO
<= PO_OUTLINE_9
) )
407 if (aTempSet
.GetItemState(EE_PARA_NUMBULLET
) == SfxItemState::SET
)
409 SvxNumRule
aRule(*aTempSet
.GetItem
<SvxNumBulletItem
>(EE_PARA_NUMBULLET
)->GetNumRule());
411 OUString
sStyleName(SdResId(STR_PSEUDOSHEET_OUTLINE
) + " 1");
412 SfxStyleSheetBase
* pFirstStyleSheet
= pSSPool
->Find( sStyleName
, SfxStyleFamily::Pseudo
);
416 pFirstStyleSheet
->GetItemSet().Put( SvxNumBulletItem( aRule
, EE_PARA_NUMBULLET
));
417 SdStyleSheet
* pRealSheet
= static_cast<SdStyleSheet
*>(pFirstStyleSheet
)->GetRealStyleSheet();
418 pRealSheet
->Broadcast(SfxHint(SfxHintId::DataChanged
));
421 aTempSet
.ClearItem( EE_PARA_NUMBULLET
);
425 pStyleSheet
->GetItemSet().Put(aTempSet
);
426 SdStyleSheet::BroadcastSdStyleSheetChange(pStyleSheet
, ePO
, pSSPool
);
429 SfxItemSet
& rAttr
= pStyleSheet
->GetItemSet();
431 sdr::properties::CleanupFillProperties( rAttr
);
433 // check for unique names of named items for xml
434 if( rAttr
.GetItemState( XATTR_FILLBITMAP
) == SfxItemState::SET
)
436 const SfxPoolItem
* pOldItem
= rAttr
.GetItem( XATTR_FILLBITMAP
);
437 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XFillBitmapItem
*>(pOldItem
)->checkForUniqueItem( mpDoc
);
440 rAttr
.Put( std::move(pNewItem
) );
443 if( rAttr
.GetItemState( XATTR_LINEDASH
) == SfxItemState::SET
)
445 const SfxPoolItem
* pOldItem
= rAttr
.GetItem( XATTR_LINEDASH
);
446 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XLineDashItem
*>(pOldItem
)->checkForUniqueItem( mpDoc
);
449 rAttr
.Put( std::move(pNewItem
) );
452 if( rAttr
.GetItemState( XATTR_LINESTART
) == SfxItemState::SET
)
454 const SfxPoolItem
* pOldItem
= rAttr
.GetItem( XATTR_LINESTART
);
455 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XLineStartItem
*>(pOldItem
)->checkForUniqueItem( mpDoc
);
458 rAttr
.Put( std::move(pNewItem
) );
461 if( rAttr
.GetItemState( XATTR_LINEEND
) == SfxItemState::SET
)
463 const SfxPoolItem
* pOldItem
= rAttr
.GetItem( XATTR_LINEEND
);
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
) == SfxItemState::SET
)
472 const SfxPoolItem
* pOldItem
= rAttr
.GetItem( XATTR_FILLGRADIENT
);
473 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XFillGradientItem
*>(pOldItem
)->checkForUniqueItem( mpDoc
);
476 rAttr
.Put( std::move(pNewItem
) );
479 if( rAttr
.GetItemState( XATTR_FILLFLOATTRANSPARENCE
) == SfxItemState::SET
)
481 const SfxPoolItem
* pOldItem
= rAttr
.GetItem( XATTR_FILLFLOATTRANSPARENCE
);
482 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XFillFloatTransparenceItem
*>(pOldItem
)->checkForUniqueItem( mpDoc
);
485 rAttr
.Put( std::move(pNewItem
) );
488 if( rAttr
.GetItemState( XATTR_FILLHATCH
) == SfxItemState::SET
)
490 const SfxPoolItem
* pOldItem
= rAttr
.GetItem( XATTR_FILLHATCH
);
491 std::unique_ptr
<SfxPoolItem
> pNewItem
= static_cast<const XFillHatchItem
*>(pOldItem
)->checkForUniqueItem( mpDoc
);
494 rAttr
.Put( std::move(pNewItem
) );
498 static_cast<SfxStyleSheet
*>( pStyleSheet
)->Broadcast( SfxHint( SfxHintId::DataChanged
) );
500 DrawViewShell
* pDrawViewShell
= dynamic_cast< DrawViewShell
* >( mpViewShell
);
503 PageKind ePageKind
= pDrawViewShell
->GetPageKind();
504 if( ePageKind
== PageKind::Notes
|| ePageKind
== PageKind::Handout
)
506 SdPage
* pPage
= mpViewShell
->GetActualPage();
508 if(pDrawViewShell
->GetEditMode() == EditMode::MasterPage
)
510 pPage
= static_cast<SdPage
*>((&(pPage
->TRG_GetMasterPage())));
515 SdrObjListIter
aIter( pPage
);
516 while( aIter
.IsMore() )
518 SdrObject
* pObj
= aIter
.Next();
519 if( dynamic_cast< const SdrPageObj
*>( pObj
) != nullptr )
522 pObj
->ActionChanged();
523 // pObj->SendRepaintBroadcast();
530 if( mpDoc
->GetOnlineSpell() )
532 const SfxPoolItem
* pTempItem
;
533 if( SfxItemState::SET
== rAttr
.GetItemState(EE_CHAR_LANGUAGE
, false, &pTempItem
) ||
534 SfxItemState::SET
== rAttr
.GetItemState(EE_CHAR_LANGUAGE_CJK
, false, &pTempItem
) ||
535 SfxItemState::SET
== rAttr
.GetItemState(EE_CHAR_LANGUAGE_CTL
, false, &pTempItem
) )
537 mpDoc
->StopOnlineSpelling();
538 mpDoc
->StartOnlineSpelling();
548 if( nSId
== SID_STYLE_NEW
)
549 pSSPool
->Remove( pStyleSheet
);
557 case SID_STYLE_NEW_BY_EXAMPLE
:
561 nRetMask
= static_cast<sal_uInt16
>(pStyleSheet
->GetMask());
562 SfxItemSet
aCoreSet( mpDoc
->GetPool() );
563 mpView
->GetAttributes( aCoreSet
, true );
565 // if the object had a template, this becomes parent of the new template
566 SfxStyleSheet
* pOldStyle
= mpView
->GetStyleSheet();
568 // if pOldStyle == pStyleSheet -> recursion
569 if( pOldStyle
!= pStyleSheet
)
573 pStyleSheet
->SetParent(pOldStyle
->GetName());
576 SfxItemSet
* pStyleSet
= &pStyleSheet
->GetItemSet();
577 pStyleSet
->Put(aCoreSet
);
579 /* apply template (but not when somebody is editing a text.
580 To do this, the edit engine had to be capable to use
581 templates on a character level. */
582 if (!mpView
->GetTextEditObject())
584 mpView
->SetStyleSheet( static_cast<SfxStyleSheet
*>(pStyleSheet
));
587 static_cast<SfxStyleSheet
*>( pStyleSheet
)->Broadcast( SfxHint( SfxHintId::DataChanged
) );
590 mpViewShell
->GetViewFrame()->GetBindings().Invalidate( SID_STYLE_FAMILY2
);
596 case SID_STYLE_UPDATE_BY_EXAMPLE
:
598 if ((mpView
->AreObjectsMarked() && mpView
->GetMarkedObjectList().GetMarkCount() == 1) ||
599 dynamic_cast< const OutlineView
*>( mpView
) != nullptr)
601 pStyleSheet
= mpView
->GetStyleSheet();
605 nRetMask
= static_cast<sal_uInt16
>(pStyleSheet
->GetMask());
606 SfxItemSet
aCoreSet( mpDoc
->GetPool() );
607 mpView
->GetAttributes( aCoreSet
);
609 SfxItemSet
* pStyleSet
= &pStyleSheet
->GetItemSet();
610 pStyleSet
->Put( aCoreSet
);
612 mpView
->SetStyleSheet( static_cast<SfxStyleSheet
*>(pStyleSheet
));
614 static_cast<SfxStyleSheet
*>( pStyleSheet
)->Broadcast( SfxHint( SfxHintId::DataChanged
) );
616 mpViewShell
->GetViewFrame()->GetBindings().Invalidate( SID_STYLE_FAMILY2
);
623 if( nRetMask
!= static_cast<sal_uInt16
>(SfxStyleSearchBits::All
) )
624 rReq
.SetReturnValue( SfxUInt16Item( nSId
, nRetMask
) );
627 void FuTemplate::Activate()
631 void FuTemplate::Deactivate()
635 } // end of namespace sd
637 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */