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