1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: linectrl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 // include ---------------------------------------------------------------
36 #include <string> // HACK: prevent conflict between STLPORT and Workshop headers
38 #ifndef _TOOLBOX_HXX //autogen
39 #include <vcl/toolbox.hxx>
41 #include <sfx2/app.hxx>
42 #include <sfx2/dispatch.hxx>
43 #include <sfx2/objsh.hxx>
45 #include <svx/dialogs.hrc>
48 #include "drawitem.hxx"
50 #include <svx/xtable.hxx>
51 #include "linectrl.hxx"
52 #include <svx/itemwin.hxx>
53 #include <svx/dialmgr.hxx>
55 using namespace ::com::sun::star::uno
;
56 using namespace ::com::sun::star::beans
;
57 using namespace ::com::sun::star::util
;
58 using namespace ::com::sun::star::frame
;
59 using namespace ::com::sun::star::lang
;
61 // Fuer Linienenden-Controller
64 // STATIC DATA -----------------------------------------------------------
66 #define RESIZE_VALUE_POPUP(value_set) \
68 Size aSize = GetOutputSizePixel(); \
70 aSize.Height() -= 4; \
71 (value_set).SetPosSizePixel( Point(2,2), aSize ); \
74 #define CALCSIZE_VALUE_POPUP(value_set,item_size) \
76 Size aSize = (value_set).CalcWindowSizePixel( (item_size) ); \
78 aSize.Height() += 4; \
79 SetOutputSizePixel( aSize ); \
83 SFX_IMPL_TOOLBOX_CONTROL( SvxLineStyleToolBoxControl
, XLineStyleItem
);
84 SFX_IMPL_TOOLBOX_CONTROL( SvxLineWidthToolBoxControl
, XLineWidthItem
);
85 SFX_IMPL_TOOLBOX_CONTROL( SvxLineColorToolBoxControl
, XLineColorItem
);
86 SFX_IMPL_TOOLBOX_CONTROL( SvxLineEndToolBoxControl
, SfxBoolItem
);
88 /*************************************************************************
90 |* SvxLineStyleToolBoxControl
92 \************************************************************************/
94 SvxLineStyleToolBoxControl::SvxLineStyleToolBoxControl( USHORT nSlotId
,
97 SfxToolBoxControl( nSlotId
, nId
, rTbx
),
102 addStatusListener( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:LineDash" )));
103 addStatusListener( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DashListState" )));
106 //========================================================================
108 SvxLineStyleToolBoxControl::~SvxLineStyleToolBoxControl()
114 //========================================================================
116 void SvxLineStyleToolBoxControl::StateChanged (
118 USHORT nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
121 SvxLineBox
* pBox
= (SvxLineBox
*)GetToolBox().GetItemWindow( GetId() );
122 DBG_ASSERT( pBox
, "Window not found!" );
124 if( eState
== SFX_ITEM_DISABLED
)
127 pBox
->SetNoSelection();
133 if ( eState
== SFX_ITEM_AVAILABLE
)
135 if( nSID
== SID_ATTR_LINE_STYLE
)
138 pStyleItem
= (XLineStyleItem
*)pState
->Clone();
140 else if( nSID
== SID_ATTR_LINE_DASH
)
143 pDashItem
= (XLineDashItem
*)pState
->Clone();
149 else if ( nSID
!= SID_DASH_LIST
)
151 // kein oder uneindeutiger Status
152 pBox
->SetNoSelection();
157 //========================================================================
159 void SvxLineStyleToolBoxControl::Update( const SfxPoolItem
* pState
)
161 if ( pState
&& bUpdate
)
165 SvxLineBox
* pBox
= (SvxLineBox
*)GetToolBox().GetItemWindow( GetId() );
166 DBG_ASSERT( pBox
, "Window not found!" );
168 // Da der Timer unerwartet zuschlagen kann, kann es vorkommen, dass
169 // die LB noch nicht gefuellt ist. Ein ClearCache() am Control im
170 // DelayHdl() blieb ohne Erfolg.
171 if( pBox
->GetEntryCount() == 0 )
177 eXLS
= ( XLineStyle
)pStyleItem
->GetValue();
184 pBox
->SelectEntryPos( 0 );
188 pBox
->SelectEntryPos( 1 );
195 String
aString( pDashItem
->GetName() );
196 pBox
->SelectEntry( aString
);
199 pBox
->SetNoSelection();
204 DBG_ERROR( "Nicht unterstuetzter Linientyp" );
209 if ( pState
&& ( pState
->ISA( SvxDashListItem
) ) )
211 // Die Liste der Linienstile hat sich geaendert
212 SvxLineBox
* pBox
= (SvxLineBox
*)GetToolBox().GetItemWindow( GetId() );
213 DBG_ASSERT( pBox
, "Window not found!" );
215 String
aString( pBox
->GetSelectEntry() );
217 pBox
->InsertEntry( SVX_RESSTR(RID_SVXSTR_INVISIBLE
) );
218 pBox
->InsertEntry( SVX_RESSTR(RID_SVXSTR_SOLID
) );
219 pBox
->Fill( ((SvxDashListItem
*)pState
)->GetDashList() );
220 pBox
->SelectEntry( aString
);
224 //========================================================================
226 Window
* SvxLineStyleToolBoxControl::CreateItemWindow( Window
*pParent
)
228 return new SvxLineBox( pParent
, m_xFrame
);
231 /*************************************************************************
233 |* SvxLineWidthToolBoxControl
235 \************************************************************************/
237 SvxLineWidthToolBoxControl::SvxLineWidthToolBoxControl(
238 USHORT nSlotId
, USHORT nId
, ToolBox
& rTbx
) :
239 SfxToolBoxControl( nSlotId
, nId
, rTbx
)
241 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:MetricUnit" )));
244 //========================================================================
246 SvxLineWidthToolBoxControl::~SvxLineWidthToolBoxControl()
250 //========================================================================
252 void SvxLineWidthToolBoxControl::StateChanged(
253 USHORT nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
255 SvxMetricField
* pFld
= (SvxMetricField
*)
256 GetToolBox().GetItemWindow( GetId() );
257 DBG_ASSERT( pFld
, "Window not found" );
259 if ( nSID
== SID_ATTR_METRIC
)
261 pFld
->RefreshDlgUnit();
265 if ( eState
== SFX_ITEM_DISABLED
)
268 pFld
->SetText( String() );
274 if ( eState
== SFX_ITEM_AVAILABLE
)
276 DBG_ASSERT( pState
->ISA(XLineWidthItem
), "falscher ItemType" );
278 // Core-Unit an MetricField uebergeben
279 // Darf nicht in CreateItemWin() geschehen!
280 SfxMapUnit eUnit
= SFX_MAPUNIT_100TH_MM
; // CD!!! GetCoreMetric();
281 pFld
->SetCoreUnit( eUnit
);
283 pFld
->Update( (const XLineWidthItem
*)pState
);
286 pFld
->Update( NULL
);
291 //========================================================================
293 Window
* SvxLineWidthToolBoxControl::CreateItemWindow( Window
*pParent
)
295 return( new SvxMetricField( pParent
, m_xFrame
) );
298 /*************************************************************************
300 |* SvxLineColorToolBoxControl
302 \************************************************************************/
304 SvxLineColorToolBoxControl::SvxLineColorToolBoxControl(
305 USHORT nSlotId
, USHORT nId
, ToolBox
& rTbx
) :
306 SfxToolBoxControl( nSlotId
, nId
, rTbx
)
308 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ColorTableState" )));
311 //========================================================================
313 SvxLineColorToolBoxControl::~SvxLineColorToolBoxControl()
317 //========================================================================
319 void SvxLineColorToolBoxControl::StateChanged(
321 USHORT nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
324 SvxColorBox
* pBox
= (SvxColorBox
*)GetToolBox().GetItemWindow( GetId() );
325 DBG_ASSERT( pBox
, "Window not found" );
327 if ( nSID
!= SID_COLOR_TABLE
)
329 if ( eState
== SFX_ITEM_DISABLED
)
332 pBox
->SetNoSelection();
338 if ( eState
== SFX_ITEM_AVAILABLE
)
340 DBG_ASSERT( pState
->ISA(XLineColorItem
), "falscher ItemTyoe" );
341 pBox
->Update( (const XLineColorItem
*) pState
);
344 pBox
->Update( NULL
);
351 //========================================================================
353 void SvxLineColorToolBoxControl::Update( const SfxPoolItem
* pState
)
355 if ( pState
&& ( pState
->ISA( SvxColorTableItem
) ) )
357 SvxColorBox
* pBox
= (SvxColorBox
*)GetToolBox().GetItemWindow( GetId() );
359 DBG_ASSERT( pBox
, "Window not found" );
361 // Die Liste der Farben (ColorTable) hat sich geaendert:
362 ::Color
aTmpColor( pBox
->GetSelectEntryColor() );
364 pBox
->Fill( ( (SvxColorTableItem
*)pState
)->GetColorTable() );
365 pBox
->SelectEntry( aTmpColor
);
369 //========================================================================
371 Window
* SvxLineColorToolBoxControl::CreateItemWindow( Window
*pParent
)
373 return new SvxColorBox( pParent
, m_aCommandURL
, m_xFrame
);
376 /*************************************************************************
380 \************************************************************************/
382 SvxLineEndWindow::SvxLineEndWindow(
384 const Reference
< XFrame
>& rFrame
,
385 const String
& rWndTitle
) :
386 SfxPopupWindow( nSlotId
,
388 WinBits( WB_BORDER
| WB_STDFLOATWIN
| WB_SIZEABLE
| WB_3DLOOK
) ),
389 pLineEndList ( NULL
),
390 aLineEndSet ( this, WinBits( WB_ITEMBORDER
| WB_3DLOOK
| WB_NO_DIRECTSELECT
) ),
393 nLineEndWidth ( 400 ),
395 mbInResize ( false ),
398 SetText( rWndTitle
);
402 SvxLineEndWindow::SvxLineEndWindow(
404 const Reference
< XFrame
>& rFrame
,
405 Window
* pParentWindow
,
406 const String
& rWndTitle
) :
407 SfxPopupWindow( nSlotId
,
410 WinBits( WB_BORDER
| WB_STDFLOATWIN
| WB_SIZEABLE
| WB_3DLOOK
) ),
411 pLineEndList ( NULL
),
412 aLineEndSet ( this, WinBits( WB_ITEMBORDER
| WB_3DLOOK
| WB_NO_DIRECTSELECT
) ),
415 nLineEndWidth ( 400 ),
417 mbInResize ( false ),
420 SetText( rWndTitle
);
424 void SvxLineEndWindow::implInit()
426 SfxObjectShell
* pDocSh
= SfxObjectShell::Current();
427 const SfxPoolItem
* pItem
= NULL
;
429 SetHelpId( HID_POPUP_LINEEND
);
430 aLineEndSet
.SetHelpId( HID_POPUP_LINEEND_CTRL
);
434 pItem
= pDocSh
->GetItem( SID_LINEEND_LIST
);
436 pLineEndList
= ( (SvxLineEndListItem
*) pItem
)->GetLineEndList();
438 pItem
= pDocSh
->GetItem( SID_ATTR_LINEEND_WIDTH_DEFAULT
);
440 nLineEndWidth
= ( (SfxUInt16Item
*) pItem
)->GetValue();
442 DBG_ASSERT( pLineEndList
, "LineEndList wurde nicht gefunden" );
444 aLineEndSet
.SetSelectHdl( LINK( this, SvxLineEndWindow
, SelectHdl
) );
445 aLineEndSet
.SetColCount( nCols
);
447 // ValueSet mit Eintraegen der LineEndList fuellen
450 AddStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:LineEndListState" )));
452 //ChangeHelpId( HID_POPUP_LINEENDSTYLE );
456 SfxPopupWindow
* SvxLineEndWindow::Clone() const
458 return new SvxLineEndWindow( GetId(), mxFrame
, GetText() );
461 // -----------------------------------------------------------------------
463 SvxLineEndWindow::~SvxLineEndWindow()
467 // -----------------------------------------------------------------------
469 IMPL_LINK( SvxLineEndWindow
, SelectHdl
, void *, EMPTYARG
)
471 XLineEndItem
* pLineEndItem
= NULL
;
472 XLineStartItem
* pLineStartItem
= NULL
;
473 USHORT nId
= aLineEndSet
.GetSelectItemId();
477 pLineStartItem
= new XLineStartItem();
481 pLineEndItem
= new XLineEndItem();
483 else if( nId
% 2 ) // LinienAnfang
485 XLineEndEntry
* pEntry
= pLineEndList
->GetLineEnd( ( nId
- 1 ) / 2 - 1 );
486 pLineStartItem
= new XLineStartItem( pEntry
->GetName(), pEntry
->GetLineEnd() );
490 XLineEndEntry
* pEntry
= pLineEndList
->GetLineEnd( nId
/ 2 - 2 );
491 pLineEndItem
= new XLineEndItem( pEntry
->GetName(), pEntry
->GetLineEnd() );
494 if ( IsInPopupMode() )
497 Sequence
< PropertyValue
> aArgs( 1 );
500 if ( pLineStartItem
)
502 aArgs
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LineStart" ));
503 pLineStartItem
->QueryValue( a
);
508 aArgs
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LineEnd" ));
509 pLineEndItem
->QueryValue( a
);
513 /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
514 This instance may be deleted in the meantime (i.e. when a dialog is opened
515 while in Dispatch()), accessing members will crash in this case. */
516 aLineEndSet
.SetNoSelection();
518 SfxToolBoxControl::Dispatch( Reference
< XDispatchProvider
>( mxFrame
->getController(), UNO_QUERY
),
519 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:LineEndStyle" )),
523 delete pLineStartItem
;
528 // -----------------------------------------------------------------------
530 void SvxLineEndWindow::FillValueSet()
534 XLineEndEntry
* pEntry
= NULL
;
538 long nCount
= pLineEndList
->Count();
540 // Erster Eintrag: kein LinienEnde
541 // Temporaer wird ein Eintrag hinzugefuegt, um die UI-Bitmap zu erhalten
542 basegfx::B2DPolyPolygon aNothing
;
543 pLineEndList
->Insert( new XLineEndEntry( aNothing
, SVX_RESSTR( RID_SVXSTR_NONE
) ) );
544 pEntry
= pLineEndList
->GetLineEnd( nCount
);
545 pBmp
= pLineEndList
->GetBitmap( nCount
);
546 DBG_ASSERT( pBmp
, "UI-Bitmap wurde nicht erzeugt" );
548 aBmpSize
= pBmp
->GetSizePixel();
549 aVD
.SetOutputSizePixel( aBmpSize
, FALSE
);
550 aBmpSize
.Width() = aBmpSize
.Width() / 2;
552 Point
aPt1( aBmpSize
.Width(), 0 );
554 aVD
.DrawBitmap( Point(), *pBmp
);
555 aLineEndSet
.InsertItem( 1, aVD
.GetBitmap( aPt0
, aBmpSize
), pEntry
->GetName() );
556 aLineEndSet
.InsertItem( 2, aVD
.GetBitmap( aPt1
, aBmpSize
), pEntry
->GetName() );
558 delete pLineEndList
->Remove( nCount
);
560 for( long i
= 0; i
< nCount
; i
++ )
562 pEntry
= pLineEndList
->GetLineEnd( i
);
563 DBG_ASSERT( pEntry
, "Konnte auf LineEndEntry nicht zugreifen" );
564 pBmp
= pLineEndList
->GetBitmap( i
);
565 DBG_ASSERT( pBmp
, "UI-Bitmap wurde nicht erzeugt" );
567 aVD
.DrawBitmap( aPt0
, *pBmp
);
568 aLineEndSet
.InsertItem( (USHORT
)((i
+1L)*2L+1L), aVD
.GetBitmap( aPt0
, aBmpSize
), pEntry
->GetName() );
569 aLineEndSet
.InsertItem( (USHORT
)((i
+2L)*2L), aVD
.GetBitmap( aPt1
, aBmpSize
), pEntry
->GetName() );
571 nLines
= Min( (USHORT
)(nCount
+ 1), (USHORT
) MAX_LINES
);
572 aLineEndSet
.SetLineCount( nLines
);
578 // -----------------------------------------------------------------------
580 void SvxLineEndWindow::Resize()
582 // since we change the size inside this call, check if we
583 // are called recursive
589 aLineEndSet
.SetColCount( nCols
);
590 aLineEndSet
.SetLineCount( nLines
);
594 Size aSize
= GetOutputSizePixel();
597 aLineEndSet
.SetPosSizePixel( Point( 2, 2 ), aSize
);
599 //SfxPopupWindow::Resize();
604 // -----------------------------------------------------------------------
606 void __EXPORT
SvxLineEndWindow::Resizing( Size
& rNewSize
)
608 Size aBitmapSize
= aBmpSize
; // -> Member
609 aBitmapSize
.Width() += 6; //
610 aBitmapSize
.Height() += 6; //
612 Size aItemSize
= aLineEndSet
.CalcItemSizePixel( aBitmapSize
); // -> Member
613 //Size aOldSize = GetOutputSizePixel(); // fuer Breite
615 USHORT nItemCount
= aLineEndSet
.GetItemCount(); // -> Member
618 long nItemW
= aItemSize
.Width();
619 long nW
= rNewSize
.Width();
620 nCols
= (USHORT
) Max( ( (ULONG
)(( nW
+ nItemW
) / ( nItemW
* 2 ) )),
625 long nItemH
= aItemSize
.Height();
626 long nH
= rNewSize
.Height();
627 nLines
= (USHORT
) Max( ( ( nH
+ nItemH
/ 2 ) / nItemH
), 1L );
629 USHORT nMaxCols
= nItemCount
/ nLines
;
630 if( nItemCount
% nLines
)
632 if( nCols
> nMaxCols
)
636 // Keine ungerade Anzahl von Spalten
639 nCols
= Max( nCols
, (USHORT
) 2 );
641 USHORT nMaxLines
= nItemCount
/ nCols
;
642 if( nItemCount
% nCols
)
644 if( nLines
> nMaxLines
)
646 nH
= nItemH
* nLines
;
648 rNewSize
.Width() = nW
;
649 rNewSize
.Height() = nH
;
651 // -----------------------------------------------------------------------
653 void SvxLineEndWindow::StartSelection()
655 aLineEndSet
.StartSelection();
658 // -----------------------------------------------------------------------
660 BOOL
SvxLineEndWindow::Close()
662 return SfxPopupWindow::Close();
665 // -----------------------------------------------------------------------
667 void SvxLineEndWindow::StateChanged(
668 USHORT nSID
, SfxItemState
, const SfxPoolItem
* pState
)
670 if ( nSID
== SID_LINEEND_LIST
)
672 // Die Liste der LinienEnden (LineEndList) hat sich geaendert:
673 if ( pState
&& pState
->ISA( SvxLineEndListItem
))
675 pLineEndList
= ((SvxLineEndListItem
*)pState
)->GetLineEndList();
676 DBG_ASSERT( pLineEndList
, "LineEndList nicht gefunden" );
681 Size aSize
= GetOutputSizePixel();
688 // -----------------------------------------------------------------------
690 void SvxLineEndWindow::PopupModeEnd()
697 SfxPopupWindow::PopupModeEnd();
700 // -----------------------------------------------------------------------
702 void SvxLineEndWindow::SetSize()
705 if( !IsInPopupMode() )
707 USHORT nItemCount
= aLineEndSet
.GetItemCount(); // -> Member
708 USHORT nMaxLines
= nItemCount
/ nCols
; // -> Member ?
709 if( nItemCount
% nCols
)
712 WinBits nBits
= aLineEndSet
.GetStyle();
713 if ( nLines
== nMaxLines
)
714 nBits
&= ~WB_VSCROLL
;
717 aLineEndSet
.SetStyle( nBits
);
720 Size
aSize( aBmpSize
);
723 aSize
= aLineEndSet
.CalcWindowSizePixel( aSize
);
726 SetOutputSizePixel( aSize
);
727 aSize
.Height() = aBmpSize
.Height();
728 aSize
.Height() += 14;
729 //SetMinOutputSizePixel( aSize );
732 void SvxLineEndWindow::GetFocus (void)
734 SfxPopupWindow::GetFocus();
735 // Grab the focus to the line ends value set so that it can be controlled
736 // with the keyboard.
737 aLineEndSet
.GrabFocus();
740 /*************************************************************************
742 |* SvxLineEndToolBoxControl
744 \************************************************************************/
746 SvxLineEndToolBoxControl::SvxLineEndToolBoxControl( USHORT nSlotId
, USHORT nId
, ToolBox
&rTbx
) :
747 SfxToolBoxControl( nSlotId
, nId
, rTbx
)
749 rTbx
.SetItemBits( nId
, TIB_DROPDOWNONLY
| rTbx
.GetItemBits( nId
) );
753 // -----------------------------------------------------------------------
755 SvxLineEndToolBoxControl::~SvxLineEndToolBoxControl()
759 // -----------------------------------------------------------------------
761 SfxPopupWindowType
SvxLineEndToolBoxControl::GetPopupWindowType() const
763 return SFX_POPUPWINDOW_ONCLICK
;
766 // -----------------------------------------------------------------------
768 SfxPopupWindow
* SvxLineEndToolBoxControl::CreatePopupWindow()
770 SvxLineEndWindow
* pLineEndWin
=
771 new SvxLineEndWindow( GetId(), m_xFrame
, &GetToolBox(), SVX_RESSTR( RID_SVXSTR_LINEEND
) );
772 pLineEndWin
->StartPopupMode( &GetToolBox(), TRUE
);
773 pLineEndWin
->StartSelection();
774 SetPopupWindow( pLineEndWin
);
778 // -----------------------------------------------------------------------
780 void SvxLineEndToolBoxControl::StateChanged( USHORT
, SfxItemState eState
, const SfxPoolItem
* )
782 USHORT nId
= GetId();
783 ToolBox
& rTbx
= GetToolBox();
785 rTbx
.EnableItem( nId
, SFX_ITEM_DISABLED
!= eState
);
786 rTbx
.SetItemState( nId
, ( SFX_ITEM_DONTCARE
== eState
) ? STATE_DONTKNOW
: STATE_NOCHECK
);