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 .
21 #include <tools/shl.hxx>
22 #include <vcl/status.hxx>
23 #include <vcl/menu.hxx>
24 #include <vcl/image.hxx>
25 #include <svl/stritem.hxx>
26 #include <svl/ptitem.hxx>
27 #include <svl/itempool.hxx>
28 #include <sfx2/app.hxx>
29 #include <sfx2/module.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <sfx2/objsh.hxx>
32 #include <svl/intitem.hxx>
34 #include "svx/pszctrl.hxx"
36 #define PAINT_OFFSET 5
38 #include <editeng/sizeitem.hxx>
39 #include <svx/dialmgr.hxx>
40 #include "svx/dlgutil.hxx"
42 #include "sfx2/module.hxx"
44 #include <svx/dialogs.hrc>
45 #include <unotools/localedatawrapper.hxx>
46 #include <comphelper/processfactory.hxx>
48 // -----------------------------------------------------------------------
52 Function used to create a text representation of
55 nVal is the metric value in the unit eUnit.
59 <SvxPosSizeStatusBarControl::Paint(const UserDrawEvent&)>
62 String
SvxPosSizeStatusBarControl::GetMetricStr_Impl( long nVal
)
64 // deliver and set the Metric of the application
65 FieldUnit eOutUnit
= SfxModule::GetModuleFieldUnit( getFrameInterface() );
66 FieldUnit eInUnit
= FUNIT_100TH_MM
;
69 const sal_Unicode cSep
= Application::GetSettings().GetLocaleDataWrapper().getNumDecimalSep()[0];
70 sal_Int64 nConvVal
= MetricField::ConvertValue( nVal
* 100, 0L, 0, eInUnit
, eOutUnit
);
72 if ( nConvVal
< 0 && ( nConvVal
/ 100 == 0 ) )
74 sMetric
+= OUString::valueOf(nConvVal
/ 100);
76 if( FUNIT_NONE
!= eOutUnit
)
79 sal_Int64 nFract
= nConvVal
% 100;
85 sMetric
+= OUString::valueOf(nFract
);
91 // -----------------------------------------------------------------------
93 SFX_IMPL_STATUSBAR_CONTROL(SvxPosSizeStatusBarControl
, SvxSizeItem
);
95 // class FunctionPopup_Impl ----------------------------------------------
97 class FunctionPopup_Impl
: public PopupMenu
100 FunctionPopup_Impl( sal_uInt16 nCheck
);
102 sal_uInt16
GetSelected() const { return nSelected
; }
105 sal_uInt16 nSelected
;
107 virtual void Select();
110 // -----------------------------------------------------------------------
112 FunctionPopup_Impl::FunctionPopup_Impl( sal_uInt16 nCheck
) :
113 PopupMenu( ResId( RID_SVXMNU_PSZ_FUNC
, DIALOG_MGR() ) ),
120 // -----------------------------------------------------------------------
122 void FunctionPopup_Impl::Select()
124 nSelected
= GetCurItemId();
127 // struct SvxPosSizeStatusBarControl_Impl --------------------------------
129 struct SvxPosSizeStatusBarControl_Impl
133 This implementation-structure of the class SvxPosSizeStatusBarControl
134 is done for the un-linking of the changes of the exported interface such as
135 the toning down of symbols that are visible externaly.
137 One instance exists for each SvxPosSizeStatusBarControl-instance
138 during it's life time
142 Point aPos
; // valid when a position is shown
143 Size aSize
; // valid when a size is shown
144 String aStr
; // valid when a text is shown
145 bool bPos
; // show position ?
146 bool bSize
; // set size ?
147 bool bTable
; // set table index ?
148 bool bHasMenu
; // set StarCalc popup menu ?
149 sal_uInt16 nFunction
; // the selected StarCalc function
150 Image aPosImage
; // Image to show the position
151 Image aSizeImage
; // Image to show the size
154 // class SvxPosSizeStatusBarControl ------------------------------------------
159 Create an instance of the implementation class,
160 load the images for the position and size
163 #define STR_POSITION ".uno:Position"
164 #define STR_TABLECELL ".uno:StateTableCell"
165 #define STR_FUNC ".uno:StatusBarFunc"
167 SvxPosSizeStatusBarControl::SvxPosSizeStatusBarControl( sal_uInt16 _nSlotId
,
170 SfxStatusBarControl( _nSlotId
, _nId
, rStb
),
171 pImp( new SvxPosSizeStatusBarControl_Impl
)
175 pImp
->bTable
= false;
176 pImp
->bHasMenu
= false;
178 pImp
->aPosImage
= Image( ResId( RID_SVXBMP_POSITION
, DIALOG_MGR() ) );
179 pImp
->aSizeImage
= Image( ResId( RID_SVXBMP_SIZE
, DIALOG_MGR() ) );
181 addStatusListener( OUString( STR_POSITION
)); // SID_ATTR_POSITION
182 addStatusListener( OUString( STR_TABLECELL
)); // SID_TABLE_CELL
183 addStatusListener( OUString( STR_FUNC
)); // SID_PSZ_FUNCTION
186 // -----------------------------------------------------------------------
191 remove the pointer to the implementation class, so that the timer is stopped
195 SvxPosSizeStatusBarControl::~SvxPosSizeStatusBarControl()
200 // -----------------------------------------------------------------------
204 SID_PSZ_FUNCTION activates the popup menu for Calc:
207 Depending on the type of the item, a special setting is enabled, the others disabled.
209 NULL/Void SfxPointItem SvxSizeItem SfxStringItem
210 ------------------------------------------------------------------------
211 Position sal_False FALSE
212 Size FALSE TRUE FALSE
213 Text sal_False sal_False TRUE
217 void SvxPosSizeStatusBarControl::StateChanged( sal_uInt16 nSID
, SfxItemState eState
,
218 const SfxPoolItem
* pState
)
220 // Because the combi-controller, always sets the curent Id as HelpId
221 // first clean the cached HelpText
222 GetStatusBar().SetHelpText( GetId(), String() );
226 case SID_ATTR_POSITION
: GetStatusBar().SetHelpId( GetId(), STR_POSITION
); break;
227 case SID_TABLE_CELL
: GetStatusBar().SetHelpId( GetId(), STR_TABLECELL
); break;
228 case SID_PSZ_FUNCTION
: GetStatusBar().SetHelpId( GetId(), STR_FUNC
); break;
232 if ( nSID
== SID_PSZ_FUNCTION
)
234 if ( eState
== SFX_ITEM_AVAILABLE
)
236 pImp
->bHasMenu
= true;
237 if ( pState
&& pState
->ISA(SfxUInt16Item
) )
238 pImp
->nFunction
= ((const SfxUInt16Item
*)pState
)->GetValue();
241 pImp
->bHasMenu
= false;
243 else if ( SFX_ITEM_AVAILABLE
!= eState
)
245 // don't switch to empty display before an empty state was
246 // notified for all display types
248 if ( nSID
== SID_TABLE_CELL
)
249 pImp
->bTable
= false;
250 else if ( nSID
== SID_ATTR_POSITION
)
252 else if ( nSID
== GetSlotId() ) // controller is registered for SID_ATTR_SIZE
256 SAL_WARN( "svx.stbcrtls","unknown slot id");
259 else if ( pState
->ISA( SfxPointItem
) )
262 pImp
->aPos
= ( (SfxPointItem
*)pState
)->GetValue();
264 pImp
->bTable
= false;
266 else if ( pState
->ISA( SvxSizeItem
) )
269 pImp
->aSize
= ( (SvxSizeItem
*)pState
)->GetSize();
271 pImp
->bTable
= false;
273 else if ( pState
->ISA( SfxStringItem
) )
275 // show string (table cel or different)
276 pImp
->aStr
= ( (SfxStringItem
*)pState
)->GetValue();
283 SAL_WARN( "svx.stbcrtls", "invalid item type" );
286 pImp
->bTable
= false;
289 if ( GetStatusBar().AreItemsVisible() )
290 GetStatusBar().SetItemData( GetId(), 0 );
292 // set only strings as text at the statusBar, so that the Help-Tips
293 // can work with the text, when it is too long for the statusBar
297 GetStatusBar().SetItemText( GetId(), aText
);
300 // -----------------------------------------------------------------------
304 execute popup menu, when the status enables this
307 void SvxPosSizeStatusBarControl::Command( const CommandEvent
& rCEvt
)
309 if ( rCEvt
.GetCommand() == COMMAND_CONTEXTMENU
&& pImp
->bHasMenu
)
311 sal_uInt16 nSelect
= pImp
->nFunction
;
313 nSelect
= PSZ_FUNC_NONE
;
314 FunctionPopup_Impl
aMenu( nSelect
);
315 if ( aMenu
.Execute( &GetStatusBar(), rCEvt
.GetMousePosPixel() ) )
317 nSelect
= aMenu
.GetSelected();
320 if (nSelect
== PSZ_FUNC_NONE
)
323 ::com::sun::star::uno::Any a
;
324 SfxUInt16Item
aItem( SID_PSZ_FUNCTION
, nSelect
);
326 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
> aArgs( 1 );
327 aArgs
[0].Name
= OUString( "StatusBarFunc" );
328 aItem
.QueryValue( a
);
331 execute( OUString( ".uno:StatusBarFunc" ), aArgs
);
332 // GetBindings().GetDispatcher()->Execute( SID_PSZ_FUNCTION, SFX_CALLMODE_RECORD, &aItem, 0L );
337 SfxStatusBarControl::Command( rCEvt
);
340 // -----------------------------------------------------------------------
344 Depending on the type to be shown, the value us shown. First the
345 rectangle is repainted (removed).
348 void SvxPosSizeStatusBarControl::Paint( const UserDrawEvent
& rUsrEvt
)
350 OutputDevice
* pDev
= rUsrEvt
.GetDevice();
351 DBG_ASSERT( pDev
, "no OutputDevice on UserDrawEvent" );
352 const Rectangle
& rRect
= rUsrEvt
.GetRect();
353 StatusBar
& rBar
= GetStatusBar();
354 Point aItemPos
= rBar
.GetItemTextPos( GetId() );
355 Color aOldLineColor
= pDev
->GetLineColor();
356 Color aOldFillColor
= pDev
->GetFillColor();
357 pDev
->SetLineColor();
358 pDev
->SetFillColor( pDev
->GetBackground().GetColor() );
360 if ( pImp
->bPos
|| pImp
->bSize
)
362 // count the position for showing the size
364 rRect
.Left() + rRect
.GetWidth() / 2 + PAINT_OFFSET
;
366 Point aPnt
= rRect
.TopLeft();
367 aPnt
.Y() = aItemPos
.Y();
368 aPnt
.X() += PAINT_OFFSET
;
369 pDev
->DrawImage( aPnt
, pImp
->aPosImage
);
370 aPnt
.X() += pImp
->aPosImage
.GetSizePixel().Width();
371 aPnt
.X() += PAINT_OFFSET
;
372 String aStr
= GetMetricStr_Impl( pImp
->aPos
.X());
373 aStr
.AppendAscii(" / ");
374 aStr
+= GetMetricStr_Impl( pImp
->aPos
.Y());
376 Rectangle( aPnt
, Point( nSizePosX
, rRect
.Bottom() ) ) );
377 pDev
->DrawText( aPnt
, aStr
);
379 // draw the size, when available
380 aPnt
.X() = nSizePosX
;
384 pDev
->DrawImage( aPnt
, pImp
->aSizeImage
);
385 aPnt
.X() += pImp
->aSizeImage
.GetSizePixel().Width();
386 Point aDrwPnt
= aPnt
;
387 aPnt
.X() += PAINT_OFFSET
;
388 aStr
= GetMetricStr_Impl( pImp
->aSize
.Width() );
389 aStr
.AppendAscii(" x ");
390 aStr
+= GetMetricStr_Impl( pImp
->aSize
.Height() );
391 pDev
->DrawRect( Rectangle( aDrwPnt
, rRect
.BottomRight() ) );
392 pDev
->DrawText( aPnt
, aStr
);
395 pDev
->DrawRect( Rectangle( aPnt
, rRect
.BottomRight() ) );
397 else if ( pImp
->bTable
)
399 pDev
->DrawRect( rRect
);
400 pDev
->DrawText( Point(
401 rRect
.Left() + rRect
.GetWidth() / 2 - pDev
->GetTextWidth( pImp
->aStr
) / 2,
402 aItemPos
.Y() ), pImp
->aStr
);
406 // Empty display if neither size nor table position are available.
407 // Date/Time are no longer used (#65302#).
408 pDev
->DrawRect( rRect
);
411 pDev
->SetLineColor( aOldLineColor
);
412 pDev
->SetFillColor( aOldFillColor
);
416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */