xref: /AOO41X/main/svx/source/tbxctrls/linectrl.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_svx.hxx"
30 
31 // include ---------------------------------------------------------------
32 
33 #include <string> // HACK: prevent conflict between STLPORT and Workshop headers
34 
35 #ifndef _TOOLBOX_HXX //autogen
36 #include <vcl/toolbox.hxx>
37 #endif
38 #include <sfx2/app.hxx>
39 #include <sfx2/dispatch.hxx>
40 #include <sfx2/objsh.hxx>
41 
42 #include <svx/dialogs.hrc>
43 #include "helpid.hrc"
44 
45 #include "svx/drawitem.hxx"
46 #include "svx/xattr.hxx"
47 #include <svx/xtable.hxx>
48 #include "svx/linectrl.hxx"
49 #include <svx/itemwin.hxx>
50 #include <svx/dialmgr.hxx>
51 
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::util;
55 using namespace ::com::sun::star::frame;
56 using namespace ::com::sun::star::lang;
57 
58 // Fuer Linienenden-Controller
59 #define MAX_LINES 12
60 
61 // STATIC DATA -----------------------------------------------------------
62 
63 #define RESIZE_VALUE_POPUP(value_set)	\
64 {														\
65     Size aSize = GetOutputSizePixel();					\
66     aSize.Width()  -= 4;								\
67     aSize.Height() -= 4;								\
68     (value_set).SetPosSizePixel( Point(2,2), aSize );	\
69 }
70 
71 #define CALCSIZE_VALUE_POPUP(value_set,item_size) \
72 {																	\
73     Size aSize = (value_set).CalcWindowSizePixel( (item_size) );	\
74     aSize.Width()  += 4;											\
75     aSize.Height() += 4;											\
76     SetOutputSizePixel( aSize );									\
77 }
78 
79 
80 SFX_IMPL_TOOLBOX_CONTROL( SvxLineStyleToolBoxControl, XLineStyleItem );
81 SFX_IMPL_TOOLBOX_CONTROL( SvxLineWidthToolBoxControl, XLineWidthItem );
82 SFX_IMPL_TOOLBOX_CONTROL( SvxLineColorToolBoxControl, XLineColorItem );
83 SFX_IMPL_TOOLBOX_CONTROL( SvxLineEndToolBoxControl,   SfxBoolItem );
84 
85 /*************************************************************************
86 |*
87 |* SvxLineStyleToolBoxControl
88 |*
89 \************************************************************************/
90 
91 SvxLineStyleToolBoxControl::SvxLineStyleToolBoxControl( sal_uInt16 nSlotId,
92                                                         sal_uInt16 nId,
93 														ToolBox& rTbx ) :
94 	SfxToolBoxControl( nSlotId, nId, rTbx ),
95 	pStyleItem		( NULL ),
96 	pDashItem		( NULL ),
97 	bUpdate			( sal_False )
98 {
99     addStatusListener( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:LineDash" )));
100     addStatusListener( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DashListState" )));
101 }
102 
103 //========================================================================
104 
105 SvxLineStyleToolBoxControl::~SvxLineStyleToolBoxControl()
106 {
107 	delete pStyleItem;
108 	delete pDashItem;
109 }
110 
111 //========================================================================
112 
113 void SvxLineStyleToolBoxControl::StateChanged (
114 
115 	sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
116 
117 {
118 	SvxLineBox* pBox = (SvxLineBox*)GetToolBox().GetItemWindow( GetId() );
119 	DBG_ASSERT( pBox, "Window not found!" );
120 
121 	if( eState == SFX_ITEM_DISABLED )
122 	{
123 		pBox->Disable();
124 		pBox->SetNoSelection();
125 	}
126 	else
127 	{
128 		pBox->Enable();
129 
130 		if ( eState == SFX_ITEM_AVAILABLE )
131 		{
132 			if( nSID == SID_ATTR_LINE_STYLE )
133 			{
134 				delete pStyleItem;
135 				pStyleItem = (XLineStyleItem*)pState->Clone();
136 			}
137 			else if( nSID == SID_ATTR_LINE_DASH )
138 			{
139 				delete pDashItem;
140 				pDashItem = (XLineDashItem*)pState->Clone();
141 			}
142 
143 			bUpdate = sal_True;
144             Update( pState );
145 		}
146 		else if ( nSID != SID_DASH_LIST )
147         {
148 			// kein oder uneindeutiger Status
149 			pBox->SetNoSelection();
150         }
151 	}
152 }
153 
154 //========================================================================
155 
156 void SvxLineStyleToolBoxControl::Update( const SfxPoolItem* pState )
157 {
158 	if ( pState && bUpdate )
159 	{
160 		bUpdate = sal_False;
161 
162 		SvxLineBox* pBox = (SvxLineBox*)GetToolBox().GetItemWindow( GetId() );
163 		DBG_ASSERT( pBox, "Window not found!" );
164 
165 		// Da der Timer unerwartet zuschlagen kann, kann es vorkommen, dass
166 		// die LB noch nicht gefuellt ist. Ein ClearCache() am Control im
167 		// DelayHdl() blieb ohne Erfolg.
168 		if( pBox->GetEntryCount() == 0 )
169             pBox->FillControl();
170 
171 		XLineStyle eXLS;
172 
173 		if ( pStyleItem )
174 			eXLS = ( XLineStyle )pStyleItem->GetValue();
175 		else
176 			eXLS = XLINE_NONE;
177 
178 		switch( eXLS )
179 		{
180 			case XLINE_NONE:
181 				pBox->SelectEntryPos( 0 );
182 				break;
183 
184 			case XLINE_SOLID:
185 				pBox->SelectEntryPos( 1 );
186 				break;
187 
188 			case XLINE_DASH:
189 			{
190 				if( pDashItem )
191 				{
192 					String aString( pDashItem->GetName() );
193 					pBox->SelectEntry( aString );
194 				}
195 				else
196 					pBox->SetNoSelection();
197 			}
198 			break;
199 
200 			default:
201 				DBG_ERROR( "Nicht unterstuetzter Linientyp" );
202 				break;
203 		}
204 	}
205 
206 	if ( pState && ( pState->ISA( SvxDashListItem ) ) )
207 	{
208 		// Die Liste der Linienstile hat sich geaendert
209 		SvxLineBox* pBox = (SvxLineBox*)GetToolBox().GetItemWindow( GetId() );
210 		DBG_ASSERT( pBox, "Window not found!" );
211 
212 		String aString( pBox->GetSelectEntry() );
213 		pBox->Clear();
214 		pBox->InsertEntry( SVX_RESSTR(RID_SVXSTR_INVISIBLE) );
215 		pBox->InsertEntry( SVX_RESSTR(RID_SVXSTR_SOLID) );
216 		pBox->Fill( ((SvxDashListItem*)pState )->GetDashList() );
217 		pBox->SelectEntry( aString );
218 	}
219 }
220 
221 //========================================================================
222 
223 Window* SvxLineStyleToolBoxControl::CreateItemWindow( Window *pParent )
224 {
225 	return new SvxLineBox( pParent, m_xFrame );
226 }
227 
228 /*************************************************************************
229 |*
230 |* SvxLineWidthToolBoxControl
231 |*
232 \************************************************************************/
233 
234 SvxLineWidthToolBoxControl::SvxLineWidthToolBoxControl(
235     sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx ) :
236 	SfxToolBoxControl( nSlotId, nId, rTbx )
237 {
238     addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:MetricUnit" )));
239 }
240 
241 //========================================================================
242 
243 SvxLineWidthToolBoxControl::~SvxLineWidthToolBoxControl()
244 {
245 }
246 
247 //========================================================================
248 
249 void SvxLineWidthToolBoxControl::StateChanged(
250 	sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
251 {
252 	SvxMetricField* pFld = (SvxMetricField*)
253 						   GetToolBox().GetItemWindow( GetId() );
254 	DBG_ASSERT( pFld, "Window not found" );
255 
256 	if ( nSID == SID_ATTR_METRIC )
257     {
258 		pFld->RefreshDlgUnit();
259     }
260     else
261     {
262         if ( eState == SFX_ITEM_DISABLED )
263 	    {
264 		    pFld->Disable();
265 		    pFld->SetText( String() );
266 	    }
267         else
268 	    {
269 		    pFld->Enable();
270 
271 		    if ( eState == SFX_ITEM_AVAILABLE )
272 		    {
273 			    DBG_ASSERT( pState->ISA(XLineWidthItem), "falscher ItemType" );
274 
275 			    // Core-Unit an MetricField uebergeben
276 			    // Darf nicht in CreateItemWin() geschehen!
277 			    SfxMapUnit eUnit = SFX_MAPUNIT_100TH_MM; // CD!!! GetCoreMetric();
278 			    pFld->SetCoreUnit( eUnit );
279 
280 			    pFld->Update( (const XLineWidthItem*)pState );
281 		    }
282 		    else
283 			    pFld->Update( NULL );
284 	    }
285     }
286 }
287 
288 //========================================================================
289 
290 Window* SvxLineWidthToolBoxControl::CreateItemWindow( Window *pParent )
291 {
292 	return( new SvxMetricField( pParent, m_xFrame ) );
293 }
294 
295 /*************************************************************************
296 |*
297 |* SvxLineColorToolBoxControl
298 |*
299 \************************************************************************/
300 
301 SvxLineColorToolBoxControl::SvxLineColorToolBoxControl(
302     sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx ) :
303 	SfxToolBoxControl( nSlotId, nId, rTbx )
304 {
305     addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ColorTableState" )));
306 }
307 
308 //========================================================================
309 
310 SvxLineColorToolBoxControl::~SvxLineColorToolBoxControl()
311 {
312 }
313 
314 //========================================================================
315 
316 void SvxLineColorToolBoxControl::StateChanged(
317 
318 	sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
319 
320 {
321 	SvxColorBox* pBox = (SvxColorBox*)GetToolBox().GetItemWindow( GetId() );
322 	DBG_ASSERT( pBox, "Window not found" );
323 
324 	if ( nSID != SID_COLOR_TABLE )
325     {
326         if ( eState == SFX_ITEM_DISABLED )
327 	    {
328 		    pBox->Disable();
329 		    pBox->SetNoSelection();
330 	    }
331 	    else
332 	    {
333 		    pBox->Enable();
334 
335 		    if ( eState == SFX_ITEM_AVAILABLE )
336 		    {
337 			    DBG_ASSERT( pState->ISA(XLineColorItem), "falscher ItemTyoe" );
338 			    pBox->Update( (const XLineColorItem*) pState );
339 		    }
340 		    else
341 			    pBox->Update( NULL );
342 	    }
343     }
344     else
345         Update( pState );
346 }
347 
348 //========================================================================
349 
350 void SvxLineColorToolBoxControl::Update( const SfxPoolItem* pState )
351 {
352 	if ( pState && ( pState->ISA( SvxColorTableItem ) ) )
353 	{
354 		SvxColorBox* pBox = (SvxColorBox*)GetToolBox().GetItemWindow( GetId() );
355 
356 		DBG_ASSERT( pBox, "Window not found" );
357 
358 		// Die Liste der Farben (ColorTable) hat sich geaendert:
359 		::Color aTmpColor( pBox->GetSelectEntryColor() );
360 		pBox->Clear();
361 		pBox->Fill( ( (SvxColorTableItem*)pState )->GetColorTable() );
362 		pBox->SelectEntry( aTmpColor );
363 	}
364 }
365 
366 //========================================================================
367 
368 Window* SvxLineColorToolBoxControl::CreateItemWindow( Window *pParent )
369 {
370     return new SvxColorBox( pParent, m_aCommandURL, m_xFrame );
371 }
372 
373 /*************************************************************************
374 |*
375 |* SvxLineEndWindow
376 |*
377 \************************************************************************/
378 
379 SvxLineEndWindow::SvxLineEndWindow(
380     sal_uInt16 nSlotId,
381     const Reference< XFrame >& rFrame,
382     const String& rWndTitle ) :
383     SfxPopupWindow( nSlotId,
384                     rFrame,
385                     WinBits( WB_BORDER | WB_STDFLOATWIN | WB_SIZEABLE | WB_3DLOOK ) ),
386 	pLineEndList	( NULL ),
387 	aLineEndSet		( this, WinBits( WB_ITEMBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT ) ),
388 	nCols			( 2 ),
389 	nLines			( 12 ),
390 	nLineEndWidth	( 400 ),
391 	bPopupMode		( sal_True ),
392 	mbInResize		( false ),
393     mxFrame         ( rFrame )
394 {
395 	SetText( rWndTitle );
396     implInit();
397 }
398 
399 SvxLineEndWindow::SvxLineEndWindow(
400     sal_uInt16 nSlotId,
401     const Reference< XFrame >& rFrame,
402     Window* pParentWindow,
403     const String& rWndTitle ) :
404     SfxPopupWindow( nSlotId,
405                     rFrame,
406                     pParentWindow,
407                     WinBits( WB_BORDER | WB_STDFLOATWIN | WB_SIZEABLE | WB_3DLOOK ) ),
408 	pLineEndList	( NULL ),
409 	aLineEndSet		( this, WinBits( WB_ITEMBORDER | WB_3DLOOK | WB_NO_DIRECTSELECT ) ),
410 	nCols			( 2 ),
411 	nLines			( 12 ),
412 	nLineEndWidth	( 400 ),
413 	bPopupMode		( sal_True ),
414 	mbInResize		( false ),
415     mxFrame         ( rFrame )
416 {
417 	SetText( rWndTitle );
418     implInit();
419 }
420 
421 void SvxLineEndWindow::implInit()
422 {
423 	SfxObjectShell*		pDocSh	= SfxObjectShell::Current();
424 	const SfxPoolItem*	pItem 	= NULL;
425 
426 	SetHelpId( HID_POPUP_LINEEND );
427 	aLineEndSet.SetHelpId( HID_POPUP_LINEEND_CTRL );
428 
429     if ( pDocSh )
430 	{
431         pItem = pDocSh->GetItem( SID_LINEEND_LIST );
432 		if( pItem )
433 			pLineEndList = ( (SvxLineEndListItem*) pItem )->GetLineEndList();
434 
435         pItem = pDocSh->GetItem( SID_ATTR_LINEEND_WIDTH_DEFAULT );
436 		if( pItem )
437 			nLineEndWidth = ( (SfxUInt16Item*) pItem )->GetValue();
438 	}
439 	DBG_ASSERT( pLineEndList, "LineEndList wurde nicht gefunden" );
440 
441 	aLineEndSet.SetSelectHdl( LINK( this, SvxLineEndWindow, SelectHdl ) );
442 	aLineEndSet.SetColCount( nCols );
443 
444 	// ValueSet mit Eintraegen der LineEndList fuellen
445 	FillValueSet();
446 
447     AddStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:LineEndListState" )));
448 
449     //ChangeHelpId( HID_POPUP_LINEENDSTYLE );
450 	aLineEndSet.Show();
451 }
452 
453 SfxPopupWindow* SvxLineEndWindow::Clone() const
454 {
455 	return new SvxLineEndWindow( GetId(), mxFrame, GetText() );
456 }
457 
458 // -----------------------------------------------------------------------
459 
460 SvxLineEndWindow::~SvxLineEndWindow()
461 {
462 }
463 
464 // -----------------------------------------------------------------------
465 
466 IMPL_LINK( SvxLineEndWindow, SelectHdl, void *, EMPTYARG )
467 {
468 	XLineEndItem*   		pLineEndItem = NULL;
469 	XLineStartItem* 		pLineStartItem = NULL;
470 	sal_uInt16 					nId = aLineEndSet.GetSelectItemId();
471 
472 	if( nId == 1 )
473 	{
474 		pLineStartItem	= new XLineStartItem();
475 	}
476 	else if( nId == 2 )
477 	{
478 		pLineEndItem	= new XLineEndItem();
479 	}
480 	else if( nId % 2 ) // LinienAnfang
481 	{
482 		XLineEndEntry* pEntry = pLineEndList->GetLineEnd( ( nId - 1 ) / 2 - 1 );
483 		pLineStartItem	= new XLineStartItem( pEntry->GetName(), pEntry->GetLineEnd() );
484 	}
485 	else // LinienEnde
486 	{
487 		XLineEndEntry* pEntry = pLineEndList->GetLineEnd( nId / 2 - 2 );
488 		pLineEndItem	= new XLineEndItem( pEntry->GetName(), pEntry->GetLineEnd() );
489 	}
490 
491 	if ( IsInPopupMode() )
492 		EndPopupMode();
493 
494     Sequence< PropertyValue > aArgs( 1 );
495     Any a;
496 
497     if ( pLineStartItem )
498     {
499         aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LineStart" ));
500         pLineStartItem->QueryValue( a );
501         aArgs[0].Value = a;
502     }
503     else
504     {
505         aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LineEnd" ));
506         pLineEndItem->QueryValue( a );
507         aArgs[0].Value = a;
508     }
509 
510     /*  #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
511         This instance may be deleted in the meantime (i.e. when a dialog is opened
512         while in Dispatch()), accessing members will crash in this case. */
513     aLineEndSet.SetNoSelection();
514 
515     SfxToolBoxControl::Dispatch( Reference< XDispatchProvider >( mxFrame->getController(), UNO_QUERY ),
516                                  ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:LineEndStyle" )),
517                                  aArgs );
518 
519     delete pLineEndItem;
520 	delete pLineStartItem;
521 
522 	return 0;
523 }
524 
525 // -----------------------------------------------------------------------
526 
527 void SvxLineEndWindow::FillValueSet()
528 {
529 	if( pLineEndList )
530 	{
531 		XLineEndEntry*		pEntry	= NULL;
532 		Bitmap*				pBmp	= NULL;
533 		VirtualDevice		aVD;
534 
535 		long nCount = pLineEndList->Count();
536 
537 		// Erster Eintrag: kein LinienEnde
538 		// Temporaer wird ein Eintrag hinzugefuegt, um die UI-Bitmap zu erhalten
539 		basegfx::B2DPolyPolygon aNothing;
540 		pLineEndList->Insert( new XLineEndEntry( aNothing, SVX_RESSTR( RID_SVXSTR_NONE ) ) );
541 		pEntry = pLineEndList->GetLineEnd( nCount );
542 		pBmp = pLineEndList->GetBitmap( nCount );
543 		DBG_ASSERT( pBmp, "UI-Bitmap wurde nicht erzeugt" );
544 
545 		aBmpSize = pBmp->GetSizePixel();
546 		aVD.SetOutputSizePixel( aBmpSize, sal_False );
547 		aBmpSize.Width() = aBmpSize.Width() / 2;
548 		Point aPt0( 0, 0 );
549 		Point aPt1( aBmpSize.Width(), 0 );
550 
551 		aVD.DrawBitmap( Point(), *pBmp );
552 		aLineEndSet.InsertItem( 1, aVD.GetBitmap( aPt0, aBmpSize ), pEntry->GetName() );
553 		aLineEndSet.InsertItem( 2, aVD.GetBitmap( aPt1, aBmpSize ), pEntry->GetName() );
554 
555 		delete pLineEndList->Remove( nCount );
556 
557 		for( long i = 0; i < nCount; i++ )
558 		{
559 			pEntry = pLineEndList->GetLineEnd( i );
560 			DBG_ASSERT( pEntry, "Konnte auf LineEndEntry nicht zugreifen" );
561 			pBmp = pLineEndList->GetBitmap( i );
562 			DBG_ASSERT( pBmp, "UI-Bitmap wurde nicht erzeugt" );
563 
564 			aVD.DrawBitmap( aPt0, *pBmp );
565 			aLineEndSet.InsertItem( (sal_uInt16)((i+1L)*2L+1L), aVD.GetBitmap( aPt0, aBmpSize ), pEntry->GetName() );
566 			aLineEndSet.InsertItem( (sal_uInt16)((i+2L)*2L), 	aVD.GetBitmap( aPt1, aBmpSize ), pEntry->GetName() );
567 		}
568 		nLines = Min( (sal_uInt16)(nCount + 1), (sal_uInt16) MAX_LINES );
569 		aLineEndSet.SetLineCount( nLines );
570 
571 		SetSize();
572 	}
573 }
574 
575 // -----------------------------------------------------------------------
576 
577 void SvxLineEndWindow::Resize()
578 {
579 	// since we change the size inside this call, check if we
580 	// are called recursive
581 	if( !mbInResize )
582 	{
583 		mbInResize = true;
584 		if ( !IsRollUp() )
585 		{
586 			aLineEndSet.SetColCount( nCols );
587 			aLineEndSet.SetLineCount( nLines );
588 
589 			SetSize();
590 
591 			Size aSize = GetOutputSizePixel();
592 			aSize.Width()  -= 4;
593 			aSize.Height() -= 4;
594 			aLineEndSet.SetPosSizePixel( Point( 2, 2 ), aSize );
595 		}
596 		//SfxPopupWindow::Resize();
597 		mbInResize = false;
598 	}
599 }
600 
601 // -----------------------------------------------------------------------
602 
603 void __EXPORT SvxLineEndWindow::Resizing( Size& rNewSize )
604 {
605 	Size aBitmapSize = aBmpSize; // -> Member
606 	aBitmapSize.Width()  += 6; //
607 	aBitmapSize.Height() += 6; //
608 
609 	Size aItemSize = aLineEndSet.CalcItemSizePixel( aBitmapSize );  // -> Member
610 	//Size aOldSize = GetOutputSizePixel(); // fuer Breite
611 
612 	sal_uInt16 nItemCount = aLineEndSet.GetItemCount(); // -> Member
613 
614 	// Spalten ermitteln
615 	long nItemW = aItemSize.Width();
616 	long nW = rNewSize.Width();
617 	nCols = (sal_uInt16) Max( ( (sal_uIntPtr)(( nW + nItemW ) / ( nItemW * 2 ) )),
618 											(sal_uIntPtr) 1L );
619 	nCols *= 2;
620 
621 	// Reihen ermitteln
622 	long nItemH = aItemSize.Height();
623 	long nH = rNewSize.Height();
624 	nLines = (sal_uInt16) Max( ( ( nH + nItemH / 2 ) / nItemH ), 1L );
625 
626 	sal_uInt16 nMaxCols  = nItemCount / nLines;
627 	if( nItemCount % nLines )
628 		nMaxCols++;
629 	if( nCols > nMaxCols )
630 		nCols = nMaxCols;
631 	nW = nItemW * nCols;
632 
633 	// Keine ungerade Anzahl von Spalten
634 	if( nCols % 2 )
635 		nCols--;
636 	nCols = Max( nCols, (sal_uInt16) 2 );
637 
638 	sal_uInt16 nMaxLines  = nItemCount / nCols;
639 	if( nItemCount % nCols )
640 		nMaxLines++;
641 	if( nLines > nMaxLines )
642 		nLines = nMaxLines;
643 	nH = nItemH * nLines;
644 
645 	rNewSize.Width() = nW;
646 	rNewSize.Height() = nH;
647 }
648 // -----------------------------------------------------------------------
649 
650 void SvxLineEndWindow::StartSelection()
651 {
652 	aLineEndSet.StartSelection();
653 }
654 
655 // -----------------------------------------------------------------------
656 
657 sal_Bool SvxLineEndWindow::Close()
658 {
659 	return SfxPopupWindow::Close();
660 }
661 
662 // -----------------------------------------------------------------------
663 
664 void SvxLineEndWindow::StateChanged(
665     sal_uInt16 nSID, SfxItemState, const SfxPoolItem* pState )
666 {
667     if ( nSID == SID_LINEEND_LIST )
668     {
669 		// Die Liste der LinienEnden (LineEndList) hat sich geaendert:
670         if ( pState && pState->ISA( SvxLineEndListItem ))
671         {
672 		    pLineEndList = ((SvxLineEndListItem*)pState)->GetLineEndList();
673 		    DBG_ASSERT( pLineEndList, "LineEndList nicht gefunden" );
674 
675 		    aLineEndSet.Clear();
676 		    FillValueSet();
677 
678 		    Size aSize = GetOutputSizePixel();
679 		    Resizing( aSize );
680 		    Resize();
681         }
682     }
683 }
684 
685 // -----------------------------------------------------------------------
686 
687 void SvxLineEndWindow::PopupModeEnd()
688 {
689 	if ( IsVisible() )
690 	{
691 		bPopupMode = sal_False;
692 		SetSize();
693 	}
694 	SfxPopupWindow::PopupModeEnd();
695 }
696 
697 // -----------------------------------------------------------------------
698 
699 void SvxLineEndWindow::SetSize()
700 {
701 	//if( !bPopupMode )
702 	if( !IsInPopupMode() )
703 	{
704 		sal_uInt16 nItemCount = aLineEndSet.GetItemCount(); // -> Member
705 		sal_uInt16 nMaxLines  = nItemCount / nCols; // -> Member ?
706 		if( nItemCount % nCols )
707 			nMaxLines++;
708 
709 		WinBits nBits = aLineEndSet.GetStyle();
710 		if ( nLines == nMaxLines )
711 			nBits &= ~WB_VSCROLL;
712 		else
713 			nBits |= WB_VSCROLL;
714 		aLineEndSet.SetStyle( nBits );
715 	}
716 
717 	Size aSize( aBmpSize );
718 	aSize.Width()  += 6;
719 	aSize.Height() += 6;
720 	aSize = aLineEndSet.CalcWindowSizePixel( aSize );
721 	aSize.Width()  += 4;
722 	aSize.Height() += 4;
723 	SetOutputSizePixel( aSize );
724 	aSize.Height() = aBmpSize.Height();
725 	aSize.Height() += 14;
726 	//SetMinOutputSizePixel( aSize );
727 }
728 
729 void SvxLineEndWindow::GetFocus (void)
730 {
731 	SfxPopupWindow::GetFocus();
732     // Grab the focus to the line ends value set so that it can be controlled
733     // with the keyboard.
734 	aLineEndSet.GrabFocus();
735 }
736 
737 /*************************************************************************
738 |*
739 |* SvxLineEndToolBoxControl
740 |*
741 \************************************************************************/
742 
743 SvxLineEndToolBoxControl::SvxLineEndToolBoxControl(	sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox &rTbx ) :
744 	SfxToolBoxControl( nSlotId, nId, rTbx )
745 {
746 	rTbx.SetItemBits( nId, TIB_DROPDOWNONLY | rTbx.GetItemBits( nId ) );
747 	rTbx.Invalidate();
748 }
749 
750 // -----------------------------------------------------------------------
751 
752 SvxLineEndToolBoxControl::~SvxLineEndToolBoxControl()
753 {
754 }
755 
756 // -----------------------------------------------------------------------
757 
758 SfxPopupWindowType SvxLineEndToolBoxControl::GetPopupWindowType() const
759 {
760 	return SFX_POPUPWINDOW_ONCLICK;
761 }
762 
763 // -----------------------------------------------------------------------
764 
765 SfxPopupWindow*	SvxLineEndToolBoxControl::CreatePopupWindow()
766 {
767 	SvxLineEndWindow* pLineEndWin =
768 		new SvxLineEndWindow( GetId(), m_xFrame, &GetToolBox(), SVX_RESSTR( RID_SVXSTR_LINEEND ) );
769 	pLineEndWin->StartPopupMode( &GetToolBox(), sal_True );
770 	pLineEndWin->StartSelection();
771     SetPopupWindow( pLineEndWin );
772 	return pLineEndWin;
773 }
774 
775 // -----------------------------------------------------------------------
776 
777 void SvxLineEndToolBoxControl::StateChanged( sal_uInt16, SfxItemState eState, const SfxPoolItem* )
778 {
779 	sal_uInt16 nId = GetId();
780 	ToolBox& rTbx = GetToolBox();
781 
782 	rTbx.EnableItem( nId, SFX_ITEM_DISABLED != eState );
783 	rTbx.SetItemState( nId, ( SFX_ITEM_DONTCARE == eState ) ? STATE_DONTKNOW : STATE_NOCHECK );
784 }
785