xref: /trunk/main/vcl/source/window/btndlg.cxx (revision 9f62ea84)
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 
293 		// Focus evt. auf den entsprechenden Button setzen
294 		if ( mnFocusButtonId != BUTTONDIALOG_BUTTON_NOTFOUND )
295 		{
296 			ImplBtnDlgItem* pItem = mpItemList->First();
297 			while ( pItem )
298 			{
299 				if ( pItem->mnId == mnFocusButtonId )
300 				{
301 					if ( pItem->mpPushButton->IsVisible() )
302 						pItem->mpPushButton->GrabFocus();
303 					break;
304 				}
305 
306 				pItem = mpItemList->Next();
307 			}
308 		}
309 	}
310 
311 	Dialog::StateChanged( nType );
312 }
313 
314 // -----------------------------------------------------------------------
315 
316 void ButtonDialog::Click()
317 {
318 	if ( !maClickHdl )
319 	{
320 		if ( IsInExecute() )
321 			EndDialog( GetCurButtonId() );
322 	}
323 	else
324 		maClickHdl.Call( this );
325 }
326 
327 // -----------------------------------------------------------------------
328 
329 void ButtonDialog::AddButton( const XubString& rText, sal_uInt16 nId,
330 							  sal_uInt16 nBtnFlags, long nSepPixel )
331 {
332 	// PageItem anlegen
333 	ImplBtnDlgItem* pItem	= new ImplBtnDlgItem;
334 	pItem->mnId 			= nId;
335 	pItem->mbOwnButton		= sal_True;
336 	pItem->mnSepSize		= nSepPixel;
337 	pItem->mpPushButton 	= ImplCreatePushButton( nBtnFlags );
338 	if ( rText.Len() )
339 		pItem->mpPushButton->SetText( rText );
340 
341 	// In die Liste eintragen
342 	mpItemList->Insert( pItem, LIST_APPEND );
343 
344 	if ( nBtnFlags & BUTTONDIALOG_FOCUSBUTTON )
345 		mnFocusButtonId = nId;
346 
347 	mbFormat = sal_True;
348 }
349 
350 // -----------------------------------------------------------------------
351 
352 void ButtonDialog::AddButton( StandardButtonType eType, sal_uInt16 nId,
353 							  sal_uInt16 nBtnFlags, long nSepPixel )
354 {
355 	// PageItem anlegen
356 	ImplBtnDlgItem* pItem	= new ImplBtnDlgItem;
357 	pItem->mnId 			= nId;
358 	pItem->mbOwnButton		= sal_True;
359 	pItem->mnSepSize		= nSepPixel;
360 
361 	if ( eType == BUTTON_OK )
362 		nBtnFlags |= BUTTONDIALOG_OKBUTTON;
363 	else if ( eType == BUTTON_HELP )
364 		nBtnFlags |= BUTTONDIALOG_HELPBUTTON;
365 	else if ( (eType == BUTTON_CANCEL) || (eType == BUTTON_CLOSE) )
366 		nBtnFlags |= BUTTONDIALOG_CANCELBUTTON;
367 	pItem->mpPushButton = ImplCreatePushButton( nBtnFlags );
368 
369 	// Standard-Buttons have the right text already
370 	if ( !((eType == BUTTON_OK) 	&& (pItem->mpPushButton->GetType() == WINDOW_OKBUTTON)) ||
371 		 !((eType == BUTTON_CANCEL) && (pItem->mpPushButton->GetType() == WINDOW_CANCELBUTTON)) ||
372 		 !((eType == BUTTON_HELP)	&& (pItem->mpPushButton->GetType() == WINDOW_HELPBUTTON)) )
373 	{
374 		pItem->mpPushButton->SetText( Button::GetStandardText( eType ) );
375 		pItem->mpPushButton->SetHelpText( Button::GetStandardHelpText( eType ) );
376 	}
377 
378 	if ( nBtnFlags & BUTTONDIALOG_FOCUSBUTTON )
379 		mnFocusButtonId = nId;
380 
381 	// In die Liste eintragen
382 	mpItemList->Insert( pItem, LIST_APPEND );
383 
384 	mbFormat = sal_True;
385 }
386 
387 // -----------------------------------------------------------------------
388 
389 void ButtonDialog::AddButton( PushButton* pBtn, sal_uInt16 nId,
390 							  sal_uInt16 nBtnFlags, long nSepPixel )
391 {
392 	// PageItem anlegen
393 	ImplBtnDlgItem* pItem	= new ImplBtnDlgItem;
394 	pItem->mnId 			= nId;
395 	pItem->mbOwnButton		= sal_False;
396 	pItem->mnSepSize		= nSepPixel;
397 	pItem->mpPushButton 	= pBtn;
398 
399 	if ( nBtnFlags & BUTTONDIALOG_FOCUSBUTTON )
400 		mnFocusButtonId = nId;
401 
402 	// In die View-Liste eintragen
403 	mpItemList->Insert( pItem, LIST_APPEND );
404 
405 	mbFormat = sal_True;
406 }
407 
408 // -----------------------------------------------------------------------
409 
410 void ButtonDialog::RemoveButton( sal_uInt16 nId )
411 {
412 	ImplBtnDlgItem* pItem = mpItemList->First();
413 	while ( pItem )
414 	{
415 		if ( pItem->mnId == nId )
416 		{
417 			pItem->mpPushButton->Hide();
418 			if ( pItem->mbOwnButton )
419 				delete pItem->mpPushButton;
420 			delete pItem;
421 			mpItemList->Remove();
422 			mbFormat = sal_True;
423 			break;
424 		}
425 
426 		pItem = mpItemList->Next();
427 	}
428 
429 	DBG_ERRORFILE( "ButtonDialog::RemoveButton(): ButtonId invalid" );
430 }
431 
432 // -----------------------------------------------------------------------
433 
434 void ButtonDialog::Clear()
435 {
436 	ImplBtnDlgItem* pItem = mpItemList->First();
437 	while ( pItem )
438 	{
439 		pItem->mpPushButton->Hide();
440 		if ( pItem->mbOwnButton )
441 			delete pItem->mpPushButton;
442 		delete pItem;
443 		pItem = mpItemList->Next();
444 	}
445 
446 	mpItemList->Clear();
447 	mbFormat = sal_True;
448 }
449 
450 // -----------------------------------------------------------------------
451 
452 sal_uInt16 ButtonDialog::GetButtonCount() const
453 {
454 	return (sal_uInt16)mpItemList->Count();
455 }
456 
457 // -----------------------------------------------------------------------
458 
459 sal_uInt16 ButtonDialog::GetButtonId( sal_uInt16 nButton ) const
460 {
461 	if ( nButton < mpItemList->Count() )
462 		return (sal_uInt16)mpItemList->GetObject( nButton )->mnId;
463 	else
464 		return BUTTONDIALOG_BUTTON_NOTFOUND;
465 }
466 
467 // -----------------------------------------------------------------------
468 
469 PushButton* ButtonDialog::GetPushButton( sal_uInt16 nId ) const
470 {
471 	ImplBtnDlgItem* pItem = ImplGetItem( nId );
472 
473 	if ( pItem )
474 		return pItem->mpPushButton;
475 	else
476 		return NULL;
477 }
478 
479 // -----------------------------------------------------------------------
480 
481 void ButtonDialog::SetButtonText( sal_uInt16 nId, const XubString& rText )
482 {
483 	ImplBtnDlgItem* pItem = ImplGetItem( nId );
484 
485 	if ( pItem )
486 	{
487 		pItem->mpPushButton->SetText( rText );
488 		mbFormat = sal_True;
489 	}
490 }
491 
492 // -----------------------------------------------------------------------
493 
494 XubString ButtonDialog::GetButtonText( sal_uInt16 nId ) const
495 {
496 	ImplBtnDlgItem* pItem = ImplGetItem( nId );
497 
498 	if ( pItem )
499 		return pItem->mpPushButton->GetText();
500 	else
501 		return ImplGetSVEmptyStr();
502 }
503 
504 // -----------------------------------------------------------------------
505 
506 void ButtonDialog::SetButtonHelpText( sal_uInt16 nId, const XubString& rText )
507 {
508 	ImplBtnDlgItem* pItem = ImplGetItem( nId );
509 
510 	if ( pItem )
511 		pItem->mpPushButton->SetHelpText( rText );
512 }
513 
514 // -----------------------------------------------------------------------
515 
516 XubString ButtonDialog::GetButtonHelpText( sal_uInt16 nId ) const
517 {
518 	ImplBtnDlgItem* pItem = ImplGetItem( nId );
519 
520 	if ( pItem )
521 		return pItem->mpPushButton->GetHelpText();
522 	else
523 		return ImplGetSVEmptyStr();
524 }
525 
526 // -----------------------------------------------------------------------
527 
528 void ButtonDialog::SetButtonHelpId( sal_uInt16 nId, const rtl::OString& rHelpId )
529 {
530 	ImplBtnDlgItem* pItem = ImplGetItem( nId );
531 
532 	if ( pItem )
533 		pItem->mpPushButton->SetHelpId( rHelpId );
534 }
535 
536 // -----------------------------------------------------------------------
537 
538 rtl::OString ButtonDialog::GetButtonHelpId( sal_uInt16 nId ) const
539 {
540 	ImplBtnDlgItem* pItem = ImplGetItem( nId );
541 
542 	return pItem ? rtl::OString( pItem->mpPushButton->GetHelpId() ) : rtl::OString();
543 }
544