bump product version to 5.0.4.1
[LibreOffice.git] / sfx2 / source / dialog / mgetempl.cxx
blob8b69def6daeee9d2b66e09b3cdad77cc6e975281
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
41 #include "dialog.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())
54 , pItem(0)
55 , bModified(false)
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
85 SetExchangeSupport();
87 if ( aFollow == aName )
88 m_pEditStyleBtn->Disable();
89 else
90 m_pEditStyleBtn->Enable();
92 sal_Int32 linkSelectPos = m_pBaseLb->GetSelectEntryPos();
93 if ( linkSelectPos == 0 )
94 m_pEditLinkStyleBtn->Disable();
95 else
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();
105 if ( pDocShell )
106 pPool = pDocShell->GetStyleSheetPool();
107 OSL_ENSURE( pPool, "no Pool or no DocShell" );
109 if ( pPool )
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 );
120 aName = 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());
131 m_pNameRw->Hide();
132 m_pNameRo->Show();
133 FixedText *pLabel = get<FixedText>("nameft");
134 pLabel->set_mnemonic_widget(m_pNameRo);
137 if ( pStyle->HasFollowSupport() && pPool )
139 SfxStyleSheetBase* pPoolStyle = pPool->First();
141 while ( pPoolStyle )
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() );
151 else
153 m_pFollowFt->Hide();
154 m_pFollowLb->Hide();
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();
165 while ( pPoolStyle )
167 const OUString aStr( pPoolStyle->GetName() );
168 // own name as base template
169 if ( aStr != aName )
170 m_pBaseLb->InsertEntry( aStr );
171 pPoolStyle = pPool->Next();
174 else
176 m_pBaseFt->Disable();
177 m_pBaseLb->Disable();
180 size_t nCount = pFamilies->size();
181 size_t i;
182 for ( i = 0; i < nCount; ++i )
184 pItem = pFamilies->at( i );
186 if ( pItem->GetFamily() == pStyle->GetFamily() )
187 break;
190 if ( i < nCount )
192 sal_uInt16 nStyleFilterIdx = 0xffff;
193 // Filter flags
194 const SfxStyleFilter& rList = pItem->GetFilterList();
195 nCount = rList.size();
196 sal_uInt16 nIdx = 0;
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;
216 ++nIdx;
220 if ( nStyleFilterIdx != 0xFFFF )
221 m_pFilterLb->SelectEntryPos( nStyleFilterIdx );
224 if ( !m_pFilterLb->GetEntryCount() || !pStyle->IsUserDefined() )
226 pItem = 0;
227 m_pFilterFt->Disable();
228 m_pFilterLb->Disable();
230 else
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))
243 m_pAutoCB->Show();
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()
254 disposeOnce();
257 void SfxManageStyleSheetPage::dispose()
259 m_pNameRw->SetGetFocusHdl( Link<>() );
260 m_pNameRw->SetLoseFocusHdl( Link<>() );
261 delete pFamilies;
262 pItem = 0;
263 pStyle = 0;
264 m_pNameRo.clear();
265 m_pNameRw.clear();
266 m_pAutoCB.clear();
267 m_pFollowFt.clear();
268 m_pFollowLb.clear();
269 m_pEditStyleBtn.clear();
270 m_pBaseFt.clear();
271 m_pBaseLb.clear();
272 m_pEditLinkStyleBtn.clear();
273 m_pFilterFt.clear();
274 m_pFilterLb.clear();
275 m_pDescFt.clear();
276 SfxTabPage::dispose();
281 void SfxManageStyleSheetPage::UpdateName_Impl( ListBox* pBox,
282 const OUString& rNew )
284 /* [Description]
286 After the change of a template name update the ListBox pBox
288 [Parameter]
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 );
302 if ( bSelect )
303 pBox->SelectEntry( rNew );
309 void SfxManageStyleSheetPage::SetDescriptionText_Impl()
311 /* [Description]
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();
320 if ( pModule )
322 const SfxPoolItem* pPoolItem = pModule->GetItem( SID_ATTR_METRIC );
323 if ( pPoolItem )
324 eFieldUnit = (FieldUnit) static_cast<const SfxUInt16Item*>( pPoolItem )->GetValue();
327 switch ( eFieldUnit )
329 case FUNIT_MM: eUnit = SFX_MAPUNIT_MM; break;
330 case FUNIT_CM:
331 case FUNIT_M:
332 case FUNIT_KM: eUnit = SFX_MAPUNIT_CM; break;
333 case FUNIT_POINT:
334 case FUNIT_PICA: eUnit = SFX_MAPUNIT_POINT; break;
335 case FUNIT_INCH:
336 case FUNIT_FOOT:
337 case FUNIT_MILE: eUnit = SFX_MAPUNIT_INCH; break;
339 default:
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();
351 else
352 m_pEditStyleBtn->Disable();
353 return 0;
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 ))
364 return 0;
368 IMPL_LINK_NOARG( SfxManageStyleSheetPage, EditLinkStyleSelectHdl_Impl )
370 sal_Int32 linkSelectPos = m_pBaseLb->GetSelectEntryPos();
371 if ( linkSelectPos == 0 )
372 m_pEditLinkStyleBtn->Disable();
373 else
374 m_pEditLinkStyleBtn->Enable();
375 return 0;
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 );
383 return 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;
403 if( nMask )
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,
413 pItems, nModi );
415 if ( !mpItem )
416 return false;
418 return true;
422 IMPL_LINK( SfxManageStyleSheetPage, GetFocusHdl, Edit *, pEdit )
424 /* [Description]
426 StarView Handler; GetFocus-Handler of the Edits with the template name.
430 aBuf = comphelper::string::stripStart(pEdit->GetText(), ' ');
431 return 0;
434 IMPL_LINK( SfxManageStyleSheetPage, LoseFocusHdl, Edit *, pEdit )
436 /* [Description]
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
447 if ( aStr != aBuf )
448 UpdateName_Impl(m_pFollowLb, aStr);
449 return 0;
452 bool SfxManageStyleSheetPage::FillItemSet( SfxItemSet* rSet )
454 /* [Description]
456 Handler for setting the (modified) data. I called from the OK of the
457 SfxTabDialog.
459 [Parameter]
461 SfxItemSet &rAttrSet The set, which receives the data.
463 [Return value]
465 sal_Bool sal_True: The data had been changed
466 sal_False: The data had not been changed
468 [Cross-reference]
470 <class SfxTabDialog>
474 const sal_Int32 nFilterIdx = m_pFilterLb->GetSelectEntryPos();
476 // Set Filter
478 if ( LISTBOX_ENTRY_NOTFOUND != nFilterIdx &&
479 m_pFilterLb->IsValueChangedFromSaved() &&
480 m_pFilterLb->IsEnabled() )
482 bModified = true;
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()));
494 return bModified;
499 void SfxManageStyleSheetPage::Reset( const SfxItemSet* /*rAttrSet*/ )
501 /* [Description]
503 Handler to initialize the page with the initial data.
505 [Parameter]
507 const SfxItemSet &rAttrSet The data set
509 [Cross-reference]
511 <class SfxTabDialog>
515 bModified = false;
516 OUString sCmp( pStyle->GetName() );
518 if ( sCmp != aName )
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 );
532 else
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() );
545 else
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)
578 /* [Description]
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
582 other pages.
584 [Parameter]
586 const SfxItemSet& the set for the exchange of data; is not used here.
588 [Cross-reference]
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 )
609 /* [Description]
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.
614 [Parameter]
616 SfxItemSet* the set for the exchange of data; is not used here.
618 [Cross-reference]
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);
635 aBox->Execute();
636 m_pNameRw->GrabFocus();
637 m_pNameRw->SetSelection( Selection( SELECTION_MIN, SELECTION_MAX ) );
638 return SfxTabPage::KEEP_PAGE;
640 bModified = true;
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);
652 aBox->Execute();
653 m_pFollowLb->GrabFocus();
654 return SfxTabPage::KEEP_PAGE;
656 bModified = true;
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);
672 aBox->Execute();
673 m_pBaseLb->GrabFocus();
674 return SfxTabPage::KEEP_PAGE;
676 bModified = true;
677 nRet = sfxpg(nRet | SfxTabPage::REFRESH_SET);
681 if ( pItemSet )
682 FillItemSet( pItemSet );
684 return nRet;
687 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */