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 <comphelper/string.hxx>
21 #include <vcl/layout.hxx>
22 #include <vcl/msgbox.hxx>
23 #include <vcl/field.hxx>
24 #include <svl/eitem.hxx>
25 #include <svl/intitem.hxx>
26 #include <svl/style.hxx>
28 #include <sfx2/styfitem.hxx>
29 #include <sfx2/styledlg.hxx>
30 #include <sfx2/tabdlg.hxx>
31 #include <sfx2/app.hxx>
32 #include <sfx2/mgetempl.hxx>
33 #include <sfx2/objsh.hxx>
34 #include "sfxtypes.hxx"
35 #include <sfx2/sfxresid.hxx>
36 #include <sfx2/module.hxx>
38 #include <sfx2/templdlg.hxx>
39 #include "templdgi.hxx"
40 #include <sfx2/sfx.hrc>
43 #include <svl/style.hrc>
44 #include <svl/stritem.hxx>
45 #include <sfx2/dispatch.hxx>
47 /* SfxManageStyleSheetPage Constructor
49 * initializes the list box with the templates
51 SfxManageStyleSheetPage::SfxManageStyleSheetPage(vcl::Window
* pParent
, const SfxItemSet
& rAttrSet
)
52 : SfxTabPage(pParent
, "ManageStylePage", "sfx/ui/managestylepage.ui", &rAttrSet
)
53 , pStyle(&static_cast<SfxStyleDialog
*>(GetParentDialog())->GetStyleSheet())
56 , aName(pStyle
->GetName())
57 , aFollow(pStyle
->GetFollow())
58 , aParent(pStyle
->GetParent())
59 , nFlags(pStyle
->GetMask())
61 get(m_pNameRo
, "namero");
62 get(m_pNameRw
, "namerw");
63 m_pNameRo
->set_width_request(m_pNameRw
->get_preferred_size().Width());
64 get(m_pAutoCB
, "autoupdate");
65 get(m_pFollowFt
, "nextstyleft");
66 get(m_pFollowLb
, "nextstyle");
67 m_pFollowLb
->SetStyle(m_pFollowLb
->GetStyle() | WB_SORT
);
68 const sal_Int32
nMaxWidth(62);
69 m_pFollowLb
->setMaxWidthChars(nMaxWidth
);
70 get(m_pEditStyleBtn
, "editstyle");
71 get(m_pBaseFt
, "linkedwithft");
72 get(m_pBaseLb
, "linkedwith");
73 get(m_pEditLinkStyleBtn
, "editlinkstyle");
74 m_pBaseLb
->SetStyle(m_pBaseLb
->GetStyle() | WB_SORT
);
75 m_pBaseLb
->setMaxWidthChars(nMaxWidth
);
76 get(m_pFilterFt
, "categoryft");
77 get(m_pFilterLb
, "category");
78 //note that the code depends on categories not being lexically
79 //sorted, so if its changed to sorted, the code needs to
80 //be adapted to be position unaware
81 m_pFilterLb
->setMaxWidthChars(nMaxWidth
);
82 get(m_pDescFt
, "desc");
84 // this Page needs ExchangeSupport
87 if ( aFollow
== aName
)
88 m_pEditStyleBtn
->Disable();
90 m_pEditStyleBtn
->Enable();
92 sal_Int32 linkSelectPos
= m_pBaseLb
->GetSelectEntryPos();
93 if ( linkSelectPos
== 0 )
94 m_pEditLinkStyleBtn
->Disable();
96 m_pEditLinkStyleBtn
->Enable();
98 ResMgr
* pResMgr
= SfxGetpApp()->GetModule_Impl()->GetResMgr();
99 OSL_ENSURE( pResMgr
, "No ResMgr in Module" );
100 pFamilies
= new SfxStyleFamilies( ResId( DLG_STYLE_DESIGNER
, *pResMgr
) );
102 SfxStyleSheetBasePool
* pPool
= 0;
103 SfxObjectShell
* pDocShell
= SfxObjectShell::Current();
106 pPool
= pDocShell
->GetStyleSheetPool();
107 OSL_ENSURE( pPool
, "no Pool or no DocShell" );
111 pPool
->SetSearchMask( pStyle
->GetFamily() );
112 pPool
->First(); // for SW - update internal list
115 if ( pStyle
->GetName().isEmpty() && pPool
)
117 // NullString as Name -> generate Name
118 OUString
aNoName(SfxStyleDialog::GenerateUnusedName(*pPool
));
119 pStyle
->SetName( aNoName
);
121 aFollow
= pStyle
->GetFollow();
122 aParent
= pStyle
->GetParent();
124 m_pNameRw
->SetText(pStyle
->GetName());
126 // Set the field read-only if it is NOT an user-defined style
127 // but allow selecting and copying
128 if (!pStyle
->IsUserDefined())
130 m_pNameRo
->SetText(m_pNameRw
->GetText());
133 FixedText
*pLabel
= get
<FixedText
>("nameft");
134 pLabel
->set_mnemonic_widget(m_pNameRo
);
137 if ( pStyle
->HasFollowSupport() && pPool
)
139 SfxStyleSheetBase
* pPoolStyle
= pPool
->First();
143 m_pFollowLb
->InsertEntry( pPoolStyle
->GetName() );
144 pPoolStyle
= pPool
->Next();
147 // A new Template is not yet in the Pool
148 if ( LISTBOX_ENTRY_NOTFOUND
== m_pFollowLb
->GetEntryPos( pStyle
->GetName() ) )
149 m_pFollowLb
->InsertEntry( pStyle
->GetName() );
157 if ( pStyle
->HasParentSupport() && pPool
)
159 if ( pStyle
->HasClearParentSupport() )
160 // the base template can be set to NULL
161 m_pBaseLb
->InsertEntry( SfxResId(STR_NONE
).toString() );
163 SfxStyleSheetBase
* pPoolStyle
= pPool
->First();
167 const OUString
aStr( pPoolStyle
->GetName() );
168 // own name as base template
170 m_pBaseLb
->InsertEntry( aStr
);
171 pPoolStyle
= pPool
->Next();
176 m_pBaseFt
->Disable();
177 m_pBaseLb
->Disable();
180 size_t nCount
= pFamilies
->size();
182 for ( i
= 0; i
< nCount
; ++i
)
184 pItem
= pFamilies
->at( i
);
186 if ( pItem
->GetFamily() == pStyle
->GetFamily() )
192 sal_uInt16 nStyleFilterIdx
= 0xffff;
194 const SfxStyleFilter
& rList
= pItem
->GetFilterList();
195 nCount
= rList
.size();
197 sal_uInt16 nMask
= pStyle
->GetMask() & ~SFXSTYLEBIT_USERDEF
;
199 if ( !nMask
) // User Template?
200 nMask
= pStyle
->GetMask();
202 for ( i
= 0; i
< nCount
; ++i
)
204 SfxFilterTupel
* pTupel
= rList
[ i
];
206 if ( pTupel
->nFlags
!= SFXSTYLEBIT_AUTO
&&
207 pTupel
->nFlags
!= SFXSTYLEBIT_USED
&&
208 pTupel
->nFlags
!= SFXSTYLEBIT_ALL_VISIBLE
&&
209 pTupel
->nFlags
!= SFXSTYLEBIT_ALL
)
211 m_pFilterLb
->InsertEntry( pTupel
->aName
, nIdx
);
212 m_pFilterLb
->SetEntryData(nIdx
, reinterpret_cast<void*>(i
));
214 if ( ( pTupel
->nFlags
& nMask
) == nMask
)
215 nStyleFilterIdx
= nIdx
;
220 if ( nStyleFilterIdx
!= 0xFFFF )
221 m_pFilterLb
->SelectEntryPos( nStyleFilterIdx
);
224 if ( !m_pFilterLb
->GetEntryCount() || !pStyle
->IsUserDefined() )
227 m_pFilterFt
->Disable();
228 m_pFilterLb
->Disable();
231 m_pFilterLb
->SaveValue();
232 SetDescriptionText_Impl();
234 if ( m_pFollowLb
->IsEnabled() || m_pBaseLb
->IsEnabled() )
236 m_pNameRw
->SetGetFocusHdl(
237 LINK( this, SfxManageStyleSheetPage
, GetFocusHdl
) );
238 m_pNameRw
->SetLoseFocusHdl(
239 LINK( this, SfxManageStyleSheetPage
, LoseFocusHdl
) );
241 // It is a style with auto update? (SW only)
242 if(SfxItemState::SET
== rAttrSet
.GetItemState(SID_ATTR_AUTO_STYLE_UPDATE
))
244 m_pFollowLb
->SetSelectHdl( LINK( this, SfxManageStyleSheetPage
, EditStyleSelectHdl_Impl
) );
245 m_pBaseLb
->SetSelectHdl( LINK( this, SfxManageStyleSheetPage
, EditLinkStyleSelectHdl_Impl
) );
246 m_pEditStyleBtn
->SetClickHdl( LINK( this, SfxManageStyleSheetPage
, EditStyleHdl_Impl
) );
247 m_pEditLinkStyleBtn
->SetClickHdl( LINK( this, SfxManageStyleSheetPage
, EditLinkStyleHdl_Impl
) );
252 SfxManageStyleSheetPage::~SfxManageStyleSheetPage()
257 void SfxManageStyleSheetPage::dispose()
259 m_pNameRw
->SetGetFocusHdl( Link
<>() );
260 m_pNameRw
->SetLoseFocusHdl( Link
<>() );
269 m_pEditStyleBtn
.clear();
272 m_pEditLinkStyleBtn
.clear();
276 SfxTabPage::dispose();
281 void SfxManageStyleSheetPage::UpdateName_Impl( ListBox
* pBox
,
282 const OUString
& rNew
)
286 After the change of a template name update the ListBox pBox
290 ListBox* pBox ListBox, whose entries are to be updated
291 const String& rNew the new Name
295 if ( pBox
->IsEnabled() )
297 // it is the current entry, which name was modified
298 const bool bSelect
= pBox
->GetSelectEntry() == aBuf
;
299 pBox
->RemoveEntry( aBuf
);
300 pBox
->InsertEntry( rNew
);
303 pBox
->SelectEntry( rNew
);
309 void SfxManageStyleSheetPage::SetDescriptionText_Impl()
313 Set attribute description. Get the set metric for this.
317 SfxMapUnit eUnit
= SFX_MAPUNIT_CM
;
318 FieldUnit
eFieldUnit( FUNIT_CM
);
319 SfxModule
* pModule
= SfxModule::GetActiveModule();
322 const SfxPoolItem
* pPoolItem
= pModule
->GetItem( SID_ATTR_METRIC
);
324 eFieldUnit
= (FieldUnit
) static_cast<const SfxUInt16Item
*>( pPoolItem
)->GetValue();
327 switch ( eFieldUnit
)
329 case FUNIT_MM
: eUnit
= SFX_MAPUNIT_MM
; break;
332 case FUNIT_KM
: eUnit
= SFX_MAPUNIT_CM
; break;
334 case FUNIT_PICA
: eUnit
= SFX_MAPUNIT_POINT
; break;
337 case FUNIT_MILE
: eUnit
= SFX_MAPUNIT_INCH
; break;
340 OSL_FAIL( "non supported field unit" );
342 m_pDescFt
->SetText( pStyle
->GetDescription( eUnit
) );
345 IMPL_LINK_NOARG( SfxManageStyleSheetPage
, EditStyleSelectHdl_Impl
)
347 OUString
aTemplName(m_pFollowLb
->GetSelectEntry());
348 OUString
aEditTemplName(m_pNameRo
->GetText());
349 if (!( aTemplName
== aEditTemplName
))
350 m_pEditStyleBtn
->Enable();
352 m_pEditStyleBtn
->Disable();
356 IMPL_LINK_NOARG( SfxManageStyleSheetPage
, EditStyleHdl_Impl
)
359 OUString
aTemplName(m_pFollowLb
->GetSelectEntry());
360 if (Execute_Impl( SID_STYLE_EDIT
, aTemplName
, OUString(),(sal_uInt16
)pStyle
->GetFamily(), 0 ))
368 IMPL_LINK_NOARG( SfxManageStyleSheetPage
, EditLinkStyleSelectHdl_Impl
)
370 sal_Int32 linkSelectPos
= m_pBaseLb
->GetSelectEntryPos();
371 if ( linkSelectPos
== 0 )
372 m_pEditLinkStyleBtn
->Disable();
374 m_pEditLinkStyleBtn
->Enable();
378 IMPL_LINK_NOARG( SfxManageStyleSheetPage
, EditLinkStyleHdl_Impl
)
380 OUString
aTemplName(m_pBaseLb
->GetSelectEntry());
381 if (aTemplName
!= SfxResId(STR_NONE
))
382 Execute_Impl( SID_STYLE_EDIT
, aTemplName
, OUString(),(sal_uInt16
)pStyle
->GetFamily(), 0 );
386 // Internal: Perform functions through the Dispatcher
387 bool SfxManageStyleSheetPage::Execute_Impl(
388 sal_uInt16 nId
, const OUString
&rStr
, const OUString
& rRefStr
, sal_uInt16 nFamily
,
389 sal_uInt16 nMask
, const sal_uInt16
* pModifier
)
392 SfxDispatcher
&rDispatcher
= *SfxGetpApp()->GetDispatcher_Impl();
393 SfxStringItem
aItem(nId
, rStr
);
394 SfxUInt16Item
aFamily(SID_STYLE_FAMILY
, nFamily
);
395 SfxUInt16Item
aMask( SID_STYLE_MASK
, nMask
);
396 SfxStringItem
aUpdName(SID_STYLE_UPD_BY_EX_NAME
, rStr
);
397 SfxStringItem
aRefName( SID_STYLE_REFERENCE
, rRefStr
);
398 const SfxPoolItem
* pItems
[ 6 ];
399 sal_uInt16 nCount
= 0;
400 if( !rStr
.isEmpty() )
401 pItems
[ nCount
++ ] = &aItem
;
402 pItems
[ nCount
++ ] = &aFamily
;
404 pItems
[ nCount
++ ] = &aMask
;
405 if ( !rRefStr
.isEmpty() )
406 pItems
[ nCount
++ ] = &aRefName
;
408 pItems
[ nCount
++ ] = 0;
410 sal_uInt16 nModi
= pModifier
? *pModifier
: 0;
411 const SfxPoolItem
* mpItem
= rDispatcher
.Execute(
412 nId
, SfxCallMode::SYNCHRON
| SfxCallMode::RECORD
| SfxCallMode::MODAL
,
422 IMPL_LINK( SfxManageStyleSheetPage
, GetFocusHdl
, Edit
*, pEdit
)
426 StarView Handler; GetFocus-Handler of the Edits with the template name.
430 aBuf
= comphelper::string::stripStart(pEdit
->GetText(), ' ');
434 IMPL_LINK( SfxManageStyleSheetPage
, LoseFocusHdl
, Edit
*, pEdit
)
438 StarView Handler; lose-focus-handler of the edits of the template name.
439 This will update the listbox with the subsequent templates. The current
440 template itself is not returned in the listbox of the base templates.
444 const OUString
aStr(comphelper::string::stripStart(pEdit
->GetText(), ' '));
445 pEdit
->SetText( aStr
);
446 // Update the Listbox of the base template if possible
448 UpdateName_Impl(m_pFollowLb
, aStr
);
452 bool SfxManageStyleSheetPage::FillItemSet( SfxItemSet
* rSet
)
456 Handler for setting the (modified) data. I called from the OK of the
461 SfxItemSet &rAttrSet The set, which receives the data.
465 sal_Bool sal_True: The data had been changed
466 sal_False: The data had not been changed
474 const sal_Int32 nFilterIdx
= m_pFilterLb
->GetSelectEntryPos();
478 if ( LISTBOX_ENTRY_NOTFOUND
!= nFilterIdx
&&
479 m_pFilterLb
->IsValueChangedFromSaved() &&
480 m_pFilterLb
->IsEnabled() )
483 OSL_ENSURE( pItem
, "No Item" );
484 // is only possibly for user templates
485 sal_uInt16 nMask
= pItem
->GetFilterList()[ reinterpret_cast<size_t>(m_pFilterLb
->GetEntryData( nFilterIdx
)) ]->nFlags
| SFXSTYLEBIT_USERDEF
;
486 pStyle
->SetMask( nMask
);
488 if(m_pAutoCB
->IsVisible() &&
489 m_pAutoCB
->IsValueChangedFromSaved())
491 rSet
->Put(SfxBoolItem(SID_ATTR_AUTO_STYLE_UPDATE
, m_pAutoCB
->IsChecked()));
499 void SfxManageStyleSheetPage::Reset( const SfxItemSet
* /*rAttrSet*/ )
503 Handler to initialize the page with the initial data.
507 const SfxItemSet &rAttrSet The data set
516 OUString
sCmp( pStyle
->GetName() );
519 pStyle
->SetName( aName
);
520 m_pNameRw
->SetText( aName
);
521 m_pNameRw
->SetSelection( Selection( SELECTION_MIN
, SELECTION_MAX
) );
523 if ( m_pFollowLb
->IsEnabled() )
525 sCmp
= pStyle
->GetFollow();
527 if ( sCmp
!= aFollow
)
528 pStyle
->SetFollow( aFollow
);
530 if ( aFollow
.isEmpty() )
531 m_pFollowLb
->SelectEntry( aName
);
533 m_pFollowLb
->SelectEntry( aFollow
);
536 if ( m_pBaseLb
->IsEnabled() )
538 sCmp
= pStyle
->GetParent();
540 if ( sCmp
!= aParent
)
541 pStyle
->SetParent( aParent
);
543 if ( aParent
.isEmpty() )
544 m_pBaseLb
->SelectEntry( SfxResId(STR_NONE
).toString() );
546 m_pBaseLb
->SelectEntry( aParent
);
548 if ( SfxResId(STR_STANDARD
).toString().equals(aName
) )
550 // the default template can not be linked
551 m_pBaseFt
->Disable();
552 m_pBaseLb
->Disable();
556 if ( m_pFilterLb
->IsEnabled() )
558 sal_uInt16 nCmp
= pStyle
->GetMask();
560 if ( nCmp
!= nFlags
)
561 pStyle
->SetMask( nFlags
);
562 m_pFilterLb
->SelectEntryPos( m_pFilterLb
->GetSavedValue() );
568 VclPtr
<SfxTabPage
> SfxManageStyleSheetPage::Create( vcl::Window
* pParent
,
569 const SfxItemSet
*rAttrSet
)
571 return VclPtr
<SfxManageStyleSheetPage
>::Create( pParent
, *rAttrSet
);
576 void SfxManageStyleSheetPage::ActivatePage( const SfxItemSet
& rSet
)
580 ActivatePage handler of SfxTabDialog, is used for the update of the
581 descriptive text, since this might have changed through changes of data on
586 const SfxItemSet& the set for the exchange of data; is not used here.
590 <SfxTabDialog::ActivatePage(const SfxItemSet &)>
594 SetDescriptionText_Impl();
596 // It is a style with auto update? (SW only)
597 const SfxPoolItem
* pPoolItem
;
599 if ( SfxItemState::SET
==
600 rSet
.GetItemState( SID_ATTR_AUTO_STYLE_UPDATE
, false, &pPoolItem
) )
601 m_pAutoCB
->Check( static_cast<const SfxBoolItem
*>(pPoolItem
)->GetValue() );
602 m_pAutoCB
->SaveValue();
607 SfxTabPage::sfxpg
SfxManageStyleSheetPage::DeactivatePage( SfxItemSet
* pItemSet
)
611 DeactivatePage-handler of SfxTabDialog; data is set on the template, so
612 that the correct inheritance on the other pages of the dialog is made.
613 If an error occurs, leaving the page is prevented.
616 SfxItemSet* the set for the exchange of data; is not used here.
620 <SfxTabDialog::DeactivatePage(SfxItemSet*)>
624 sfxpg nRet
= SfxTabPage::LEAVE_PAGE
;
626 if ( m_pNameRw
->IsModified() )
628 // By pressing <Enter> LoseFocus() is not trigged through StarView
629 if ( m_pNameRw
->HasFocus() )
630 LoseFocusHdl( m_pNameRw
);
632 if (!pStyle
->SetName(comphelper::string::stripStart(m_pNameRw
->GetText(), ' ')))
634 ScopedVclPtrInstance
< MessageDialog
> aBox(this, SfxResId( STR_TABPAGE_INVALIDNAME
), VCL_MESSAGE_INFO
);
636 m_pNameRw
->GrabFocus();
637 m_pNameRw
->SetSelection( Selection( SELECTION_MIN
, SELECTION_MAX
) );
638 return SfxTabPage::KEEP_PAGE
;
643 if ( pStyle
->HasFollowSupport() && m_pFollowLb
->IsEnabled() )
645 const OUString
aFollowEntry( m_pFollowLb
->GetSelectEntry() );
647 if ( pStyle
->GetFollow() != aFollowEntry
)
649 if ( !pStyle
->SetFollow( aFollowEntry
) )
651 ScopedVclPtrInstance
< MessageDialog
> aBox(this, SfxResId( STR_TABPAGE_INVALIDSTYLE
), VCL_MESSAGE_INFO
);
653 m_pFollowLb
->GrabFocus();
654 return SfxTabPage::KEEP_PAGE
;
660 if ( m_pBaseLb
->IsEnabled() )
662 OUString
aParentEntry( m_pBaseLb
->GetSelectEntry() );
664 if ( SfxResId(STR_NONE
).toString().equals(aParentEntry
) || aParentEntry
== pStyle
->GetName() )
665 aParentEntry
.clear();
667 if ( pStyle
->GetParent() != aParentEntry
)
669 if ( !pStyle
->SetParent( aParentEntry
) )
671 ScopedVclPtrInstance
< MessageDialog
> aBox(this, SfxResId( STR_TABPAGE_INVALIDPARENT
), VCL_MESSAGE_INFO
);
673 m_pBaseLb
->GrabFocus();
674 return SfxTabPage::KEEP_PAGE
;
677 nRet
= sfxpg(nRet
| SfxTabPage::REFRESH_SET
);
682 FillItemSet( pItemSet
);
687 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */