xref: /trunk/main/vcl/source/window/btndlg.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <tools/ref.hxx>
32 #include <tools/debug.hxx>
33 #include <tools/rc.h>
34 
35 #include <svdata.hxx>
36 
37 #include <vcl/button.hxx>
38 #include <vcl/btndlg.hxx>
39 
40 
41 
42 // =======================================================================
43 
44 struct ImplBtnDlgItem
45 {
46     sal_uInt16              mnId;
47     sal_Bool                mbOwnButton;
48     sal_Bool                mbDummyAlign;
49     long                mnSepSize;
50     PushButton*         mpPushButton;
51 };
52 
53 DECLARE_LIST( ImplBtnDlgItemList, ImplBtnDlgItem* )
54 
55 // =======================================================================
56 
57 void ButtonDialog::ImplInitButtonDialogData()
58 {
59     mpItemList              = new ImplBtnDlgItemList( 8, 8 );
60     mnButtonSize            = 0;
61     mnCurButtonId           = 0;
62     mnFocusButtonId         = BUTTONDIALOG_BUTTON_NOTFOUND;
63     mbFormat                = sal_True;
64 }
65 
66 // -----------------------------------------------------------------------
67 
68 ButtonDialog::ButtonDialog( WindowType nType ) :
69     Dialog( nType )
70 {
71     ImplInitButtonDialogData();
72 }
73 
74 // -----------------------------------------------------------------------
75 
76 ButtonDialog::ButtonDialog( Window* pParent, WinBits nStyle ) :
77     Dialog( WINDOW_BUTTONDIALOG )
78 {
79     ImplInitButtonDialogData();
80     ImplInit( pParent, nStyle );
81 }
82 
83 // -----------------------------------------------------------------------
84 
85 ButtonDialog::ButtonDialog( Window* pParent, const ResId& rResId ) :
86     Dialog( WINDOW_BUTTONDIALOG )
87 {
88     ImplInitButtonDialogData();
89     rResId.SetRT( RSC_DIALOG );     // !!!!!!!!!! RSC_BUTTONDIALOG !!!!!!!!
90     ImplInit( pParent, ImplInitRes( rResId ) );
91     ImplLoadRes( rResId );
92 }
93 
94 // -----------------------------------------------------------------------
95 
96 ButtonDialog::~ButtonDialog()
97 {
98     ImplBtnDlgItem* pItem = mpItemList->First();
99     while ( pItem )
100     {
101         if ( pItem->mpPushButton && pItem->mbOwnButton )
102             delete pItem->mpPushButton;
103         delete pItem;
104         pItem = mpItemList->Next();
105     }
106 
107     delete mpItemList;
108 }
109 
110 // -----------------------------------------------------------------------
111 
112 PushButton* ButtonDialog::ImplCreatePushButton( sal_uInt16 nBtnFlags )
113 {
114     PushButton* pBtn;
115     WinBits     nStyle = 0;
116 
117     if ( nBtnFlags & BUTTONDIALOG_DEFBUTTON )
118         nStyle |= WB_DEFBUTTON;
119     if ( nBtnFlags & BUTTONDIALOG_CANCELBUTTON )
120         pBtn = new CancelButton( this, nStyle );
121     else if ( nBtnFlags & BUTTONDIALOG_OKBUTTON )
122         pBtn = new OKButton( this, nStyle );
123     else if ( nBtnFlags & BUTTONDIALOG_HELPBUTTON )
124         pBtn = new HelpButton( this, nStyle );
125     else
126         pBtn = new PushButton( this, nStyle );
127 
128     if ( !(nBtnFlags & BUTTONDIALOG_HELPBUTTON) )
129         pBtn->SetClickHdl( LINK( this, ButtonDialog, ImplClickHdl ) );
130 
131     return pBtn;
132 }
133 
134 // -----------------------------------------------------------------------
135 
136 ImplBtnDlgItem* ButtonDialog::ImplGetItem( sal_uInt16 nId ) const
137 {
138     ImplBtnDlgItem* pItem = mpItemList->First();
139     while ( pItem )
140     {
141         if ( pItem->mnId == nId )
142             return pItem;
143 
144         pItem = mpItemList->Next();
145     }
146 
147     return NULL;
148 }
149 
150 // -----------------------------------------------------------------------
151 
152 long ButtonDialog::ImplGetButtonSize()
153 {
154     if ( !mbFormat )
155         return mnButtonSize;
156 
157     // Calculate ButtonSize
158     long    nLastSepSize = 0;
159     long    nSepSize = 0;
160     long    nButtonCount = 0;
161     maCtrlSize = Size( IMPL_MINSIZE_BUTTON_WIDTH, IMPL_MINSIZE_BUTTON_HEIGHT );
162     ImplBtnDlgItem* pItem = mpItemList->First();
163     while ( pItem )
164     {
165         nSepSize += nLastSepSize;
166 
167         long nTxtWidth = pItem->mpPushButton->GetCtrlTextWidth( pItem->mpPushButton->GetText() );
168         nTxtWidth += IMPL_EXTRA_BUTTON_WIDTH;
169         if ( nTxtWidth > maCtrlSize.Width() )
170             maCtrlSize.Width() = nTxtWidth;
171         long nTxtHeight = pItem->mpPushButton->GetTextHeight();
172         nTxtHeight += IMPL_EXTRA_BUTTON_HEIGHT;
173         if ( nTxtHeight > maCtrlSize.Height() )
174             maCtrlSize.Height() = nTxtHeight;
175 
176         nSepSize += pItem->mnSepSize;
177 
178         if ( GetStyle() & WB_HORZ )
179             nLastSepSize = IMPL_SEP_BUTTON_X;
180         else
181             nLastSepSize = IMPL_SEP_BUTTON_Y;
182 
183         nButtonCount++;
184 
185         pItem = mpItemList->Next();
186     }
187 
188     if ( GetStyle() & WB_HORZ )
189         mnButtonSize  = nSepSize + (nButtonCount*maCtrlSize.Width());
190     else
191         mnButtonSize = nSepSize + (nButtonCount*maCtrlSize.Height());
192 
193     return mnButtonSize;
194 }
195 
196 // -----------------------------------------------------------------------
197 
198 void ButtonDialog::ImplPosControls()
199 {
200     if ( !mbFormat )
201         return;
202 
203     // Create PushButtons and determine Sizes
204     ImplGetButtonSize();
205 
206     // determine dialog size
207     ImplBtnDlgItem* pItem;
208     Size            aDlgSize = maPageSize;
209     long            nX;
210     long            nY;
211     if ( GetStyle() & WB_HORZ )
212     {
213         if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Width() )
214             aDlgSize.Width() = mnButtonSize+(IMPL_DIALOG_OFFSET*2);
215         if ( GetStyle() & WB_LEFT )
216             nX = IMPL_DIALOG_OFFSET;
217         else if ( GetStyle() & WB_RIGHT )
218             nX = aDlgSize.Width()-mnButtonSize-IMPL_DIALOG_OFFSET;
219         else
220             nX = (aDlgSize.Width()-mnButtonSize)/2;
221 
222         aDlgSize.Height() += IMPL_DIALOG_OFFSET+maCtrlSize.Height();
223         nY = aDlgSize.Height()-maCtrlSize.Height()-IMPL_DIALOG_OFFSET;
224     }
225     else
226     {
227         if ( mnButtonSize+(IMPL_DIALOG_OFFSET*2) > aDlgSize.Height() )
228             aDlgSize.Height() = mnButtonSize+(IMPL_DIALOG_OFFSET*2);
229         if ( GetStyle() & WB_BOTTOM )
230             nY = aDlgSize.Height()-mnButtonSize-IMPL_DIALOG_OFFSET;
231         else if ( GetStyle() & WB_VCENTER )
232             nY = (aDlgSize.Height()-mnButtonSize)/2;
233         else
234             nY = IMPL_DIALOG_OFFSET;
235 
236         aDlgSize.Width() += IMPL_DIALOG_OFFSET+maCtrlSize.Width();
237         nX = aDlgSize.Width()-maCtrlSize.Width()-IMPL_DIALOG_OFFSET;
238     }
239 
240     // Arrange PushButtons
241     pItem = mpItemList->First();
242     while ( pItem )
243     {
244         if ( GetStyle() & WB_HORZ )
245             nX += pItem->mnSepSize;
246         else
247             nY += pItem->mnSepSize;
248         pItem->mpPushButton->SetPosSizePixel( Point( nX, nY ), maCtrlSize );
249         pItem->mpPushButton->Show();
250         if ( GetStyle() & WB_HORZ )
251             nX += maCtrlSize.Width()+IMPL_SEP_BUTTON_X;
252         else
253             nY += maCtrlSize.Height()+IMPL_SEP_BUTTON_Y;
254 
255         pItem = mpItemList->Next();
256     }
257 
258     SetOutputSizePixel( aDlgSize );
259 
260     mbFormat = sal_False;
261 }
262 
263 // -----------------------------------------------------------------------
264 
265 IMPL_LINK( ButtonDialog, ImplClickHdl, PushButton*, pBtn )
266 {
267     ImplBtnDlgItem* pItem = mpItemList->First();
268     while ( pItem )
269     {
270         if ( pItem->mpPushButton == pBtn )
271         {
272             mnCurButtonId = pItem->mnId;
273             Click();
274             break;
275         }
276 
277         pItem = mpItemList->Next();
278     }
279 
280     return 0;
281 }
282 
283 // -----------------------------------------------------------------------
284 
285 void ButtonDialog::Resize()
286 {
287 }
288 
289 // -----------------------------------------------------------------------
290 
291 void ButtonDialog::StateChanged( StateChangedType nType )
292 {
293     if ( nType == STATE_CHANGE_INITSHOW )
294     {
295         ImplPosControls();
296 
297         // Focus evt. auf den entsprechenden Button setzen
298         if ( mnFocusButtonId != BUTTONDIALOG_BUTTON_NOTFOUND )
299         {
300             ImplBtnDlgItem* pItem = mpItemList->First();
301             while ( pItem )
302             {
303                 if ( pItem->mnId == mnFocusButtonId )
304                 {
305                     if ( pItem->mpPushButton->IsVisible() )
306                         pItem->mpPushButton->GrabFocus();
307                     break;
308                 }
309 
310                 pItem = mpItemList->Next();
311             }
312         }
313     }
314 
315     Dialog::StateChanged( nType );
316 }
317 
318 // -----------------------------------------------------------------------
319 
320 void ButtonDialog::Click()
321 {
322     if ( !maClickHdl )
323     {
324         if ( IsInExecute() )
325             EndDialog( GetCurButtonId() );
326     }
327     else
328         maClickHdl.Call( this );
329 }
330 
331 // -----------------------------------------------------------------------
332 
333 void ButtonDialog::AddButton( const XubString& rText, sal_uInt16 nId,
334                               sal_uInt16 nBtnFlags, long nSepPixel )
335 {
336     // PageItem anlegen
337     ImplBtnDlgItem* pItem   = new ImplBtnDlgItem;
338     pItem->mnId             = nId;
339     pItem->mbOwnButton      = sal_True;
340     pItem->mnSepSize        = nSepPixel;
341     pItem->mpPushButton     = ImplCreatePushButton( nBtnFlags );
342     if ( rText.Len() )
343         pItem->mpPushButton->SetText( rText );
344 
345     // In die Liste eintragen
346     mpItemList->Insert( pItem, LIST_APPEND );
347 
348     if ( nBtnFlags & BUTTONDIALOG_FOCUSBUTTON )
349         mnFocusButtonId = nId;
350 
351     mbFormat = sal_True;
352 }
353 
354 // -----------------------------------------------------------------------
355 
356 void ButtonDialog::AddButton( StandardButtonType eType, sal_uInt16 nId,
357                               sal_uInt16 nBtnFlags, long nSepPixel )
358 {
359     // PageItem anlegen
360     ImplBtnDlgItem* pItem   = new ImplBtnDlgItem;
361     pItem->mnId             = nId;
362     pItem->mbOwnButton      = sal_True;
363     pItem->mnSepSize        = nSepPixel;
364 
365     if ( eType == BUTTON_OK )
366         nBtnFlags |= BUTTONDIALOG_OKBUTTON;
367     else if ( eType == BUTTON_HELP )
368         nBtnFlags |= BUTTONDIALOG_HELPBUTTON;
369     else if ( (eType == BUTTON_CANCEL) || (eType == BUTTON_CLOSE) )
370         nBtnFlags |= BUTTONDIALOG_CANCELBUTTON;
371     pItem->mpPushButton = ImplCreatePushButton( nBtnFlags );
372 
373     // Standard-Buttons have the right text already
374     if ( !((eType == BUTTON_OK)     && (pItem->mpPushButton->GetType() == WINDOW_OKBUTTON)) ||
375          !((eType == BUTTON_CANCEL) && (pItem->mpPushButton->GetType() == WINDOW_CANCELBUTTON)) ||
376          !((eType == BUTTON_HELP)   && (pItem->mpPushButton->GetType() == WINDOW_HELPBUTTON)) )
377     {
378         pItem->mpPushButton->SetText( Button::GetStandardText( eType ) );
379         pItem->mpPushButton->SetHelpText( Button::GetStandardHelpText( eType ) );
380     }
381 
382     if ( nBtnFlags & BUTTONDIALOG_FOCUSBUTTON )
383         mnFocusButtonId = nId;
384 
385     // In die Liste eintragen
386     mpItemList->Insert( pItem, LIST_APPEND );
387 
388     mbFormat = sal_True;
389 }
390 
391 // -----------------------------------------------------------------------
392 
393 void ButtonDialog::AddButton( PushButton* pBtn, sal_uInt16 nId,
394                               sal_uInt16 nBtnFlags, long nSepPixel )
395 {
396     // PageItem anlegen
397     ImplBtnDlgItem* pItem   = new ImplBtnDlgItem;
398     pItem->mnId             = nId;
399     pItem->mbOwnButton      = sal_False;
400     pItem->mnSepSize        = nSepPixel;
401     pItem->mpPushButton     = pBtn;
402 
403     if ( nBtnFlags & BUTTONDIALOG_FOCUSBUTTON )
404         mnFocusButtonId = nId;
405 
406     // In die View-Liste eintragen
407     mpItemList->Insert( pItem, LIST_APPEND );
408 
409     mbFormat = sal_True;
410 }
411 
412 // -----------------------------------------------------------------------
413 
414 void ButtonDialog::RemoveButton( sal_uInt16 nId )
415 {
416     ImplBtnDlgItem* pItem = mpItemList->First();
417     while ( pItem )
418     {
419         if ( pItem->mnId == nId )
420         {
421             pItem->mpPushButton->Hide();
422             if ( pItem->mbOwnButton )
423                 delete pItem->mpPushButton;
424             delete pItem;
425             mpItemList->Remove();
426             mbFormat = sal_True;
427             break;
428         }
429 
430         pItem = mpItemList->Next();
431     }
432 
433     DBG_ERRORFILE( "ButtonDialog::RemoveButton(): ButtonId invalid" );
434 }
435 
436 // -----------------------------------------------------------------------
437 
438 void ButtonDialog::Clear()
439 {
440     ImplBtnDlgItem* pItem = mpItemList->First();
441     while ( pItem )
442     {
443         pItem->mpPushButton->Hide();
444         if ( pItem->mbOwnButton )
445             delete pItem->mpPushButton;
446         delete pItem;
447         pItem = mpItemList->Next();
448     }
449 
450     mpItemList->Clear();
451     mbFormat = sal_True;
452 }
453 
454 // -----------------------------------------------------------------------
455 
456 sal_uInt16 ButtonDialog::GetButtonCount() const
457 {
458     return (sal_uInt16)mpItemList->Count();
459 }
460 
461 // -----------------------------------------------------------------------
462 
463 sal_uInt16 ButtonDialog::GetButtonId( sal_uInt16 nButton ) const
464 {
465     if ( nButton < mpItemList->Count() )
466         return (sal_uInt16)mpItemList->GetObject( nButton )->mnId;
467     else
468         return BUTTONDIALOG_BUTTON_NOTFOUND;
469 }
470 
471 // -----------------------------------------------------------------------
472 
473 PushButton* ButtonDialog::GetPushButton( sal_uInt16 nId ) const
474 {
475     ImplBtnDlgItem* pItem = ImplGetItem( nId );
476 
477     if ( pItem )
478         return pItem->mpPushButton;
479     else
480         return NULL;
481 }
482 
483 // -----------------------------------------------------------------------
484 
485 void ButtonDialog::SetButtonText( sal_uInt16 nId, const XubString& rText )
486 {
487     ImplBtnDlgItem* pItem = ImplGetItem( nId );
488 
489     if ( pItem )
490     {
491         pItem->mpPushButton->SetText( rText );
492         mbFormat = sal_True;
493     }
494 }
495 
496 // -----------------------------------------------------------------------
497 
498 XubString ButtonDialog::GetButtonText( sal_uInt16 nId ) const
499 {
500     ImplBtnDlgItem* pItem = ImplGetItem( nId );
501 
502     if ( pItem )
503         return pItem->mpPushButton->GetText();
504     else
505         return ImplGetSVEmptyStr();
506 }
507 
508 // -----------------------------------------------------------------------
509 
510 void ButtonDialog::SetButtonHelpText( sal_uInt16 nId, const XubString& rText )
511 {
512     ImplBtnDlgItem* pItem = ImplGetItem( nId );
513 
514     if ( pItem )
515         pItem->mpPushButton->SetHelpText( rText );
516 }
517 
518 // -----------------------------------------------------------------------
519 
520 XubString ButtonDialog::GetButtonHelpText( sal_uInt16 nId ) const
521 {
522     ImplBtnDlgItem* pItem = ImplGetItem( nId );
523 
524     if ( pItem )
525         return pItem->mpPushButton->GetHelpText();
526     else
527         return ImplGetSVEmptyStr();
528 }
529 
530 // -----------------------------------------------------------------------
531 
532 void ButtonDialog::SetButtonHelpId( sal_uInt16 nId, const rtl::OString& rHelpId )
533 {
534     ImplBtnDlgItem* pItem = ImplGetItem( nId );
535 
536     if ( pItem )
537         pItem->mpPushButton->SetHelpId( rHelpId );
538 }
539 
540 // -----------------------------------------------------------------------
541 
542 rtl::OString ButtonDialog::GetButtonHelpId( sal_uInt16 nId ) const
543 {
544     ImplBtnDlgItem* pItem = ImplGetItem( nId );
545 
546     return pItem ? rtl::OString( pItem->mpPushButton->GetHelpId() ) : rtl::OString();
547 }
548