update dev300-m57
[ooovba.git] / sfx2 / source / dialog / basedlgs.cxx
blobd93a4884c192f528f71124e49084f0f9c6c3efb9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: basedlgs.cxx,v $
10 * $Revision: 1.33 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 // include ---------------------------------------------------------------
36 #include <stdlib.h>
37 #include <vcl/fixed.hxx>
38 #include <vcl/help.hxx>
39 #include <vcl/msgbox.hxx>
40 #include <svtools/eitem.hxx>
41 #include <svtools/viewoptions.hxx>
42 #include <svtools/fixedhyper.hxx>
43 #include <svtools/controldims.hrc>
45 #include <sfx2/basedlgs.hxx>
46 #include <sfx2/viewfrm.hxx>
47 #include <sfx2/tabdlg.hxx>
48 #include <sfx2/app.hxx>
49 #include <sfx2/bindings.hxx>
50 #include <sfx2/dispatch.hxx>
51 #include <sfx2/childwin.hxx>
52 #include <sfx2/viewsh.hxx>
53 #include "sfxhelp.hxx"
54 #include "workwin.hxx"
55 #include "sfxresid.hxx"
56 #include "dialog.hrc"
58 using namespace ::com::sun::star::uno;
59 using namespace ::rtl;
61 #define USERITEM_NAME OUString::createFromAscii( "UserItem" )
63 class SfxModelessDialog_Impl : public SfxListener
65 public:
66 ByteString aWinState;
67 SfxChildWindow* pMgr;
68 BOOL bConstructed;
69 void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
71 Timer aMoveTimer;
74 void SfxModelessDialog_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint )
76 if ( rHint.IsA(TYPE(SfxSimpleHint)) )
78 switch( ( (SfxSimpleHint&) rHint ).GetId() )
80 case SFX_HINT_DYING:
81 pMgr->Destroy();
82 break;
87 class SfxFloatingWindow_Impl : public SfxListener
89 public:
90 ByteString aWinState;
91 SfxChildWindow* pMgr;
92 BOOL bConstructed;
93 Timer aMoveTimer;
95 void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
98 void SfxFloatingWindow_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint )
100 if ( rHint.IsA(TYPE(SfxSimpleHint)) )
102 switch( ( (SfxSimpleHint&) rHint ).GetId() )
104 case SFX_HINT_DYING:
105 pMgr->Destroy();
106 break;
111 // class SfxModalDefParentHelper -----------------------------------------
113 SfxModalDefParentHelper::SfxModalDefParentHelper( Window *pWindow)
115 pOld = Application::GetDefDialogParent();
116 Application::SetDefDialogParent( pWindow );
119 // -----------------------------------------------------------------------
121 SfxModalDefParentHelper::~SfxModalDefParentHelper()
123 Application::SetDefDialogParent( pOld );
126 // -----------------------------------------------------------------------
128 void SfxModalDialog::SetDialogData_Impl()
130 // save settings (position and user data)
131 SvtViewOptions aDlgOpt( E_DIALOG, String::CreateFromInt32( nUniqId ) );
132 aDlgOpt.SetWindowState(
133 OUString::createFromAscii( GetWindowState( WINDOWSTATE_MASK_POS ).GetBuffer() ) );
134 if ( aExtraData.Len() )
135 aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aExtraData ) ) );
138 // -----------------------------------------------------------------------
140 void SfxModalDialog::GetDialogData_Impl()
142 /* [Beschreibung]
144 Hilfsfunktion; liest die Dialogposition aus der Ini-Datei
145 und setzt diese am "ubergebenen Window.
149 SvtViewOptions aDlgOpt( E_DIALOG, String::CreateFromInt32( nUniqId ) );
150 if ( aDlgOpt.Exists() )
152 // load settings
153 SetWindowState( ByteString( aDlgOpt.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US ) );
154 Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME );
155 OUString aTemp;
156 if ( aUserItem >>= aTemp )
157 aExtraData = String( aTemp );
161 // -----------------------------------------------------------------------
163 void SfxModalDialog::init()
165 GetDialogData_Impl();
166 aTimer.SetTimeout( 100 );
167 aTimer.SetTimeoutHdl( LINK( this, SfxModalDialog, TimerHdl_Impl ) );
168 aTimer.Start();
171 // -----------------------------------------------------------------------
173 SfxModalDialog::SfxModalDialog(Window* pParent, const ResId &rResId )
175 /* [Beschreibung]
177 Konstruktor der allgemeinen Basisklasse f"ur modale Dialoge;
178 ResId wird als ID im ini-file verwendet.
179 Die dort gespeicherte Position wird gesetzt.
182 : ModalDialog(pParent, rResId),
183 nUniqId(rResId.GetId()),
184 pInputSet(0),
185 pOutputSet(0)
187 init();
190 // -----------------------------------------------------------------------
192 SfxModalDialog::SfxModalDialog(Window* pParent,
193 sal_uInt32 nUniqueId,
194 WinBits nWinStyle) :
195 /* [Beschreibung]
197 Konstruktor der allgemeinen Basisklasse f"ur modale Dialoge;
198 ID f"ur das ini-file wird explizit "ubergeben.
199 Die dort gespeicherte Position wird gesetzt.
202 ModalDialog(pParent, nWinStyle),
203 nUniqId(nUniqueId),
204 pInputSet(0),
205 pOutputSet(0)
207 init();
210 // -----------------------------------------------------------------------
212 SfxModalDialog::~SfxModalDialog()
214 /* [Beschreibung]
216 Dtor; schreibt Dialogposition in das ini-file
221 SfxHelpPI *pHelpPI = SFX_APP()->GetHelpPI();
222 if ( pHelpPI )
223 pHelpPI->ResetTopic();
225 SetDialogData_Impl();
226 aTimer.Stop();
227 delete pOutputSet;
230 void SfxModalDialog::CreateOutputItemSet( SfxItemPool& rPool )
232 DBG_ASSERT( !pOutputSet, "Double creation of OutputSet!" );
233 if (!pOutputSet)
234 pOutputSet = new SfxAllItemSet( rPool );
237 // -----------------------------------------------------------------------
239 IMPL_LINK( SfxModalDialog, TimerHdl_Impl, Timer*, EMPTYARG )
242 SfxHelpPI *pHelpPI = SFX_APP()->GetHelpPI();
243 if ( pHelpPI )
244 pHelpPI->LoadTopic( GetHelpId() );
246 return 0L;
249 void SfxModalDialog::CreateOutputItemSet( const SfxItemSet& rSet )
251 DBG_ASSERT( !pOutputSet, "Double creation of OutputSet!" );
252 if (!pOutputSet)
254 pOutputSet = new SfxItemSet( rSet );
255 pOutputSet->ClearItem();
259 //-------------------------------------------------------------------------
260 void SfxModelessDialog::StateChanged( StateChangedType nStateChange )
262 if ( nStateChange == STATE_CHANGE_INITSHOW )
264 if ( pImp->aWinState.Len() )
266 SetWindowState( pImp->aWinState );
268 else
270 Point aPos = GetPosPixel();
271 if ( !aPos.X() )
273 aSize = GetSizePixel();
275 Size aParentSize = GetParent()->GetOutputSizePixel();
276 Size aDlgSize = GetSizePixel();
277 aPos.X() += ( aParentSize.Width() - aDlgSize.Width() ) / 2;
278 aPos.Y() += ( aParentSize.Height() - aDlgSize.Height() ) / 2;
280 Point aPoint;
281 Rectangle aRect = GetDesktopRectPixel();
282 aPoint.X() = aRect.Right() - aDlgSize.Width();
283 aPoint.Y() = aRect.Bottom() - aDlgSize.Height();
285 aPoint = OutputToScreenPixel( aPoint );
287 if ( aPos.X() > aPoint.X() )
288 aPos.X() = aPoint.X() ;
289 if ( aPos.Y() > aPoint.Y() )
290 aPos.Y() = aPoint.Y();
292 if ( aPos.X() < 0 ) aPos.X() = 0;
293 if ( aPos.Y() < 0 ) aPos.Y() = 0;
295 SetPosPixel( aPos );
299 pImp->bConstructed = TRUE;
302 ModelessDialog::StateChanged( nStateChange );
305 void SfxModelessDialog::Initialize(SfxChildWinInfo *pInfo)
307 /* [Beschreibung]
309 Initialisierung der Klasse SfxModelessDialog "uber ein SfxChildWinInfo.
310 Die Initialisierung erfolgt erst in einem 2.Schritt
311 nach dem ctor und sollte vom ctor der abgeleiteten Klasse
312 oder von dem des SfxChildWindows aufgerufen werden.
316 pImp->aWinState = pInfo->aWinState;
319 void SfxModelessDialog::Resize()
321 /* [Beschreibung]
323 Diese virtuelle Methode der Klasse FloatingWindow merkt sich ggf. eine
324 ver"anderte Gr"o\se.
325 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
326 auch SfxFloatingWindow::Resize() gerufen werden.
330 ModelessDialog::Resize();
331 if ( pImp->bConstructed && pImp->pMgr )
333 // start timer for saving window status information
334 pImp->aMoveTimer.Start();
338 void SfxModelessDialog::Move()
340 ModelessDialog::Move();
341 if ( pImp->bConstructed && pImp->pMgr && IsReallyVisible() )
343 // start timer for saving window status information
344 pImp->aMoveTimer.Start();
349 Implements a timer event that is triggered by a move or resize of the window
350 This will save config information to Views.xcu with a small delay
352 IMPL_LINK( SfxModelessDialog, TimerHdl, Timer*, EMPTYARG)
354 pImp->aMoveTimer.Stop();
355 if ( pImp->bConstructed && pImp->pMgr )
357 if ( !IsRollUp() )
358 aSize = GetSizePixel();
359 ULONG nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE;
360 if ( GetStyle() & WB_SIZEABLE )
361 nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT );
362 pImp->aWinState = GetWindowState( nMask );
363 GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SFX_CHILDWIN_DOCKINGWINDOW, SFX_ALIGNDOCKINGWINDOW, pImp->pMgr->GetType() );
365 return 0;
368 // -----------------------------------------------------------------------
370 SfxModelessDialog::SfxModelessDialog( SfxBindings *pBindinx,
371 SfxChildWindow *pCW,
372 Window* pParent, WinBits nWinBits ) :
373 ModelessDialog (pParent, nWinBits),
374 pBindings(pBindinx),
375 pImp( new SfxModelessDialog_Impl )
377 pImp->pMgr = pCW;
378 pImp->bConstructed = FALSE;
379 sal_uInt32 nId = GetHelpId();
380 SetHelpId(0);
381 SetUniqueId( nId );
382 if ( pBindinx )
383 pImp->StartListening( *pBindinx );
384 pImp->aMoveTimer.SetTimeout(50);
385 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxModelessDialog,TimerHdl));
388 // -----------------------------------------------------------------------
390 SfxModelessDialog::SfxModelessDialog( SfxBindings *pBindinx,
391 SfxChildWindow *pCW, Window *pParent,
392 const ResId& rResId ) :
393 ModelessDialog(pParent, rResId),
394 pBindings(pBindinx),
395 pImp( new SfxModelessDialog_Impl )
397 pImp->pMgr = pCW;
398 pImp->bConstructed = FALSE;
399 sal_uInt32 nId = GetHelpId();
400 SetHelpId(0);
401 SetUniqueId( nId );
402 if ( pBindinx )
403 pImp->StartListening( *pBindinx );
404 pImp->aMoveTimer.SetTimeout(50);
405 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxModelessDialog,TimerHdl));
408 // -----------------------------------------------------------------------
410 long SfxModelessDialog::Notify( NotifyEvent& rEvt )
412 /* [Beschreibung]
414 Wenn ein ModelessDialog aktiviert wird, wird sein ViewFrame aktiviert.
415 Notwendig ist das bei PlugInFrames.
419 if ( rEvt.GetType() == EVENT_GETFOCUS )
421 pBindings->SetActiveFrame( pImp->pMgr->GetFrame() );
422 pImp->pMgr->Activate_Impl();
423 Window* pWindow = rEvt.GetWindow();
424 ULONG nHelpId = 0;
425 while ( !nHelpId && pWindow )
427 nHelpId = pWindow->GetHelpId();
428 pWindow = pWindow->GetParent();
431 if ( nHelpId )
432 SfxHelp::OpenHelpAgent( pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), nHelpId );
434 else if ( rEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() )
436 pBindings->SetActiveFrame( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > () );
437 pImp->pMgr->Deactivate_Impl();
439 else if( rEvt.GetType() == EVENT_KEYINPUT )
441 // KeyInput zuerst f"ur Dialogfunktionen zulassen ( TAB etc. )
442 if ( !ModelessDialog::Notify( rEvt ) && SfxViewShell::Current() )
443 // dann auch global g"ultige Acceleratoren verwenden
444 return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() );
445 return sal_True;
448 return ModelessDialog::Notify( rEvt );
451 // -----------------------------------------------------------------------
453 SfxModelessDialog::~SfxModelessDialog()
455 /* [Beschreibung]
457 Dtor
461 if ( pImp->pMgr->GetFrame().is() && pImp->pMgr->GetFrame() == pBindings->GetActiveFrame() )
462 pBindings->SetActiveFrame( NULL );
463 delete pImp;
466 //-------------------------------------------------------------------------
468 sal_Bool SfxModelessDialog::Close()
470 /* [Beschreibung]
472 Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des
473 ChildWindow-Slots zerst"ort wird.
474 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
475 danach SfxModelessDialogWindow::Close() gerufen werden, wenn nicht das
476 Close() mit "return sal_False" abgebrochen wird.
481 // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert
482 // werden kann
483 SfxBoolItem aValue( pImp->pMgr->GetType(), sal_False);
484 pBindings->GetDispatcher_Impl()->Execute(
485 pImp->pMgr->GetType(),
486 SFX_CALLMODE_RECORD|SFX_CALLMODE_SYNCHRON, &aValue, 0L );
487 return sal_True;
490 //-------------------------------------------------------------------------
492 void SfxModelessDialog::FillInfo(SfxChildWinInfo& rInfo) const
494 /* [Beschreibung]
496 F"ullt ein SfxChildWinInfo mit f"ur SfxModelessDialof spezifischen Daten,
497 damit sie in die INI-Datei geschrieben werden koennen.
498 Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in
499 der ChildWindow-Klasse erh"alt.
500 ModelessDialogs haben keine spezifischen Informationen, so dass die
501 Basisimplementierung nichts tut und daher nicht gerufen werden mu\s.
505 rInfo.aSize = aSize;
506 if ( IsRollUp() )
507 rInfo.nFlags |= SFX_CHILDWIN_ZOOMIN;
510 // -----------------------------------------------------------------------
512 long SfxFloatingWindow::Notify( NotifyEvent& rEvt )
514 /* [Beschreibung]
516 Wenn ein ModelessDialog aktiviert wird, wird sein ViewFrame aktiviert.
517 Notwendig ist das bei PlugInFrames.
521 if ( rEvt.GetType() == EVENT_GETFOCUS )
523 pBindings->SetActiveFrame( pImp->pMgr->GetFrame() );
524 pImp->pMgr->Activate_Impl();
525 Window* pWindow = rEvt.GetWindow();
526 ULONG nHelpId = 0;
527 while ( !nHelpId && pWindow )
529 nHelpId = pWindow->GetHelpId();
530 pWindow = pWindow->GetParent();
533 if ( nHelpId )
534 SfxHelp::OpenHelpAgent( pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), nHelpId );
536 else if ( rEvt.GetType() == EVENT_LOSEFOCUS )
538 if ( !HasChildPathFocus() )
540 pBindings->SetActiveFrame( NULL );
541 pImp->pMgr->Deactivate_Impl();
544 else if( rEvt.GetType() == EVENT_KEYINPUT )
546 // KeyInput zuerst f"ur Dialogfunktionen zulassen
547 if ( !FloatingWindow::Notify( rEvt ) && SfxViewShell::Current() )
548 // dann auch global g"ultige Acceleratoren verwenden
549 return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() );
550 return sal_True;
553 return FloatingWindow::Notify( rEvt );
556 // -----------------------------------------------------------------------
558 SfxFloatingWindow::SfxFloatingWindow( SfxBindings *pBindinx,
559 SfxChildWindow *pCW,
560 Window* pParent, WinBits nWinBits) :
561 FloatingWindow (pParent, nWinBits),
562 pBindings(pBindinx),
563 pImp( new SfxFloatingWindow_Impl )
565 pImp->pMgr = pCW;
566 pImp->bConstructed = FALSE;
567 sal_uInt32 nId = GetHelpId();
568 SetHelpId(0);
569 SetUniqueId( nId );
570 if ( pBindinx )
571 pImp->StartListening( *pBindinx );
572 pImp->aMoveTimer.SetTimeout(50);
573 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxFloatingWindow,TimerHdl));
576 // -----------------------------------------------------------------------
578 SfxFloatingWindow::SfxFloatingWindow( SfxBindings *pBindinx,
579 SfxChildWindow *pCW,
580 Window* pParent,
581 const ResId& rResId) :
582 FloatingWindow(pParent, rResId),
583 pBindings(pBindinx),
584 pImp( new SfxFloatingWindow_Impl )
586 pImp->pMgr = pCW;
587 pImp->bConstructed = FALSE;
588 sal_uInt32 nId = GetHelpId();
589 SetHelpId(0);
590 SetUniqueId( nId );
591 if ( pBindinx )
592 pImp->StartListening( *pBindinx );
593 pImp->aMoveTimer.SetTimeout(50);
594 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxFloatingWindow,TimerHdl));
597 //-------------------------------------------------------------------------
599 sal_Bool SfxFloatingWindow::Close()
601 /* [Beschreibung]
603 Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des
604 ChildWindow-Slots zerst"ort wird.
605 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
606 danach SfxFloatingWindow::Close() gerufen werden, wenn nicht das Close()
607 mit "return sal_False" abgebrochen wird.
612 // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert
613 // werden kann
614 SfxBoolItem aValue( pImp->pMgr->GetType(), sal_False);
615 pBindings->GetDispatcher_Impl()->Execute(
616 pImp->pMgr->GetType(),
617 SFX_CALLMODE_RECORD|SFX_CALLMODE_SYNCHRON, &aValue, 0L );
618 return sal_True;
621 // -----------------------------------------------------------------------
623 SfxFloatingWindow::~SfxFloatingWindow()
625 /* [Beschreibung]
627 Dtor
631 if ( pImp->pMgr->GetFrame() == pBindings->GetActiveFrame() )
632 pBindings->SetActiveFrame( NULL );
633 delete pImp;
636 //-------------------------------------------------------------------------
638 void SfxFloatingWindow::Resize()
640 /* [Beschreibung]
642 Diese virtuelle Methode der Klasse FloatingWindow merkt sich ggf. eine
643 ver"anderte Gr"o\se.
644 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
645 auch SfxFloatingWindow::Resize() gerufen werden.
649 FloatingWindow::Resize();
650 if ( pImp->bConstructed && pImp->pMgr )
652 // start timer for saving window status information
653 pImp->aMoveTimer.Start();
657 void SfxFloatingWindow::Move()
659 FloatingWindow::Move();
660 if ( pImp->bConstructed && pImp->pMgr )
662 // start timer for saving window status information
663 pImp->aMoveTimer.Start();
668 Implements a timer event that is triggered by a move or resize of the window
669 This will save config information to Views.xcu with a small delay
671 IMPL_LINK( SfxFloatingWindow, TimerHdl, Timer*, EMPTYARG)
673 pImp->aMoveTimer.Stop();
674 if ( pImp->bConstructed && pImp->pMgr )
676 if ( !IsRollUp() )
677 aSize = GetSizePixel();
678 ULONG nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE;
679 if ( GetStyle() & WB_SIZEABLE )
680 nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT );
681 pImp->aWinState = GetWindowState( nMask );
682 GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SFX_CHILDWIN_DOCKINGWINDOW, SFX_ALIGNDOCKINGWINDOW, pImp->pMgr->GetType() );
684 return 0;
687 //-------------------------------------------------------------------------
688 void SfxFloatingWindow::StateChanged( StateChangedType nStateChange )
690 if ( nStateChange == STATE_CHANGE_INITSHOW )
692 // FloatingWindows are not centered by default
693 if ( pImp->aWinState.Len() )
694 SetWindowState( pImp->aWinState );
695 pImp->bConstructed = TRUE;
698 FloatingWindow::StateChanged( nStateChange );
702 void SfxFloatingWindow::Initialize(SfxChildWinInfo *pInfo)
704 /* [Beschreibung]
706 Initialisierung der Klasse SfxFloatingWindow "uber ein SfxChildWinInfo.
707 Die Initialisierung erfolgt erst in einem 2.Schritt
708 nach dem ctor und sollte vom ctor der abgeleiteten Klasse
709 oder von dem des SfxChildWindows aufgerufen werden.
712 pImp->aWinState = pInfo->aWinState;
715 //-------------------------------------------------------------------------
717 void SfxFloatingWindow::FillInfo(SfxChildWinInfo& rInfo) const
719 /* [Beschreibung]
721 F"ullt ein SfxChildWinInfo mit f"ur SfxFloatingWindow spezifischen Daten,
722 damit sie in die INI-Datei geschrieben werden koennen.
723 Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in
724 der ChildWindow-Klasse erh"alt.
725 Eingetragen werden hier gemerkte Gr"o\se und das ZoomIn-Flag.
726 Wird diese Methode "uberschrieben, mu\s zuerst die Basisimplementierung
727 gerufen werden.
731 rInfo.aSize = aSize;
732 if ( IsRollUp() )
733 rInfo.nFlags |= SFX_CHILDWIN_ZOOMIN;
736 // SfxSingleTabDialog ----------------------------------------------------
738 IMPL_LINK( SfxSingleTabDialog, OKHdl_Impl, Button *, EMPTYARG )
740 /* [Beschreibung]
742 Ok_Handler; f"ur die gesetzte Page wird FillItemSet() gerufen.
746 if ( !GetInputItemSet() )
748 // TabPage without ItemSet
749 EndDialog( RET_OK );
750 return 1;
753 if ( !GetOutputItemSet() )
755 CreateOutputItemSet( *GetInputItemSet() );
757 sal_Bool bModified = sal_False;
759 if ( pImpl->m_pSfxPage->HasExchangeSupport() )
761 int nRet = pImpl->m_pSfxPage->DeactivatePage( GetOutputSetImpl() );
762 if ( nRet != SfxTabPage::LEAVE_PAGE )
763 return 0;
764 else
765 bModified = ( GetOutputItemSet()->Count() > 0 );
767 else
768 bModified = pImpl->m_pSfxPage->FillItemSet( *GetOutputSetImpl() );
770 if ( bModified )
772 // auch noch schnell User-Daten im IniManager abspeichern
773 pImpl->m_pSfxPage->FillUserData();
774 String sData( pImpl->m_pSfxPage->GetUserData() );
775 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( GetUniqId() ) );
776 aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( sData ) ) );
777 EndDialog( RET_OK );
779 else
780 EndDialog( RET_CANCEL );
781 return 0;
784 // -----------------------------------------------------------------------
786 SfxSingleTabDialog::SfxSingleTabDialog
788 Window *pParent,
789 const SfxItemSet& rSet,
790 sal_uInt16 nUniqueId
793 /* [Beschreibung]
795 Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge;
796 ID f"ur das ini-file wird "ubergeben.
799 SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ),
801 pOKBtn ( 0 ),
802 pCancelBtn ( 0 ),
803 pHelpBtn ( 0 ),
804 pImpl ( new SingleTabDlgImpl )
806 DBG_WARNING( "please use the ctor with ViewFrame" );
807 SetInputSet( &rSet );
810 // -----------------------------------------------------------------------
812 SfxSingleTabDialog::SfxSingleTabDialog
814 Window* pParent,
815 sal_uInt16 nUniqueId,
816 const SfxItemSet* pInSet
819 /* [Beschreibung]
821 Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge;
822 ID f"ur das ini-file wird "ubergeben.
823 Sollte nicht mehr benutzt werden.
826 : SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ),
828 pOKBtn ( 0 ),
829 pCancelBtn ( 0 ),
830 pHelpBtn ( 0 ),
831 pImpl ( new SingleTabDlgImpl )
833 DBG_WARNING( "bitte den Ctor mit ViewFrame verwenden" );
834 SetInputSet( pInSet );
837 // -----------------------------------------------------------------------
839 SfxSingleTabDialog::SfxSingleTabDialog
841 Window* pParent,
842 sal_uInt16 nUniqueId,
843 const String& rInfoURL
846 /* [Beschreibung]
848 Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge;
849 ID f"ur das ini-file wird "ubergeben.
852 : SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ),
854 pOKBtn ( NULL ),
855 pCancelBtn ( NULL ),
856 pHelpBtn ( NULL ),
857 pImpl ( new SingleTabDlgImpl )
859 pImpl->m_sInfoURL = rInfoURL;
862 // -----------------------------------------------------------------------
864 SfxSingleTabDialog::~SfxSingleTabDialog()
866 delete pOKBtn;
867 delete pCancelBtn;
868 delete pHelpBtn;
869 delete pImpl->m_pTabPage;
870 delete pImpl->m_pSfxPage;
871 delete pImpl->m_pLine;
872 delete pImpl->m_pInfoImage;
873 delete pImpl;
876 // -----------------------------------------------------------------------
878 void SfxSingleTabDialog::SetPage( TabPage* pNewPage )
880 if ( !pImpl->m_pLine )
881 pImpl->m_pLine = new FixedLine( this );
883 if ( !pOKBtn )
885 pOKBtn = new OKButton( this, WB_DEFBUTTON );
886 pOKBtn->SetClickHdl( LINK( this, SfxSingleTabDialog, OKHdl_Impl ) );
889 if ( pImpl->m_sInfoURL.Len() > 0 && !pImpl->m_pInfoImage )
891 pImpl->m_pInfoImage = new ::svt::FixedHyperlinkImage( this );
892 Image aInfoImage = Image( SfxResId( IMG_INFO ) );
893 Size aImageSize = aInfoImage.GetSizePixel();
894 aImageSize.Width() += 4;
895 aImageSize.Height() += 4;
896 pImpl->m_pInfoImage->SetSizePixel( aImageSize );
897 pImpl->m_pInfoImage->SetImage( aInfoImage );
898 pImpl->m_pInfoImage->SetURL( pImpl->m_sInfoURL );
899 pImpl->m_pInfoImage->SetClickHdl( pImpl->m_aInfoLink );
902 if ( pImpl->m_pTabPage )
903 delete pImpl->m_pTabPage;
904 if ( pImpl->m_pSfxPage )
905 delete pImpl->m_pSfxPage;
906 pImpl->m_pTabPage = pNewPage;
908 if ( pImpl->m_pTabPage )
910 // Gr"ossen und Positionen anpassen
911 pImpl->m_pTabPage->SetPosPixel( Point() );
912 Size aOutSz( pImpl->m_pTabPage->GetSizePixel() );
913 Size aOffSz = LogicToPixel( Size( RSC_SP_CTRL_X, RSC_SP_CTRL_Y ), MAP_APPFONT );
914 Size aFLSz = LogicToPixel( Size( aOutSz.Width(), RSC_CD_FIXEDLINE_HEIGHT ) );
915 Size aBtnSz = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ), MAP_APPFONT );
917 Point aPnt( 0, aOutSz.Height() );
918 pImpl->m_pLine->SetPosSizePixel( aPnt, aFLSz );
919 aPnt.X() = aOutSz.Width() - aOffSz.Width() - aBtnSz.Width();
920 aPnt.Y() += aFLSz.Height() + ( aOffSz.Height() / 2 );
921 pOKBtn->SetPosSizePixel( aPnt, aBtnSz );
923 if ( pImpl->m_pInfoImage )
925 aPnt.X() = aOffSz.Width();
926 long nDelta = ( pImpl->m_pInfoImage->GetSizePixel().Height() - aBtnSz.Height() ) / 2;
927 aPnt.Y() -= nDelta;
928 pImpl->m_pInfoImage->SetPosPixel( aPnt );
929 pImpl->m_pInfoImage->Show();
932 aOutSz.Height() += aFLSz.Height() + ( aOffSz.Height() / 2 ) + aBtnSz.Height() + aOffSz.Height();
933 SetOutputSizePixel( aOutSz );
935 pImpl->m_pLine->Show();
936 pOKBtn->Show();
937 pImpl->m_pTabPage->Show();
939 // Text der TabPage in den Dialog setzen
940 SetText( pImpl->m_pTabPage->GetText() );
942 // Dialog bekommt HelpId der TabPage
943 SetHelpId( pImpl->m_pTabPage->GetHelpId() );
944 SetUniqueId( pImpl->m_pTabPage->GetUniqueId() );
948 // -----------------------------------------------------------------------
950 void SfxSingleTabDialog::SetTabPage( SfxTabPage* pTabPage,
951 GetTabPageRanges pRangesFunc )
952 /* [Beschreibung]
954 Setzen einer (neuen) TabPage; eine bereits vorhandene Page
955 wird gel"oscht.
956 Die "ubergebene Page wird durch Aufruf von Reset() mit dem
957 initial "ubergebenen Itemset initialisiert.
961 if ( !pOKBtn )
963 pOKBtn = new OKButton( this, WB_DEFBUTTON );
964 pOKBtn->SetClickHdl( LINK( this, SfxSingleTabDialog, OKHdl_Impl ) );
966 if ( !pCancelBtn )
967 pCancelBtn = new CancelButton( this );
968 if ( !pHelpBtn )
969 pHelpBtn = new HelpButton( this );
971 if ( pImpl->m_pTabPage )
972 delete pImpl->m_pTabPage;
973 if ( pImpl->m_pSfxPage )
974 delete pImpl->m_pSfxPage;
975 pImpl->m_pSfxPage = pTabPage;
976 fnGetRanges = pRangesFunc;
978 if ( pImpl->m_pSfxPage )
980 // erstmal die User-Daten besorgen, dann erst Reset()
981 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( GetUniqId() ) );
982 String sUserData;
983 Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME );
984 OUString aTemp;
985 if ( aUserItem >>= aTemp )
986 sUserData = String( aTemp );
987 pImpl->m_pSfxPage->SetUserData( sUserData );
988 pImpl->m_pSfxPage->Reset( *GetInputItemSet() );
989 pImpl->m_pSfxPage->Show();
991 // Gr"ossen und Positionen anpassen
992 pImpl->m_pSfxPage->SetPosPixel( Point() );
993 Size aOutSz( pImpl->m_pSfxPage->GetSizePixel() );
994 Size aBtnSiz = LogicToPixel( Size( 50, 14 ), MAP_APPFONT );
995 Point aPnt( aOutSz.Width(), LogicToPixel( Point( 0, 6 ), MAP_APPFONT ).Y() );
996 aOutSz.Width() += aBtnSiz.Width() + LogicToPixel( Size( 6, 0 ), MAP_APPFONT ).Width();
997 SetOutputSizePixel( aOutSz );
998 pOKBtn->SetPosSizePixel( aPnt, aBtnSiz );
999 pOKBtn->Show();
1000 aPnt.Y() = LogicToPixel( Point( 0, 23 ), MAP_APPFONT ).Y();
1001 pCancelBtn->SetPosSizePixel( aPnt, aBtnSiz );
1002 pCancelBtn->Show();
1003 aPnt.Y() = LogicToPixel( Point( 0, 43 ), MAP_APPFONT ).Y();
1004 pHelpBtn->SetPosSizePixel( aPnt, aBtnSiz );
1006 if ( Help::IsContextHelpEnabled() )
1007 pHelpBtn->Show();
1009 // Text der TabPage in den Dialog setzen
1010 SetText( pImpl->m_pSfxPage->GetText() );
1012 // Dialog bekommt HelpId der TabPage
1013 SetHelpId( pImpl->m_pSfxPage->GetHelpId() );
1014 SetUniqueId( pImpl->m_pSfxPage->GetUniqueId() );
1018 // -----------------------------------------------------------------------
1020 void SfxSingleTabDialog::SetInfoLink( const Link& rLink )
1022 pImpl->m_aInfoLink = rLink;
1025 //--------------------------------------------------------------------
1026 // Vergleichsfunktion fuer qsort
1028 #ifdef WNT
1029 int __cdecl BaseDlgsCmpUS_Impl( const void* p1, const void* p2 )
1030 #else
1031 #if defined(OS2) && defined(ICC)
1032 int _Optlink BaseDlgsCmpUS_Impl( const void* p1, const void* p2 )
1033 #else
1034 extern "C" int BaseDlgsCmpUS_Impl( const void* p1, const void* p2 )
1035 #endif
1036 #endif
1038 return *(sal_uInt16*)p1 - *(sal_uInt16*)p2;
1041 // -----------------------------------------------------------------------
1044 Bildet das Set "uber die Ranges der Page. Die Page muss die statische
1045 Methode f"ur das Erfragen ihrer Ranges bei SetTabPage angegeben haben,
1046 liefert also ihr Set onDemand.
1048 const sal_uInt16* SfxSingleTabDialog::GetInputRanges( const SfxItemPool& rPool )
1050 if ( GetInputItemSet() )
1052 DBG_ERROR( "Set bereits vorhanden!" );
1053 return GetInputItemSet()->GetRanges();
1056 if ( pRanges )
1057 return pRanges;
1058 SvUShorts aUS(16, 16);
1060 if ( fnGetRanges)
1062 const sal_uInt16 *pTmpRanges = (fnGetRanges)();
1063 const sal_uInt16 *pIter = pTmpRanges;
1064 sal_uInt16 nLen;
1065 for ( nLen = 0; *pIter; ++nLen, ++pIter )
1067 aUS.Insert( pTmpRanges, nLen, aUS.Count() );
1070 //! Doppelte Ids entfernen?
1071 sal_uInt16 nCount = aUS.Count();
1073 for ( sal_uInt16 i = 0; i < nCount; ++i )
1074 aUS[i] = rPool.GetWhich( aUS[i]) ;
1076 // sortieren
1077 if ( aUS.Count() > 1 )
1078 qsort( (void*)aUS.GetData(), aUS.Count(), sizeof(sal_uInt16), BaseDlgsCmpUS_Impl );
1080 pRanges = new sal_uInt16[aUS.Count() + 1];
1081 memcpy( pRanges, aUS.GetData(), sizeof(sal_uInt16) * aUS.Count() );
1082 pRanges[aUS.Count()] = 0;
1083 return pRanges;