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