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