Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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>
27 :
28 : #include <sfx2/styfitem.hxx>
29 : #include <sfx2/styledlg.hxx>
30 : #include <sfx2/app.hxx>
31 : #include <sfx2/mgetempl.hxx>
32 : #include <sfx2/objsh.hxx>
33 : #include "sfxtypes.hxx"
34 : #include <sfx2/sfxresid.hxx>
35 : #include <sfx2/module.hxx>
36 :
37 : #include <sfx2/sfx.hrc>
38 : #include "dialog.hrc"
39 :
40 : #include <svl/style.hrc>
41 :
42 : /* SfxManageStyleSheetPage Constructor
43 : *
44 : * initializes the list box with the templates
45 : */
46 0 : SfxManageStyleSheetPage::SfxManageStyleSheetPage(vcl::Window* pParent, const SfxItemSet& rAttrSet)
47 : : SfxTabPage(pParent, "ManageStylePage", "sfx/ui/managestylepage.ui", &rAttrSet)
48 0 : , pStyle(&static_cast<SfxStyleDialog*>(GetParentDialog())->GetStyleSheet())
49 : , pItem(0)
50 : , bModified(false)
51 0 : , aName(pStyle->GetName())
52 0 : , aFollow(pStyle->GetFollow())
53 0 : , aParent(pStyle->GetParent())
54 0 : , nFlags(pStyle->GetMask())
55 : {
56 0 : get(m_pNameRo, "namero");
57 0 : get(m_pNameRw, "namerw");
58 0 : m_pNameRo->set_width_request(m_pNameRw->get_preferred_size().Width());
59 0 : get(m_pAutoCB, "autoupdate");
60 0 : get(m_pFollowFt, "nextstyleft");
61 0 : get(m_pFollowLb, "nextstyle");
62 0 : m_pFollowLb->SetStyle(m_pFollowLb->GetStyle() | WB_SORT);
63 0 : const sal_Int32 nMaxWidth(62);
64 0 : m_pFollowLb->setMaxWidthChars(nMaxWidth);
65 0 : get(m_pBaseFt, "linkedwithft");
66 0 : get(m_pBaseLb, "linkedwith");
67 0 : m_pBaseLb->SetStyle(m_pBaseLb->GetStyle() | WB_SORT);
68 0 : m_pBaseLb->setMaxWidthChars(nMaxWidth);
69 0 : get(m_pFilterFt, "categoryft");
70 0 : get(m_pFilterLb, "category");
71 : //note that the code depends on categories not being lexically
72 : //sorted, so if its changed to sorted, the code needs to
73 : //be adapted to be position unaware
74 0 : m_pFilterLb->setMaxWidthChars(nMaxWidth);
75 0 : get(m_pDescFt, "desc");
76 :
77 : // this Page needs ExchangeSupport
78 0 : SetExchangeSupport();
79 :
80 0 : ResMgr* pResMgr = SfxGetpApp()->GetModule_Impl()->GetResMgr();
81 : OSL_ENSURE( pResMgr, "No ResMgr in Module" );
82 0 : pFamilies = new SfxStyleFamilies( ResId( DLG_STYLE_DESIGNER, *pResMgr ) );
83 :
84 0 : SfxStyleSheetBasePool* pPool = 0;
85 0 : SfxObjectShell* pDocShell = SfxObjectShell::Current();
86 :
87 0 : if ( pDocShell )
88 0 : pPool = pDocShell->GetStyleSheetPool();
89 : OSL_ENSURE( pPool, "no Pool or no DocShell" );
90 :
91 0 : if ( pPool )
92 : {
93 0 : pPool->SetSearchMask( pStyle->GetFamily() );
94 0 : pPool->First(); // for SW - update internal list
95 : }
96 :
97 0 : if ( pStyle->GetName().isEmpty() && pPool )
98 : {
99 : // NullString as Name -> generate Name
100 0 : OUString aNoName(SfxStyleDialog::GenerateUnusedName(*pPool));
101 0 : pStyle->SetName( aNoName );
102 0 : aName = aNoName;
103 0 : aFollow = pStyle->GetFollow();
104 0 : aParent = pStyle->GetParent();
105 : }
106 0 : m_pNameRw->SetText(pStyle->GetName());
107 :
108 : // Set the field read-only if it is NOT an user-defined style
109 : // but allow selecting and copying
110 0 : if (!pStyle->IsUserDefined())
111 : {
112 0 : m_pNameRo->SetText(m_pNameRw->GetText());
113 0 : m_pNameRw->Hide();
114 0 : m_pNameRo->Show();
115 0 : FixedText *pLabel = get<FixedText>("nameft");
116 0 : pLabel->set_mnemonic_widget(m_pNameRo);
117 : }
118 :
119 0 : if ( pStyle->HasFollowSupport() && pPool )
120 : {
121 0 : SfxStyleSheetBase* pPoolStyle = pPool->First();
122 :
123 0 : while ( pPoolStyle )
124 : {
125 0 : m_pFollowLb->InsertEntry( pPoolStyle->GetName() );
126 0 : pPoolStyle = pPool->Next();
127 : }
128 :
129 : // A new Template is not yet in the Pool
130 0 : if ( LISTBOX_ENTRY_NOTFOUND == m_pFollowLb->GetEntryPos( pStyle->GetName() ) )
131 0 : m_pFollowLb->InsertEntry( pStyle->GetName() );
132 : }
133 : else
134 : {
135 0 : m_pFollowFt->Hide();
136 0 : m_pFollowLb->Hide();
137 : }
138 :
139 0 : if ( pStyle->HasParentSupport() && pPool )
140 : {
141 0 : if ( pStyle->HasClearParentSupport() )
142 : // the base template can be set to NULL
143 0 : m_pBaseLb->InsertEntry( SfxResId(STR_NONE).toString() );
144 :
145 0 : SfxStyleSheetBase* pPoolStyle = pPool->First();
146 :
147 0 : while ( pPoolStyle )
148 : {
149 0 : const OUString aStr( pPoolStyle->GetName() );
150 : // own name as base template
151 0 : if ( aStr != aName )
152 0 : m_pBaseLb->InsertEntry( aStr );
153 0 : pPoolStyle = pPool->Next();
154 0 : }
155 : }
156 : else
157 : {
158 0 : m_pBaseFt->Disable();
159 0 : m_pBaseLb->Disable();
160 : }
161 :
162 0 : size_t nCount = pFamilies->size();
163 : size_t i;
164 0 : for ( i = 0; i < nCount; ++i )
165 : {
166 0 : pItem = pFamilies->at( i );
167 :
168 0 : if ( pItem->GetFamily() == pStyle->GetFamily() )
169 0 : break;
170 : }
171 :
172 0 : if ( i < nCount )
173 : {
174 0 : sal_uInt16 nStyleFilterIdx = 0xffff;
175 : // Filter flags
176 0 : const SfxStyleFilter& rList = pItem->GetFilterList();
177 0 : nCount = rList.size();
178 0 : sal_uInt16 nIdx = 0;
179 0 : sal_uInt16 nMask = pStyle->GetMask() & ~SFXSTYLEBIT_USERDEF;
180 :
181 0 : if ( !nMask ) // User Template?
182 0 : nMask = pStyle->GetMask();
183 :
184 0 : for ( i = 0; i < nCount; ++i )
185 : {
186 0 : SfxFilterTupel* pTupel = rList[ i ];
187 :
188 0 : if ( pTupel->nFlags != SFXSTYLEBIT_AUTO &&
189 0 : pTupel->nFlags != SFXSTYLEBIT_USED &&
190 0 : pTupel->nFlags != SFXSTYLEBIT_ALL_VISIBLE &&
191 0 : pTupel->nFlags != SFXSTYLEBIT_ALL )
192 : {
193 0 : m_pFilterLb->InsertEntry( pTupel->aName, nIdx );
194 0 : m_pFilterLb->SetEntryData(nIdx, reinterpret_cast<void*>(i));
195 :
196 0 : if ( ( pTupel->nFlags & nMask ) == nMask )
197 0 : nStyleFilterIdx = nIdx;
198 0 : ++nIdx;
199 : }
200 : }
201 :
202 0 : if ( nStyleFilterIdx != 0xFFFF )
203 0 : m_pFilterLb->SelectEntryPos( nStyleFilterIdx );
204 : }
205 :
206 0 : if ( !m_pFilterLb->GetEntryCount() || !pStyle->IsUserDefined() )
207 : {
208 0 : pItem = 0;
209 0 : m_pFilterFt->Disable();
210 0 : m_pFilterLb->Disable();
211 : }
212 : else
213 0 : m_pFilterLb->SaveValue();
214 0 : SetDescriptionText_Impl();
215 :
216 0 : if ( m_pFollowLb->IsEnabled() || m_pBaseLb->IsEnabled() )
217 : {
218 : m_pNameRw->SetGetFocusHdl(
219 0 : LINK( this, SfxManageStyleSheetPage, GetFocusHdl ) );
220 : m_pNameRw->SetLoseFocusHdl(
221 0 : LINK( this, SfxManageStyleSheetPage, LoseFocusHdl ) );
222 : }
223 : // It is a style with auto update? (SW only)
224 0 : if(SfxItemState::SET == rAttrSet.GetItemState(SID_ATTR_AUTO_STYLE_UPDATE))
225 0 : m_pAutoCB->Show();
226 0 : }
227 :
228 :
229 :
230 0 : SfxManageStyleSheetPage::~SfxManageStyleSheetPage()
231 :
232 : /* [Description]
233 :
234 : Destructor, release of the data
235 : */
236 :
237 : {
238 0 : m_pNameRw->SetGetFocusHdl( Link() );
239 0 : m_pNameRw->SetLoseFocusHdl( Link() );
240 0 : delete pFamilies;
241 0 : pItem = 0;
242 0 : pStyle = 0;
243 :
244 0 : }
245 :
246 :
247 :
248 0 : void SfxManageStyleSheetPage::UpdateName_Impl( ListBox* pBox,
249 : const OUString& rNew )
250 :
251 : /* [Description]
252 :
253 : After the change of a template name update the ListBox pBox
254 :
255 : [Parameter]
256 :
257 : ListBox* pBox ListBox, whose entries are to be updated
258 : const String& rNew the new Name
259 : */
260 :
261 : {
262 0 : if ( pBox->IsEnabled() )
263 : {
264 : // it is the current entry, which name was modified
265 0 : const bool bSelect = pBox->GetSelectEntry() == aBuf;
266 0 : pBox->RemoveEntry( aBuf );
267 0 : pBox->InsertEntry( rNew );
268 :
269 0 : if ( bSelect )
270 0 : pBox->SelectEntry( rNew );
271 : }
272 0 : }
273 :
274 :
275 :
276 0 : void SfxManageStyleSheetPage::SetDescriptionText_Impl()
277 :
278 : /* [Description]
279 :
280 : Set attribute description. Get the set metric for this.
281 : */
282 :
283 : {
284 0 : SfxMapUnit eUnit = SFX_MAPUNIT_CM;
285 0 : FieldUnit eFieldUnit( FUNIT_CM );
286 0 : SfxModule* pModule = SfxModule::GetActiveModule();
287 0 : if ( pModule )
288 : {
289 0 : const SfxPoolItem* pPoolItem = pModule->GetItem( SID_ATTR_METRIC );
290 0 : if ( pPoolItem )
291 0 : eFieldUnit = (FieldUnit) static_cast<const SfxUInt16Item*>( pPoolItem )->GetValue();
292 : }
293 :
294 0 : switch ( eFieldUnit )
295 : {
296 0 : case FUNIT_MM: eUnit = SFX_MAPUNIT_MM; break;
297 : case FUNIT_CM:
298 : case FUNIT_M:
299 0 : case FUNIT_KM: eUnit = SFX_MAPUNIT_CM; break;
300 : case FUNIT_POINT:
301 0 : case FUNIT_PICA: eUnit = SFX_MAPUNIT_POINT; break;
302 : case FUNIT_INCH:
303 : case FUNIT_FOOT:
304 0 : case FUNIT_MILE: eUnit = SFX_MAPUNIT_INCH; break;
305 :
306 : default:
307 : OSL_FAIL( "non supported field unit" );
308 : }
309 0 : m_pDescFt->SetText( pStyle->GetDescription( eUnit ) );
310 0 : }
311 :
312 :
313 :
314 0 : IMPL_LINK_INLINE_START( SfxManageStyleSheetPage, GetFocusHdl, Edit *, pEdit )
315 :
316 : /* [Description]
317 :
318 : StarView Handler; GetFocus-Handler of the Edits with the template name.
319 : */
320 :
321 : {
322 0 : aBuf = comphelper::string::stripStart(pEdit->GetText(), ' ');
323 0 : return 0;
324 : }
325 0 : IMPL_LINK_INLINE_END( SfxManageStyleSheetPage, GetFocusHdl, Edit *, pEdit )
326 :
327 :
328 :
329 0 : IMPL_LINK_INLINE_START( SfxManageStyleSheetPage, LoseFocusHdl, Edit *, pEdit )
330 :
331 : /* [Description]
332 :
333 : StarView Handler; lose-focus-handler of the edits of the template name.
334 : This will update the listbox with the subsequent templates. The current
335 : template itself is not returned in the listbox of the base templates.
336 : */
337 :
338 : {
339 0 : const OUString aStr(comphelper::string::stripStart(pEdit->GetText(), ' '));
340 0 : pEdit->SetText( aStr );
341 : // Update the Listbox of the base template if possible
342 0 : if ( aStr != aBuf )
343 0 : UpdateName_Impl(m_pFollowLb, aStr);
344 0 : return 0;
345 : }
346 0 : IMPL_LINK_INLINE_END( SfxManageStyleSheetPage, LoseFocusHdl, Edit *, pEdit )
347 :
348 :
349 :
350 0 : bool SfxManageStyleSheetPage::FillItemSet( SfxItemSet* rSet )
351 :
352 : /* [Description]
353 :
354 : Handler for setting the (modified) data. I called from the OK of the
355 : SfxTabDialog.
356 :
357 : [Parameter]
358 :
359 : SfxItemSet &rAttrSet The set, which receives the data.
360 :
361 : [Return value]
362 :
363 : sal_Bool sal_True: The data had been changed
364 : sal_False: The data had not been changed
365 :
366 : [Cross-reference]
367 :
368 : <class SfxTabDialog>
369 : */
370 :
371 : {
372 0 : const sal_Int32 nFilterIdx = m_pFilterLb->GetSelectEntryPos();
373 :
374 : // Set Filter
375 :
376 0 : if ( LISTBOX_ENTRY_NOTFOUND != nFilterIdx &&
377 0 : m_pFilterLb->IsValueChangedFromSaved() &&
378 0 : m_pFilterLb->IsEnabled() )
379 : {
380 0 : bModified = true;
381 : OSL_ENSURE( pItem, "No Item" );
382 : // is only possibly for user templates
383 0 : sal_uInt16 nMask = pItem->GetFilterList()[ reinterpret_cast<size_t>(m_pFilterLb->GetEntryData( nFilterIdx )) ]->nFlags | SFXSTYLEBIT_USERDEF;
384 0 : pStyle->SetMask( nMask );
385 : }
386 0 : if(m_pAutoCB->IsVisible() &&
387 0 : m_pAutoCB->IsValueChangedFromSaved())
388 : {
389 0 : rSet->Put(SfxBoolItem(SID_ATTR_AUTO_STYLE_UPDATE, m_pAutoCB->IsChecked()));
390 : }
391 :
392 0 : return bModified;
393 : }
394 :
395 :
396 :
397 0 : void SfxManageStyleSheetPage::Reset( const SfxItemSet* /*rAttrSet*/ )
398 :
399 : /* [Description]
400 :
401 : Handler to initialize the page with the initial data.
402 :
403 : [Parameter]
404 :
405 : const SfxItemSet &rAttrSet The data set
406 :
407 : [Cross-reference]
408 :
409 : <class SfxTabDialog>
410 : */
411 :
412 : {
413 0 : bModified = false;
414 0 : OUString sCmp( pStyle->GetName() );
415 :
416 0 : if ( sCmp != aName )
417 0 : pStyle->SetName( aName );
418 0 : m_pNameRw->SetText( aName );
419 0 : m_pNameRw->SetSelection( Selection( SELECTION_MIN, SELECTION_MAX ) );
420 :
421 0 : if ( m_pFollowLb->IsEnabled() )
422 : {
423 0 : sCmp = pStyle->GetFollow();
424 :
425 0 : if ( sCmp != aFollow )
426 0 : pStyle->SetFollow( aFollow );
427 :
428 0 : if ( aFollow.isEmpty() )
429 0 : m_pFollowLb->SelectEntry( aName );
430 : else
431 0 : m_pFollowLb->SelectEntry( aFollow );
432 : }
433 :
434 0 : if ( m_pBaseLb->IsEnabled() )
435 : {
436 0 : sCmp = pStyle->GetParent();
437 :
438 0 : if ( sCmp != aParent )
439 0 : pStyle->SetParent( aParent );
440 :
441 0 : if ( aParent.isEmpty() )
442 0 : m_pBaseLb->SelectEntry( SfxResId(STR_NONE).toString() );
443 : else
444 0 : m_pBaseLb->SelectEntry( aParent );
445 :
446 0 : if ( SfxResId(STR_STANDARD).toString().equals(aName) )
447 : {
448 : // the default template can not be linked
449 0 : m_pBaseFt->Disable();
450 0 : m_pBaseLb->Disable();
451 : }
452 : }
453 :
454 0 : if ( m_pFilterLb->IsEnabled() )
455 : {
456 0 : sal_uInt16 nCmp = pStyle->GetMask();
457 :
458 0 : if ( nCmp != nFlags )
459 0 : pStyle->SetMask( nFlags );
460 0 : m_pFilterLb->SelectEntryPos( m_pFilterLb->GetSavedValue() );
461 0 : }
462 0 : }
463 :
464 :
465 :
466 0 : SfxTabPage* SfxManageStyleSheetPage::Create( vcl::Window* pParent,
467 : const SfxItemSet *rAttrSet )
468 :
469 : /* [Description]
470 :
471 : Factory for the creation of the page.
472 :
473 : [Cross-reference]
474 :
475 : <class SfxTabDialog>
476 : */
477 :
478 : {
479 0 : return new SfxManageStyleSheetPage( pParent, *rAttrSet );
480 : }
481 :
482 :
483 :
484 0 : void SfxManageStyleSheetPage::ActivatePage( const SfxItemSet& rSet)
485 :
486 : /* [Description]
487 :
488 : ActivatePage handler of SfxTabDialog, is used for the update of the
489 : descriptive text, since this might have changed through changes of data on
490 : other pages.
491 :
492 : [Parameter]
493 :
494 : const SfxItemSet& the set for the exchange of data; is not used here.
495 :
496 : [Cross-reference]
497 :
498 : <SfxTabDialog::ActivatePage(const SfxItemSet &)>
499 : */
500 :
501 : {
502 0 : SetDescriptionText_Impl();
503 :
504 : // It is a style with auto update? (SW only)
505 : const SfxPoolItem* pPoolItem;
506 :
507 0 : if ( SfxItemState::SET ==
508 0 : rSet.GetItemState( SID_ATTR_AUTO_STYLE_UPDATE, false, &pPoolItem ) )
509 0 : m_pAutoCB->Check( static_cast<const SfxBoolItem*>(pPoolItem)->GetValue() );
510 0 : m_pAutoCB->SaveValue();
511 0 : }
512 :
513 :
514 :
515 0 : int SfxManageStyleSheetPage::DeactivatePage( SfxItemSet* pItemSet )
516 :
517 : /* [Description]
518 :
519 : DeactivatePage-handler of SfxTabDialog; data is set on the template, so
520 : that the correct inheritance on the other pages of the dialog is made.
521 : If an error occurs, leaving the page is prevented.
522 : [Parameter]
523 :
524 : SfxItemSet* the set for the exchange of data; is not used here.
525 :
526 : [Cross-reference]
527 :
528 : <SfxTabDialog::DeactivatePage(SfxItemSet*)>
529 : */
530 :
531 : {
532 0 : int nRet = SfxTabPage::LEAVE_PAGE;
533 :
534 0 : if ( m_pNameRw->IsModified() )
535 : {
536 : // By pressing <Enter> LoseFocus() is not trigged through StarView
537 0 : if ( m_pNameRw->HasFocus() )
538 0 : LoseFocusHdl( m_pNameRw );
539 :
540 0 : if (!pStyle->SetName(comphelper::string::stripStart(m_pNameRw->GetText(), ' ')))
541 : {
542 0 : MessageDialog aBox( this, SfxResId( STR_TABPAGE_INVALIDNAME ), VCL_MESSAGE_INFO );
543 0 : aBox.Execute();
544 0 : m_pNameRw->GrabFocus();
545 0 : m_pNameRw->SetSelection( Selection( SELECTION_MIN, SELECTION_MAX ) );
546 0 : return SfxTabPage::KEEP_PAGE;
547 : }
548 0 : bModified = true;
549 : }
550 :
551 0 : if ( pStyle->HasFollowSupport() && m_pFollowLb->IsEnabled() )
552 : {
553 0 : const OUString aFollowEntry( m_pFollowLb->GetSelectEntry() );
554 :
555 0 : if ( pStyle->GetFollow() != aFollowEntry )
556 : {
557 0 : if ( !pStyle->SetFollow( aFollowEntry ) )
558 : {
559 0 : MessageDialog aBox( this, SfxResId( STR_TABPAGE_INVALIDSTYLE ), VCL_MESSAGE_INFO );
560 0 : aBox.Execute();
561 0 : m_pFollowLb->GrabFocus();
562 0 : return SfxTabPage::KEEP_PAGE;
563 : }
564 0 : bModified = true;
565 0 : }
566 : }
567 :
568 0 : if ( m_pBaseLb->IsEnabled() )
569 : {
570 0 : OUString aParentEntry( m_pBaseLb->GetSelectEntry() );
571 :
572 0 : if ( SfxResId(STR_NONE).toString().equals(aParentEntry) || aParentEntry == pStyle->GetName() )
573 0 : aParentEntry = OUString();
574 :
575 0 : if ( pStyle->GetParent() != aParentEntry )
576 : {
577 0 : if ( !pStyle->SetParent( aParentEntry ) )
578 : {
579 0 : MessageDialog aBox( this, SfxResId( STR_TABPAGE_INVALIDPARENT ), VCL_MESSAGE_INFO );
580 0 : aBox.Execute();
581 0 : m_pBaseLb->GrabFocus();
582 0 : return SfxTabPage::KEEP_PAGE;
583 : }
584 0 : bModified = true;
585 0 : nRet |= (int)SfxTabPage::REFRESH_SET;
586 0 : }
587 : }
588 :
589 0 : if ( pItemSet )
590 0 : FillItemSet( pItemSet );
591 :
592 0 : return nRet;
593 951 : }
594 :
595 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|