xref: /AOO41X/main/sfx2/source/dialog/tabdlg.cxx (revision 4d7c9de063a797b8b4f3d45e3561e82ad1f8ef1f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sfx2.hxx"
26 
27 #include <limits.h>
28 #include <stdlib.h>
29 #include <vcl/msgbox.hxx>
30 #include <unotools/viewoptions.hxx>
31 
32 #define _SVSTDARR_USHORTS
33 #include <svl/svstdarr.hxx>
34 
35 #include "appdata.hxx"
36 #include "sfxtypes.hxx"
37 #include <sfx2/minarray.hxx>
38 #include <sfx2/tabdlg.hxx>
39 #include <sfx2/viewfrm.hxx>
40 #include <sfx2/app.hxx>
41 #include "sfx2/sfxresid.hxx"
42 #include "sfx2/sfxhelp.hxx"
43 #include <sfx2/ctrlitem.hxx>
44 #include <sfx2/bindings.hxx>
45 #include <sfx2/sfxdlg.hxx>
46 #include <sfx2/itemconnect.hxx>
47 
48 #include "dialog.hrc"
49 #include "helpid.hrc"
50 
51 #if ENABLE_LAYOUT_SFX_TABDIALOG
52 #undef TabPage
53 #undef SfxTabPage
54 #define SfxTabPage ::SfxTabPage
55 #undef SfxTabDialog
56 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */
57 
58 using namespace ::com::sun::star::uno;
59 using namespace ::rtl;
60 
61 #define USERITEM_NAME           OUString::createFromAscii( "UserItem" )
62 
63 TYPEINIT1(LAYOUT_NS_SFX_TABDIALOG SfxTabDialogItem,SfxSetItem);
64 
65 struct TabPageImpl
66 {
67     sal_Bool                        mbStandard;
68     sfx::ItemConnectionArray    maItemConn;
69     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > mxFrame;
70 
TabPageImplTabPageImpl71     TabPageImpl() : mbStandard( sal_False ) {}
72 };
73 
74 NAMESPACE_LAYOUT_SFX_TABDIALOG
75 
76 struct Data_Impl
77 {
78     sal_uInt16 nId;                  // Die ID
79     CreateTabPage fnCreatePage;  // Pointer auf die Factory
80     GetTabPageRanges fnGetRanges;// Pointer auf die Ranges-Funktion
81     SfxTabPage* pTabPage;        // die TabPage selber
82     sal_Bool bOnDemand;              // Flag: ItemSet onDemand
83     sal_Bool bRefresh;               // Flag: Seite mu\s neu initialisiert werden
84 
85     // Konstruktor
Data_ImplData_Impl86     Data_Impl( sal_uInt16 Id, CreateTabPage fnPage,
87                GetTabPageRanges fnRanges, sal_Bool bDemand ) :
88 
89         nId         ( Id ),
90         fnCreatePage( fnPage ),
91         fnGetRanges ( fnRanges ),
92         pTabPage    ( 0 ),
93         bOnDemand   ( bDemand ),
94         bRefresh    ( sal_False )
95     {
96         if ( !fnCreatePage  )
97         {
98             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
99             if ( pFact )
100             {
101                 fnCreatePage = pFact->GetTabPageCreatorFunc( nId );
102                 fnGetRanges = pFact->GetTabPageRangesFunc( nId );
103             }
104         }
105     }
106 };
107 
SfxTabDialogItem(const SfxTabDialogItem & rAttr,SfxItemPool * pItemPool)108 SfxTabDialogItem::SfxTabDialogItem( const SfxTabDialogItem& rAttr, SfxItemPool* pItemPool )
109     : SfxSetItem( rAttr, pItemPool )
110 {
111 }
112 
SfxTabDialogItem(sal_uInt16 nId,const SfxItemSet & rItemSet)113 SfxTabDialogItem::SfxTabDialogItem( sal_uInt16 nId, const SfxItemSet& rItemSet )
114     : SfxSetItem( nId, rItemSet )
115 {
116 }
117 
Clone(SfxItemPool * pToPool) const118 SfxPoolItem* __EXPORT SfxTabDialogItem::Clone(SfxItemPool* pToPool) const
119 {
120     return new SfxTabDialogItem( *this, pToPool );
121 }
122 
Create(SvStream &,sal_uInt16) const123 SfxPoolItem* __EXPORT SfxTabDialogItem::Create(SvStream& /*rStream*/, sal_uInt16 /*nVersion*/) const
124 {
125     DBG_ERROR( "Use it only in UI!" );
126     return NULL;
127 }
128 
129 class SfxTabDialogController : public SfxControllerItem
130 {
131     SfxTabDialog*   pDialog;
132     const SfxItemSet*     pSet;
133 public:
SfxTabDialogController(sal_uInt16 nSlotId,SfxBindings & rBindings,SfxTabDialog * pDlg)134                     SfxTabDialogController( sal_uInt16 nSlotId, SfxBindings& rBindings, SfxTabDialog* pDlg )
135                         : SfxControllerItem( nSlotId, rBindings )
136                         , pDialog( pDlg )
137                         , pSet( NULL )
138                     {}
139 
140                     ~SfxTabDialogController();
141 
142     DECL_LINK(      Execute_Impl, void* );
143     virtual void    StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState );
144 };
145 
~SfxTabDialogController()146 SfxTabDialogController::~SfxTabDialogController()
147 {
148     delete pSet;
149 }
150 
IMPL_LINK(SfxTabDialogController,Execute_Impl,void *,pVoid)151 IMPL_LINK( SfxTabDialogController, Execute_Impl, void*, pVoid )
152 {
153     (void)pVoid; //unused
154     if ( pDialog->OK_Impl() && pDialog->Ok() )
155     {
156         const SfxPoolItem* aItems[2];
157         SfxTabDialogItem aItem( GetId(), *pDialog->GetOutputItemSet() );
158         aItems[0] = &aItem;
159         aItems[1] = NULL;
160         GetBindings().Execute( GetId(), aItems );
161     }
162 
163     return 0;
164 }
165 
StateChanged(sal_uInt16,SfxItemState,const SfxPoolItem * pState)166 void SfxTabDialogController::StateChanged( sal_uInt16 /*nSID*/, SfxItemState /*eState*/, const SfxPoolItem* pState )
167 {
168     const SfxSetItem* pSetItem = PTR_CAST( SfxSetItem, pState );
169     if ( pSetItem )
170     {
171         pSet = pDialog->pSet = pSetItem->GetItemSet().Clone();
172         sal_Bool bDialogStarted = sal_False;
173         for ( sal_uInt16 n=0; n<pDialog->aTabCtrl.GetPageCount(); n++ )
174         {
175             sal_uInt16 nPageId = pDialog->aTabCtrl.GetPageId( n );
176             SfxTabPage* pTabPage = dynamic_cast<SfxTabPage*> (pDialog->aTabCtrl.GetTabPage( nPageId ));
177             if ( pTabPage )
178             {
179                 pTabPage->Reset( pSetItem->GetItemSet() );
180                 bDialogStarted = sal_True;
181             }
182         }
183 
184         if ( bDialogStarted )
185             pDialog->Show();
186     }
187     else
188         pDialog->Hide();
189 }
190 
191 DECL_PTRARRAY(SfxTabDlgData_Impl, Data_Impl *, 4,4)
192 
193 struct TabDlg_Impl
194 {
195     sal_Bool                bModified       : 1,
196                         bModal          : 1,
197                         bInOK           : 1,
198                         bHideResetBtn   : 1;
199     SfxTabDlgData_Impl* pData;
200 
201     PushButton*         pApplyButton;
202     SfxTabDialogController* pController;
203 
TabDlg_ImplTabDlg_Impl204     TabDlg_Impl( sal_uInt8 nCnt ) :
205 
206         bModified       ( sal_False ),
207         bModal          ( sal_True ),
208         bInOK           ( sal_False ),
209         bHideResetBtn   ( sal_False ),
210         pData           ( new SfxTabDlgData_Impl( nCnt ) ),
211         pApplyButton    ( NULL ),
212         pController     ( NULL )
213     {}
214 };
215 
216 Data_Impl* Find( SfxTabDlgData_Impl& rArr, sal_uInt16 nId, sal_uInt16* pPos = 0 );
217 
Find(SfxTabDlgData_Impl & rArr,sal_uInt16 nId,sal_uInt16 * pPos)218 Data_Impl* Find( SfxTabDlgData_Impl& rArr, sal_uInt16 nId, sal_uInt16* pPos )
219 {
220     const sal_uInt16 nCount = rArr.Count();
221 
222     for ( sal_uInt16 i = 0; i < nCount; ++i )
223     {
224         Data_Impl* pObj = rArr[i];
225 
226         if ( pObj->nId == nId )
227         {
228             if ( pPos )
229                 *pPos = i;
230             return pObj;
231         }
232     }
233     return 0;
234 }
235 
236 #if !ENABLE_LAYOUT_SFX_TABDIALOG
237 
SetFrame(const::com::sun::star::uno::Reference<::com::sun::star::frame::XFrame> & xFrame)238 void SfxTabPage::SetFrame(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame)
239 {
240     if (pImpl)
241         pImpl->mxFrame = xFrame;
242 }
243 
GetFrame()244 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SfxTabPage::GetFrame()
245 {
246     if (pImpl)
247         return pImpl->mxFrame;
248     return ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >();
249 }
250 
SfxTabPage(Window * pParent,const ResId & rResId,const SfxItemSet & rAttrSet)251 SfxTabPage::SfxTabPage( Window *pParent,
252                         const ResId &rResId, const SfxItemSet &rAttrSet ) :
253 
254 /*  [Beschreibung]
255 
256     Konstruktor
257 */
258 
259     TabPage( pParent, rResId ),
260 
261     pSet                ( &rAttrSet ),
262     bHasExchangeSupport ( sal_False ),
263     pTabDlg             ( NULL ),
264     pImpl               ( new TabPageImpl )
265 
266 {
267 }
268 // -----------------------------------------------------------------------
SfxTabPage(Window * pParent,WinBits nStyle,const SfxItemSet & rAttrSet)269 SfxTabPage:: SfxTabPage( Window *pParent, WinBits nStyle, const SfxItemSet &rAttrSet ) :
270     TabPage(pParent, nStyle),
271     pSet                ( &rAttrSet ),
272     bHasExchangeSupport ( sal_False ),
273     pTabDlg             ( NULL ),
274     pImpl               ( new TabPageImpl )
275 {
276 }
277 // -----------------------------------------------------------------------
278 
~SfxTabPage()279 SfxTabPage::~SfxTabPage()
280 
281 /*  [Beschreibung]
282 
283     Destruktor
284 */
285 
286 {
287 #if !ENABLE_LAYOUT
288     delete pImpl;
289 #endif /* ENABLE_LAYOUT */
290 }
291 
292 // -----------------------------------------------------------------------
293 
FillItemSet(SfxItemSet & rSet)294 sal_Bool SfxTabPage::FillItemSet( SfxItemSet& rSet )
295 {
296     return pImpl->maItemConn.DoFillItemSet( rSet, GetItemSet() );
297 }
298 
299 // -----------------------------------------------------------------------
300 
Reset(const SfxItemSet & rSet)301 void SfxTabPage::Reset( const SfxItemSet& rSet )
302 {
303     pImpl->maItemConn.DoApplyFlags( rSet );
304     pImpl->maItemConn.DoReset( rSet );
305 }
306 
307 // -----------------------------------------------------------------------
308 
ActivatePage(const SfxItemSet &)309 void SfxTabPage::ActivatePage( const SfxItemSet& )
310 
311 /*  [Beschreibung]
312 
313     Defaultimplementierung der virtuellen ActivatePage-Methode
314     Diese wird gerufen, wenn eine Seite des Dialogs den Datenaustausch
315     zwischen Pages unterst"utzt.
316 
317     <SfxTabPage::DeactivatePage(SfxItemSet *)>
318 */
319 
320 {
321 }
322 
323 // -----------------------------------------------------------------------
324 
DeactivatePage(SfxItemSet *)325 int SfxTabPage::DeactivatePage( SfxItemSet* )
326 
327 /*  [Beschreibung]
328 
329     Defaultimplementierung der virtuellen DeactivatePage-Methode
330     Diese wird vor dem Verlassen einer Seite durch den Sfx gerufen;
331     die Anwendung kann "uber den Returnwert steuern,
332     ob die Seite verlassen werden soll.
333     Falls die Seite "uber bHasExchangeSupport
334     anzeigt, da\s sie einen Datenaustausch zwischen Seiten
335     unterst"utzt, wird ein Pointer auf das Austausch-Set als
336     Parameter "ubergeben. Dieser nimmt die Daten f"ur den Austausch
337     entgegen; das Set steht anschlie\send als Parameter in
338     <SfxTabPage::ActivatePage(const SfxItemSet &)> zur Verf"ugung.
339 
340     [R"uckgabewert]
341 
342     LEAVE_PAGE; Verlassen der Seite erlauben
343 */
344 
345 {
346     return LEAVE_PAGE;
347 }
348 
349 // -----------------------------------------------------------------------
350 
FillUserData()351 void SfxTabPage::FillUserData()
352 
353 /*  [Beschreibung]
354 
355    virtuelle Methode, wird von der Basisklasse im Destruktor gerufen
356    um spezielle Informationen der TabPage in der Ini-Datei zu speichern.
357    Beim "Uberladen muss ein String zusammengestellt werden, der mit
358    <SetUserData()> dann weggeschrieben wird.
359 */
360 
361 {
362 }
363 
364 // -----------------------------------------------------------------------
365 
IsReadOnly() const366 sal_Bool SfxTabPage::IsReadOnly() const
367 
368 /*  [Description]
369 
370 */
371 
372 {
373     return sal_False;
374 }
375 
376 // -----------------------------------------------------------------------
377 
GetItem(const SfxItemSet & rSet,sal_uInt16 nSlot,sal_Bool bDeep)378 const SfxPoolItem* SfxTabPage::GetItem( const SfxItemSet& rSet, sal_uInt16 nSlot, sal_Bool bDeep )
379 
380 /*  [Beschreibung]
381 
382     static Methode: hiermit wird der Code der TabPage-Implementierungen
383     vereinfacht.
384 
385 */
386 
387 {
388     const SfxItemPool* pPool = rSet.GetPool();
389     sal_uInt16 nWh = pPool->GetWhich( nSlot, bDeep );
390     const SfxPoolItem* pItem = 0;
391 #ifdef DEBUG
392     SfxItemState eState;
393     eState =
394 #endif
395             rSet.GetItemState( nWh, sal_True, &pItem );  // -Wall required??
396 
397     if ( !pItem && nWh != nSlot )
398         pItem = &pPool->GetDefaultItem( nWh );
399     return pItem;
400 }
401 
402 // -----------------------------------------------------------------------
403 
GetOldItem(const SfxItemSet & rSet,sal_uInt16 nSlot,sal_Bool bDeep)404 const SfxPoolItem* SfxTabPage::GetOldItem( const SfxItemSet& rSet,
405                                            sal_uInt16 nSlot, sal_Bool bDeep )
406 
407 /*  [Beschreibung]
408 
409     Diese Methode gibt f"ur Vergleiche den alten Wert eines
410     Attributs zur"uck.
411 */
412 
413 {
414     const SfxItemSet& rOldSet = GetItemSet();
415     sal_uInt16 nWh = GetWhich( nSlot, bDeep );
416     const SfxPoolItem* pItem = 0;
417 
418     if ( pImpl->mbStandard && rOldSet.GetParent() )
419         pItem = GetItem( *rOldSet.GetParent(), nSlot );
420     else if ( rSet.GetParent() &&
421               SFX_ITEM_DONTCARE == rSet.GetItemState( nWh ) )
422         pItem = GetItem( *rSet.GetParent(), nSlot );
423     else
424         pItem = GetItem( rOldSet, nSlot );
425     return pItem;
426 }
427 
428 // -----------------------------------------------------------------------
429 
GetExchangeItem(const SfxItemSet & rSet,sal_uInt16 nSlot)430 const SfxPoolItem* SfxTabPage::GetExchangeItem( const SfxItemSet& rSet,
431                                                 sal_uInt16 nSlot )
432 
433 /*  [Beschreibung]
434 
435     Diese Methode gibt f"ur Vergleiche den alten Wert eines
436     Attributs zur"uck. Dabei wird ber"ucksichtigt, ob der Dialog
437     gerade mit OK beendet wurde.
438 */
439 
440 {
441     if ( pTabDlg && !pTabDlg->IsInOK() && pTabDlg->GetExampleSet() )
442         return GetItem( *pTabDlg->GetExampleSet(), nSlot );
443     else
444         return GetOldItem( rSet, nSlot );
445 }
446 
447 // add CHINA001  begin
PageCreated(SfxAllItemSet)448 void SfxTabPage::PageCreated( SfxAllItemSet /*aSet*/ )
449 {
450     DBG_ASSERT(0, "SfxTabPage::PageCreated should not be called");
451 }//CHINA001
452 // add CHINA001 end
453 
454 // -----------------------------------------------------------------------
455 
AddItemConnection(sfx::ItemConnectionBase * pConnection)456 void SfxTabPage::AddItemConnection( sfx::ItemConnectionBase* pConnection )
457 {
458     pImpl->maItemConn.AddConnection( pConnection );
459 }
460 
461 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */
462 
463 #if ENABLE_LAYOUT_SFX_TABDIALOG
464 #undef ResId
465 #define ResId(id, foo) #id
466 #undef TabDialog
467 #define TabDialog(parent, res_id) Dialog (parent, "tab-dialog.xml", "tab-dialog")
468 
469 #define aOKBtn(this) aOKBtn (this, "BTN_OK")
470 #undef PushButton
471 #define PushButton(this) layout::PushButton (this, "BTN_USER")
472 #define aCancelBtn(this) aCancelBtn (this, "BTN_CANCEL")
473 #define aHelpBtn(this) aHelpBtn (this, "BTN_HELP")
474 #define aResetBtn(this) aResetBtn (this, "BTN_RESET")
475 #define aBaseFmtBtn(this) aBaseFmtBtn (this, "BTN_BASEFMT")
476 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */
477 
478 #define INI_LIST(ItemSetPtr) \
479     aTabCtrl    ( this, ResId(ID_TABCONTROL,*rResId.GetResMgr() ) ),\
480     aOKBtn      ( this ),\
481     pUserBtn    ( pUserButtonText? new PushButton(this): 0 ),\
482     aCancelBtn  ( this ),\
483     aHelpBtn    ( this ),\
484     aResetBtn   ( this ),\
485     aBaseFmtBtn ( this ),\
486     pSet        ( ItemSetPtr ),\
487     pOutSet     ( 0 ),\
488     pImpl       ( new TabDlg_Impl( (sal_uInt8)aTabCtrl.GetPageCount() ) ), \
489     pRanges     ( 0 ), \
490     nResId      ( rResId.GetId() ), \
491     nAppPageId  ( USHRT_MAX ), \
492     bItemsReset ( sal_False ),\
493     bFmt        ( bEditFmt ),\
494     pExampleSet ( 0 )
495 
496 // -----------------------------------------------------------------------
497 
SfxTabDialog(SfxViewFrame * pViewFrame,Window * pParent,const ResId & rResId,const SfxItemSet * pItemSet,sal_Bool bEditFmt,const String * pUserButtonText)498 SfxTabDialog::SfxTabDialog
499 
500 /*  [Beschreibung]
501 
502     Konstruktor
503 */
504 
505 (
506     SfxViewFrame* pViewFrame,       // Frame, zu dem der Dialog geh"ort
507     Window* pParent,                // Parent-Fenster
508     const ResId& rResId,            // ResourceId
509     const SfxItemSet* pItemSet,     // Itemset mit den Daten;
510                                     // kann NULL sein, wenn Pages onDemand
511     sal_Bool bEditFmt,      // Flag: es werden Vorlagen bearbeitet
512                         // wenn ja -> zus"atzlicher Button f"ur Standard
513     const String* pUserButtonText   // Text fuer BenutzerButton;
514                                     // wenn != 0, wird der UserButton erzeugt
515 ) :
516     TabDialog( pParent, rResId ),
517     pFrame( pViewFrame ),
518     INI_LIST(pItemSet)
519 {
520     Init_Impl( bFmt, pUserButtonText );
521 }
522 
523 // -----------------------------------------------------------------------
524 
SfxTabDialog(Window * pParent,const ResId & rResId,const SfxItemSet * pItemSet,sal_Bool bEditFmt,const String * pUserButtonText)525 SfxTabDialog::SfxTabDialog
526 
527 /*  [Beschreibung]
528 
529     Konstruktor, tempor"ar ohne Frame
530 */
531 
532 (
533     Window* pParent,                // Parent-Fenster
534     const ResId& rResId,            // ResourceId
535     const SfxItemSet* pItemSet,     // Itemset mit den Daten; kann NULL sein,
536                                     // wenn Pages onDemand
537     sal_Bool bEditFmt,      // Flag: es werden Vorlagen bearbeitet
538                         // wenn ja -> zus"atzlicher Button f"ur Standard
539     const String* pUserButtonText   // Text f"ur BenutzerButton;
540                                     // wenn != 0, wird der UserButton erzeugt
541 ) :
542     TabDialog( pParent, rResId ),
543     pFrame( 0 ),
544     INI_LIST(pItemSet)
545 {
546     Init_Impl( bFmt, pUserButtonText );
547     DBG_WARNING( "bitte den Ctor mit ViewFrame verwenden" );
548 }
549 
SfxTabDialog(Window * pParent,const ResId & rResId,sal_uInt16 nSetId,SfxBindings & rBindings,sal_Bool bEditFmt,const String * pUserButtonText)550 SfxTabDialog::SfxTabDialog
551 
552 /*  [Beschreibung]
553 
554     Konstruktor, tempor"ar ohne Frame
555 */
556 
557 (
558     Window* pParent,                // Parent-Fenster
559     const ResId& rResId,            // ResourceId
560     sal_uInt16 nSetId,
561     SfxBindings& rBindings,
562     sal_Bool bEditFmt,      // Flag: es werden Vorlagen bearbeitet
563                         // wenn ja -> zus"atzlicher Button f"ur Standard
564     const String* pUserButtonText   // Text f"ur BenutzerButton;
565                                     // wenn != 0, wird der UserButton erzeugt
566 ) :
567     TabDialog( pParent, rResId ),
568     pFrame( 0 ),
569     INI_LIST(NULL)
570 {
571     rBindings.ENTERREGISTRATIONS();
572     pImpl->pController = new SfxTabDialogController( nSetId, rBindings, this );
573     rBindings.LEAVEREGISTRATIONS();
574 
575     EnableApplyButton( sal_True );
576     SetApplyHandler( LINK( pImpl->pController, SfxTabDialogController, Execute_Impl ) );
577 
578     rBindings.Invalidate( nSetId );
579     rBindings.Update( nSetId );
580     DBG_ASSERT( pSet, "No ItemSet!" );
581 
582     Init_Impl( bFmt, pUserButtonText );
583 }
584 
585 // -----------------------------------------------------------------------
586 
587 #if ENABLE_LAYOUT_SFX_TABDIALOG
588 #undef ResId
589 #undef TabDialog
590 #undef aOKBtn
591 #undef PushButton
592 #undef aCancelBtn
593 #undef aHelpBtn
594 #undef aResetBtn
595 #undef aBaseFmtBtn
596 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */
597 
~SfxTabDialog()598 SfxTabDialog::~SfxTabDialog()
599 {
600     // save settings (screen position and current page)
601     SvtViewOptions aDlgOpt( E_TABDIALOG, String::CreateFromInt32( nResId ) );
602 #if !ENABLE_LAYOUT_SFX_TABDIALOG
603     aDlgOpt.SetWindowState( OUString::createFromAscii( GetWindowState( WINDOWSTATE_MASK_POS ).GetBuffer() ) );
604 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */
605     aDlgOpt.SetPageID( aTabCtrl.GetCurPageId() );
606 
607     const sal_uInt16 nCount = pImpl->pData->Count();
608     for ( sal_uInt16 i = 0; i < nCount; ++i )
609     {
610         Data_Impl* pDataObject = pImpl->pData->GetObject(i);
611 
612         if ( pDataObject->pTabPage )
613         {
614             // save settings of all pages (user data)
615             pDataObject->pTabPage->FillUserData();
616             String aPageData( pDataObject->pTabPage->GetUserData() );
617             if ( aPageData.Len() )
618             {
619                 // save settings of all pages (user data)
620                 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) );
621                 aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aPageData ) ) );
622             }
623 
624             if ( pDataObject->bOnDemand )
625                 delete (SfxItemSet*)&pDataObject->pTabPage->GetItemSet();
626             delete pDataObject->pTabPage;
627         }
628         delete pDataObject;
629     }
630 
631     delete pImpl->pController;
632     delete pImpl->pApplyButton;
633     delete pImpl->pData;
634     delete pImpl;
635     delete pUserBtn;
636     delete pOutSet;
637     delete pExampleSet;
638     delete [] pRanges;
639 }
640 
641 // -----------------------------------------------------------------------
642 
Init_Impl(sal_Bool bFmtFlag,const String * pUserButtonText)643 void SfxTabDialog::Init_Impl( sal_Bool bFmtFlag, const String* pUserButtonText )
644 
645 /*  [Beschreibung]
646 
647     interne Initialisierung des Dialogs
648 */
649 
650 {
651     aOKBtn.SetClickHdl( LINK( this, SfxTabDialog, OkHdl ) );
652     aResetBtn.SetClickHdl( LINK( this, SfxTabDialog, ResetHdl ) );
653     aResetBtn.SetText( String( SfxResId( STR_RESET ) ) );
654     aTabCtrl.SetActivatePageHdl(
655             LINK( this, SfxTabDialog, ActivatePageHdl ) );
656     aTabCtrl.SetDeactivatePageHdl(
657             LINK( this, SfxTabDialog, DeactivatePageHdl ) );
658     aTabCtrl.Show();
659     aOKBtn.Show();
660     aCancelBtn.Show();
661     aHelpBtn.Show();
662     aResetBtn.Show();
663     aResetBtn.SetHelpId( HID_TABDLG_RESET_BTN );
664 
665     if ( pUserBtn )
666     {
667         pUserBtn->SetText( *pUserButtonText );
668         pUserBtn->SetClickHdl( LINK( this, SfxTabDialog, UserHdl ) );
669         pUserBtn->Show();
670     }
671 
672     /* TODO: Check what is up with bFmt/bFmtFlag. Comment below suggests a
673              different behavior than implemented!! */
674     if ( bFmtFlag )
675     {
676         String aStd( SfxResId( STR_STANDARD_SHORTCUT ) );
677         aBaseFmtBtn.SetText( aStd );
678         aBaseFmtBtn.SetClickHdl( LINK( this, SfxTabDialog, BaseFmtHdl ) );
679         aBaseFmtBtn.SetHelpId( HID_TABDLG_STANDARD_BTN );
680 
681         // bFmt = tempor"ares Flag im Ctor() "ubergeben,
682         // wenn bFmt == 2, dann auch sal_True,
683         // zus"atzlich Ausblendung vom StandardButton,
684         // nach der Initialisierung wieder auf sal_True setzen
685         if ( bFmtFlag != 2 )
686             aBaseFmtBtn.Show();
687         else
688             bFmtFlag = sal_True;
689     }
690 
691     if ( pSet )
692     {
693         pExampleSet = new SfxItemSet( *pSet );
694         pOutSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() );
695     }
696 
697     aOKBtn.SetAccessibleRelationMemberOf( &aOKBtn );
698     aCancelBtn.SetAccessibleRelationMemberOf( &aCancelBtn );
699     aHelpBtn.SetAccessibleRelationMemberOf( &aHelpBtn );
700     aResetBtn.SetAccessibleRelationMemberOf( &aResetBtn );
701 }
702 
703 // -----------------------------------------------------------------------
704 
RemoveResetButton()705 void SfxTabDialog::RemoveResetButton()
706 {
707     aResetBtn.Hide();
708     pImpl->bHideResetBtn = sal_True;
709 }
710 
711 // -----------------------------------------------------------------------
712 
713 #if ENABLE_LAYOUT_SFX_TABDIALOG
714 #undef TabDialog
715 #define TabDialog Dialog
716 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */
717 
Execute()718 short SfxTabDialog::Execute()
719 {
720     if ( !aTabCtrl.GetPageCount() )
721         return RET_CANCEL;
722     Start_Impl();
723     return TabDialog::Execute();
724 }
725 
726 // -----------------------------------------------------------------------
727 
StartExecuteModal(const Link & rEndDialogHdl)728 void SfxTabDialog::StartExecuteModal( const Link& rEndDialogHdl )
729 {
730 #if !ENABLE_LAYOUT_SFX_TABDIALOG
731     if ( !aTabCtrl.GetPageCount() )
732         return;
733     Start_Impl();
734     TabDialog::StartExecuteModal( rEndDialogHdl );
735 #else
736     rEndDialogHdl.IsSet();
737 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */
738 }
739 
740 // -----------------------------------------------------------------------
741 
Start(sal_Bool bShow)742 void SfxTabDialog::Start( sal_Bool bShow )
743 {
744     aCancelBtn.SetClickHdl( LINK( this, SfxTabDialog, CancelHdl ) );
745     pImpl->bModal = sal_False;
746     Start_Impl();
747 
748     if ( bShow )
749         Show();
750 
751     if ( IsVisible() && ( !HasChildPathFocus() || HasFocus() ) )
752         GrabFocusToFirstControl();
753 }
754 
755 // -----------------------------------------------------------------------
756 
SetApplyHandler(const Link & _rHdl)757 void SfxTabDialog::SetApplyHandler(const Link& _rHdl)
758 {
759     DBG_ASSERT( pImpl->pApplyButton, "SfxTabDialog::GetApplyHandler: no apply button enabled!" );
760     if ( pImpl->pApplyButton )
761         pImpl->pApplyButton->SetClickHdl( _rHdl );
762 }
763 
764 // -----------------------------------------------------------------------
765 
GetApplyHandler() const766 Link SfxTabDialog::GetApplyHandler() const
767 {
768     DBG_ASSERT( pImpl->pApplyButton, "SfxTabDialog::GetApplyHandler: no button enabled!" );
769     if ( !pImpl->pApplyButton )
770         return Link();
771 
772     return pImpl->pApplyButton->GetClickHdl();
773 }
774 
775 // -----------------------------------------------------------------------
776 
EnableApplyButton(sal_Bool bEnable)777 void SfxTabDialog::EnableApplyButton(sal_Bool bEnable)
778 {
779     if ( IsApplyButtonEnabled() == bEnable )
780         // nothing to do
781         return;
782 
783     // create or remove the apply button
784     if ( bEnable )
785     {
786         pImpl->pApplyButton = new PushButton( this );
787 #if !ENABLE_LAYOUT_SFX_TABDIALOG
788         // in the z-order, the apply button should be behind the ok button, thus appearing at the right side of it
789         pImpl->pApplyButton->SetZOrder(&aOKBtn, WINDOW_ZORDER_BEHIND);
790 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */
791         pImpl->pApplyButton->SetText( String( SfxResId( STR_APPLY ) ) );
792         pImpl->pApplyButton->Show();
793 
794         pImpl->pApplyButton->SetHelpId( HID_TABDLG_APPLY_BTN );
795     }
796     else
797     {
798         delete pImpl->pApplyButton;
799         pImpl->pApplyButton = NULL;
800     }
801 
802 #if !ENABLE_LAYOUT_SFX_TABDIALOG
803     // adjust the layout
804     if (IsReallyShown())
805         AdjustLayout();
806 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */
807 }
808 
809 // -----------------------------------------------------------------------
810 
IsApplyButtonEnabled() const811 sal_Bool SfxTabDialog::IsApplyButtonEnabled() const
812 {
813     return ( NULL != pImpl->pApplyButton );
814 }
815 
816 // -----------------------------------------------------------------------
817 
GetApplyButton() const818 const PushButton* SfxTabDialog::GetApplyButton() const
819 {
820     return pImpl->pApplyButton;
821 }
822 
823 // -----------------------------------------------------------------------
824 
GetApplyButton()825 PushButton* SfxTabDialog::GetApplyButton()
826 {
827     return pImpl->pApplyButton;
828 }
829 
830 // -----------------------------------------------------------------------
831 
Start_Impl()832 void SfxTabDialog::Start_Impl()
833 {
834     DBG_ASSERT( pImpl->pData->Count() == aTabCtrl.GetPageCount(), "not all pages registered" );
835     sal_uInt16 nActPage = aTabCtrl.GetPageId( 0 );
836 
837     // load old settings, when exists
838     SvtViewOptions aDlgOpt( E_TABDIALOG, String::CreateFromInt32( nResId ) );
839     if ( aDlgOpt.Exists() )
840     {
841 #if !ENABLE_LAYOUT_SFX_TABDIALOG
842         SetWindowState( ByteString( aDlgOpt.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US ) );
843 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */
844 
845         // initiale TabPage aus Programm/Hilfe/Konfig
846         nActPage = (sal_uInt16)aDlgOpt.GetPageID();
847 
848         if ( USHRT_MAX != nAppPageId )
849             nActPage = nAppPageId;
850         else
851         {
852             sal_uInt16 nAutoTabPageId = SFX_APP()->Get_Impl()->nAutoTabPageId;
853             if ( nAutoTabPageId )
854                 nActPage = nAutoTabPageId;
855         }
856 
857         if ( TAB_PAGE_NOTFOUND == aTabCtrl.GetPagePos( nActPage ) )
858             nActPage = aTabCtrl.GetPageId( 0 );
859     }
860     else if ( USHRT_MAX != nAppPageId && TAB_PAGE_NOTFOUND != aTabCtrl.GetPagePos( nAppPageId ) )
861         nActPage = nAppPageId;
862 
863     aTabCtrl.SetCurPageId( nActPage );
864     ActivatePageHdl( &aTabCtrl );
865 }
866 
AddTabPage(sal_uInt16 nId,sal_Bool bItemsOnDemand)867 void SfxTabDialog::AddTabPage( sal_uInt16 nId, sal_Bool bItemsOnDemand )
868 {
869     AddTabPage( nId, 0, 0, bItemsOnDemand );
870 }
871 
AddTabPage(sal_uInt16 nId,const String & rRiderText,sal_Bool bItemsOnDemand,sal_uInt16 nPos)872 void SfxTabDialog::AddTabPage( sal_uInt16 nId, const String &rRiderText, sal_Bool bItemsOnDemand, sal_uInt16 nPos )
873 {
874     AddTabPage( nId, rRiderText, 0, 0, bItemsOnDemand, nPos );
875 }
876 
877 #ifdef SV_HAS_RIDERBITMAPS
878 
AddTabPage(sal_uInt16 nId,const Bitmap & rRiderBitmap,sal_Bool bItemsOnDemand,sal_uInt16 nPos)879 void SfxTabDialog::AddTabPage( sal_uInt16 nId, const Bitmap &rRiderBitmap, sal_Bool bItemsOnDemand, sal_uInt16 nPos )
880 {
881     AddTabPage( nId, rRiderBitmap, 0, 0, bItemsOnDemand, nPos );
882 }
883 
884 #endif
885 
886 // -----------------------------------------------------------------------
887 
AddTabPage(sal_uInt16 nId,CreateTabPage pCreateFunc,GetTabPageRanges pRangesFunc,sal_Bool bItemsOnDemand)888 void SfxTabDialog::AddTabPage
889 
890 /*  [Beschreibung]
891 
892     Hinzuf"ugen einer Seite zu dem Dialog.
893     Mu\s korrespondieren zu einem entsprechende Eintrag im
894     TabControl in der Resource des Dialogs.
895 */
896 
897 (
898     sal_uInt16 nId,                     // ID der Seite
899     CreateTabPage pCreateFunc,      // Pointer auf die Factory-Methode
900     GetTabPageRanges pRangesFunc,   // Pointer auf die Methode f"ur das
901                                     // Erfragen der Ranges onDemand
902     sal_Bool bItemsOnDemand             // gibt an, ob das Set dieser Seite beim
903                                     // Erzeugen der Seite erfragt wird
904 )
905 {
906     pImpl->pData->Append(
907         new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) );
908 }
909 
910 // -----------------------------------------------------------------------
911 
AddTabPage(sal_uInt16 nId,const String & rRiderText,CreateTabPage pCreateFunc,GetTabPageRanges pRangesFunc,sal_Bool bItemsOnDemand,sal_uInt16 nPos)912 void SfxTabDialog::AddTabPage
913 
914 /*  [Beschreibung]
915 
916     Hinzuf"ugen einer Seite zu dem Dialog.
917     Der Ridertext wird "ubergeben, die Seite hat keine Entsprechung im
918     TabControl in der Resource des Dialogs.
919 */
920 
921 (
922     sal_uInt16 nId,
923     const String& rRiderText,
924     CreateTabPage pCreateFunc,
925     GetTabPageRanges pRangesFunc,
926     sal_Bool bItemsOnDemand,
927     sal_uInt16 nPos
928 )
929 {
930     DBG_ASSERT( TAB_PAGE_NOTFOUND == aTabCtrl.GetPagePos( nId ),
931                 "Doppelte Page-Ids in der Tabpage" );
932     aTabCtrl.InsertPage( nId, rRiderText, nPos );
933     pImpl->pData->Append(
934         new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) );
935 }
936 
937 // -----------------------------------------------------------------------
938 #ifdef SV_HAS_RIDERBITMAPS
939 
AddTabPage(sal_uInt16 nId,const Bitmap & rRiderBitmap,CreateTabPage pCreateFunc,GetTabPageRanges pRangesFunc,sal_Bool bItemsOnDemand,sal_uInt16 nPos)940 void SfxTabDialog::AddTabPage
941 
942 /*  [Beschreibung]
943 
944     Hinzuf"ugen einer Seite zu dem Dialog.
945     Die Riderbitmap wird "ubergeben, die Seite hat keine Entsprechung im
946     TabControl in der Resource des Dialogs.
947 */
948 
949 (
950     sal_uInt16 nId,
951     const Bitmap &rRiderBitmap,
952     CreateTabPage pCreateFunc,
953     GetTabPageRanges pRangesFunc,
954     sal_Bool bItemsOnDemand,
955     sal_uInt16 nPos
956 )
957 {
958     DBG_ASSERT( TAB_PAGE_NOTFOUND == aTabCtrl.GetPagePos( nId ),
959                 "Doppelte Page-Ids in der Tabpage" );
960     aTabCtrl.InsertPage( nId, rRiderBitmap, nPos );
961     pImpl->pData->Append(
962         new Data_Impl( nId, pCreateFunc, pRangesFunc, bItemsOnDemand ) );
963 }
964 #endif
965 
966 // -----------------------------------------------------------------------
967 
RemoveTabPage(sal_uInt16 nId)968 void SfxTabDialog::RemoveTabPage( sal_uInt16 nId )
969 
970 /*  [Beschreibung]
971 
972     L"oschen der TabPage mit der ID nId
973 */
974 
975 {
976     sal_uInt16 nPos = 0;
977     aTabCtrl.RemovePage( nId );
978     Data_Impl* pDataObject = Find( *pImpl->pData, nId, &nPos );
979 
980     if ( pDataObject )
981     {
982         if ( pDataObject->pTabPage )
983         {
984             pDataObject->pTabPage->FillUserData();
985             String aPageData( pDataObject->pTabPage->GetUserData() );
986             if ( aPageData.Len() )
987             {
988                 // save settings of this page (user data)
989                 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) );
990                 aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aPageData ) ) );
991             }
992 
993             if ( pDataObject->bOnDemand )
994                 delete (SfxItemSet*)&pDataObject->pTabPage->GetItemSet();
995             delete pDataObject->pTabPage;
996         }
997 
998         delete pDataObject;
999         pImpl->pData->Remove( nPos );
1000     }
1001     else
1002     {
1003         DBG_WARNINGFILE( "TabPage-Id nicht bekannt" );
1004     }
1005 }
1006 
1007 // -----------------------------------------------------------------------
1008 
PageCreated(sal_uInt16,SfxTabPage &)1009 void SfxTabDialog::PageCreated
1010 
1011 /*  [Beschreibung]
1012 
1013     Defaultimplemetierung der virtuellen Methode.
1014     Diese wird unmittelbar nach dem Erzeugen einer Seite gerufen.
1015     Hier kann der Dialog direkt an der TabPage Methoden rufen.
1016 */
1017 
1018 (
1019     sal_uInt16,         // Id der erzeugten Seite
1020     SfxTabPage&     // Referenz auf die erzeugte Seite
1021 )
1022 {
1023 }
1024 
1025 // -----------------------------------------------------------------------
1026 
GetInputSetImpl()1027 SfxItemSet* SfxTabDialog::GetInputSetImpl()
1028 
1029 /*  [Beschreibung]
1030 
1031     Abgeleitete Klassen legen ggf. fuer den InputSet neuen Speicher an.
1032     Dieser mu\s im Destruktor auch wieder freigegeben werden. Dazu mu\s
1033     diese Methode gerufen werden.
1034 */
1035 
1036 {
1037     return (SfxItemSet*)pSet;
1038 }
1039 
1040 // -----------------------------------------------------------------------
1041 
GetTabPage(sal_uInt16 nPageId) const1042 SfxTabPage* SfxTabDialog::GetTabPage( sal_uInt16 nPageId ) const
1043 
1044 /*  [Beschreibung]
1045 
1046     TabPage mit der "Ubergebenen Id zur"uckgeben.
1047 */
1048 
1049 {
1050     sal_uInt16 nPos = 0;
1051     Data_Impl* pDataObject = Find( *pImpl->pData, nPageId, &nPos );
1052 
1053     if ( pDataObject )
1054         return pDataObject->pTabPage;
1055     return NULL;
1056 }
1057 
1058 // -----------------------------------------------------------------------
1059 
IsInOK() const1060 sal_Bool SfxTabDialog::IsInOK() const
1061 
1062 /*  [Beschreibung]
1063 
1064 */
1065 
1066 {
1067     return pImpl->bInOK;
1068 }
1069 
1070 // -----------------------------------------------------------------------
1071 
Ok()1072 short SfxTabDialog::Ok()
1073 
1074 /*  [Beschreibung]
1075 
1076     Ok-Handler des Dialogs
1077     Das OutputSet wird erstellt und jede Seite wird mit
1078     dem bzw. ihrem speziellen OutputSet durch Aufruf der Methode
1079     <SfxTabPage::FillItemSet(SfxItemSet &)> dazu aufgefordert,
1080     die vom Benuzter eingestellten Daten in das Set zu tun.
1081 
1082     [R"uckgabewert]
1083 
1084     RET_OK: wenn mindestens eine Seite sal_True als Returnwert von
1085             FillItemSet geliefert hat, sonst RET_CANCEL.
1086 */
1087 
1088 {
1089     pImpl->bInOK = sal_True;
1090 
1091     if ( !pOutSet )
1092     {
1093         if ( !pExampleSet && pSet )
1094             pOutSet = pSet->Clone( sal_False ); // ohne Items
1095         else if ( pExampleSet )
1096             pOutSet = new SfxItemSet( *pExampleSet );
1097     }
1098     sal_Bool bModified = sal_False;
1099 
1100     const sal_uInt16 nCount = pImpl->pData->Count();
1101 
1102     for ( sal_uInt16 i = 0; i < nCount; ++i )
1103     {
1104         Data_Impl* pDataObject = pImpl->pData->GetObject(i);
1105         SfxTabPage* pTabPage = pDataObject->pTabPage;
1106 
1107         if ( pTabPage )
1108         {
1109             if ( pDataObject->bOnDemand )
1110             {
1111                 SfxItemSet& rSet = (SfxItemSet&)pTabPage->GetItemSet();
1112                 rSet.ClearItem();
1113                 bModified |= pTabPage->FillItemSet( rSet );
1114             }
1115             else if ( pSet && !pTabPage->HasExchangeSupport() )
1116             {
1117                 SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() );
1118 
1119                 if ( pTabPage->FillItemSet( aTmp ) )
1120                 {
1121                     bModified |= sal_True;
1122                     pExampleSet->Put( aTmp );
1123                     pOutSet->Put( aTmp );
1124                 }
1125             }
1126         }
1127     }
1128 
1129     if ( pImpl->bModified || ( pOutSet && pOutSet->Count() > 0 ) )
1130         bModified |= sal_True;
1131 
1132     if ( bFmt == 2 )
1133         bModified |= sal_True;
1134     return bModified ? RET_OK : RET_CANCEL;
1135 }
1136 
1137 // -----------------------------------------------------------------------
1138 
IMPL_LINK(SfxTabDialog,CancelHdl,Button *,pButton)1139 IMPL_LINK( SfxTabDialog, CancelHdl, Button*, pButton )
1140 {
1141     (void)pButton; //unused
1142     Close();
1143     return 0;
1144 }
1145 
1146 // -----------------------------------------------------------------------
1147 
CreateInputItemSet(sal_uInt16)1148 SfxItemSet* SfxTabDialog::CreateInputItemSet( sal_uInt16 )
1149 
1150 /*  [Beschreibung]
1151 
1152     Defaultimplemetierung der virtuellen Methode.
1153     Diese wird gerufen, wenn Pages ihre Sets onDenamd anlegen
1154 */
1155 
1156 {
1157     DBG_WARNINGFILE( "CreateInputItemSet nicht implementiert" );
1158     return new SfxAllItemSet( SFX_APP()->GetPool() );
1159 }
1160 
1161 // -----------------------------------------------------------------------
1162 
GetRefreshedSet()1163 const SfxItemSet* SfxTabDialog::GetRefreshedSet()
1164 
1165 /*  [Beschreibung]
1166 
1167     Defaultimplemetierung der virtuellen Methode.
1168     Diese wird gerufen, wenn <SfxTabPage::DeactivatePage(SfxItemSet *)>
1169     <SfxTabPage::REFRESH_SET> liefert.
1170 */
1171 
1172 {
1173     DBG_ERRORFILE( "GetRefreshedSet nicht implementiert" );
1174     return 0;
1175 }
1176 
1177 // -----------------------------------------------------------------------
1178 
IMPL_LINK(SfxTabDialog,OkHdl,Button *,EMPTYARG)1179 IMPL_LINK( SfxTabDialog, OkHdl, Button *, EMPTYARG )
1180 
1181 /*  [Beschreibung]
1182 
1183     Handler des Ok-Buttons
1184     Dieser ruft f"ur die aktuelle Seite
1185     <SfxTabPage::DeactivatePage(SfxItemSet *)>.
1186     Liefert diese <SfxTabPage::LEAVE_PAGE>, wird <SfxTabDialog::Ok()> gerufen
1187     und so der Dialog beendet.
1188 */
1189 
1190 {
1191     pImpl->bInOK = sal_True;
1192 
1193     if ( OK_Impl() )
1194     {
1195         if ( pImpl->bModal )
1196             EndDialog( Ok() );
1197         else
1198         {
1199             Ok();
1200             Close();
1201         }
1202     }
1203     return 0;
1204 }
1205 
1206 // -----------------------------------------------------------------------
1207 
PrepareLeaveCurrentPage()1208 bool SfxTabDialog::PrepareLeaveCurrentPage()
1209 {
1210     sal_uInt16 const nId = aTabCtrl.GetCurPageId();
1211     SfxTabPage* pPage = dynamic_cast<SfxTabPage*> (aTabCtrl.GetTabPage( nId ));
1212     bool bEnd = !pPage;
1213 
1214     if ( pPage )
1215     {
1216         int nRet = SfxTabPage::LEAVE_PAGE;
1217         if ( pSet )
1218         {
1219             SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() );
1220 
1221             if ( pPage->HasExchangeSupport() )
1222                 nRet = pPage->DeactivatePage( &aTmp );
1223             else
1224                 nRet = pPage->DeactivatePage( NULL );
1225 
1226             if ( ( SfxTabPage::LEAVE_PAGE & nRet ) == SfxTabPage::LEAVE_PAGE
1227                  && aTmp.Count() )
1228             {
1229                 pExampleSet->Put( aTmp );
1230                 pOutSet->Put( aTmp );
1231             }
1232         }
1233         else
1234             nRet = pPage->DeactivatePage( NULL );
1235         bEnd = nRet;
1236     }
1237 
1238     return bEnd;
1239 }
1240 
1241 
1242 // -----------------------------------------------------------------------
1243 
IMPL_LINK(SfxTabDialog,UserHdl,Button *,EMPTYARG)1244 IMPL_LINK( SfxTabDialog, UserHdl, Button *, EMPTYARG )
1245 
1246 /*  [Beschreibung]
1247 
1248     Handler des User-Buttons
1249     Dieser ruft f"ur die aktuelle Seite
1250     <SfxTabPage::DeactivatePage(SfxItemSet *)>.
1251     Liefert diese <SfxTabPage::LEAVE_PAGE>, wird <SfxTabDialog::Ok()> gerufen.
1252     Mit dem Return-Wert von <SfxTabDialog::Ok()> wird dann der Dialog beendet.
1253 */
1254 
1255 {
1256     if ( PrepareLeaveCurrentPage () )
1257     {
1258         short nRet = Ok();
1259 
1260         if ( RET_OK == nRet )
1261             nRet = RET_USER;
1262         else
1263             nRet = RET_USER_CANCEL;
1264         EndDialog( nRet );
1265     }
1266     return 0;
1267 }
1268 
1269 // -----------------------------------------------------------------------
1270 
IMPL_LINK(SfxTabDialog,ResetHdl,Button *,EMPTYARG)1271 IMPL_LINK( SfxTabDialog, ResetHdl, Button *, EMPTYARG )
1272 
1273 /*  [Beschreibung]
1274 
1275     Handler hinter dem Zur"ucksetzen-Button.
1276     Die aktuelle Page wird mit ihren initialen Daten
1277     neu initialisiert; alle Einstellungen, die der Benutzer
1278     auf dieser Seite get"atigt hat, werden aufgehoben.
1279 */
1280 
1281 {
1282     const sal_uInt16 nId = aTabCtrl.GetCurPageId();
1283     Data_Impl* pDataObject = Find( *pImpl->pData, nId );
1284     DBG_ASSERT( pDataObject, "Id nicht bekannt" );
1285 
1286     if ( pDataObject->bOnDemand )
1287     {
1288         // CSet auf AIS hat hier Probleme, daher getrennt
1289         const SfxItemSet* pItemSet = &pDataObject->pTabPage->GetItemSet();
1290         pDataObject->pTabPage->Reset( *(SfxItemSet*)pItemSet );
1291     }
1292     else
1293         pDataObject->pTabPage->Reset( *pSet );
1294     return 0;
1295 }
1296 
1297 // -----------------------------------------------------------------------
1298 
IMPL_LINK(SfxTabDialog,BaseFmtHdl,Button *,EMPTYARG)1299 IMPL_LINK( SfxTabDialog, BaseFmtHdl, Button *, EMPTYARG )
1300 
1301 /*  [Beschreibung]
1302 
1303     Handler hinter dem Standard-Button.
1304     Dieser Button steht beim Bearbeiten von StyleSheets zur Verf"ugung.
1305     Alle in dem bearbeiteten StyleSheet eingestellten Attribute
1306     werden gel"oscht.
1307 */
1308 
1309 {
1310     const sal_uInt16 nId = aTabCtrl.GetCurPageId();
1311     Data_Impl* pDataObject = Find( *pImpl->pData, nId );
1312     DBG_ASSERT( pDataObject, "Id nicht bekannt" );
1313     bFmt = 2;
1314 
1315     if ( pDataObject->fnGetRanges )
1316     {
1317         if ( !pExampleSet )
1318             pExampleSet = new SfxItemSet( *pSet );
1319 
1320         const SfxItemPool* pPool = pSet->GetPool();
1321         const sal_uInt16* pTmpRanges = (pDataObject->fnGetRanges)();
1322         SfxItemSet aTmpSet( *pExampleSet );
1323 
1324         while ( *pTmpRanges )
1325         {
1326             const sal_uInt16* pU = pTmpRanges + 1;
1327 
1328             if ( *pTmpRanges == *pU )
1329             {
1330                 // Range mit zwei gleichen Werten -> nur ein Item setzen
1331                 sal_uInt16 nWh = pPool->GetWhich( *pTmpRanges );
1332                 pExampleSet->ClearItem( nWh );
1333                 aTmpSet.ClearItem( nWh );
1334                 // am OutSet mit InvalidateItem,
1335                 // damit die "Anderung wirksam wird
1336                 pOutSet->InvalidateItem( nWh );
1337             }
1338             else
1339             {
1340                 // richtiger Range mit mehreren Werten
1341                 sal_uInt16 nTmp = *pTmpRanges, nTmpEnd = *pU;
1342                 DBG_ASSERT( nTmp <= nTmpEnd, "Range ist falsch sortiert" );
1343 
1344                 if ( nTmp > nTmpEnd )
1345                 {
1346                     // wenn wirklich falsch sortiert, dann neu setzen
1347                     sal_uInt16 nTmp1 = nTmp;
1348                     nTmp = nTmpEnd;
1349                     nTmpEnd = nTmp1;
1350                 }
1351 
1352                 while ( nTmp <= nTmpEnd )
1353                 {
1354                     // "uber den Range iterieren, und die Items setzen
1355                     sal_uInt16 nWh = pPool->GetWhich( nTmp );
1356                     pExampleSet->ClearItem( nWh );
1357                     aTmpSet.ClearItem( nWh );
1358                     // am OutSet mit InvalidateItem,
1359                     // damit die "Anderung wirksam wird
1360                     pOutSet->InvalidateItem( nWh );
1361                     nTmp++;
1362                 }
1363             }
1364             // zum n"achsten Paar gehen
1365             pTmpRanges += 2;
1366         }
1367         // alle Items neu gesetzt -> dann an der aktuellen Page Reset() rufen
1368         DBG_ASSERT( pDataObject->pTabPage, "die Page ist weg" );
1369         pDataObject->pTabPage->Reset( aTmpSet );
1370         pDataObject->pTabPage->pImpl->mbStandard = sal_True;
1371     }
1372     return 1;
1373 }
1374 
1375 // -----------------------------------------------------------------------
1376 
1377 #if ENABLE_LAYOUT_SFX_TABDIALOG
1378 #define tabControlWindow pTabCtrl->GetWindow ()
1379 #else /* !ENABLE_LAYOUT_SFX_TABDIALOG */
1380 #define tabControlWindow pTabCtrl
1381 #endif /* !ENABLE_LAYOUT_SFX_TABDIALOG */
1382 
IMPL_LINK(SfxTabDialog,ActivatePageHdl,TabControl *,pTabCtrl)1383 IMPL_LINK( SfxTabDialog, ActivatePageHdl, TabControl *, pTabCtrl )
1384 
1385 /*  [Beschreibung]
1386 
1387     Handler, der vor dem Umschalten auf eine andere Seite
1388     durch Starview gerufen wird.
1389     Existiert die Seite noch nicht, so wird sie erzeugt und
1390     die virtuelle Methode <SfxTabDialog::PageCreated( sal_uInt16, SfxTabPage &)>
1391     gerufen. Existiert die Seite bereits, so wird ggf.
1392     <SfxTabPage::Reset(const SfxItemSet &)> oder
1393     <SfxTabPage::ActivatePage(const SfxItemSet &)> gerufen.
1394 */
1395 
1396 {
1397     sal_uInt16 const nId = pTabCtrl->GetCurPageId();
1398 
1399     DBG_ASSERT( pImpl->pData->Count(), "keine Pages angemeldet" );
1400     SFX_APP();
1401 
1402     // Tab Page schon da?
1403     SfxTabPage* pTabPage = dynamic_cast<SfxTabPage*> (pTabCtrl->GetTabPage( nId ));
1404     Data_Impl* pDataObject = Find( *pImpl->pData, nId );
1405     DBG_ASSERT( pDataObject, "Id nicht bekannt" );
1406 
1407     // ggf. TabPage erzeugen:
1408     if ( !pTabPage )
1409     {
1410 #if ENABLE_LAYOUT_SFX_TABDIALOG
1411         if (dynamic_cast<layout SfxTabPage*> (pTabPage))
1412             layout::TabPage::global_parent = pTabCtrl->GetWindow ();
1413 #endif
1414         const SfxItemSet* pTmpSet = 0;
1415 
1416         if ( pSet )
1417         {
1418             if ( bItemsReset && pSet->GetParent() )
1419                 pTmpSet = pSet->GetParent();
1420             else
1421                 pTmpSet = pSet;
1422         }
1423 
1424         if ( pTmpSet && !pDataObject->bOnDemand )
1425             pTabPage = (pDataObject->fnCreatePage)( tabControlWindow, *pTmpSet );
1426         else
1427             pTabPage = (pDataObject->fnCreatePage)
1428                             ( tabControlWindow, *CreateInputItemSet( nId ) );
1429         DBG_ASSERT( NULL == pDataObject->pTabPage, "create TabPage more than once" );
1430         pDataObject->pTabPage = pTabPage;
1431 
1432 #if !ENABLE_LAYOUT_SFX_TABDIALOG
1433         pDataObject->pTabPage->SetTabDialog( this );
1434 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */
1435         SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( pDataObject->nId ) );
1436         String sUserData;
1437         Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME );
1438         OUString aTemp;
1439         if ( aUserItem >>= aTemp )
1440             sUserData = String( aTemp );
1441         pTabPage->SetUserData( sUserData );
1442         Size aSiz = pTabPage->GetSizePixel();
1443 
1444 #if ENABLE_LAYOUT
1445         Size optimalSize = pTabPage->GetOptimalSize (WINDOWSIZE_MINIMUM);
1446 #if ENABLE_LAYOUT_SFX_TABDIALOG
1447         if (dynamic_cast<layout SfxTabPage*> (pTabPage))
1448         {
1449             if (optimalSize.Height () && optimalSize.Width ())
1450             {
1451                 optimalSize.Width () = optimalSize.Width ();
1452                 optimalSize.Height () = optimalSize.Height () + 40;
1453             }
1454         }
1455 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */
1456         if (optimalSize.Height () > 0 && optimalSize.Width () > 0 )
1457             aSiz = optimalSize;
1458 #endif /* ENABLE_LAYOUT */
1459 
1460         Size aCtrlSiz = pTabCtrl->GetTabPageSizePixel();
1461         // Gr"o/se am TabControl nur dann setzen, wenn < als TabPage
1462         if ( aCtrlSiz.Width() < aSiz.Width() ||
1463              aCtrlSiz.Height() < aSiz.Height() )
1464         {
1465             pTabCtrl->SetTabPageSizePixel( aSiz );
1466         }
1467 
1468         PageCreated( nId, *pTabPage );
1469 
1470         if ( pDataObject->bOnDemand )
1471             pTabPage->Reset( (SfxItemSet &)pTabPage->GetItemSet() );
1472         else
1473             pTabPage->Reset( *pSet );
1474 
1475         pTabCtrl->SetTabPage( nId, pTabPage );
1476     }
1477     else if ( pDataObject->bRefresh )
1478         pTabPage->Reset( *pSet );
1479     pDataObject->bRefresh = sal_False;
1480 
1481 #if ENABLE_LAYOUT_SFX_TABDIALOG
1482     pTabCtrl->GetPagePos (nId);
1483 #endif /* ENABLE_LAYOUT_SFX_TABDIALOG */
1484 
1485     if ( pExampleSet )
1486         pTabPage->ActivatePage( *pExampleSet );
1487     sal_Bool bReadOnly = pTabPage->IsReadOnly();
1488     ( bReadOnly || pImpl->bHideResetBtn ) ? aResetBtn.Hide() : aResetBtn.Show();
1489     return 0;
1490 }
1491 
1492 // -----------------------------------------------------------------------
1493 
IMPL_LINK(SfxTabDialog,DeactivatePageHdl,TabControl *,pTabCtrl)1494 IMPL_LINK( SfxTabDialog, DeactivatePageHdl, TabControl *, pTabCtrl )
1495 
1496 /*  [Beschreibung]
1497 
1498     Handler, der vor dem Verlassen einer Seite durch Starview gerufen wird.
1499 
1500     [Querverweise]
1501 
1502     <SfxTabPage::DeactivatePage(SfxItemSet *)>
1503 */
1504 
1505 {
1506     sal_uInt16 nId = pTabCtrl->GetCurPageId();
1507     SFX_APP();
1508     SfxTabPage *pPage = dynamic_cast<SfxTabPage*> (pTabCtrl->GetTabPage( nId ));
1509     DBG_ASSERT( pPage, "keine aktive Page" );
1510 #ifdef DBG_UTIL
1511     Data_Impl* pDataObject = Find( *pImpl->pData, pTabCtrl->GetCurPageId() );
1512     DBG_ASSERT( pDataObject, "keine Datenstruktur zur aktuellen Seite" );
1513     if ( pPage->HasExchangeSupport() && pDataObject->bOnDemand )
1514     {
1515         DBG_WARNING( "Datenaustausch bei ItemsOnDemand ist nicht gewuenscht!" );
1516     }
1517 #endif
1518 
1519     int nRet = SfxTabPage::LEAVE_PAGE;
1520 
1521     if ( !pExampleSet && pPage->HasExchangeSupport() && pSet )
1522         pExampleSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() );
1523 
1524     if ( pSet )
1525     {
1526         SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() );
1527 
1528         if ( pPage->HasExchangeSupport() )
1529             nRet = pPage->DeactivatePage( &aTmp );
1530         else
1531             nRet = pPage->DeactivatePage( NULL );
1532 //!     else
1533 //!         pPage->FillItemSet( aTmp );
1534 
1535         if ( ( SfxTabPage::LEAVE_PAGE & nRet ) == SfxTabPage::LEAVE_PAGE &&
1536              aTmp.Count() )
1537         {
1538             pExampleSet->Put( aTmp );
1539             pOutSet->Put( aTmp );
1540         }
1541     }
1542     else
1543     {
1544         if ( pPage->HasExchangeSupport() ) //!!!
1545         {
1546             if ( !pExampleSet )
1547             {
1548                 SfxItemPool* pPool = pPage->GetItemSet().GetPool();
1549                 pExampleSet =
1550                     new SfxItemSet( *pPool, GetInputRanges( *pPool ) );
1551             }
1552             nRet = pPage->DeactivatePage( pExampleSet );
1553         }
1554         else
1555             nRet = pPage->DeactivatePage( NULL );
1556     }
1557 
1558     if ( nRet & SfxTabPage::REFRESH_SET )
1559     {
1560         pSet = GetRefreshedSet();
1561         DBG_ASSERT( pSet, "GetRefreshedSet() liefert NULL" );
1562         // alle Pages als neu zu initialsieren flaggen
1563         const sal_uInt16 nCount = pImpl->pData->Count();
1564 
1565         for ( sal_uInt16 i = 0; i < nCount; ++i )
1566         {
1567             Data_Impl* pObj = (*pImpl->pData)[i];
1568 
1569             if ( pObj->pTabPage != pPage ) // eigene Page nicht mehr refreshen
1570                 pObj->bRefresh = sal_True;
1571             else
1572                 pObj->bRefresh = sal_False;
1573         }
1574     }
1575     if ( nRet & SfxTabPage::LEAVE_PAGE )
1576         return sal_True;
1577     else
1578         return sal_False;
1579 }
1580 
1581 // -----------------------------------------------------------------------
1582 
GetOutputItemSet(sal_uInt16 nId) const1583 const SfxItemSet* SfxTabDialog::GetOutputItemSet
1584 
1585 /*  [Beschreibung]
1586 
1587     Liefert die Pages, die ihre Sets onDemand liefern, das OutputItemSet.
1588 
1589     [Querverweise]
1590 
1591     <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, sal_Bool)>
1592     <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)>
1593     <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)>
1594 */
1595 
1596 (
1597     sal_uInt16 nId  // die Id, unter der die Seite bei AddTabPage()
1598                 // hinzugef"ugt wurde.
1599 ) const
1600 {
1601     Data_Impl* pDataObject = Find( *pImpl->pData, nId );
1602     DBG_ASSERT( pDataObject, "TabPage nicht gefunden" );
1603 
1604     if ( pDataObject )
1605     {
1606         if ( !pDataObject->pTabPage )
1607             return NULL;
1608 
1609         if ( pDataObject->bOnDemand )
1610             return &pDataObject->pTabPage->GetItemSet();
1611         // else
1612         return pOutSet;
1613     }
1614     return NULL;
1615 }
1616 
1617 // -----------------------------------------------------------------------
1618 
FillOutputItemSet()1619 int SfxTabDialog::FillOutputItemSet()
1620 {
1621     int nRet = SfxTabPage::LEAVE_PAGE;
1622     if ( OK_Impl() )
1623         Ok();
1624     else
1625         nRet = SfxTabPage::KEEP_PAGE;
1626     return nRet;
1627 }
1628 
1629 // -----------------------------------------------------------------------
1630 
1631 #ifdef WNT
TabDlgCmpUS_Impl(const void * p1,const void * p2)1632 int __cdecl TabDlgCmpUS_Impl( const void* p1, const void* p2 )
1633 #else
1634 #if defined(OS2) && defined(ICC)
1635 int _Optlink TabDlgCmpUS_Impl( const void* p1, const void* p2 )
1636 #else
1637 extern "C" int TabDlgCmpUS_Impl( const void* p1, const void* p2 )
1638 #endif
1639 #endif
1640 
1641 /*  [Beschreibung]
1642 
1643     Vergleichsfunktion f"ur qsort
1644 */
1645 
1646 {
1647     return *(sal_uInt16*)p1 - *(sal_uInt16*)p2;
1648 }
1649 
1650 // -----------------------------------------------------------------------
1651 
ShowPage(sal_uInt16 nId)1652 void SfxTabDialog::ShowPage( sal_uInt16 nId )
1653 
1654 /*  [Beschreibung]
1655 
1656     Es wird die TabPage mit der "ubergebenen Id aktiviert.
1657 */
1658 
1659 {
1660     aTabCtrl.SetCurPageId( nId );
1661     ActivatePageHdl( &aTabCtrl );
1662 }
1663 
1664 // -----------------------------------------------------------------------
1665 
GetInputRanges(const SfxItemPool & rPool)1666 const sal_uInt16* SfxTabDialog::GetInputRanges( const SfxItemPool& rPool )
1667 
1668 /*  [Beschreibung]
1669 
1670     Bildet das Set "uber die Ranges aller Seiten des Dialogs.
1671     Die Pages m"ussen die statische Methode f"ur das Erfragen ihrer
1672     Ranges bei AddTabPage angegeben haben, liefern also ihre Sets onDemand.
1673 
1674     [Querverweise]
1675 
1676     <SfxTabDialog::AddTabPage(sal_uInt16, CreateTabPage, GetTabPageRanges, sal_Bool)>
1677     <SfxTabDialog::AddTabPage(sal_uInt16, const String &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)>
1678     <SfxTabDialog::AddTabPage(sal_uInt16, const Bitmap &, CreateTabPage, GetTabPageRanges, sal_Bool, sal_uInt16)>
1679 
1680     [R"uckgabewert]
1681 
1682     Pointer auf nullterminiertes Array von USHORTs
1683     Dieses Array geh"ort dem Dialog und wird beim
1684     Zerst"oren des Dialogs gel"oscht.
1685 */
1686 
1687 {
1688     if ( pSet )
1689     {
1690         DBG_ERRORFILE( "Set bereits vorhanden!" );
1691         return pSet->GetRanges();
1692     }
1693 
1694     if ( pRanges )
1695         return pRanges;
1696     SvUShorts aUS( 16, 16 );
1697     sal_uInt16 nCount = pImpl->pData->Count();
1698 
1699     sal_uInt16 i;
1700     for ( i = 0; i < nCount; ++i )
1701     {
1702         Data_Impl* pDataObject = pImpl->pData->GetObject(i);
1703 
1704         if ( pDataObject->fnGetRanges )
1705         {
1706             const sal_uInt16* pTmpRanges = (pDataObject->fnGetRanges)();
1707             const sal_uInt16* pIter = pTmpRanges;
1708 
1709             sal_uInt16 nLen;
1710             for( nLen = 0; *pIter; ++nLen, ++pIter )
1711                 ;
1712             aUS.Insert( pTmpRanges, nLen, aUS.Count() );
1713         }
1714     }
1715 
1716     //! Doppelte Ids entfernen?
1717 #ifndef TF_POOLABLE
1718     if ( rPool.HasMap() )
1719 #endif
1720     {
1721         nCount = aUS.Count();
1722 
1723         for ( i = 0; i < nCount; ++i )
1724             aUS[i] = rPool.GetWhich( aUS[i] );
1725     }
1726 
1727     // sortieren
1728     if ( aUS.Count() > 1 )
1729         qsort( (void*)aUS.GetData(),
1730                aUS.Count(), sizeof(sal_uInt16), TabDlgCmpUS_Impl );
1731 
1732     // Ranges erzeugen
1733     //!! Auskommentiert, da fehlerhaft
1734     /*
1735     pRanges = new sal_uInt16[aUS.Count() * 2 + 1];
1736     int j = 0;
1737     i = 0;
1738 
1739     while ( i < aUS.Count() )
1740     {
1741         pRanges[j++] = aUS[i];
1742         // aufeinanderfolgende Zahlen
1743         for( ; i < aUS.Count()-1; ++i )
1744             if ( aUS[i] + 1 != aUS[i+1] )
1745                 break;
1746         pRanges[j++] = aUS[i++];
1747     }
1748     pRanges[j] = 0;     // terminierende NULL
1749     */
1750 
1751     pRanges = new sal_uInt16[aUS.Count() + 1];
1752     memcpy(pRanges, aUS.GetData(), sizeof(sal_uInt16) * aUS.Count());
1753     pRanges[aUS.Count()] = 0;
1754     return pRanges;
1755 }
1756 
1757 // -----------------------------------------------------------------------
1758 
SetInputSet(const SfxItemSet * pInSet)1759 void SfxTabDialog::SetInputSet( const SfxItemSet* pInSet )
1760 
1761 /*  [Beschreibung]
1762 
1763     Mit dieser Methode kann nachtr"aglich der Input-Set initial oder
1764     neu gesetzt werden.
1765 */
1766 
1767 {
1768     bool bSet = ( pSet != NULL );
1769 
1770     pSet = pInSet;
1771 
1772     if ( !bSet && !pExampleSet && !pOutSet )
1773     {
1774         pExampleSet = new SfxItemSet( *pSet );
1775         pOutSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() );
1776     }
1777 }
1778 
Notify(NotifyEvent & rNEvt)1779 long SfxTabDialog::Notify( NotifyEvent& rNEvt )
1780 {
1781     if ( rNEvt.GetType() == EVENT_GETFOCUS )
1782     {
1783         SfxViewFrame* pViewFrame = GetViewFrame() ? GetViewFrame() : SfxViewFrame::Current();
1784         if ( pViewFrame )
1785         {
1786             Window* pWindow = rNEvt.GetWindow();
1787             rtl::OString sHelpId;
1788             while ( !sHelpId.getLength() && pWindow )
1789             {
1790                 sHelpId = pWindow->GetHelpId();
1791                 pWindow = pWindow->GetParent();
1792             }
1793 
1794             if ( sHelpId.getLength() )
1795                 SfxHelp::OpenHelpAgent( &pViewFrame->GetFrame(), sHelpId );
1796         }
1797     }
1798 
1799     return TabDialog::Notify( rNEvt );
1800 }
1801 
1802 END_NAMESPACE_LAYOUT_SFX_TABDIALOG
1803