xref: /trunk/main/vcl/source/window/btndlg.cxx (revision cdf0e10c)
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