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 ---------------------------------------------------------------
28
29 #include <stdlib.h>
30 #include <vcl/fixed.hxx>
31 #include <vcl/help.hxx>
32 #include <vcl/msgbox.hxx>
33 #include <svl/eitem.hxx>
34 #include <unotools/viewoptions.hxx>
35 #include <svtools/fixedhyper.hxx>
36 #include <svtools/controldims.hrc>
37
38 #include <sfx2/basedlgs.hxx>
39 #include <sfx2/viewfrm.hxx>
40 #include <sfx2/tabdlg.hxx>
41 #include <sfx2/app.hxx>
42 #include <sfx2/bindings.hxx>
43 #include <sfx2/dispatch.hxx>
44 #include <sfx2/childwin.hxx>
45 #include <sfx2/viewsh.hxx>
46 #include "sfx2/sfxhelp.hxx"
47 #include "workwin.hxx"
48 #include "sfx2/sfxresid.hxx"
49 #include "dialog.hrc"
50
51 using namespace ::com::sun::star::uno;
52 using namespace ::rtl;
53
54 #define USERITEM_NAME OUString::createFromAscii( "UserItem" )
55
56 class SfxModelessDialog_Impl : public SfxListener
57 {
58 public:
59 ByteString aWinState;
60 SfxChildWindow* pMgr;
61 sal_Bool bConstructed;
62 void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
63
64 Timer aMoveTimer;
65 };
66
Notify(SfxBroadcaster &,const SfxHint & rHint)67 void SfxModelessDialog_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint )
68 {
69 if ( rHint.IsA(TYPE(SfxSimpleHint)) )
70 {
71 switch( ( (SfxSimpleHint&) rHint ).GetId() )
72 {
73 case SFX_HINT_DYING:
74 pMgr->Destroy();
75 break;
76 }
77 }
78 }
79
80 class SfxFloatingWindow_Impl : public SfxListener
81 {
82 public:
83 ByteString aWinState;
84 SfxChildWindow* pMgr;
85 sal_Bool bConstructed;
86 Timer aMoveTimer;
87
88 void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
89 };
90
Notify(SfxBroadcaster &,const SfxHint & rHint)91 void SfxFloatingWindow_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint )
92 {
93 if ( rHint.IsA(TYPE(SfxSimpleHint)) )
94 {
95 switch( ( (SfxSimpleHint&) rHint ).GetId() )
96 {
97 case SFX_HINT_DYING:
98 pMgr->Destroy();
99 break;
100 }
101 }
102 }
103
104 // class SfxModalDefParentHelper -----------------------------------------
105
SfxModalDefParentHelper(Window * pWindow)106 SfxModalDefParentHelper::SfxModalDefParentHelper( Window *pWindow)
107 {
108 pOld = Application::GetDefDialogParent();
109 Application::SetDefDialogParent( pWindow );
110 }
111
112 // -----------------------------------------------------------------------
113
~SfxModalDefParentHelper()114 SfxModalDefParentHelper::~SfxModalDefParentHelper()
115 {
116 Application::SetDefDialogParent( pOld );
117 }
118
119 // -----------------------------------------------------------------------
120
SetDialogData_Impl()121 void SfxModalDialog::SetDialogData_Impl()
122 {
123 // save settings (position and user data)
124 SvtViewOptions aDlgOpt( E_DIALOG, String::CreateFromInt32( nUniqId ) );
125 aDlgOpt.SetWindowState(
126 OUString::createFromAscii( GetWindowState( WINDOWSTATE_MASK_POS ).GetBuffer() ) );
127 if ( aExtraData.Len() )
128 aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aExtraData ) ) );
129 }
130
131 // -----------------------------------------------------------------------
132
GetDialogData_Impl()133 void SfxModalDialog::GetDialogData_Impl()
134
135 /* [Beschreibung]
136
137 Hilfsfunktion; liest die Dialogposition aus der Ini-Datei
138 und setzt diese am "ubergebenen Window.
139 */
140
141 {
142 SvtViewOptions aDlgOpt( E_DIALOG, String::CreateFromInt32( nUniqId ) );
143 if ( aDlgOpt.Exists() )
144 {
145 // load settings
146 SetWindowState( ByteString( aDlgOpt.GetWindowState().getStr(), RTL_TEXTENCODING_ASCII_US ) );
147 Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME );
148 OUString aTemp;
149 if ( aUserItem >>= aTemp )
150 aExtraData = String( aTemp );
151 }
152 }
153
154 // -----------------------------------------------------------------------
155
init()156 void SfxModalDialog::init()
157 {
158 GetDialogData_Impl();
159 }
160
161 // -----------------------------------------------------------------------
162
SfxModalDialog(Window * pParent,const ResId & rResId)163 SfxModalDialog::SfxModalDialog(Window* pParent, const ResId &rResId )
164
165 /* [Beschreibung]
166
167 Konstruktor der allgemeinen Basisklasse f"ur modale Dialoge;
168 ResId wird als ID im ini-file verwendet.
169 Die dort gespeicherte Position wird gesetzt.
170 */
171
172 : ModalDialog(pParent, rResId),
173 nUniqId(rResId.GetId()),
174 pInputSet(0),
175 pOutputSet(0)
176 {
177 init();
178 }
179
180 // -----------------------------------------------------------------------
181
SfxModalDialog(Window * pParent,sal_uInt32 nUniqueId,WinBits nWinStyle)182 SfxModalDialog::SfxModalDialog(Window* pParent,
183 sal_uInt32 nUniqueId,
184 WinBits nWinStyle) :
185 /* [Beschreibung]
186
187 Konstruktor der allgemeinen Basisklasse f"ur modale Dialoge;
188 ID f"ur das ini-file wird explizit "ubergeben.
189 Die dort gespeicherte Position wird gesetzt.
190 */
191
192 ModalDialog(pParent, nWinStyle),
193 nUniqId(nUniqueId),
194 pInputSet(0),
195 pOutputSet(0)
196 {
197 init();
198 }
199
200 // -----------------------------------------------------------------------
201
~SfxModalDialog()202 SfxModalDialog::~SfxModalDialog()
203
204 /* [Beschreibung]
205
206 Dtor; schreibt Dialogposition in das ini-file
207 */
208
209 {
210 SetDialogData_Impl();
211 delete pOutputSet;
212 }
213
CreateOutputItemSet(SfxItemPool & rPool)214 void SfxModalDialog::CreateOutputItemSet( SfxItemPool& rPool )
215 {
216 DBG_ASSERT( !pOutputSet, "Double creation of OutputSet!" );
217 if (!pOutputSet)
218 pOutputSet = new SfxAllItemSet( rPool );
219 }
220
221 // -----------------------------------------------------------------------
222
CreateOutputItemSet(const SfxItemSet & rSet)223 void SfxModalDialog::CreateOutputItemSet( const SfxItemSet& rSet )
224 {
225 DBG_ASSERT( !pOutputSet, "Double creation of OutputSet!" );
226 if (!pOutputSet)
227 {
228 pOutputSet = new SfxItemSet( rSet );
229 pOutputSet->ClearItem();
230 }
231 }
232
233 //-------------------------------------------------------------------------
StateChanged(StateChangedType nStateChange)234 void SfxModelessDialog::StateChanged( StateChangedType nStateChange )
235 {
236 if ( nStateChange == STATE_CHANGE_INITSHOW )
237 {
238 if ( pImp->aWinState.Len() )
239 {
240 SetWindowState( pImp->aWinState );
241 }
242 else
243 {
244 Point aPos = GetPosPixel();
245 if ( !aPos.X() )
246 {
247 aSize = GetSizePixel();
248
249 Size aParentSize = GetParent()->GetOutputSizePixel();
250 Size aDlgSize = GetSizePixel();
251 aPos.X() += ( aParentSize.Width() - aDlgSize.Width() ) / 2;
252 aPos.Y() += ( aParentSize.Height() - aDlgSize.Height() ) / 2;
253
254 Point aPoint;
255 Rectangle aRect = GetDesktopRectPixel();
256 aPoint.X() = aRect.Right() - aDlgSize.Width();
257 aPoint.Y() = aRect.Bottom() - aDlgSize.Height();
258
259 aPoint = OutputToScreenPixel( aPoint );
260
261 if ( aPos.X() > aPoint.X() )
262 aPos.X() = aPoint.X() ;
263 if ( aPos.Y() > aPoint.Y() )
264 aPos.Y() = aPoint.Y();
265
266 if ( aPos.X() < 0 ) aPos.X() = 0;
267 if ( aPos.Y() < 0 ) aPos.Y() = 0;
268
269 SetPosPixel( aPos );
270 }
271 }
272
273 pImp->bConstructed = sal_True;
274 }
275
276 ModelessDialog::StateChanged( nStateChange );
277 }
278
Initialize(SfxChildWinInfo * pInfo)279 void SfxModelessDialog::Initialize(SfxChildWinInfo *pInfo)
280
281 /* [Beschreibung]
282
283 Initialisierung der Klasse SfxModelessDialog "uber ein SfxChildWinInfo.
284 Die Initialisierung erfolgt erst in einem 2.Schritt
285 nach dem ctor und sollte vom ctor der abgeleiteten Klasse
286 oder von dem des SfxChildWindows aufgerufen werden.
287 */
288
289 {
290 pImp->aWinState = pInfo->aWinState;
291 }
292
Resize()293 void SfxModelessDialog::Resize()
294
295 /* [Beschreibung]
296
297 Diese virtuelle Methode der Klasse FloatingWindow merkt sich ggf. eine
298 ver"anderte Gr"o\se.
299 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
300 auch SfxFloatingWindow::Resize() gerufen werden.
301 */
302
303 {
304 ModelessDialog::Resize();
305 if ( pImp->bConstructed && pImp->pMgr )
306 {
307 // start timer for saving window status information
308 pImp->aMoveTimer.Start();
309 }
310 }
311
Move()312 void SfxModelessDialog::Move()
313 {
314 ModelessDialog::Move();
315 if ( pImp->bConstructed && pImp->pMgr && IsReallyVisible() )
316 {
317 // start timer for saving window status information
318 pImp->aMoveTimer.Start();
319 }
320 }
321
322 /*
323 Implements a timer event that is triggered by a move or resize of the window
324 This will save config information to Views.xcu with a small delay
325 */
IMPL_LINK(SfxModelessDialog,TimerHdl,Timer *,EMPTYARG)326 IMPL_LINK( SfxModelessDialog, TimerHdl, Timer*, EMPTYARG)
327 {
328 pImp->aMoveTimer.Stop();
329 if ( pImp->bConstructed && pImp->pMgr )
330 {
331 if ( !IsRollUp() )
332 aSize = GetSizePixel();
333 sal_uIntPtr nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE;
334 if ( GetStyle() & WB_SIZEABLE )
335 nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT );
336 pImp->aWinState = GetWindowState( nMask );
337 GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SFX_CHILDWIN_DOCKINGWINDOW, SFX_ALIGNDOCKINGWINDOW, pImp->pMgr->GetType() );
338 }
339 return 0;
340 }
341
342 // -----------------------------------------------------------------------
343
SfxModelessDialog(SfxBindings * pBindinx,SfxChildWindow * pCW,Window * pParent,WinBits nWinBits)344 SfxModelessDialog::SfxModelessDialog( SfxBindings *pBindinx,
345 SfxChildWindow *pCW,
346 Window* pParent, WinBits nWinBits ) :
347 ModelessDialog (pParent, nWinBits),
348 pBindings(pBindinx),
349 pImp( new SfxModelessDialog_Impl )
350 {
351 pImp->pMgr = pCW;
352 pImp->bConstructed = sal_False;
353 SetUniqueId( GetHelpId() );
354 SetHelpId("");
355 if ( pBindinx )
356 pImp->StartListening( *pBindinx );
357 pImp->aMoveTimer.SetTimeout(50);
358 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxModelessDialog,TimerHdl));
359 }
360
361 // -----------------------------------------------------------------------
362
SfxModelessDialog(SfxBindings * pBindinx,SfxChildWindow * pCW,Window * pParent,const ResId & rResId)363 SfxModelessDialog::SfxModelessDialog( SfxBindings *pBindinx,
364 SfxChildWindow *pCW, Window *pParent,
365 const ResId& rResId ) :
366 ModelessDialog(pParent, rResId),
367 pBindings(pBindinx),
368 pImp( new SfxModelessDialog_Impl )
369 {
370 pImp->pMgr = pCW;
371 pImp->bConstructed = sal_False;
372 SetUniqueId( GetHelpId() );
373 SetHelpId("");
374 if ( pBindinx )
375 pImp->StartListening( *pBindinx );
376 pImp->aMoveTimer.SetTimeout(50);
377 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxModelessDialog,TimerHdl));
378 }
379
380 // -----------------------------------------------------------------------
381
Notify(NotifyEvent & rEvt)382 long SfxModelessDialog::Notify( NotifyEvent& rEvt )
383
384 /* [Beschreibung]
385
386 Wenn ein ModelessDialog aktiviert wird, wird sein ViewFrame aktiviert.
387 Notwendig ist das bei PlugInFrames.
388 */
389
390 {
391 if ( rEvt.GetType() == EVENT_GETFOCUS )
392 {
393 pBindings->SetActiveFrame( pImp->pMgr->GetFrame() );
394 pImp->pMgr->Activate_Impl();
395 Window* pWindow = rEvt.GetWindow();
396 rtl::OString sHelpId;
397 while ( !sHelpId.getLength() && pWindow )
398 {
399 sHelpId = pWindow->GetHelpId();
400 pWindow = pWindow->GetParent();
401 }
402
403 if ( sHelpId.getLength() )
404 SfxHelp::OpenHelpAgent( &pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), sHelpId );
405 }
406 else if ( rEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() )
407 {
408 pBindings->SetActiveFrame( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > () );
409 pImp->pMgr->Deactivate_Impl();
410 }
411 else if( rEvt.GetType() == EVENT_KEYINPUT )
412 {
413 // KeyInput zuerst f"ur Dialogfunktionen zulassen ( TAB etc. )
414 if ( !ModelessDialog::Notify( rEvt ) && SfxViewShell::Current() )
415 // dann auch global g"ultige Acceleratoren verwenden
416 return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() );
417 return sal_True;
418 }
419
420 return ModelessDialog::Notify( rEvt );
421 }
422
423 // -----------------------------------------------------------------------
424
~SfxModelessDialog()425 SfxModelessDialog::~SfxModelessDialog()
426
427 /* [Beschreibung]
428
429 Dtor
430 */
431
432 {
433 if ( pImp->pMgr->GetFrame().is() && pImp->pMgr->GetFrame() == pBindings->GetActiveFrame() )
434 pBindings->SetActiveFrame( NULL );
435 delete pImp;
436 }
437
438 //-------------------------------------------------------------------------
439
Close()440 sal_Bool SfxModelessDialog::Close()
441
442 /* [Beschreibung]
443
444 Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des
445 ChildWindow-Slots zerst"ort wird.
446 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
447 danach SfxModelessDialogWindow::Close() gerufen werden, wenn nicht das
448 Close() mit "return sal_False" abgebrochen wird.
449
450 */
451
452 {
453 // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert
454 // werden kann
455 SfxBoolItem aValue( pImp->pMgr->GetType(), sal_False);
456 pBindings->GetDispatcher_Impl()->Execute(
457 pImp->pMgr->GetType(),
458 SFX_CALLMODE_RECORD|SFX_CALLMODE_SYNCHRON, &aValue, 0L );
459 return sal_True;
460 }
461
462 //-------------------------------------------------------------------------
463
FillInfo(SfxChildWinInfo & rInfo) const464 void SfxModelessDialog::FillInfo(SfxChildWinInfo& rInfo) const
465
466 /* [Beschreibung]
467
468 F"ullt ein SfxChildWinInfo mit f"ur SfxModelessDialof spezifischen Daten,
469 damit sie in die INI-Datei geschrieben werden koennen.
470 Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in
471 der ChildWindow-Klasse erh"alt.
472 ModelessDialogs haben keine spezifischen Informationen, so dass die
473 Basisimplementierung nichts tut und daher nicht gerufen werden mu\s.
474 */
475
476 {
477 rInfo.aSize = aSize;
478 if ( IsRollUp() )
479 rInfo.nFlags |= SFX_CHILDWIN_ZOOMIN;
480 }
481
482 // -----------------------------------------------------------------------
483
Notify(NotifyEvent & rEvt)484 long SfxFloatingWindow::Notify( NotifyEvent& rEvt )
485
486 /* [Beschreibung]
487
488 Wenn ein ModelessDialog aktiviert wird, wird sein ViewFrame aktiviert.
489 Notwendig ist das bei PlugInFrames.
490 */
491
492 {
493 if ( rEvt.GetType() == EVENT_GETFOCUS )
494 {
495 pBindings->SetActiveFrame( pImp->pMgr->GetFrame() );
496 pImp->pMgr->Activate_Impl();
497 Window* pWindow = rEvt.GetWindow();
498 rtl::OString sHelpId;
499 while ( !sHelpId.getLength() && pWindow )
500 {
501 sHelpId = pWindow->GetHelpId();
502 pWindow = pWindow->GetParent();
503 }
504
505 if ( sHelpId.getLength() )
506 SfxHelp::OpenHelpAgent( &pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), sHelpId );
507 }
508 else if ( rEvt.GetType() == EVENT_LOSEFOCUS )
509 {
510 if ( !HasChildPathFocus() )
511 {
512 pBindings->SetActiveFrame( NULL );
513 pImp->pMgr->Deactivate_Impl();
514 }
515 }
516 else if( rEvt.GetType() == EVENT_KEYINPUT )
517 {
518 // KeyInput zuerst f"ur Dialogfunktionen zulassen
519 if ( !FloatingWindow::Notify( rEvt ) && SfxViewShell::Current() )
520 // dann auch global g"ultige Acceleratoren verwenden
521 return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() );
522 return sal_True;
523 }
524
525 return FloatingWindow::Notify( rEvt );
526 }
527
528 // -----------------------------------------------------------------------
529
SfxFloatingWindow(SfxBindings * pBindinx,SfxChildWindow * pCW,Window * pParent,WinBits nWinBits)530 SfxFloatingWindow::SfxFloatingWindow( SfxBindings *pBindinx,
531 SfxChildWindow *pCW,
532 Window* pParent, WinBits nWinBits) :
533 FloatingWindow (pParent, nWinBits),
534 pBindings(pBindinx),
535 pImp( new SfxFloatingWindow_Impl )
536 {
537 pImp->pMgr = pCW;
538 pImp->bConstructed = sal_False;
539 SetUniqueId( GetHelpId() );
540 SetHelpId("");
541 if ( pBindinx )
542 pImp->StartListening( *pBindinx );
543 pImp->aMoveTimer.SetTimeout(50);
544 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxFloatingWindow,TimerHdl));
545 }
546
547 // -----------------------------------------------------------------------
548
SfxFloatingWindow(SfxBindings * pBindinx,SfxChildWindow * pCW,Window * pParent,const ResId & rResId)549 SfxFloatingWindow::SfxFloatingWindow( SfxBindings *pBindinx,
550 SfxChildWindow *pCW,
551 Window* pParent,
552 const ResId& rResId) :
553 FloatingWindow(pParent, rResId),
554 pBindings(pBindinx),
555 pImp( new SfxFloatingWindow_Impl )
556 {
557 pImp->pMgr = pCW;
558 pImp->bConstructed = sal_False;
559 SetUniqueId( GetHelpId() );
560 SetHelpId("");
561 if ( pBindinx )
562 pImp->StartListening( *pBindinx );
563 pImp->aMoveTimer.SetTimeout(50);
564 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxFloatingWindow,TimerHdl));
565 }
566
567 //-------------------------------------------------------------------------
568
Close()569 sal_Bool SfxFloatingWindow::Close()
570
571 /* [Beschreibung]
572
573 Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des
574 ChildWindow-Slots zerst"ort wird.
575 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
576 danach SfxFloatingWindow::Close() gerufen werden, wenn nicht das Close()
577 mit "return sal_False" abgebrochen wird.
578
579 */
580
581 {
582 // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert
583 // werden kann
584 SfxBoolItem aValue( pImp->pMgr->GetType(), sal_False);
585 pBindings->GetDispatcher_Impl()->Execute(
586 pImp->pMgr->GetType(),
587 SFX_CALLMODE_RECORD|SFX_CALLMODE_SYNCHRON, &aValue, 0L );
588 return sal_True;
589 }
590
591 // -----------------------------------------------------------------------
592
~SfxFloatingWindow()593 SfxFloatingWindow::~SfxFloatingWindow()
594
595 /* [Beschreibung]
596
597 Dtor
598 */
599
600 {
601 if ( pImp->pMgr->GetFrame() == pBindings->GetActiveFrame() )
602 pBindings->SetActiveFrame( NULL );
603 delete pImp;
604 }
605
606 //-------------------------------------------------------------------------
607
Resize()608 void SfxFloatingWindow::Resize()
609
610 /* [Beschreibung]
611
612 Diese virtuelle Methode der Klasse FloatingWindow merkt sich ggf. eine
613 ver"anderte Gr"o\se.
614 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
615 auch SfxFloatingWindow::Resize() gerufen werden.
616 */
617
618 {
619 FloatingWindow::Resize();
620 if ( pImp->bConstructed && pImp->pMgr )
621 {
622 // start timer for saving window status information
623 pImp->aMoveTimer.Start();
624 }
625 }
626
Move()627 void SfxFloatingWindow::Move()
628 {
629 FloatingWindow::Move();
630 if ( pImp->bConstructed && pImp->pMgr )
631 {
632 // start timer for saving window status information
633 pImp->aMoveTimer.Start();
634 }
635 }
636
637 /*
638 Implements a timer event that is triggered by a move or resize of the window
639 This will save config information to Views.xcu with a small delay
640 */
IMPL_LINK(SfxFloatingWindow,TimerHdl,Timer *,EMPTYARG)641 IMPL_LINK( SfxFloatingWindow, TimerHdl, Timer*, EMPTYARG)
642 {
643 pImp->aMoveTimer.Stop();
644 if ( pImp->bConstructed && pImp->pMgr )
645 {
646 if ( !IsRollUp() )
647 aSize = GetSizePixel();
648 sal_uIntPtr nMask = WINDOWSTATE_MASK_POS | WINDOWSTATE_MASK_STATE;
649 if ( GetStyle() & WB_SIZEABLE )
650 nMask |= ( WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT );
651 pImp->aWinState = GetWindowState( nMask );
652 GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SFX_CHILDWIN_DOCKINGWINDOW, SFX_ALIGNDOCKINGWINDOW, pImp->pMgr->GetType() );
653 }
654 return 0;
655 }
656
657 //-------------------------------------------------------------------------
StateChanged(StateChangedType nStateChange)658 void SfxFloatingWindow::StateChanged( StateChangedType nStateChange )
659 {
660 if ( nStateChange == STATE_CHANGE_INITSHOW )
661 {
662 // FloatingWindows are not centered by default
663 if ( pImp->aWinState.Len() )
664 SetWindowState( pImp->aWinState );
665 pImp->bConstructed = sal_True;
666 }
667
668 FloatingWindow::StateChanged( nStateChange );
669 }
670
671
Initialize(SfxChildWinInfo * pInfo)672 void SfxFloatingWindow::Initialize(SfxChildWinInfo *pInfo)
673
674 /* [Beschreibung]
675
676 Initialisierung der Klasse SfxFloatingWindow "uber ein SfxChildWinInfo.
677 Die Initialisierung erfolgt erst in einem 2.Schritt
678 nach dem ctor und sollte vom ctor der abgeleiteten Klasse
679 oder von dem des SfxChildWindows aufgerufen werden.
680 */
681 {
682 pImp->aWinState = pInfo->aWinState;
683 }
684
685 //-------------------------------------------------------------------------
686
FillInfo(SfxChildWinInfo & rInfo) const687 void SfxFloatingWindow::FillInfo(SfxChildWinInfo& rInfo) const
688
689 /* [Beschreibung]
690
691 F"ullt ein SfxChildWinInfo mit f"ur SfxFloatingWindow spezifischen Daten,
692 damit sie in die INI-Datei geschrieben werden koennen.
693 Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in
694 der ChildWindow-Klasse erh"alt.
695 Eingetragen werden hier gemerkte Gr"o\se und das ZoomIn-Flag.
696 Wird diese Methode "uberschrieben, mu\s zuerst die Basisimplementierung
697 gerufen werden.
698 */
699
700 {
701 rInfo.aSize = aSize;
702 if ( IsRollUp() )
703 rInfo.nFlags |= SFX_CHILDWIN_ZOOMIN;
704 }
705
706 // SfxSingleTabDialog ----------------------------------------------------
707
IMPL_LINK(SfxSingleTabDialog,OKHdl_Impl,Button *,EMPTYARG)708 IMPL_LINK( SfxSingleTabDialog, OKHdl_Impl, Button *, EMPTYARG )
709
710 /* [Beschreibung]
711
712 Ok_Handler; f"ur die gesetzte Page wird FillItemSet() gerufen.
713 */
714
715 {
716 if ( !GetInputItemSet() )
717 {
718 // TabPage without ItemSet
719 EndDialog( RET_OK );
720 return 1;
721 }
722
723 if ( !GetOutputItemSet() )
724 {
725 CreateOutputItemSet( *GetInputItemSet() );
726 }
727 sal_Bool bModified = sal_False;
728
729 if ( pImpl->m_pSfxPage->HasExchangeSupport() )
730 {
731 int nRet = pImpl->m_pSfxPage->DeactivatePage( GetOutputSetImpl() );
732 if ( nRet != SfxTabPage::LEAVE_PAGE )
733 return 0;
734 else
735 bModified = ( GetOutputItemSet()->Count() > 0 );
736 }
737 else
738 bModified = pImpl->m_pSfxPage->FillItemSet( *GetOutputSetImpl() );
739
740 if ( bModified )
741 {
742 // auch noch schnell User-Daten im IniManager abspeichern
743 pImpl->m_pSfxPage->FillUserData();
744 String sData( pImpl->m_pSfxPage->GetUserData() );
745 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( GetUniqId() ) );
746 aPageOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( sData ) ) );
747 EndDialog( RET_OK );
748 }
749 else
750 EndDialog( RET_CANCEL );
751 return 0;
752 }
753
754 // -----------------------------------------------------------------------
755
SfxSingleTabDialog(Window * pParent,const SfxItemSet & rSet,sal_uInt16 nUniqueId)756 SfxSingleTabDialog::SfxSingleTabDialog
757 (
758 Window *pParent,
759 const SfxItemSet& rSet,
760 sal_uInt16 nUniqueId
761 ) :
762
763 /* [Beschreibung]
764
765 Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge;
766 ID f"ur das ini-file wird "ubergeben.
767 */
768
769 SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ),
770
771 pOKBtn ( 0 ),
772 pCancelBtn ( 0 ),
773 pHelpBtn ( 0 ),
774 pImpl ( new SingleTabDlgImpl )
775 {
776 DBG_WARNING( "please use the ctor with ViewFrame" );
777 SetInputSet( &rSet );
778 }
779
780 // -----------------------------------------------------------------------
781
SfxSingleTabDialog(Window * pParent,sal_uInt16 nUniqueId,const SfxItemSet * pInSet)782 SfxSingleTabDialog::SfxSingleTabDialog
783 (
784 Window* pParent,
785 sal_uInt16 nUniqueId,
786 const SfxItemSet* pInSet
787 )
788
789 /* [Beschreibung]
790
791 Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge;
792 ID f"ur das ini-file wird "ubergeben.
793 Sollte nicht mehr benutzt werden.
794 */
795
796 : SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ),
797
798 pOKBtn ( 0 ),
799 pCancelBtn ( 0 ),
800 pHelpBtn ( 0 ),
801 pImpl ( new SingleTabDlgImpl )
802 {
803 DBG_WARNING( "bitte den Ctor mit ViewFrame verwenden" );
804 SetInputSet( pInSet );
805 }
806
807 // -----------------------------------------------------------------------
808
SfxSingleTabDialog(Window * pParent,sal_uInt16 nUniqueId,const String & rInfoURL)809 SfxSingleTabDialog::SfxSingleTabDialog
810 (
811 Window* pParent,
812 sal_uInt16 nUniqueId,
813 const String& rInfoURL
814 )
815
816 /* [Beschreibung]
817
818 Konstruktor der allgemeinen Basisklasse f"ur SingleTab-Dialoge;
819 ID f"ur das ini-file wird "ubergeben.
820 */
821
822 : SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ),
823
824 pOKBtn ( NULL ),
825 pCancelBtn ( NULL ),
826 pHelpBtn ( NULL ),
827 pImpl ( new SingleTabDlgImpl )
828 {
829 pImpl->m_sInfoURL = rInfoURL;
830 }
831
832 // -----------------------------------------------------------------------
833
~SfxSingleTabDialog()834 SfxSingleTabDialog::~SfxSingleTabDialog()
835 {
836 delete pOKBtn;
837 delete pCancelBtn;
838 delete pHelpBtn;
839 delete pImpl->m_pTabPage;
840 delete pImpl->m_pSfxPage;
841 delete pImpl->m_pLine;
842 delete pImpl->m_pInfoImage;
843 delete pImpl;
844 }
845
846 // -----------------------------------------------------------------------
847
SetPage(TabPage * pNewPage)848 void SfxSingleTabDialog::SetPage( TabPage* pNewPage )
849 {
850 if ( !pImpl->m_pLine )
851 pImpl->m_pLine = new FixedLine( this );
852
853 if ( !pOKBtn )
854 {
855 pOKBtn = new OKButton( this, WB_DEFBUTTON );
856 pOKBtn->SetClickHdl( LINK( this, SfxSingleTabDialog, OKHdl_Impl ) );
857 }
858
859 if ( pImpl->m_sInfoURL.Len() > 0 && !pImpl->m_pInfoImage )
860 {
861 pImpl->m_pInfoImage = new ::svt::FixedHyperlinkImage( this );
862 Image aInfoImage = Image( SfxResId( IMG_INFO ) );
863 Size aImageSize = aInfoImage.GetSizePixel();
864 aImageSize.Width() += 4;
865 aImageSize.Height() += 4;
866 pImpl->m_pInfoImage->SetSizePixel( aImageSize );
867 pImpl->m_pInfoImage->SetImage( aInfoImage );
868 pImpl->m_pInfoImage->SetURL( pImpl->m_sInfoURL );
869 pImpl->m_pInfoImage->SetClickHdl( pImpl->m_aInfoLink );
870 }
871
872 if ( pImpl->m_pTabPage )
873 delete pImpl->m_pTabPage;
874 if ( pImpl->m_pSfxPage )
875 delete pImpl->m_pSfxPage;
876 pImpl->m_pTabPage = pNewPage;
877
878 if ( pImpl->m_pTabPage )
879 {
880 // Gr"ossen und Positionen anpassen
881 pImpl->m_pTabPage->SetPosPixel( Point() );
882 Size aOutSz( pImpl->m_pTabPage->GetSizePixel() );
883 Size aOffSz = LogicToPixel( Size( RSC_SP_CTRL_X, RSC_SP_CTRL_Y ), MAP_APPFONT );
884 Size aFLSz = LogicToPixel( Size( aOutSz.Width(), RSC_CD_FIXEDLINE_HEIGHT ) );
885 Size aBtnSz = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ), MAP_APPFONT );
886
887 Point aPnt( 0, aOutSz.Height() );
888 pImpl->m_pLine->SetPosSizePixel( aPnt, aFLSz );
889 aPnt.X() = aOutSz.Width() - aOffSz.Width() - aBtnSz.Width();
890 aPnt.Y() += aFLSz.Height() + ( aOffSz.Height() / 2 );
891 pOKBtn->SetPosSizePixel( aPnt, aBtnSz );
892
893 if ( pImpl->m_pInfoImage )
894 {
895 aPnt.X() = aOffSz.Width();
896 long nDelta = ( pImpl->m_pInfoImage->GetSizePixel().Height() - aBtnSz.Height() ) / 2;
897 aPnt.Y() -= nDelta;
898 pImpl->m_pInfoImage->SetPosPixel( aPnt );
899 pImpl->m_pInfoImage->Show();
900 }
901
902 aOutSz.Height() += aFLSz.Height() + ( aOffSz.Height() / 2 ) + aBtnSz.Height() + aOffSz.Height();
903 SetOutputSizePixel( aOutSz );
904
905 pImpl->m_pLine->Show();
906 pOKBtn->Show();
907 pImpl->m_pTabPage->Show();
908
909 // Text der TabPage in den Dialog setzen
910 SetText( pImpl->m_pTabPage->GetText() );
911
912 // Dialog bekommt HelpId der TabPage
913 SetHelpId( pImpl->m_pTabPage->GetHelpId() );
914 SetUniqueId( pImpl->m_pTabPage->GetUniqueId() );
915 }
916 }
917
918 // -----------------------------------------------------------------------
919
SetTabPage(SfxTabPage * pTabPage,GetTabPageRanges pRangesFunc)920 void SfxSingleTabDialog::SetTabPage( SfxTabPage* pTabPage,
921 GetTabPageRanges pRangesFunc )
922 /* [Beschreibung]
923
924 Setzen einer (neuen) TabPage; eine bereits vorhandene Page
925 wird gel"oscht.
926 Die "ubergebene Page wird durch Aufruf von Reset() mit dem
927 initial "ubergebenen Itemset initialisiert.
928 */
929
930 {
931 if ( !pOKBtn )
932 {
933 pOKBtn = new OKButton( this, WB_DEFBUTTON );
934 pOKBtn->SetClickHdl( LINK( this, SfxSingleTabDialog, OKHdl_Impl ) );
935 }
936 if ( !pCancelBtn )
937 pCancelBtn = new CancelButton( this );
938 if ( !pHelpBtn )
939 pHelpBtn = new HelpButton( this );
940
941 if ( pImpl->m_pTabPage )
942 delete pImpl->m_pTabPage;
943 if ( pImpl->m_pSfxPage )
944 delete pImpl->m_pSfxPage;
945 pImpl->m_pSfxPage = pTabPage;
946 fnGetRanges = pRangesFunc;
947
948 if ( pImpl->m_pSfxPage )
949 {
950 // erstmal die User-Daten besorgen, dann erst Reset()
951 SvtViewOptions aPageOpt( E_TABPAGE, String::CreateFromInt32( GetUniqId() ) );
952 String sUserData;
953 Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME );
954 OUString aTemp;
955 if ( aUserItem >>= aTemp )
956 sUserData = String( aTemp );
957 pImpl->m_pSfxPage->SetUserData( sUserData );
958 pImpl->m_pSfxPage->Reset( *GetInputItemSet() );
959 pImpl->m_pSfxPage->Show();
960
961 // Gr"ossen und Positionen anpassen
962 pImpl->m_pSfxPage->SetPosPixel( Point() );
963 Size aOutSz( pImpl->m_pSfxPage->GetSizePixel() );
964 Size aBtnSiz = LogicToPixel( Size( 50, 14 ), MAP_APPFONT );
965 Point aPnt( aOutSz.Width(), LogicToPixel( Point( 0, 6 ), MAP_APPFONT ).Y() );
966 aOutSz.Width() += aBtnSiz.Width() + LogicToPixel( Size( 6, 0 ), MAP_APPFONT ).Width();
967 SetOutputSizePixel( aOutSz );
968 pOKBtn->SetPosSizePixel( aPnt, aBtnSiz );
969 pOKBtn->Show();
970 aPnt.Y() = LogicToPixel( Point( 0, 23 ), MAP_APPFONT ).Y();
971 pCancelBtn->SetPosSizePixel( aPnt, aBtnSiz );
972 pCancelBtn->Show();
973 aPnt.Y() = LogicToPixel( Point( 0, 43 ), MAP_APPFONT ).Y();
974 pHelpBtn->SetPosSizePixel( aPnt, aBtnSiz );
975
976 if ( Help::IsContextHelpEnabled() )
977 pHelpBtn->Show();
978
979 // Text der TabPage in den Dialog setzen
980 SetText( pImpl->m_pSfxPage->GetText() );
981
982 // Dialog bekommt HelpId der TabPage
983 SetHelpId( pImpl->m_pSfxPage->GetHelpId() );
984 SetUniqueId( pImpl->m_pSfxPage->GetUniqueId() );
985 }
986 }
987
988 // -----------------------------------------------------------------------
989
SetInfoLink(const Link & rLink)990 void SfxSingleTabDialog::SetInfoLink( const Link& rLink )
991 {
992 pImpl->m_aInfoLink = rLink;
993 }
994
995 //--------------------------------------------------------------------
996 // Vergleichsfunktion fuer qsort
997
998 #ifdef WNT
BaseDlgsCmpUS_Impl(const void * p1,const void * p2)999 int __cdecl BaseDlgsCmpUS_Impl( const void* p1, const void* p2 )
1000 #else
1001 #if defined(OS2) && defined(ICC)
1002 int _Optlink BaseDlgsCmpUS_Impl( const void* p1, const void* p2 )
1003 #else
1004 extern "C" int BaseDlgsCmpUS_Impl( const void* p1, const void* p2 )
1005 #endif
1006 #endif
1007 {
1008 return *(sal_uInt16*)p1 - *(sal_uInt16*)p2;
1009 }
1010
1011 // -----------------------------------------------------------------------
1012
1013 /*
1014 Bildet das Set "uber die Ranges der Page. Die Page muss die statische
1015 Methode f"ur das Erfragen ihrer Ranges bei SetTabPage angegeben haben,
1016 liefert also ihr Set onDemand.
1017 */
GetInputRanges(const SfxItemPool & rPool)1018 const sal_uInt16* SfxSingleTabDialog::GetInputRanges( const SfxItemPool& rPool )
1019 {
1020 if ( GetInputItemSet() )
1021 {
1022 DBG_ERROR( "Set bereits vorhanden!" );
1023 return GetInputItemSet()->GetRanges();
1024 }
1025
1026 if ( pRanges )
1027 return pRanges;
1028 SvUShorts aUS(16, 16);
1029
1030 if ( fnGetRanges)
1031 {
1032 const sal_uInt16 *pTmpRanges = (fnGetRanges)();
1033 const sal_uInt16 *pIter = pTmpRanges;
1034 sal_uInt16 nLen;
1035 for ( nLen = 0; *pIter; ++nLen, ++pIter )
1036 ;
1037 aUS.Insert( pTmpRanges, nLen, aUS.Count() );
1038 }
1039
1040 //! Doppelte Ids entfernen?
1041 sal_uInt16 nCount = aUS.Count();
1042
1043 for ( sal_uInt16 i = 0; i < nCount; ++i )
1044 aUS[i] = rPool.GetWhich( aUS[i]) ;
1045
1046 // sortieren
1047 if ( aUS.Count() > 1 )
1048 qsort( (void*)aUS.GetData(), aUS.Count(), sizeof(sal_uInt16), BaseDlgsCmpUS_Impl );
1049
1050 pRanges = new sal_uInt16[aUS.Count() + 1];
1051 memcpy( pRanges, aUS.GetData(), sizeof(sal_uInt16) * aUS.Count() );
1052 pRanges[aUS.Count()] = 0;
1053 return pRanges;
1054 }
1055
1056