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 :
21 : #include <limits.h>
22 : #include <stdlib.h>
23 : #include <algorithm>
24 : #include <vcl/builder.hxx>
25 : #include <vcl/msgbox.hxx>
26 : #include <unotools/viewoptions.hxx>
27 :
28 : #include "appdata.hxx"
29 : #include "sfxtypes.hxx"
30 : #include <sfx2/minarray.hxx>
31 : #include <sfx2/tabdlg.hxx>
32 : #include <sfx2/viewfrm.hxx>
33 : #include <sfx2/app.hxx>
34 : #include "sfx2/sfxresid.hxx"
35 : #include "sfx2/sfxhelp.hxx"
36 : #include <sfx2/ctrlitem.hxx>
37 : #include <sfx2/bindings.hxx>
38 : #include <sfx2/sfxdlg.hxx>
39 : #include <sfx2/itemconnect.hxx>
40 :
41 : #include "dialog.hrc"
42 : #include "helpid.hrc"
43 :
44 : using namespace ::com::sun::star::uno;
45 : using namespace ::rtl;
46 :
47 : #define USERITEM_NAME OUString("UserItem")
48 :
49 0 : TYPEINIT1(SfxTabDialogItem,SfxSetItem);
50 :
51 0 : struct TabPageImpl
52 : {
53 : sal_Bool mbStandard;
54 : sfx::ItemConnectionArray maItemConn;
55 : ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > mxFrame;
56 :
57 0 : TabPageImpl() : mbStandard( sal_False ) {}
58 : };
59 :
60 : struct Data_Impl
61 : {
62 : sal_uInt16 nId; // The ID
63 : CreateTabPage fnCreatePage; // Pointer to Factory
64 : GetTabPageRanges fnGetRanges; // Pointer to Ranges-Function
65 : SfxTabPage* pTabPage; // The TabPage itself
66 : sal_Bool bOnDemand; // Flag: ItemSet onDemand
67 : sal_Bool bRefresh; // Flag: Page must be re-initialized
68 :
69 : // Constructor
70 0 : Data_Impl( sal_uInt16 Id, CreateTabPage fnPage,
71 : GetTabPageRanges fnRanges, sal_Bool bDemand ) :
72 :
73 : nId ( Id ),
74 : fnCreatePage( fnPage ),
75 : fnGetRanges ( fnRanges ),
76 : pTabPage ( 0 ),
77 : bOnDemand ( bDemand ),
78 0 : bRefresh ( sal_False )
79 : {
80 0 : if ( !fnCreatePage )
81 : {
82 0 : SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
83 0 : if ( pFact )
84 : {
85 0 : fnCreatePage = pFact->GetTabPageCreatorFunc( nId );
86 0 : fnGetRanges = pFact->GetTabPageRangesFunc( nId );
87 : }
88 : }
89 0 : }
90 : };
91 :
92 0 : SfxTabDialogItem::SfxTabDialogItem( const SfxTabDialogItem& rAttr, SfxItemPool* pItemPool )
93 0 : : SfxSetItem( rAttr, pItemPool )
94 : {
95 0 : }
96 :
97 0 : SfxTabDialogItem::SfxTabDialogItem( sal_uInt16 nId, const SfxItemSet& rItemSet )
98 0 : : SfxSetItem( nId, rItemSet )
99 : {
100 0 : }
101 :
102 0 : SfxPoolItem* SfxTabDialogItem::Clone(SfxItemPool* pToPool) const
103 : {
104 0 : return new SfxTabDialogItem( *this, pToPool );
105 : }
106 :
107 0 : SfxPoolItem* SfxTabDialogItem::Create(SvStream& /*rStream*/, sal_uInt16 /*nVersion*/) const
108 : {
109 : OSL_FAIL( "Use it only in UI!" );
110 0 : return NULL;
111 : }
112 :
113 : class SfxTabDialogController : public SfxControllerItem
114 : {
115 : SfxTabDialog* pDialog;
116 : const SfxItemSet* pSet;
117 : public:
118 : SfxTabDialogController( sal_uInt16 nSlotId, SfxBindings& rBindings, SfxTabDialog* pDlg )
119 : : SfxControllerItem( nSlotId, rBindings )
120 : , pDialog( pDlg )
121 : , pSet( NULL )
122 : {}
123 :
124 : ~SfxTabDialogController();
125 :
126 : virtual void StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState );
127 : };
128 :
129 0 : SfxTabDialogController::~SfxTabDialogController()
130 : {
131 0 : delete pSet;
132 0 : }
133 :
134 0 : void SfxTabDialogController::StateChanged( sal_uInt16 /*nSID*/, SfxItemState /*eState*/, const SfxPoolItem* pState )
135 : {
136 0 : const SfxSetItem* pSetItem = PTR_CAST( SfxSetItem, pState );
137 0 : if ( pSetItem )
138 : {
139 0 : pSet = pDialog->pSet = pSetItem->GetItemSet().Clone();
140 0 : sal_Bool bDialogStarted = sal_False;
141 0 : for ( sal_uInt16 n=0; n<pDialog->m_pTabCtrl->GetPageCount(); n++ )
142 : {
143 0 : sal_uInt16 nPageId = pDialog->m_pTabCtrl->GetPageId( n );
144 0 : SfxTabPage* pTabPage = dynamic_cast<SfxTabPage*> (pDialog->m_pTabCtrl->GetTabPage( nPageId ));
145 0 : if ( pTabPage )
146 : {
147 0 : pTabPage->Reset( pSetItem->GetItemSet() );
148 0 : bDialogStarted = sal_True;
149 : }
150 : }
151 :
152 0 : if ( bDialogStarted )
153 0 : pDialog->Show();
154 : }
155 : else
156 0 : pDialog->Hide();
157 0 : }
158 :
159 0 : DECL_PTRARRAY(SfxTabDlgData_Impl, Data_Impl *, 4,4)
160 :
161 : struct TabDlg_Impl
162 : {
163 : sal_Bool bModified : 1,
164 : bModal : 1,
165 : bInOK : 1,
166 : bHideResetBtn : 1;
167 : SfxTabDlgData_Impl* pData;
168 :
169 : SfxTabDialogController* pController;
170 :
171 0 : TabDlg_Impl( sal_uInt8 nCnt ) :
172 :
173 : bModified ( sal_False ),
174 : bModal ( sal_True ),
175 : bInOK ( sal_False ),
176 : bHideResetBtn ( sal_False ),
177 0 : pData ( new SfxTabDlgData_Impl( nCnt ) ),
178 0 : pController ( NULL )
179 0 : {}
180 : };
181 :
182 : Data_Impl* Find( SfxTabDlgData_Impl& rArr, sal_uInt16 nId, sal_uInt16* pPos = 0 );
183 :
184 0 : Data_Impl* Find( SfxTabDlgData_Impl& rArr, sal_uInt16 nId, sal_uInt16* pPos )
185 : {
186 0 : const sal_uInt16 nCount = rArr.Count();
187 :
188 0 : for ( sal_uInt16 i = 0; i < nCount; ++i )
189 : {
190 0 : Data_Impl* pObj = rArr[i];
191 :
192 0 : if ( pObj->nId == nId )
193 : {
194 0 : if ( pPos )
195 0 : *pPos = i;
196 0 : return pObj;
197 : }
198 : }
199 0 : return 0;
200 : }
201 :
202 0 : void SfxTabPage::SetFrame(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame)
203 : {
204 0 : if (pImpl)
205 0 : pImpl->mxFrame = xFrame;
206 0 : }
207 :
208 0 : ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SfxTabPage::GetFrame()
209 : {
210 0 : if (pImpl)
211 0 : return pImpl->mxFrame;
212 0 : return ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >();
213 : }
214 :
215 0 : SfxTabPage::SfxTabPage( Window *pParent,
216 : const ResId &rResId, const SfxItemSet &rAttrSet ) :
217 :
218 : /* [Description]
219 :
220 : Constructor
221 : */
222 :
223 : TabPage( pParent, rResId ),
224 :
225 : pSet ( &rAttrSet ),
226 : bHasExchangeSupport ( sal_False ),
227 : pTabDlg ( NULL ),
228 0 : pImpl ( new TabPageImpl )
229 :
230 : {
231 0 : }
232 :
233 :
234 0 : SfxTabPage::SfxTabPage(Window *pParent, const rtl::OString& rID, const rtl::OUString& rUIXMLDescription, const SfxItemSet &rAttrSet)
235 : : TabPage(pParent, rID, rUIXMLDescription)
236 : , pSet ( &rAttrSet )
237 : , bHasExchangeSupport ( sal_False )
238 : , pTabDlg ( NULL )
239 0 : , pImpl ( new TabPageImpl )
240 : {
241 0 : }
242 :
243 : // -----------------------------------------------------------------------
244 0 : SfxTabPage:: SfxTabPage( Window *pParent, WinBits nStyle, const SfxItemSet &rAttrSet ) :
245 : TabPage(pParent, nStyle),
246 : pSet ( &rAttrSet ),
247 : bHasExchangeSupport ( sal_False ),
248 : pTabDlg ( NULL ),
249 0 : pImpl ( new TabPageImpl )
250 : {
251 0 : }
252 : // -----------------------------------------------------------------------
253 :
254 0 : SfxTabPage::~SfxTabPage()
255 :
256 : /* [Description]
257 :
258 : Destructor
259 : */
260 :
261 : {
262 0 : delete pImpl;
263 0 : }
264 :
265 : // -----------------------------------------------------------------------
266 :
267 0 : sal_Bool SfxTabPage::FillItemSet( SfxItemSet& rSet )
268 : {
269 0 : return pImpl->maItemConn.DoFillItemSet( rSet, GetItemSet() );
270 : }
271 :
272 : // -----------------------------------------------------------------------
273 :
274 0 : void SfxTabPage::Reset( const SfxItemSet& rSet )
275 : {
276 0 : pImpl->maItemConn.DoApplyFlags( rSet );
277 0 : pImpl->maItemConn.DoReset( rSet );
278 0 : }
279 :
280 : // -----------------------------------------------------------------------
281 :
282 0 : void SfxTabPage::ActivatePage( const SfxItemSet& )
283 :
284 : /* [Description]
285 :
286 : Default implementation of the virtual ActivatePage method. This method is
287 : called when a page of dialogue supports the exchange of data between pages.
288 : <SfxTabPage::DeactivatePage(SfxItemSet *)>
289 : */
290 :
291 : {
292 0 : }
293 :
294 : // -----------------------------------------------------------------------
295 :
296 0 : int SfxTabPage::DeactivatePage( SfxItemSet* )
297 :
298 : /* [Description]
299 :
300 : Default implementation of the virtual DeactivatePage method. This method is
301 : called by Sfx when leaving a page; the application can, through the return
302 : value, control whether to leave the page. If the page is displayed through
303 : bHasExchangeSupport which supports data exchange between pages, then a
304 : pointer to the exchange set is passed as parameter. This takes on data for
305 : the exchange, then the set is available as a parameter in
306 : <SfxTabPage::ActivatePage(const SfxItemSet &)>.
307 :
308 : [Return value]
309 :
310 : LEAVE_PAGE; Allow leaving the page
311 : */
312 :
313 : {
314 0 : return LEAVE_PAGE;
315 : }
316 :
317 : // -----------------------------------------------------------------------
318 :
319 0 : void SfxTabPage::FillUserData()
320 :
321 : /* [Description]
322 :
323 : Virtual method is called by the base class in the destructor to save
324 : specific information of the TabPage in the ini-file. When overloading a
325 : string must be compiled, which is then flushed with the <SetUserData()>.
326 : */
327 :
328 : {
329 0 : }
330 :
331 : // -----------------------------------------------------------------------
332 :
333 0 : sal_Bool SfxTabPage::IsReadOnly() const
334 : {
335 0 : return sal_False;
336 : }
337 :
338 : // -----------------------------------------------------------------------
339 :
340 0 : const SfxPoolItem* SfxTabPage::GetItem( const SfxItemSet& rSet, sal_uInt16 nSlot, sal_Bool bDeep )
341 :
342 : /* [Description]
343 :
344 : static Method: hereby are the implementations of the TabPage code
345 : beeing simplified.
346 : */
347 :
348 : {
349 0 : const SfxItemPool* pPool = rSet.GetPool();
350 0 : sal_uInt16 nWh = pPool->GetWhich( nSlot, bDeep );
351 0 : const SfxPoolItem* pItem = 0;
352 0 : rSet.GetItemState( nWh, sal_True, &pItem );
353 :
354 0 : if ( !pItem && nWh != nSlot )
355 0 : pItem = &pPool->GetDefaultItem( nWh );
356 0 : return pItem;
357 : }
358 :
359 : // -----------------------------------------------------------------------
360 :
361 0 : const SfxPoolItem* SfxTabPage::GetOldItem( const SfxItemSet& rSet,
362 : sal_uInt16 nSlot, sal_Bool bDeep )
363 :
364 : /* [Description]
365 :
366 : This method returns an attribute for comparison of the old value.
367 : */
368 :
369 : {
370 0 : const SfxItemSet& rOldSet = GetItemSet();
371 0 : sal_uInt16 nWh = GetWhich( nSlot, bDeep );
372 0 : const SfxPoolItem* pItem = 0;
373 :
374 0 : if ( pImpl->mbStandard && rOldSet.GetParent() )
375 0 : pItem = GetItem( *rOldSet.GetParent(), nSlot );
376 0 : else if ( rSet.GetParent() &&
377 0 : SFX_ITEM_DONTCARE == rSet.GetItemState( nWh ) )
378 0 : pItem = GetItem( *rSet.GetParent(), nSlot );
379 : else
380 0 : pItem = GetItem( rOldSet, nSlot );
381 0 : return pItem;
382 : }
383 :
384 0 : void SfxTabPage::PageCreated( SfxAllItemSet /*aSet*/ )
385 : {
386 : DBG_ASSERT(0, "SfxTabPage::PageCreated should not be called");
387 0 : }
388 :
389 : // -----------------------------------------------------------------------
390 :
391 0 : void SfxTabPage::AddItemConnection( sfx::ItemConnectionBase* pConnection )
392 : {
393 0 : pImpl->maItemConn.AddConnection( pConnection );
394 0 : }
395 :
396 : #define INI_LIST(ItemSetPtr) \
397 : pSet(ItemSetPtr) \
398 : , pOutSet(0) \
399 : , pRanges(0) \
400 : , nResId(rResId.GetId()) \
401 : , nAppPageId(USHRT_MAX) \
402 : , bItemsReset(sal_False) \
403 : , bFmt(bEditFmt)\
404 : , pExampleSet(0)
405 :
406 : // -----------------------------------------------------------------------
407 :
408 0 : SfxTabDialog::SfxTabDialog
409 :
410 : /* [Description]
411 :
412 : Constructor
413 : */
414 :
415 : (
416 : SfxViewFrame* pViewFrame, // Frame, to which the Dialog belongs
417 : Window* pParent, // Parent Window
418 : const ResId& rResId, // ResourceId
419 : const SfxItemSet* pItemSet, // Itemset with the data;
420 : // can be NULL, when Pages are onDemand
421 : sal_Bool bEditFmt, // Flag: templates are processed
422 : // when yes -> additional Button for standard
423 : const String* pUserButtonText // Text for UserButton;
424 : // if != 0, the UserButton is created
425 : )
426 : : TabDialog(pParent, rResId)
427 : , pFrame(pViewFrame)
428 0 : , INI_LIST(pItemSet)
429 : {
430 0 : Init_Impl( bFmt, pUserButtonText, rResId );
431 0 : }
432 :
433 : // -----------------------------------------------------------------------
434 :
435 0 : SfxTabDialog::SfxTabDialog
436 :
437 : /* [Description]
438 :
439 : Constructor, temporary without Frame
440 : */
441 :
442 : (
443 : Window* pParent, // Parent Window
444 : const ResId& rResId, // ResourceId
445 : const SfxItemSet* pItemSet, // Itemset with the data;
446 : // can be NULL, when Pages are onDemand
447 : sal_Bool bEditFmt, // Flag: templates are processed
448 : // when yes -> additional Button for standard
449 : const String* pUserButtonText // Text for UserButton;
450 : // if != 0, the UserButton is created
451 : )
452 : : TabDialog(pParent, rResId)
453 : , pFrame(0)
454 0 : , INI_LIST(pItemSet)
455 : {
456 0 : Init_Impl( bFmt, pUserButtonText, rResId );
457 : DBG_WARNING( "Please use the Construtor with the ViewFrame" );
458 0 : }
459 :
460 : // -----------------------------------------------------------------------
461 :
462 0 : SfxTabDialog::~SfxTabDialog()
463 : {
464 0 : SavePosAndId();
465 :
466 0 : const sal_uInt16 nCount = pImpl->pData->Count();
467 0 : for ( sal_uInt16 i = 0; i < nCount; ++i )
468 : {
469 0 : Data_Impl* pDataObject = pImpl->pData->GetObject(i);
470 :
471 0 : if ( pDataObject->pTabPage )
472 : {
473 : // save settings of all pages (user data)
474 0 : pDataObject->pTabPage->FillUserData();
475 0 : String aPageData( pDataObject->pTabPage->GetUserData() );
476 0 : if ( aPageData.Len() )
477 : {
478 : // save settings of all pages (user data)
479 0 : SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) );
480 0 : aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aPageData ) ) );
481 : }
482 :
483 0 : if ( pDataObject->bOnDemand )
484 0 : delete (SfxItemSet*)&pDataObject->pTabPage->GetItemSet();
485 0 : delete pDataObject->pTabPage;
486 : }
487 0 : delete pDataObject;
488 : }
489 :
490 0 : delete pImpl->pController;
491 0 : delete pImpl->pData;
492 0 : delete pImpl;
493 0 : delete pOutSet;
494 0 : delete pExampleSet;
495 0 : delete [] pRanges;
496 :
497 0 : if (m_bOwnsBaseFmtBtn)
498 0 : delete m_pBaseFmtBtn;
499 0 : if (m_bOwnsResetBtn)
500 0 : delete m_pResetBtn;
501 0 : if (m_bOwnsHelpBtn)
502 0 : delete m_pHelpBtn;
503 0 : if (m_bOwnsCancelBtn)
504 0 : delete m_pCancelBtn;
505 0 : if (m_bOwnsUserBtn)
506 0 : delete m_pUserBtn;
507 0 : if (m_bOwnsApplyBtn)
508 0 : delete m_pApplyBtn;
509 0 : if (m_bOwnsOKBtn)
510 0 : delete m_pOKBtn;
511 0 : if (m_bOwnsActionArea)
512 0 : delete m_pActionArea;
513 0 : if (m_bOwnsTabCtrl)
514 0 : delete m_pTabCtrl;
515 0 : if (m_bOwnsVBox)
516 0 : delete m_pBox;
517 0 : }
518 :
519 : // -----------------------------------------------------------------------
520 :
521 0 : void SfxTabDialog::Init_Impl( sal_Bool bFmtFlag, const String* pUserButtonText, const ResId& rResId )
522 :
523 : /* [Description]
524 :
525 : internal initialization of the dialogue
526 : */
527 :
528 : {
529 0 : m_pBox = get_content_area();
530 0 : m_bOwnsVBox = m_pBox == NULL;
531 0 : if (m_bOwnsVBox)
532 : {
533 0 : m_pBox = new VclVBox(this, false, 7);
534 0 : m_pBox->set_expand(true);
535 : }
536 :
537 0 : m_pTabCtrl = m_pUIBuilder ? m_pUIBuilder->get<TabControl>(SAL_STRINGIFY(ID_TABCONTROL)) : NULL;
538 0 : m_bOwnsTabCtrl = m_pTabCtrl == NULL;
539 0 : if (m_bOwnsTabCtrl)
540 : {
541 0 : m_pTabCtrl = new TabControl(m_pBox, ResId(ID_TABCONTROL, *rResId.GetResMgr()));
542 0 : m_pTabCtrl->set_expand(true);
543 : }
544 :
545 0 : m_pActionArea = get_action_area();
546 0 : m_bOwnsActionArea = m_pActionArea == NULL;
547 0 : if (m_bOwnsActionArea)
548 0 : m_pActionArea = new VclHButtonBox(m_pBox);
549 :
550 0 : m_pOKBtn = m_pUIBuilder ? m_pUIBuilder->get<OKButton>("ok") : NULL;
551 0 : m_bOwnsOKBtn = m_pOKBtn == NULL;
552 0 : if (m_bOwnsOKBtn)
553 0 : m_pOKBtn = new OKButton(m_pActionArea);
554 :
555 0 : m_pApplyBtn = m_pUIBuilder ? m_pUIBuilder->get<PushButton>("apply") : NULL;
556 0 : m_bOwnsApplyBtn = m_pApplyBtn == NULL;
557 0 : if (m_bOwnsApplyBtn)
558 0 : m_pApplyBtn = NULL;
559 :
560 0 : m_pUserBtn = m_pUIBuilder ? m_pUIBuilder->get<PushButton>("user") : NULL;
561 0 : m_bOwnsUserBtn = m_pUserBtn == NULL;
562 0 : if (m_bOwnsUserBtn)
563 0 : m_pUserBtn = pUserButtonText ? new PushButton(m_pActionArea) : NULL;
564 :
565 0 : m_pCancelBtn = m_pUIBuilder ? m_pUIBuilder->get<CancelButton>("cancel") : NULL;
566 0 : m_bOwnsCancelBtn = m_pCancelBtn == NULL;
567 0 : if (m_bOwnsCancelBtn)
568 0 : m_pCancelBtn = new CancelButton(m_pActionArea);
569 :
570 0 : m_pHelpBtn = m_pUIBuilder ? m_pUIBuilder->get<HelpButton>("help") : NULL;
571 0 : m_bOwnsHelpBtn = m_pHelpBtn == NULL;
572 0 : if (m_bOwnsHelpBtn)
573 0 : m_pHelpBtn = new HelpButton(m_pActionArea);
574 :
575 0 : m_pResetBtn = m_pUIBuilder ? m_pUIBuilder->get<PushButton>("reset") : NULL;
576 0 : m_bOwnsResetBtn = m_pResetBtn == NULL;
577 0 : if (m_bOwnsResetBtn)
578 0 : m_pResetBtn = new PushButton(m_pActionArea);
579 :
580 0 : m_pBaseFmtBtn = m_pUIBuilder ? m_pUIBuilder->get<PushButton>("standard") : NULL;
581 0 : m_bOwnsBaseFmtBtn = m_pBaseFmtBtn == NULL;
582 0 : if (m_bOwnsBaseFmtBtn)
583 0 : m_pBaseFmtBtn = new PushButton(m_pActionArea);
584 :
585 0 : pImpl = new TabDlg_Impl(m_pTabCtrl->GetPageCount());
586 :
587 0 : m_pOKBtn->SetClickHdl( LINK( this, SfxTabDialog, OkHdl ) );
588 0 : m_pCancelBtn->SetClickHdl( LINK( this, SfxTabDialog, CancelHdl ) );
589 0 : m_pResetBtn->SetClickHdl( LINK( this, SfxTabDialog, ResetHdl ) );
590 0 : m_pResetBtn->SetText( SfxResId( STR_RESET ).toString() );
591 : m_pTabCtrl->SetActivatePageHdl(
592 0 : LINK( this, SfxTabDialog, ActivatePageHdl ) );
593 : m_pTabCtrl->SetDeactivatePageHdl(
594 0 : LINK( this, SfxTabDialog, DeactivatePageHdl ) );
595 0 : m_pActionArea->Show();
596 0 : m_pBox->Show();
597 0 : m_pTabCtrl->Show();
598 0 : m_pOKBtn->Show();
599 0 : m_pCancelBtn->Show();
600 0 : m_pHelpBtn->Show();
601 0 : m_pResetBtn->Show();
602 0 : m_pResetBtn->SetHelpId( HID_TABDLG_RESET_BTN );
603 :
604 0 : if ( m_pUserBtn )
605 : {
606 0 : m_pUserBtn->SetText( *pUserButtonText );
607 0 : m_pUserBtn->SetClickHdl( LINK( this, SfxTabDialog, UserHdl ) );
608 0 : m_pUserBtn->Show();
609 : }
610 :
611 : /* TODO: Check what is up with bFmt/bFmtFlag. Comment below suggests a
612 : different behavior than implemented!! */
613 0 : if ( bFmtFlag )
614 : {
615 0 : m_pBaseFmtBtn->SetText( SfxResId( STR_STANDARD_SHORTCUT ).toString() );
616 0 : m_pBaseFmtBtn->SetClickHdl( LINK( this, SfxTabDialog, BaseFmtHdl ) );
617 0 : m_pBaseFmtBtn->SetHelpId( HID_TABDLG_STANDARD_BTN );
618 :
619 : // bFmt = temporary Flag passed on in the Constructor(),
620 : // if bFmt == 2, then also sal_True,
621 : // additional suppression of the standard button,
622 : // after the Initializing set to sal_True again
623 0 : if ( bFmtFlag != 2 )
624 0 : m_pBaseFmtBtn->Show();
625 : else
626 0 : bFmtFlag = sal_True;
627 : }
628 :
629 0 : if ( pSet )
630 : {
631 0 : pExampleSet = new SfxItemSet( *pSet );
632 0 : pOutSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() );
633 : }
634 :
635 0 : m_pOKBtn->SetAccessibleRelationMemberOf( m_pOKBtn );
636 0 : m_pCancelBtn->SetAccessibleRelationMemberOf( m_pCancelBtn );
637 0 : m_pHelpBtn->SetAccessibleRelationMemberOf( m_pHelpBtn );
638 0 : m_pResetBtn->SetAccessibleRelationMemberOf( m_pResetBtn );
639 0 : }
640 :
641 : // -----------------------------------------------------------------------
642 :
643 0 : void SfxTabDialog::RemoveResetButton()
644 : {
645 0 : m_pResetBtn->Hide();
646 0 : pImpl->bHideResetBtn = sal_True;
647 0 : }
648 :
649 : // -----------------------------------------------------------------------
650 :
651 0 : short SfxTabDialog::Execute()
652 : {
653 0 : if ( !m_pTabCtrl->GetPageCount() )
654 0 : return RET_CANCEL;
655 0 : Start_Impl();
656 0 : return TabDialog::Execute();
657 : }
658 :
659 : // -----------------------------------------------------------------------
660 :
661 0 : void SfxTabDialog::StartExecuteModal( const Link& rEndDialogHdl )
662 : {
663 0 : if ( !m_pTabCtrl->GetPageCount() )
664 0 : return;
665 0 : Start_Impl();
666 0 : TabDialog::StartExecuteModal( rEndDialogHdl );
667 : }
668 :
669 : // -----------------------------------------------------------------------
670 :
671 0 : void SfxTabDialog::Start( sal_Bool bShow )
672 : {
673 0 : pImpl->bModal = sal_False;
674 0 : Start_Impl();
675 :
676 0 : if ( bShow )
677 0 : Show();
678 0 : }
679 :
680 : // -----------------------------------------------------------------------
681 :
682 0 : void SfxTabDialog::SetApplyHandler(const Link& _rHdl)
683 : {
684 : DBG_ASSERT( m_pApplyBtn, "SfxTabDialog::GetApplyHandler: no apply button enabled!" );
685 0 : if ( m_pApplyBtn )
686 0 : m_pApplyBtn->SetClickHdl( _rHdl );
687 0 : }
688 :
689 : // -----------------------------------------------------------------------
690 :
691 0 : void SfxTabDialog::EnableApplyButton(sal_Bool bEnable)
692 : {
693 0 : if ( IsApplyButtonEnabled() == bEnable )
694 : // nothing to do
695 0 : return;
696 :
697 : // create or remove the apply button
698 0 : if ( bEnable )
699 : {
700 0 : m_pApplyBtn = new PushButton(m_pActionArea);
701 : // in the z-order, the apply button should be behind the ok button, thus appearing at the right side of it
702 0 : m_pApplyBtn->SetZOrder(m_pOKBtn, WINDOW_ZORDER_BEHIND);
703 0 : m_pApplyBtn->SetText(SfxResId( STR_APPLY ).toString());
704 0 : m_pApplyBtn->Show();
705 :
706 0 : m_pApplyBtn->SetHelpId( HID_TABDLG_APPLY_BTN );
707 : }
708 : else
709 : {
710 0 : delete m_pApplyBtn;
711 0 : m_pApplyBtn = NULL;
712 : }
713 :
714 : // adjust the layout
715 0 : if (IsReallyShown())
716 0 : AdjustLayout();
717 : }
718 :
719 : // -----------------------------------------------------------------------
720 :
721 0 : sal_Bool SfxTabDialog::IsApplyButtonEnabled() const
722 : {
723 0 : return ( NULL != m_pApplyBtn );
724 : }
725 :
726 : // -----------------------------------------------------------------------
727 :
728 0 : void SfxTabDialog::Start_Impl()
729 : {
730 : //We need to force all tabs to exist to get overall optimal size for dialog
731 0 : for (sal_uInt16 n=0; n < m_pTabCtrl->GetPageCount(); ++n)
732 : {
733 0 : sal_uInt16 nPageId = m_pTabCtrl->GetPageId(n);
734 0 : if (!m_pTabCtrl->GetTabPage(nPageId))
735 : {
736 0 : m_pTabCtrl->SetCurPageId(nPageId);
737 0 : ActivatePageHdl(m_pTabCtrl);
738 : }
739 : }
740 :
741 : DBG_ASSERT( pImpl->pData->Count() == m_pTabCtrl->GetPageCount(), "not all pages registered" );
742 0 : sal_uInt16 nActPage = m_pTabCtrl->GetPageId( 0 );
743 :
744 : // load old settings, when exists
745 0 : SvtViewOptions aDlgOpt( E_TABDIALOG, String::CreateFromInt32( nResId ) );
746 0 : if ( aDlgOpt.Exists() )
747 : {
748 0 : SetWindowState(rtl::OUStringToOString(aDlgOpt.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US));
749 :
750 : // initial TabPage from Program/Help/config
751 0 : nActPage = (sal_uInt16)aDlgOpt.GetPageID();
752 :
753 0 : if ( USHRT_MAX != nAppPageId )
754 0 : nActPage = nAppPageId;
755 : else
756 : {
757 0 : sal_uInt16 nAutoTabPageId = SFX_APP()->Get_Impl()->nAutoTabPageId;
758 0 : if ( nAutoTabPageId )
759 0 : nActPage = nAutoTabPageId;
760 : }
761 :
762 0 : if ( TAB_PAGE_NOTFOUND == m_pTabCtrl->GetPagePos( nActPage ) )
763 0 : nActPage = m_pTabCtrl->GetPageId( 0 );
764 : }
765 0 : else if ( USHRT_MAX != nAppPageId && TAB_PAGE_NOTFOUND != m_pTabCtrl->GetPagePos( nAppPageId ) )
766 0 : nActPage = nAppPageId;
767 :
768 0 : m_pTabCtrl->SetCurPageId( nActPage );
769 0 : ActivatePageHdl( m_pTabCtrl );
770 0 : }
771 :
772 0 : void SfxTabDialog::AddTabPage( sal_uInt16 nId, sal_Bool bItemsOnDemand )
773 : {
774 0 : AddTabPage( nId, 0, 0, bItemsOnDemand );
775 0 : }
776 :
777 0 : void SfxTabDialog::AddTabPage( sal_uInt16 nId, const String &rRiderText, sal_Bool bItemsOnDemand, sal_uInt16 nPos )
778 : {
779 0 : AddTabPage( nId, rRiderText, 0, 0, bItemsOnDemand, nPos );
780 0 : }
781 :
782 : #ifdef SV_HAS_RIDERBITMAPS
783 :
784 : void SfxTabDialog::AddTabPage( sal_uInt16 nId, const Bitmap &rRiderBitmap, sal_Bool bItemsOnDemand, sal_uInt16 nPos )
785 : {
786 : AddTabPage( nId, rRiderBitmap, 0, 0, bItemsOnDemand, nPos );
787 : }
788 :
789 : #endif
790 :
791 : // -----------------------------------------------------------------------
792 :
793 0 : void SfxTabDialog::AddTabPage
794 :
795 : /* [Description]
796 :
797 : Adding a page to the dialogue. Must correspond to a entry in the
798 : TabControl in the resource of the dialogue.
799 : */
800 :
801 : (
802 : sal_uInt16 nId, // Page ID
803 : CreateTabPage pCreateFunc, // Pointer to the Factory Method
804 : GetTabPageRanges pRangesFunc, // Pointer to the Method for quering
805 : // Ranges onDemand
806 : sal_Bool bItemsOnDemand // indicates whether the set of this page is
807 : // requested when created
808 : )
809 : {
810 : pImpl->pData->Append(
811 0 : new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) );
812 0 : }
813 :
814 : // -----------------------------------------------------------------------
815 :
816 0 : void SfxTabDialog::AddTabPage
817 :
818 : /* [Description]
819 :
820 : Add a page to the dialog. The Rider text is passed on, the page has no
821 : counterpart in the TabControl in the resource of the dialogue.
822 : */
823 :
824 : (
825 : sal_uInt16 nId,
826 : const String& rRiderText,
827 : CreateTabPage pCreateFunc,
828 : GetTabPageRanges pRangesFunc,
829 : sal_Bool bItemsOnDemand,
830 : sal_uInt16 nPos
831 : )
832 : {
833 : DBG_ASSERT( TAB_PAGE_NOTFOUND == m_pTabCtrl->GetPagePos( nId ),
834 : "Double Page-Ids in the Tabpage" );
835 0 : m_pTabCtrl->InsertPage( nId, rRiderText, nPos );
836 : pImpl->pData->Append(
837 0 : new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) );
838 0 : }
839 :
840 : // -----------------------------------------------------------------------
841 : #ifdef SV_HAS_RIDERBITMAPS
842 :
843 : void SfxTabDialog::AddTabPage
844 :
845 : /* [Description]
846 :
847 : Add a page to the dialog. The riders bitmap is passed on, the page has no
848 : counterpart in the TabControl in the resource of the dialogue.
849 : */
850 :
851 : (
852 : sal_uInt16 nId,
853 : const Bitmap &rRiderBitmap,
854 : CreateTabPage pCreateFunc,
855 : GetTabPageRanges pRangesFunc,
856 : sal_Bool bItemsOnDemand,
857 : sal_uInt16 nPos
858 : )
859 : {
860 : DBG_ASSERT( TAB_PAGE_NOTFOUND == m_pTabCtrl->GetPagePos( nId ),
861 : "Duplicate Page-Ids in the Tabpage" );
862 : m_pTabCtrl->InsertPage( nId, rRiderBitmap, nPos );
863 : pImpl->pData->Append(
864 : new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) );
865 : }
866 : #endif
867 :
868 : // -----------------------------------------------------------------------
869 :
870 0 : void SfxTabDialog::RemoveTabPage( sal_uInt16 nId )
871 :
872 : /* [Description]
873 :
874 : Delete the TabPage with ID nId
875 : */
876 :
877 : {
878 0 : sal_uInt16 nPos = 0;
879 0 : m_pTabCtrl->RemovePage( nId );
880 0 : Data_Impl* pDataObject = Find( *pImpl->pData, nId, &nPos );
881 :
882 0 : if ( pDataObject )
883 : {
884 0 : if ( pDataObject->pTabPage )
885 : {
886 0 : pDataObject->pTabPage->FillUserData();
887 0 : String aPageData( pDataObject->pTabPage->GetUserData() );
888 0 : if ( aPageData.Len() )
889 : {
890 : // save settings of this page (user data)
891 0 : SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) );
892 0 : aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aPageData ) ) );
893 : }
894 :
895 0 : if ( pDataObject->bOnDemand )
896 0 : delete (SfxItemSet*)&pDataObject->pTabPage->GetItemSet();
897 0 : delete pDataObject->pTabPage;
898 : }
899 :
900 0 : delete pDataObject;
901 0 : pImpl->pData->Remove( nPos );
902 : }
903 : else
904 : {
905 : SAL_INFO( "sfx2.dialog", "TabPage-Id not known" );
906 : }
907 0 : }
908 :
909 : // -----------------------------------------------------------------------
910 :
911 0 : void SfxTabDialog::PageCreated
912 :
913 : /* [Description]
914 :
915 : Default implemetation of the virtual method. This is called immediately
916 : after creating a page. Here the dialogue can call the TabPage Method
917 : directly.
918 : */
919 :
920 : (
921 : sal_uInt16, // Id of the created page
922 : SfxTabPage& // Reference to the created page
923 : )
924 : {
925 0 : }
926 :
927 : // -----------------------------------------------------------------------
928 :
929 0 : SfxItemSet* SfxTabDialog::GetInputSetImpl()
930 :
931 : /* [Description]
932 :
933 : Derived classes may create new storage for the InputSet. This has to be
934 : released in the Destructor. To do this, this method must be called.
935 : */
936 :
937 : {
938 0 : return (SfxItemSet*)pSet;
939 : }
940 :
941 : // -----------------------------------------------------------------------
942 :
943 0 : SfxTabPage* SfxTabDialog::GetTabPage( sal_uInt16 nPageId ) const
944 :
945 : /* [Description]
946 :
947 : Return TabPage with the specified Id.
948 : */
949 :
950 : {
951 0 : sal_uInt16 nPos = 0;
952 0 : Data_Impl* pDataObject = Find( *pImpl->pData, nPageId, &nPos );
953 :
954 0 : if ( pDataObject )
955 0 : return pDataObject->pTabPage;
956 0 : return NULL;
957 : }
958 :
959 0 : void SfxTabDialog::SavePosAndId()
960 : {
961 : // save settings (screen position and current page)
962 0 : SvtViewOptions aDlgOpt( E_TABDIALOG, String::CreateFromInt32( nResId ) );
963 0 : aDlgOpt.SetWindowState(OStringToOUString(GetWindowState(WINDOWSTATE_MASK_POS),RTL_TEXTENCODING_ASCII_US));
964 0 : aDlgOpt.SetPageID( m_pTabCtrl->GetCurPageId() );
965 0 : }
966 :
967 : // -----------------------------------------------------------------------
968 :
969 0 : short SfxTabDialog::Ok()
970 :
971 : /* [Description]
972 :
973 : Ok handler for the Dialogue.
974 :
975 : Dialog's current location and current page are saved for the next time
976 : the dialog is shown.
977 :
978 : The OutputSet is created and for each page this or the special OutputSet
979 : is set by calling the method <SfxTabPage::FillItemSet(SfxItemSet &)>, to
980 : insert the entered data by the user into the set.
981 :
982 : [Return value]
983 :
984 : RET_OK: if at least one page has returned from FillItemSet,
985 : otherwise RET_CANCEL.
986 : */
987 :
988 : {
989 0 : SavePosAndId(); //See fdo#38828 "Apply" resetting window position
990 :
991 0 : pImpl->bInOK = sal_True;
992 :
993 0 : if ( !pOutSet )
994 : {
995 0 : if ( !pExampleSet && pSet )
996 0 : pOutSet = pSet->Clone( sal_False ); // without Items
997 0 : else if ( pExampleSet )
998 0 : pOutSet = new SfxItemSet( *pExampleSet );
999 : }
1000 0 : sal_Bool bModified = sal_False;
1001 :
1002 0 : const sal_uInt16 nCount = pImpl->pData->Count();
1003 :
1004 0 : for ( sal_uInt16 i = 0; i < nCount; ++i )
1005 : {
1006 0 : Data_Impl* pDataObject = pImpl->pData->GetObject(i);
1007 0 : SfxTabPage* pTabPage = pDataObject->pTabPage;
1008 :
1009 0 : if ( pTabPage )
1010 : {
1011 0 : if ( pDataObject->bOnDemand )
1012 : {
1013 0 : SfxItemSet& rSet = (SfxItemSet&)pTabPage->GetItemSet();
1014 0 : rSet.ClearItem();
1015 0 : bModified |= pTabPage->FillItemSet( rSet );
1016 : }
1017 0 : else if ( pSet && !pTabPage->HasExchangeSupport() )
1018 : {
1019 0 : SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() );
1020 :
1021 0 : if ( pTabPage->FillItemSet( aTmp ) )
1022 : {
1023 0 : bModified |= sal_True;
1024 0 : pExampleSet->Put( aTmp );
1025 0 : pOutSet->Put( aTmp );
1026 0 : }
1027 : }
1028 : }
1029 : }
1030 :
1031 0 : if ( pImpl->bModified || ( pOutSet && pOutSet->Count() > 0 ) )
1032 0 : bModified |= sal_True;
1033 :
1034 0 : if ( bFmt == 2 )
1035 0 : bModified |= sal_True;
1036 0 : return bModified ? RET_OK : RET_CANCEL;
1037 : }
1038 :
1039 : // -----------------------------------------------------------------------
1040 :
1041 0 : IMPL_LINK_NOARG(SfxTabDialog, CancelHdl)
1042 : {
1043 0 : EndDialog( RET_USER_CANCEL );
1044 0 : return 0;
1045 : }
1046 :
1047 : // -----------------------------------------------------------------------
1048 :
1049 0 : SfxItemSet* SfxTabDialog::CreateInputItemSet( sal_uInt16 )
1050 :
1051 : /* [Description]
1052 :
1053 : Default implemetation of the virtual Method.
1054 : This is called when pages create their sets onDenamd.
1055 : */
1056 :
1057 : {
1058 : SAL_WARN( "sfx2.dialog", "CreateInputItemSet not implemented" );
1059 0 : return new SfxAllItemSet( SFX_APP()->GetPool() );
1060 : }
1061 :
1062 : // -----------------------------------------------------------------------
1063 :
1064 0 : const SfxItemSet* SfxTabDialog::GetRefreshedSet()
1065 :
1066 : /* [Description]
1067 :
1068 : Default implemetation of the virtual Method.
1069 : This is called, when <SfxTabPage::DeactivatePage(SfxItemSet *)>
1070 : returns <SfxTabPage::REFRESH_SET>.
1071 : */
1072 :
1073 : {
1074 : SAL_INFO ( "sfx2.dialog", "GetRefreshedSet not implemented" );
1075 0 : return 0;
1076 : }
1077 :
1078 : // -----------------------------------------------------------------------
1079 :
1080 0 : IMPL_LINK_NOARG(SfxTabDialog, OkHdl)
1081 :
1082 : /* [Description]
1083 :
1084 : Handler of the Ok-Buttons
1085 : This calls the current page <SfxTabPage::DeactivatePage(SfxItemSet *)>.
1086 : Returns <SfxTabPage::LEAVE_PAGE>, <SfxTabDialog::Ok()> is called
1087 : and the Dialog is ended.
1088 : */
1089 :
1090 : {
1091 0 : pImpl->bInOK = sal_True;
1092 :
1093 0 : if ( OK_Impl() )
1094 : {
1095 0 : if ( pImpl->bModal )
1096 0 : EndDialog( Ok() );
1097 : else
1098 : {
1099 0 : Ok();
1100 0 : Close();
1101 : }
1102 : }
1103 0 : return 0;
1104 : }
1105 :
1106 : // -----------------------------------------------------------------------
1107 :
1108 0 : bool SfxTabDialog::PrepareLeaveCurrentPage()
1109 : {
1110 0 : sal_uInt16 const nId = m_pTabCtrl->GetCurPageId();
1111 0 : SfxTabPage* pPage = dynamic_cast<SfxTabPage*> (m_pTabCtrl->GetTabPage( nId ));
1112 0 : bool bEnd = !pPage;
1113 :
1114 0 : if ( pPage )
1115 : {
1116 0 : int nRet = SfxTabPage::LEAVE_PAGE;
1117 0 : if ( pSet )
1118 : {
1119 0 : SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() );
1120 :
1121 0 : if ( pPage->HasExchangeSupport() )
1122 0 : nRet = pPage->DeactivatePage( &aTmp );
1123 : else
1124 0 : nRet = pPage->DeactivatePage( NULL );
1125 :
1126 0 : if ( ( SfxTabPage::LEAVE_PAGE & nRet ) == SfxTabPage::LEAVE_PAGE
1127 0 : && aTmp.Count() )
1128 : {
1129 0 : pExampleSet->Put( aTmp );
1130 0 : pOutSet->Put( aTmp );
1131 0 : }
1132 : }
1133 : else
1134 0 : nRet = pPage->DeactivatePage( NULL );
1135 0 : bEnd = nRet;
1136 : }
1137 :
1138 0 : return bEnd;
1139 : }
1140 :
1141 :
1142 : // -----------------------------------------------------------------------
1143 :
1144 0 : IMPL_LINK_NOARG(SfxTabDialog, UserHdl)
1145 :
1146 : /* [Description]
1147 :
1148 : Handler of the User-Buttons
1149 : This calls the current page <SfxTabPage::DeactivatePage(SfxItemSet *)>.
1150 : returns this <SfxTabPage::LEAVE_PAGE> and <SfxTabDialog::Ok()> is called.
1151 : Then the Dialog is ended with the Return value <SfxTabDialog::Ok()>
1152 : */
1153 :
1154 : {
1155 0 : if ( PrepareLeaveCurrentPage () )
1156 : {
1157 0 : short nRet = Ok();
1158 :
1159 0 : if ( RET_OK == nRet )
1160 0 : nRet = RET_USER;
1161 : else
1162 0 : nRet = RET_USER_CANCEL;
1163 0 : EndDialog( nRet );
1164 : }
1165 0 : return 0;
1166 : }
1167 :
1168 : // -----------------------------------------------------------------------
1169 :
1170 0 : IMPL_LINK_NOARG(SfxTabDialog, ResetHdl)
1171 :
1172 : /* [Description]
1173 :
1174 : Handler behind the reset button.
1175 : The Current Page is new initialized with their initial data, all the
1176 : settings that the user has made on this page are repealed.
1177 : */
1178 :
1179 : {
1180 0 : const sal_uInt16 nId = m_pTabCtrl->GetCurPageId();
1181 0 : Data_Impl* pDataObject = Find( *pImpl->pData, nId );
1182 : DBG_ASSERT( pDataObject, "Id not known" );
1183 :
1184 0 : if ( pDataObject->bOnDemand )
1185 : {
1186 : // CSet on AIS has problems here, thus separated
1187 0 : const SfxItemSet* pItemSet = &pDataObject->pTabPage->GetItemSet();
1188 0 : pDataObject->pTabPage->Reset( *(SfxItemSet*)pItemSet );
1189 : }
1190 : else
1191 0 : pDataObject->pTabPage->Reset( *pSet );
1192 0 : return 0;
1193 : }
1194 :
1195 : // -----------------------------------------------------------------------
1196 :
1197 0 : IMPL_LINK_NOARG(SfxTabDialog, BaseFmtHdl)
1198 :
1199 : /* [Description]
1200 :
1201 : Handler behind the Standard-Button.
1202 : This button is available when editing style sheets. All the set attributes
1203 : in the edited stylesheet are deleted.
1204 : */
1205 :
1206 : {
1207 0 : const sal_uInt16 nId = m_pTabCtrl->GetCurPageId();
1208 0 : Data_Impl* pDataObject = Find( *pImpl->pData, nId );
1209 : DBG_ASSERT( pDataObject, "Id not known" );
1210 0 : bFmt = 2;
1211 :
1212 0 : if ( pDataObject->fnGetRanges )
1213 : {
1214 0 : if ( !pExampleSet )
1215 0 : pExampleSet = new SfxItemSet( *pSet );
1216 :
1217 0 : const SfxItemPool* pPool = pSet->GetPool();
1218 0 : const sal_uInt16* pTmpRanges = (pDataObject->fnGetRanges)();
1219 0 : SfxItemSet aTmpSet( *pExampleSet );
1220 :
1221 0 : while ( *pTmpRanges )
1222 : {
1223 0 : const sal_uInt16* pU = pTmpRanges + 1;
1224 :
1225 0 : if ( *pTmpRanges == *pU )
1226 : {
1227 : // Range which two identical values -> only set one Item
1228 0 : sal_uInt16 nWh = pPool->GetWhich( *pTmpRanges );
1229 0 : pExampleSet->ClearItem( nWh );
1230 0 : aTmpSet.ClearItem( nWh );
1231 : // At the Outset of InvalidateItem,
1232 : // so that the change takes effect
1233 0 : pOutSet->InvalidateItem( nWh );
1234 : }
1235 : else
1236 : {
1237 : // Correct Range with multiple values
1238 0 : sal_uInt16 nTmp = *pTmpRanges, nTmpEnd = *pU;
1239 : DBG_ASSERT( nTmp <= nTmpEnd, "Range is sorted the wrong way" );
1240 :
1241 0 : if ( nTmp > nTmpEnd )
1242 : {
1243 : // If really sorted wrongly, then set new
1244 0 : sal_uInt16 nTmp1 = nTmp;
1245 0 : nTmp = nTmpEnd;
1246 0 : nTmpEnd = nTmp1;
1247 : }
1248 :
1249 0 : while ( nTmp <= nTmpEnd )
1250 : {
1251 : // Iterate over the Range and set the Items
1252 0 : sal_uInt16 nWh = pPool->GetWhich( nTmp );
1253 0 : pExampleSet->ClearItem( nWh );
1254 0 : aTmpSet.ClearItem( nWh );
1255 : // At the Outset of InvalidateItem,
1256 : // so that the change takes effect
1257 0 : pOutSet->InvalidateItem( nWh );
1258 0 : nTmp++;
1259 : }
1260 : }
1261 : // Go to the next pair
1262 0 : pTmpRanges += 2;
1263 : }
1264 : // Set all Items as new -> the call the current Page Reset()
1265 : DBG_ASSERT( pDataObject->pTabPage, "the Page is gone" );
1266 0 : pDataObject->pTabPage->Reset( aTmpSet );
1267 0 : pDataObject->pTabPage->pImpl->mbStandard = sal_True;
1268 : }
1269 0 : return 1;
1270 : }
1271 :
1272 : // -----------------------------------------------------------------------
1273 :
1274 0 : IMPL_LINK( SfxTabDialog, ActivatePageHdl, TabControl *, pTabCtrl )
1275 :
1276 : /* [Description]
1277 :
1278 : Handler that is called by StarView for switching to a different page.
1279 : If the page not exist yet then it is created and the virtual Method
1280 : <SfxTabDialog::PageCreated( sal_uInt16, SfxTabPage &)> is called. If the page
1281 : exist, then the if possible the <SfxTabPage::Reset(const SfxItemSet &)> or
1282 : <SfxTabPage::ActivatePage(const SfxItemSet &)> is called.
1283 : */
1284 :
1285 : {
1286 0 : sal_uInt16 const nId = pTabCtrl->GetCurPageId();
1287 :
1288 : DBG_ASSERT( pImpl->pData->Count(), "no Pages registered" );
1289 0 : SFX_APP();
1290 :
1291 : // Tab Page schon da?
1292 0 : SfxTabPage* pTabPage = dynamic_cast<SfxTabPage*> (pTabCtrl->GetTabPage( nId ));
1293 0 : Data_Impl* pDataObject = Find( *pImpl->pData, nId );
1294 : DBG_ASSERT( pDataObject, "Id not known" );
1295 :
1296 : // Create TabPage if possible:
1297 0 : if ( !pTabPage )
1298 : {
1299 0 : const SfxItemSet* pTmpSet = 0;
1300 :
1301 0 : if ( pSet )
1302 : {
1303 0 : if ( bItemsReset && pSet->GetParent() )
1304 0 : pTmpSet = pSet->GetParent();
1305 : else
1306 0 : pTmpSet = pSet;
1307 : }
1308 :
1309 0 : if ( pTmpSet && !pDataObject->bOnDemand )
1310 0 : pTabPage = (pDataObject->fnCreatePage)( pTabCtrl, *pTmpSet );
1311 : else
1312 : pTabPage = (pDataObject->fnCreatePage)
1313 0 : ( pTabCtrl, *CreateInputItemSet( nId ) );
1314 : DBG_ASSERT( NULL == pDataObject->pTabPage, "create TabPage more than once" );
1315 0 : pDataObject->pTabPage = pTabPage;
1316 :
1317 0 : pDataObject->pTabPage->SetTabDialog( this );
1318 0 : SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) );
1319 0 : String sUserData;
1320 0 : Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME );
1321 0 : OUString aTemp;
1322 0 : if ( aUserItem >>= aTemp )
1323 0 : sUserData = String( aTemp );
1324 0 : pTabPage->SetUserData( sUserData );
1325 0 : Size aSiz = pTabPage->GetSizePixel();
1326 :
1327 0 : Size aCtrlSiz = pTabCtrl->GetTabPageSizePixel();
1328 : // Only set Size on TabControl when < as TabPage
1329 0 : if ( aCtrlSiz.Width() < aSiz.Width() ||
1330 0 : aCtrlSiz.Height() < aSiz.Height() )
1331 : {
1332 0 : pTabCtrl->SetTabPageSizePixel( aSiz );
1333 : }
1334 :
1335 0 : PageCreated( nId, *pTabPage );
1336 :
1337 0 : if ( pDataObject->bOnDemand )
1338 0 : pTabPage->Reset( (SfxItemSet &)pTabPage->GetItemSet() );
1339 : else
1340 0 : pTabPage->Reset( *pSet );
1341 :
1342 0 : pTabCtrl->SetTabPage( nId, pTabPage );
1343 : }
1344 0 : else if ( pDataObject->bRefresh )
1345 0 : pTabPage->Reset( *pSet );
1346 0 : pDataObject->bRefresh = sal_False;
1347 :
1348 0 : if ( pExampleSet )
1349 0 : pTabPage->ActivatePage( *pExampleSet );
1350 0 : sal_Bool bReadOnly = pTabPage->IsReadOnly();
1351 0 : ( bReadOnly || pImpl->bHideResetBtn ) ? m_pResetBtn->Hide() : m_pResetBtn->Show();
1352 0 : return 0;
1353 : }
1354 :
1355 : // -----------------------------------------------------------------------
1356 :
1357 0 : IMPL_LINK( SfxTabDialog, DeactivatePageHdl, TabControl *, pTabCtrl )
1358 :
1359 : /* [Description]
1360 :
1361 : Handler that is called by StarView before leaving a page.
1362 :
1363 : [Cross-reference]
1364 :
1365 : <SfxTabPage::DeactivatePage(SfxItemSet *)>
1366 : */
1367 :
1368 : {
1369 0 : sal_uInt16 nId = pTabCtrl->GetCurPageId();
1370 0 : SFX_APP();
1371 0 : SfxTabPage *pPage = dynamic_cast<SfxTabPage*> (pTabCtrl->GetTabPage( nId ));
1372 : DBG_ASSERT( pPage, "no active Page" );
1373 : #ifdef DBG_UTIL
1374 : Data_Impl* pDataObject = Find( *pImpl->pData, pTabCtrl->GetCurPageId() );
1375 : DBG_ASSERT( pDataObject, "no Data structur for current page" );
1376 : if ( pPage->HasExchangeSupport() && pDataObject->bOnDemand )
1377 : {
1378 : DBG_WARNING( "Data exchange in ItemsOnDemand is not desired!" );
1379 : }
1380 : #endif
1381 :
1382 0 : int nRet = SfxTabPage::LEAVE_PAGE;
1383 :
1384 0 : if ( !pExampleSet && pPage->HasExchangeSupport() && pSet )
1385 0 : pExampleSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() );
1386 :
1387 0 : if ( pSet )
1388 : {
1389 0 : SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() );
1390 :
1391 0 : if ( pPage->HasExchangeSupport() )
1392 0 : nRet = pPage->DeactivatePage( &aTmp );
1393 : else
1394 0 : nRet = pPage->DeactivatePage( NULL );
1395 0 : if ( ( SfxTabPage::LEAVE_PAGE & nRet ) == SfxTabPage::LEAVE_PAGE &&
1396 0 : aTmp.Count() )
1397 : {
1398 0 : pExampleSet->Put( aTmp );
1399 0 : pOutSet->Put( aTmp );
1400 0 : }
1401 : }
1402 : else
1403 : {
1404 0 : if ( pPage->HasExchangeSupport() ) //!!!
1405 : {
1406 0 : if ( !pExampleSet )
1407 : {
1408 0 : SfxItemPool* pPool = pPage->GetItemSet().GetPool();
1409 : pExampleSet =
1410 0 : new SfxItemSet( *pPool, GetInputRanges( *pPool ) );
1411 : }
1412 0 : nRet = pPage->DeactivatePage( pExampleSet );
1413 : }
1414 : else
1415 0 : nRet = pPage->DeactivatePage( NULL );
1416 : }
1417 :
1418 0 : if ( nRet & SfxTabPage::REFRESH_SET )
1419 : {
1420 0 : pSet = GetRefreshedSet();
1421 : DBG_ASSERT( pSet, "GetRefreshedSet() returns NULL" );
1422 : // Flag all Pages as to be initialized as new
1423 0 : const sal_uInt16 nCount = pImpl->pData->Count();
1424 :
1425 0 : for ( sal_uInt16 i = 0; i < nCount; ++i )
1426 : {
1427 0 : Data_Impl* pObj = (*pImpl->pData)[i];
1428 :
1429 0 : if ( pObj->pTabPage != pPage ) // Do not refresh own Page anymore
1430 0 : pObj->bRefresh = sal_True;
1431 : else
1432 0 : pObj->bRefresh = sal_False;
1433 : }
1434 : }
1435 0 : if ( nRet & SfxTabPage::LEAVE_PAGE )
1436 0 : return sal_True;
1437 : else
1438 0 : return sal_False;
1439 : }
1440 :
1441 : // -----------------------------------------------------------------------
1442 :
1443 0 : void SfxTabDialog::ShowPage( sal_uInt16 nId )
1444 :
1445 : /* [Description]
1446 :
1447 : The TabPage is activated with the specified Id.
1448 : */
1449 :
1450 : {
1451 0 : m_pTabCtrl->SetCurPageId( nId );
1452 0 : ActivatePageHdl( m_pTabCtrl );
1453 0 : }
1454 :
1455 : // -----------------------------------------------------------------------
1456 :
1457 0 : const sal_uInt16* SfxTabDialog::GetInputRanges( const SfxItemPool& rPool )
1458 :
1459 : /* [Description]
1460 :
1461 : Makes the set over the range of all pages of the dialogue. Pages have the
1462 : static method for querying their range in AddTabPage, ie deliver their
1463 : sets onDemand.
1464 :
1465 : [Return value]
1466 :
1467 : Pointer to a null-terminated array of sal_uInt16. This array belongs to the
1468 : dialog and is deleted when the dialogue is destroy.
1469 :
1470 : [Cross-reference]
1471 :
1472 : <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, sal_Bool)>
1473 : <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)>
1474 : <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)>
1475 : */
1476 :
1477 : {
1478 0 : if ( pSet )
1479 : {
1480 : SAL_WARN( "sfx2.dialog", "Set already exists!" );
1481 0 : return pSet->GetRanges();
1482 : }
1483 :
1484 0 : if ( pRanges )
1485 0 : return pRanges;
1486 0 : std::vector<sal_uInt16> aUS;
1487 0 : sal_uInt16 nCount = pImpl->pData->Count();
1488 :
1489 : sal_uInt16 i;
1490 0 : for ( i = 0; i < nCount; ++i )
1491 : {
1492 0 : Data_Impl* pDataObject = pImpl->pData->GetObject(i);
1493 :
1494 0 : if ( pDataObject->fnGetRanges )
1495 : {
1496 0 : const sal_uInt16* pTmpRanges = (pDataObject->fnGetRanges)();
1497 0 : const sal_uInt16* pIter = pTmpRanges;
1498 :
1499 : sal_uInt16 nLen;
1500 0 : for( nLen = 0; *pIter; ++nLen, ++pIter )
1501 : ;
1502 0 : aUS.insert( aUS.end(), pTmpRanges, pTmpRanges + nLen );
1503 : }
1504 : }
1505 :
1506 : //! Remove duplicated Ids?
1507 : {
1508 0 : nCount = aUS.size();
1509 :
1510 0 : for ( i = 0; i < nCount; ++i )
1511 0 : aUS[i] = rPool.GetWhich( aUS[i] );
1512 : }
1513 :
1514 : // sort
1515 0 : if ( aUS.size() > 1 )
1516 : {
1517 0 : std::sort( aUS.begin(), aUS.end() );
1518 : }
1519 :
1520 0 : pRanges = new sal_uInt16[aUS.size() + 1];
1521 0 : std::copy( aUS.begin(), aUS.end(), pRanges );
1522 0 : pRanges[aUS.size()] = 0;
1523 0 : return pRanges;
1524 : }
1525 :
1526 : // -----------------------------------------------------------------------
1527 :
1528 0 : void SfxTabDialog::SetInputSet( const SfxItemSet* pInSet )
1529 :
1530 : /* [Description]
1531 :
1532 : With this method the Input-Set can subsequently be set initally or re-set.
1533 : */
1534 :
1535 : {
1536 0 : bool bSet = ( pSet != NULL );
1537 :
1538 0 : pSet = pInSet;
1539 :
1540 0 : if ( !bSet && !pExampleSet && !pOutSet )
1541 : {
1542 0 : pExampleSet = new SfxItemSet( *pSet );
1543 0 : pOutSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() );
1544 : }
1545 0 : }
1546 :
1547 0 : long SfxTabDialog::Notify( NotifyEvent& rNEvt )
1548 : {
1549 0 : if ( rNEvt.GetType() == EVENT_GETFOCUS )
1550 : {
1551 0 : SfxViewFrame* pViewFrame = GetViewFrame() ? GetViewFrame() : SfxViewFrame::Current();
1552 0 : if ( pViewFrame )
1553 : {
1554 0 : Window* pWindow = rNEvt.GetWindow();
1555 0 : rtl::OString sHelpId;
1556 0 : while ( sHelpId.isEmpty() && pWindow )
1557 : {
1558 0 : sHelpId = pWindow->GetHelpId();
1559 0 : pWindow = pWindow->GetParent();
1560 : }
1561 :
1562 0 : if ( !sHelpId.isEmpty() )
1563 0 : SfxHelp::OpenHelpAgent( &pViewFrame->GetFrame(), sHelpId );
1564 : }
1565 : }
1566 :
1567 0 : return TabDialog::Notify( rNEvt );
1568 234 : }
1569 :
1570 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|