bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / stbctrls / pszctrl.cxx
blob21d42773f19cfc376df4649c3a9bf70f4084b999
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <limits.h>
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"
41 #include "stbctrls.h"
42 #include "sfx2/module.hxx"
44 #include <svx/dialogs.hrc>
45 #include <unotools/localedatawrapper.hxx>
46 #include <comphelper/processfactory.hxx>
48 // -----------------------------------------------------------------------
50 /* [Description]
52 Function used to create a text representation of
53 a metric value
55 nVal is the metric value in the unit eUnit.
57 [cross reference]
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;
68 String sMetric;
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 ) )
73 sMetric += '-';
74 sMetric += OUString::valueOf(nConvVal / 100);
76 if( FUNIT_NONE != eOutUnit )
78 sMetric += cSep;
79 sal_Int64 nFract = nConvVal % 100;
81 if ( nFract < 0 )
82 nFract *= -1;
83 if ( nFract < 10 )
84 sMetric += '0';
85 sMetric += OUString::valueOf(nFract);
88 return sMetric;
91 // -----------------------------------------------------------------------
93 SFX_IMPL_STATUSBAR_CONTROL(SvxPosSizeStatusBarControl, SvxSizeItem);
95 // class FunctionPopup_Impl ----------------------------------------------
97 class FunctionPopup_Impl : public PopupMenu
99 public:
100 FunctionPopup_Impl( sal_uInt16 nCheck );
102 sal_uInt16 GetSelected() const { return nSelected; }
104 private:
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() ) ),
114 nSelected( 0 )
116 if (nCheck)
117 CheckItem( nCheck );
120 // -----------------------------------------------------------------------
122 void FunctionPopup_Impl::Select()
124 nSelected = GetCurItemId();
127 // struct SvxPosSizeStatusBarControl_Impl --------------------------------
129 struct SvxPosSizeStatusBarControl_Impl
131 /* [Description]
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 ------------------------------------------
156 /* [Description]
158 Ctor():
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,
168 sal_uInt16 _nId,
169 StatusBar& rStb ) :
170 SfxStatusBarControl( _nSlotId, _nId, rStb ),
171 pImp( new SvxPosSizeStatusBarControl_Impl )
173 pImp->bPos = false;
174 pImp->bSize = false;
175 pImp->bTable = false;
176 pImp->bHasMenu = false;
177 pImp->nFunction = 0;
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 // -----------------------------------------------------------------------
188 /* [Description]
190 Dtor():
191 remove the pointer to the implementation class, so that the timer is stopped
195 SvxPosSizeStatusBarControl::~SvxPosSizeStatusBarControl()
197 delete pImp;
200 // -----------------------------------------------------------------------
202 /* [Description]
204 SID_PSZ_FUNCTION activates the popup menu for Calc:
206 Status overview
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() );
224 switch ( nSID )
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;
229 default: 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();
240 else
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 )
251 pImp->bPos = false;
252 else if ( nSID == GetSlotId() ) // controller is registered for SID_ATTR_SIZE
253 pImp->bSize = false;
254 else
256 SAL_WARN( "svx.stbcrtls","unknown slot id");
259 else if ( pState->ISA( SfxPointItem ) )
261 // show position
262 pImp->aPos = ( (SfxPointItem*)pState )->GetValue();
263 pImp->bPos = true;
264 pImp->bTable = false;
266 else if ( pState->ISA( SvxSizeItem ) )
268 // show size
269 pImp->aSize = ( (SvxSizeItem*)pState )->GetSize();
270 pImp->bSize = true;
271 pImp->bTable = false;
273 else if ( pState->ISA( SfxStringItem ) )
275 // show string (table cel or different)
276 pImp->aStr = ( (SfxStringItem*)pState )->GetValue();
277 pImp->bTable = true;
278 pImp->bPos = false;
279 pImp->bSize = false;
281 else
283 SAL_WARN( "svx.stbcrtls", "invalid item type" );
284 pImp->bPos = false;
285 pImp->bSize = false;
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
294 String aText;
295 if ( pImp->bTable )
296 aText = pImp->aStr;
297 GetStatusBar().SetItemText( GetId(), aText );
300 // -----------------------------------------------------------------------
302 /* [Description]
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;
312 if (!nSelect)
313 nSelect = PSZ_FUNC_NONE;
314 FunctionPopup_Impl aMenu( nSelect );
315 if ( aMenu.Execute( &GetStatusBar(), rCEvt.GetMousePosPixel() ) )
317 nSelect = aMenu.GetSelected();
318 if (nSelect)
320 if (nSelect == PSZ_FUNC_NONE)
321 nSelect = 0;
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 );
329 aArgs[0].Value = a;
331 execute( OUString( ".uno:StatusBarFunc" ), aArgs );
332 // GetBindings().GetDispatcher()->Execute( SID_PSZ_FUNCTION, SFX_CALLMODE_RECORD, &aItem, 0L );
336 else
337 SfxStatusBarControl::Command( rCEvt );
340 // -----------------------------------------------------------------------
342 /* [Description]
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
363 long nSizePosX =
364 rRect.Left() + rRect.GetWidth() / 2 + PAINT_OFFSET;
365 // draw position
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());
375 pDev->DrawRect(
376 Rectangle( aPnt, Point( nSizePosX, rRect.Bottom() ) ) );
377 pDev->DrawText( aPnt, aStr );
379 // draw the size, when available
380 aPnt.X() = nSizePosX;
382 if ( pImp->bSize )
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 );
394 else
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 );
404 else
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: */