1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <vcl/toolbox.hxx>
23 #include <sfx2/app.hxx>
24 #include <sfx2/dispatch.hxx>
25 #include <sfx2/objsh.hxx>
27 #include <svx/dialogs.hrc>
30 #include "svx/drawitem.hxx"
31 #include "svx/xattr.hxx"
32 #include <svx/xtable.hxx>
33 #include "svx/linectrl.hxx"
34 #include <svx/itemwin.hxx>
35 #include <svx/dialmgr.hxx>
36 #include <svx/unoapi.hxx>
38 using namespace ::com::sun::star::uno
;
39 using namespace ::com::sun::star::beans
;
40 using namespace ::com::sun::star::util
;
41 using namespace ::com::sun::star::frame
;
42 using namespace ::com::sun::star::lang
;
44 // Fuer Linienenden-Controller
47 // STATIC DATA -----------------------------------------------------------
49 SFX_IMPL_TOOLBOX_CONTROL( SvxLineStyleToolBoxControl
, XLineStyleItem
);
50 SFX_IMPL_TOOLBOX_CONTROL( SvxLineWidthToolBoxControl
, XLineWidthItem
);
51 SFX_IMPL_TOOLBOX_CONTROL( SvxLineColorToolBoxControl
, XLineColorItem
);
52 SFX_IMPL_TOOLBOX_CONTROL( SvxLineEndToolBoxControl
, SfxBoolItem
);
54 /*************************************************************************
56 |* SvxLineStyleToolBoxControl
58 \************************************************************************/
60 SvxLineStyleToolBoxControl::SvxLineStyleToolBoxControl( sal_uInt16 nSlotId
,
63 SfxToolBoxControl( nSlotId
, nId
, rTbx
),
68 addStatusListener( OUString( ".uno:LineDash" ));
69 addStatusListener( OUString( ".uno:DashListState" ));
72 //========================================================================
74 SvxLineStyleToolBoxControl::~SvxLineStyleToolBoxControl()
80 //========================================================================
82 void SvxLineStyleToolBoxControl::StateChanged (
84 sal_uInt16 nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
87 SvxLineBox
* pBox
= (SvxLineBox
*)GetToolBox().GetItemWindow( GetId() );
88 DBG_ASSERT( pBox
, "Window not found!" );
90 if( eState
== SFX_ITEM_DISABLED
)
93 pBox
->SetNoSelection();
99 if ( eState
== SFX_ITEM_AVAILABLE
)
101 if( nSID
== SID_ATTR_LINE_STYLE
)
104 pStyleItem
= (XLineStyleItem
*)pState
->Clone();
106 else if( nSID
== SID_ATTR_LINE_DASH
)
109 pDashItem
= (XLineDashItem
*)pState
->Clone();
115 else if ( nSID
!= SID_DASH_LIST
)
117 // kein oder uneindeutiger Status
118 pBox
->SetNoSelection();
123 //========================================================================
125 void SvxLineStyleToolBoxControl::Update( const SfxPoolItem
* pState
)
127 if ( pState
&& bUpdate
)
131 SvxLineBox
* pBox
= (SvxLineBox
*)GetToolBox().GetItemWindow( GetId() );
132 DBG_ASSERT( pBox
, "Window not found!" );
134 // Da der Timer unerwartet zuschlagen kann, kann es vorkommen, dass
135 // die LB noch nicht gefuellt ist. Ein ClearCache() am Control im
136 // DelayHdl() blieb ohne Erfolg.
137 if( pBox
->GetEntryCount() == 0 )
143 eXLS
= ( XLineStyle
)pStyleItem
->GetValue();
150 pBox
->SelectEntryPos( 0 );
154 pBox
->SelectEntryPos( 1 );
161 OUString aString
= SvxUnogetInternalNameForItem(
162 XATTR_LINEDASH
, pDashItem
->GetName());
163 pBox
->SelectEntry( aString
);
166 pBox
->SetNoSelection();
171 OSL_FAIL( "Nicht unterstuetzter Linientyp" );
176 if ( pState
&& ( pState
->ISA( SvxDashListItem
) ) )
178 // Die Liste der Linienstile hat sich geaendert
179 SvxLineBox
* pBox
= (SvxLineBox
*)GetToolBox().GetItemWindow( GetId() );
180 DBG_ASSERT( pBox
, "Window not found!" );
182 String
aString( pBox
->GetSelectEntry() );
184 pBox
->InsertEntry( SVX_RESSTR(RID_SVXSTR_INVISIBLE
) );
185 pBox
->InsertEntry( SVX_RESSTR(RID_SVXSTR_SOLID
) );
186 pBox
->Fill( ((SvxDashListItem
*)pState
)->GetDashList() );
187 pBox
->SelectEntry( aString
);
191 //========================================================================
193 Window
* SvxLineStyleToolBoxControl::CreateItemWindow( Window
*pParent
)
195 return new SvxLineBox( pParent
, m_xFrame
);
198 /*************************************************************************
200 |* SvxLineWidthToolBoxControl
202 \************************************************************************/
204 SvxLineWidthToolBoxControl::SvxLineWidthToolBoxControl(
205 sal_uInt16 nSlotId
, sal_uInt16 nId
, ToolBox
& rTbx
) :
206 SfxToolBoxControl( nSlotId
, nId
, rTbx
)
208 addStatusListener( OUString( ".uno:MetricUnit" ));
211 //========================================================================
213 SvxLineWidthToolBoxControl::~SvxLineWidthToolBoxControl()
217 //========================================================================
219 void SvxLineWidthToolBoxControl::StateChanged(
220 sal_uInt16 nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
222 SvxMetricField
* pFld
= (SvxMetricField
*)
223 GetToolBox().GetItemWindow( GetId() );
224 DBG_ASSERT( pFld
, "Window not found" );
226 if ( nSID
== SID_ATTR_METRIC
)
228 pFld
->RefreshDlgUnit();
232 if ( eState
== SFX_ITEM_DISABLED
)
235 pFld
->SetText( String() );
241 if ( eState
== SFX_ITEM_AVAILABLE
)
243 DBG_ASSERT( pState
->ISA(XLineWidthItem
), "falscher ItemType" );
245 // Core-Unit an MetricField uebergeben
246 // Darf nicht in CreateItemWin() geschehen!
247 SfxMapUnit eUnit
= SFX_MAPUNIT_100TH_MM
; // CD!!! GetCoreMetric();
248 pFld
->SetCoreUnit( eUnit
);
250 pFld
->Update( (const XLineWidthItem
*)pState
);
253 pFld
->Update( NULL
);
258 //========================================================================
260 Window
* SvxLineWidthToolBoxControl::CreateItemWindow( Window
*pParent
)
262 return( new SvxMetricField( pParent
, m_xFrame
) );
265 /*************************************************************************
267 |* SvxLineColorToolBoxControl
269 \************************************************************************/
271 SvxLineColorToolBoxControl::SvxLineColorToolBoxControl(
272 sal_uInt16 nSlotId
, sal_uInt16 nId
, ToolBox
& rTbx
) :
273 SfxToolBoxControl( nSlotId
, nId
, rTbx
)
275 addStatusListener( OUString( ".uno:ColorTableState" ));
278 //========================================================================
280 SvxLineColorToolBoxControl::~SvxLineColorToolBoxControl()
284 //========================================================================
286 void SvxLineColorToolBoxControl::StateChanged(
288 sal_uInt16 nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
291 SvxColorBox
* pBox
= (SvxColorBox
*)GetToolBox().GetItemWindow( GetId() );
292 DBG_ASSERT( pBox
, "Window not found" );
294 if ( nSID
!= SID_COLOR_TABLE
)
296 if ( eState
== SFX_ITEM_DISABLED
)
299 pBox
->SetNoSelection();
305 if ( eState
== SFX_ITEM_AVAILABLE
)
307 DBG_ASSERT( pState
->ISA(XLineColorItem
), "falscher ItemTyoe" );
308 pBox
->Update( (const XLineColorItem
*) pState
);
311 pBox
->Update( NULL
);
318 //========================================================================
320 void SvxLineColorToolBoxControl::Update( const SfxPoolItem
* pState
)
322 if ( pState
&& ( pState
->ISA( SvxColorListItem
) ) )
324 SvxColorBox
* pBox
= (SvxColorBox
*)GetToolBox().GetItemWindow( GetId() );
326 DBG_ASSERT( pBox
, "Window not found" );
328 // Die Liste der Farben (ColorTable) hat sich geaendert:
329 ::Color
aTmpColor( pBox
->GetSelectEntryColor() );
331 pBox
->Fill( ( (SvxColorListItem
*)pState
)->GetColorList() );
332 pBox
->SelectEntry( aTmpColor
);
336 //========================================================================
338 Window
* SvxLineColorToolBoxControl::CreateItemWindow( Window
*pParent
)
340 return new SvxColorBox( pParent
, m_aCommandURL
, m_xFrame
);
343 /*************************************************************************
347 \************************************************************************/
349 SvxLineEndWindow::SvxLineEndWindow(
351 const Reference
< XFrame
>& rFrame
,
352 const String
& rWndTitle
) :
353 SfxPopupWindow( nSlotId
,
355 WinBits( WB_STDPOPUP
| WB_OWNERDRAWDECORATION
) ),
356 aLineEndSet ( this, WinBits( WB_ITEMBORDER
| WB_3DLOOK
| WB_NO_DIRECTSELECT
) ),
359 nLineEndWidth ( 400 ),
360 bPopupMode ( sal_True
),
361 mbInResize ( false ),
364 SetText( rWndTitle
);
368 SvxLineEndWindow::SvxLineEndWindow(
370 const Reference
< XFrame
>& rFrame
,
371 Window
* pParentWindow
,
372 const String
& rWndTitle
) :
373 SfxPopupWindow( nSlotId
,
376 WinBits( WB_STDPOPUP
| WB_OWNERDRAWDECORATION
) ),
377 aLineEndSet ( this, WinBits( WB_ITEMBORDER
| WB_3DLOOK
| WB_NO_DIRECTSELECT
) ),
380 nLineEndWidth ( 400 ),
381 bPopupMode ( sal_True
),
382 mbInResize ( false ),
385 SetText( rWndTitle
);
389 void SvxLineEndWindow::implInit()
391 SfxObjectShell
* pDocSh
= SfxObjectShell::Current();
392 const SfxPoolItem
* pItem
= NULL
;
394 SetHelpId( HID_POPUP_LINEEND
);
395 aLineEndSet
.SetHelpId( HID_POPUP_LINEEND_CTRL
);
399 pItem
= pDocSh
->GetItem( SID_LINEEND_LIST
);
401 pLineEndList
= ( (SvxLineEndListItem
*) pItem
)->GetLineEndList();
403 pItem
= pDocSh
->GetItem( SID_ATTR_LINEEND_WIDTH_DEFAULT
);
405 nLineEndWidth
= ( (SfxUInt16Item
*) pItem
)->GetValue();
407 DBG_ASSERT( pLineEndList
.is(), "LineEndList wurde nicht gefunden" );
409 aLineEndSet
.SetSelectHdl( LINK( this, SvxLineEndWindow
, SelectHdl
) );
410 aLineEndSet
.SetColCount( nCols
);
412 // ValueSet mit Eintraegen der LineEndList fuellen
415 AddStatusListener( OUString( ".uno:LineEndListState" ));
417 //ChangeHelpId( HID_POPUP_LINEENDSTYLE );
421 SfxPopupWindow
* SvxLineEndWindow::Clone() const
423 return new SvxLineEndWindow( GetId(), mxFrame
, GetText() );
426 // -----------------------------------------------------------------------
428 SvxLineEndWindow::~SvxLineEndWindow()
432 // -----------------------------------------------------------------------
434 IMPL_LINK_NOARG(SvxLineEndWindow
, SelectHdl
)
436 XLineEndItem
* pLineEndItem
= NULL
;
437 XLineStartItem
* pLineStartItem
= NULL
;
438 sal_uInt16 nId
= aLineEndSet
.GetSelectItemId();
442 pLineStartItem
= new XLineStartItem();
446 pLineEndItem
= new XLineEndItem();
448 else if( nId
% 2 ) // LinienAnfang
450 XLineEndEntry
* pEntry
= pLineEndList
->GetLineEnd( ( nId
- 1 ) / 2 - 1 );
451 pLineStartItem
= new XLineStartItem( pEntry
->GetName(), pEntry
->GetLineEnd() );
455 XLineEndEntry
* pEntry
= pLineEndList
->GetLineEnd( nId
/ 2 - 2 );
456 pLineEndItem
= new XLineEndItem( pEntry
->GetName(), pEntry
->GetLineEnd() );
459 if ( IsInPopupMode() )
462 Sequence
< PropertyValue
> aArgs( 1 );
465 if ( pLineStartItem
)
467 aArgs
[0].Name
= OUString( "LineStart" );
468 pLineStartItem
->QueryValue( a
);
473 aArgs
[0].Name
= OUString( "LineEnd" );
474 pLineEndItem
->QueryValue( a
);
478 /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
479 This instance may be deleted in the meantime (i.e. when a dialog is opened
480 while in Dispatch()), accessing members will crash in this case. */
481 aLineEndSet
.SetNoSelection();
483 SfxToolBoxControl::Dispatch( Reference
< XDispatchProvider
>( mxFrame
->getController(), UNO_QUERY
),
484 OUString( ".uno:LineEndStyle" ),
488 delete pLineStartItem
;
493 // -----------------------------------------------------------------------
495 void SvxLineEndWindow::FillValueSet()
497 if( pLineEndList
.is() )
499 XLineEndEntry
* pEntry
= NULL
;
502 long nCount
= pLineEndList
->Count();
504 // Erster Eintrag: kein LinienEnde
505 // Temporaer wird ein Eintrag hinzugefuegt, um die UI-Bitmap zu erhalten
506 basegfx::B2DPolyPolygon aNothing
;
507 pLineEndList
->Insert( new XLineEndEntry( aNothing
, SVX_RESSTR( RID_SVXSTR_NONE
) ) );
508 pEntry
= pLineEndList
->GetLineEnd( nCount
);
509 Bitmap aBmp
= pLineEndList
->GetUiBitmap( nCount
);
510 OSL_ENSURE( !aBmp
.IsEmpty(), "UI-Bitmap wurde nicht erzeugt" );
512 aBmpSize
= aBmp
.GetSizePixel();
513 aVD
.SetOutputSizePixel( aBmpSize
, sal_False
);
514 aBmpSize
.Width() = aBmpSize
.Width() / 2;
516 Point
aPt1( aBmpSize
.Width(), 0 );
518 aVD
.DrawBitmap( Point(), aBmp
);
519 aLineEndSet
.InsertItem( 1, aVD
.GetBitmap( aPt0
, aBmpSize
), pEntry
->GetName() );
520 aLineEndSet
.InsertItem( 2, aVD
.GetBitmap( aPt1
, aBmpSize
), pEntry
->GetName() );
522 delete pLineEndList
->Remove( nCount
);
524 for( long i
= 0; i
< nCount
; i
++ )
526 pEntry
= pLineEndList
->GetLineEnd( i
);
527 DBG_ASSERT( pEntry
, "Konnte auf LineEndEntry nicht zugreifen" );
528 aBmp
= pLineEndList
->GetUiBitmap( i
);
529 OSL_ENSURE( !aBmp
.IsEmpty(), "UI-Bitmap wurde nicht erzeugt" );
531 aVD
.DrawBitmap( aPt0
, aBmp
);
532 aLineEndSet
.InsertItem( (sal_uInt16
)((i
+1L)*2L+1L), aVD
.GetBitmap( aPt0
, aBmpSize
), pEntry
->GetName() );
533 aLineEndSet
.InsertItem( (sal_uInt16
)((i
+2L)*2L), aVD
.GetBitmap( aPt1
, aBmpSize
), pEntry
->GetName() );
535 nLines
= std::min( (sal_uInt16
)(nCount
+ 1), (sal_uInt16
) MAX_LINES
);
536 aLineEndSet
.SetLineCount( nLines
);
542 // -----------------------------------------------------------------------
544 void SvxLineEndWindow::Resize()
546 // since we change the size inside this call, check if we
547 // are called recursive
553 aLineEndSet
.SetColCount( nCols
);
554 aLineEndSet
.SetLineCount( nLines
);
558 Size aSize
= GetOutputSizePixel();
561 aLineEndSet
.SetPosSizePixel( Point( 2, 2 ), aSize
);
563 //SfxPopupWindow::Resize();
568 // -----------------------------------------------------------------------
570 void SvxLineEndWindow::Resizing( Size
& rNewSize
)
572 Size aBitmapSize
= aBmpSize
; // -> Member
573 aBitmapSize
.Width() += 6; //
574 aBitmapSize
.Height() += 6; //
576 Size aItemSize
= aLineEndSet
.CalcItemSizePixel( aBitmapSize
); // -> Member
577 //Size aOldSize = GetOutputSizePixel(); // fuer Breite
579 sal_uInt16 nItemCount
= aLineEndSet
.GetItemCount(); // -> Member
582 long nItemW
= aItemSize
.Width();
583 long nW
= rNewSize
.Width();
584 nCols
= (sal_uInt16
) std::max( ( (sal_uIntPtr
)(( nW
+ nItemW
) / ( nItemW
* 2 ) )),
589 long nItemH
= aItemSize
.Height();
590 long nH
= rNewSize
.Height();
591 nLines
= (sal_uInt16
) std::max( ( ( nH
+ nItemH
/ 2 ) / nItemH
), 1L );
593 sal_uInt16 nMaxCols
= nItemCount
/ nLines
;
594 if( nItemCount
% nLines
)
596 if( nCols
> nMaxCols
)
600 // Keine ungerade Anzahl von Spalten
603 nCols
= std::max( nCols
, (sal_uInt16
) 2 );
605 sal_uInt16 nMaxLines
= nItemCount
/ nCols
;
606 if( nItemCount
% nCols
)
608 if( nLines
> nMaxLines
)
610 nH
= nItemH
* nLines
;
612 rNewSize
.Width() = nW
;
613 rNewSize
.Height() = nH
;
615 // -----------------------------------------------------------------------
617 void SvxLineEndWindow::StartSelection()
619 aLineEndSet
.StartSelection();
622 // -----------------------------------------------------------------------
624 sal_Bool
SvxLineEndWindow::Close()
626 return SfxPopupWindow::Close();
629 // -----------------------------------------------------------------------
631 void SvxLineEndWindow::StateChanged(
632 sal_uInt16 nSID
, SfxItemState
, const SfxPoolItem
* pState
)
634 if ( nSID
== SID_LINEEND_LIST
)
636 // Die Liste der LinienEnden (LineEndList) hat sich geaendert:
637 if ( pState
&& pState
->ISA( SvxLineEndListItem
))
639 pLineEndList
= ((SvxLineEndListItem
*)pState
)->GetLineEndList();
640 DBG_ASSERT( pLineEndList
.is(), "LineEndList nicht gefunden" );
645 Size aSize
= GetOutputSizePixel();
652 // -----------------------------------------------------------------------
654 void SvxLineEndWindow::PopupModeEnd()
658 bPopupMode
= sal_False
;
661 SfxPopupWindow::PopupModeEnd();
664 // -----------------------------------------------------------------------
666 void SvxLineEndWindow::SetSize()
669 if( !IsInPopupMode() )
671 sal_uInt16 nItemCount
= aLineEndSet
.GetItemCount(); // -> Member
672 sal_uInt16 nMaxLines
= nItemCount
/ nCols
; // -> Member ?
673 if( nItemCount
% nCols
)
676 WinBits nBits
= aLineEndSet
.GetStyle();
677 if ( nLines
== nMaxLines
)
678 nBits
&= ~WB_VSCROLL
;
681 aLineEndSet
.SetStyle( nBits
);
684 Size
aSize( aBmpSize
);
687 aSize
= aLineEndSet
.CalcWindowSizePixel( aSize
);
690 SetOutputSizePixel( aSize
);
691 aSize
.Height() = aBmpSize
.Height();
692 aSize
.Height() += 14;
693 //SetMinOutputSizePixel( aSize );
696 void SvxLineEndWindow::GetFocus (void)
698 SfxPopupWindow::GetFocus();
699 // Grab the focus to the line ends value set so that it can be controlled
700 // with the keyboard.
701 aLineEndSet
.GrabFocus();
704 /*************************************************************************
706 |* SvxLineEndToolBoxControl
708 \************************************************************************/
710 SvxLineEndToolBoxControl::SvxLineEndToolBoxControl( sal_uInt16 nSlotId
, sal_uInt16 nId
, ToolBox
&rTbx
) :
711 SfxToolBoxControl( nSlotId
, nId
, rTbx
)
713 rTbx
.SetItemBits( nId
, TIB_DROPDOWNONLY
| rTbx
.GetItemBits( nId
) );
717 // -----------------------------------------------------------------------
719 SvxLineEndToolBoxControl::~SvxLineEndToolBoxControl()
723 // -----------------------------------------------------------------------
725 SfxPopupWindowType
SvxLineEndToolBoxControl::GetPopupWindowType() const
727 return SFX_POPUPWINDOW_ONCLICK
;
730 // -----------------------------------------------------------------------
732 SfxPopupWindow
* SvxLineEndToolBoxControl::CreatePopupWindow()
734 SvxLineEndWindow
* pLineEndWin
=
735 new SvxLineEndWindow( GetId(), m_xFrame
, &GetToolBox(), SVX_RESSTR( RID_SVXSTR_LINEEND
) );
736 pLineEndWin
->StartPopupMode( &GetToolBox(),
737 FLOATWIN_POPUPMODE_GRABFOCUS
|
738 FLOATWIN_POPUPMODE_ALLOWTEAROFF
|
739 FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
);
740 pLineEndWin
->StartSelection();
741 SetPopupWindow( pLineEndWin
);
745 // -----------------------------------------------------------------------
747 void SvxLineEndToolBoxControl::StateChanged( sal_uInt16
, SfxItemState eState
, const SfxPoolItem
* )
749 sal_uInt16 nId
= GetId();
750 ToolBox
& rTbx
= GetToolBox();
752 rTbx
.EnableItem( nId
, SFX_ITEM_DISABLED
!= eState
);
753 rTbx
.SetItemState( nId
, ( SFX_ITEM_DONTCARE
== eState
) ? STATE_DONTKNOW
: STATE_NOCHECK
);
756 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */