merge the formfield patch from ooo-build
[ooovba.git] / svx / source / stbctrls / pszctrl.cxx
bloba5376ab390c835251f5090deb1d6613d8002e790
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pszctrl.cxx,v $
10 * $Revision: 1.18 $
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 <limits.h>
37 #include <tools/shl.hxx>
38 #ifndef _STATUS_HXX //autogen
39 #include <vcl/status.hxx>
40 #endif
41 #ifndef _MENU_HXX //autogen
42 #include <vcl/menu.hxx>
43 #endif
44 #include <vcl/image.hxx>
45 #include <svtools/stritem.hxx>
46 #include <svtools/ptitem.hxx>
47 #include <svtools/itempool.hxx>
48 #include <sfx2/app.hxx>
49 #include <sfx2/module.hxx>
50 #include <sfx2/dispatch.hxx>
51 #include <sfx2/objsh.hxx>
53 #define _SVX_PSZCTRL_CXX
55 #include "pszctrl.hxx"
57 #define PAINT_OFFSET 5
59 #include <svx/sizeitem.hxx>
60 #include <svx/dialmgr.hxx>
61 #include "dlgutil.hxx"
62 #include "stbctrls.h"
64 #include <svx/dialogs.hrc>
65 #include <unotools/localedatawrapper.hxx>
66 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
67 #include <comphelper/processfactory.hxx>
68 #endif
70 // -----------------------------------------------------------------------
72 /* [Beschreibung]
74 Funktion, mit der ein metrischer Wert in textueller Darstellung
75 umgewandelt wird.
77 nVal ist hier der metrische Wert in der Einheit eUnit.
79 [Querverweise]
81 <SvxPosSizeStatusBarControl::Paint(const UserDrawEvent&)>
84 String GetMetricStr_Impl( long nVal )
86 // Applikations-Metrik besorgen und setzen
87 FieldUnit eOutUnit = GetModuleFieldUnit( NULL );
88 FieldUnit eInUnit = FUNIT_100TH_MM;
90 String sMetric;
91 const sal_Unicode cSep = Application::GetSettings().GetLocaleDataWrapper().getNumDecimalSep().GetChar(0);
92 sal_Int64 nConvVal = MetricField::ConvertValue( nVal * 100, 0L, 0, eInUnit, eOutUnit );
94 if ( nConvVal < 0 && ( nConvVal / 100 == 0 ) )
95 sMetric += '-';
96 sMetric += String::CreateFromInt64( nConvVal / 100 );
98 if( FUNIT_NONE != eOutUnit )
100 sMetric += cSep;
101 sal_Int64 nFract = nConvVal % 100;
103 if ( nFract < 0 )
104 nFract *= -1;
105 if ( nFract < 10 )
106 sMetric += '0';
107 sMetric += String::CreateFromInt64( nFract );
110 return sMetric;
113 // -----------------------------------------------------------------------
115 SFX_IMPL_STATUSBAR_CONTROL(SvxPosSizeStatusBarControl, SvxSizeItem);
117 // class FunctionPopup_Impl ----------------------------------------------
119 class FunctionPopup_Impl : public PopupMenu
121 public:
122 FunctionPopup_Impl( USHORT nCheck );
124 USHORT GetSelected() const { return nSelected; }
126 private:
127 USHORT nSelected;
129 virtual void Select();
132 // -----------------------------------------------------------------------
134 FunctionPopup_Impl::FunctionPopup_Impl( USHORT nCheck ) :
135 PopupMenu( ResId( RID_SVXMNU_PSZ_FUNC, DIALOG_MGR() ) ),
136 nSelected( 0 )
138 if (nCheck)
139 CheckItem( nCheck );
142 // -----------------------------------------------------------------------
144 void FunctionPopup_Impl::Select()
146 nSelected = GetCurItemId();
149 // struct SvxPosSizeStatusBarControl_Impl --------------------------------
151 struct SvxPosSizeStatusBarControl_Impl
153 /* [Beschreibung]
155 Diese Implementations-Struktur der Klasse SvxPosSizeStatusBarControl
156 dient der Entkopplung von "Anderungen vom exportierten Interface sowie
157 der Verringerung von extern sichtbaren Symbolen.
159 Eine Instanz exisitiert pro SvxPosSizeStatusBarControl-Instanz
160 f"ur deren Laufzeit.
164 Point aPos; // g"ultig, wenn eine Position angezeigt wird
165 Size aSize; // g"ultig, wenn eine Gr"o/se angezeigt wird
166 String aStr; // g"ultig, wenn ein Text angezeigt wird
167 BOOL bPos; // show position
168 BOOL bSize; // Gr"o/se anzeigen?
169 BOOL bTable; // Tabellenindex anzeigen?
170 BOOL bHasMenu; // StarCalc Popup-Menue anzeigen?
171 USHORT nFunction; // selektierte StarCalc Funktion
172 Image aPosImage; // Image f"ur die Positionsanzeige
173 Image aSizeImage; // Image f"ur die Gr"o/senanzeige
176 // class SvxPosSizeStatusBarControl ------------------------------------------
178 /* [Beschreibung]
180 Ctor():
181 Anlegen einer Impl-Klassen-Instanz, Default die Zeitanzeige enablen,
182 Images fu"r die Position und Gro"sse laden.
185 SvxPosSizeStatusBarControl::SvxPosSizeStatusBarControl( USHORT _nSlotId,
186 USHORT _nId,
187 StatusBar& rStb ) :
188 SfxStatusBarControl( _nSlotId, _nId, rStb ),
189 pImp( new SvxPosSizeStatusBarControl_Impl )
191 pImp->bPos = FALSE;
192 pImp->bSize = FALSE;
193 pImp->bTable = FALSE;
194 pImp->bHasMenu = FALSE;
195 pImp->nFunction = 0;
196 pImp->aPosImage = Image( ResId( RID_SVXBMP_POSITION, DIALOG_MGR() ) );
197 pImp->aSizeImage = Image( ResId( RID_SVXBMP_SIZE, DIALOG_MGR() ) );
199 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Position" )));
200 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StateTableCell" )));
201 addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StatusBarFunc" )));
204 // -----------------------------------------------------------------------
206 /* [Beschreibung]
208 Dtor():
209 Pointer auf die Impl-Klasse lo"schen, damit der Timer gestoppt wird.
212 SvxPosSizeStatusBarControl::~SvxPosSizeStatusBarControl()
214 delete pImp;
217 // -----------------------------------------------------------------------
219 /* [Beschreibung]
221 SID_PSZ_FUNCTION aktiviert das Popup-Menue fuer Calc, ansonsten:
223 Statusbenachrichtigung;
224 Je nach Item-Typ wird eine bestimmte Anzeige enabled, die anderen disabled.
226 NULL/Void SfxPointItem SvxSizeItem SfxStringItem
227 ------------------------------------------------------------------------
228 Zeit TRUE FALSE FALSE FALSE
229 Position FALSE FALSE
230 Gro"sse FALSE TRUE FALSE
231 Text FALSE FALSE TRUE
233 Ein anderes Item bewirkt einen Assert, die Zeitanzeige wird enabled.
236 void SvxPosSizeStatusBarControl::StateChanged( USHORT nSID, SfxItemState eState,
237 const SfxPoolItem* pState )
239 // da Kombi-Controller, immer die aktuelle Id als HelpId setzen
240 // gecachten HelpText vorher l"oschen
241 GetStatusBar().SetHelpText( GetId(), String() );
242 GetStatusBar().SetHelpId( GetId(), nSID );
244 if ( nSID == SID_PSZ_FUNCTION )
246 if ( eState == SFX_ITEM_AVAILABLE )
248 pImp->bHasMenu = TRUE;
249 if ( pState && pState->ISA(SfxUInt16Item) )
250 pImp->nFunction = ((const SfxUInt16Item*)pState)->GetValue();
252 else
253 pImp->bHasMenu = FALSE;
255 else if ( SFX_ITEM_AVAILABLE != eState )
257 // #i34458# don't switch to empty display before an empty state was
258 // notified for all display types
260 if ( nSID == SID_TABLE_CELL )
261 pImp->bTable = FALSE;
262 else if ( nSID == SID_ATTR_POSITION )
263 pImp->bPos = FALSE;
264 else if ( nSID == GetSlotId() ) // controller is registered for SID_ATTR_SIZE
265 pImp->bSize = FALSE;
266 else
268 DBG_ERRORFILE("unknown slot id");
271 else if ( pState->ISA( SfxPointItem ) )
273 // Position anzeigen
274 pImp->aPos = ( (SfxPointItem*)pState )->GetValue();
275 pImp->bPos = TRUE;
276 pImp->bTable = FALSE;
278 else if ( pState->ISA( SvxSizeItem ) )
280 // Groesse anzeigen
281 pImp->aSize = ( (SvxSizeItem*)pState )->GetSize();
282 pImp->bSize = TRUE;
283 pImp->bTable = FALSE;
285 else if ( pState->ISA( SfxStringItem ) )
287 // String anzeigen (Tabellen-Zelle oder anderes)
288 pImp->aStr = ( (SfxStringItem*)pState )->GetValue();
289 pImp->bTable = TRUE;
290 pImp->bPos = FALSE;
291 pImp->bSize = FALSE;
293 else
295 DBG_ERRORFILE( "invalid item type" );
296 // trotzdem Datum und Zeit anzeigen
297 pImp->bPos = FALSE;
298 pImp->bSize = FALSE;
299 pImp->bTable = FALSE;
302 if ( GetStatusBar().AreItemsVisible() )
303 GetStatusBar().SetItemData( GetId(), 0 );
305 // nur Strings auch als Text an der StatusBar setzen, damit Tip-Hilfe
306 // funktioniert, wenn der Text zu lang ist.
307 String aText;
308 if ( pImp->bTable )
309 aText = pImp->aStr;
310 GetStatusBar().SetItemText( GetId(), aText );
313 // -----------------------------------------------------------------------
315 /* [Beschreibung]
317 Popup-Menue ausfuehren, wenn per Status enabled
320 void SvxPosSizeStatusBarControl::Command( const CommandEvent& rCEvt )
322 if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU && pImp->bHasMenu )
324 USHORT nSelect = pImp->nFunction;
325 if (!nSelect)
326 nSelect = PSZ_FUNC_NONE;
327 FunctionPopup_Impl aMenu( nSelect );
328 if ( aMenu.Execute( &GetStatusBar(), rCEvt.GetMousePosPixel() ) )
330 nSelect = aMenu.GetSelected();
331 if (nSelect)
333 if (nSelect == PSZ_FUNC_NONE)
334 nSelect = 0;
336 ::com::sun::star::uno::Any a;
337 SfxUInt16Item aItem( SID_PSZ_FUNCTION, nSelect );
339 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs( 1 );
340 aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusBarFunc" ));
341 aItem.QueryValue( a );
342 aArgs[0].Value = a;
344 execute( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StatusBarFunc" )), aArgs );
345 // GetBindings().GetDispatcher()->Execute( SID_PSZ_FUNCTION, SFX_CALLMODE_RECORD, &aItem, 0L );
349 else
350 SfxStatusBarControl::Command( rCEvt );
353 // -----------------------------------------------------------------------
355 /* [Beschreibung]
357 Je nach enableden Anzeigentyp, wird der Wert angezeigt. Vorher wird
358 das Rectangle u"bermalt (gelo"scht).
361 void SvxPosSizeStatusBarControl::Paint( const UserDrawEvent& rUsrEvt )
363 OutputDevice* pDev = rUsrEvt.GetDevice();
364 DBG_ASSERT( pDev, "no OutputDevice on UserDrawEvent" );
365 const Rectangle& rRect = rUsrEvt.GetRect();
366 StatusBar& rBar = GetStatusBar();
367 Point aItemPos = rBar.GetItemTextPos( GetId() );
368 Color aOldLineColor = pDev->GetLineColor();
369 Color aOldFillColor = pDev->GetFillColor();
370 pDev->SetLineColor();
371 pDev->SetFillColor( pDev->GetBackground().GetColor() );
373 if ( pImp->bPos || pImp->bSize )
375 // Position fuer Size-Anzeige berechnen
376 long nSizePosX =
377 rRect.Left() + rRect.GetWidth() / 2 + PAINT_OFFSET;
378 // Position zeichnen
379 Point aPnt = rRect.TopLeft();
380 aPnt.Y() = aItemPos.Y();
381 aPnt.X() += PAINT_OFFSET;
382 pDev->DrawImage( aPnt, pImp->aPosImage );
383 aPnt.X() += pImp->aPosImage.GetSizePixel().Width();
384 aPnt.X() += PAINT_OFFSET;
385 String aStr = GetMetricStr_Impl( pImp->aPos.X());
386 aStr.AppendAscii(" / ");
387 aStr += GetMetricStr_Impl( pImp->aPos.Y());
388 pDev->DrawRect(
389 Rectangle( aPnt, Point( nSizePosX, rRect.Bottom() ) ) );
390 pDev->DrawText( aPnt, aStr );
392 // falls verf"ugbar, Gr"osse zeichnen
393 aPnt.X() = nSizePosX;
395 if ( pImp->bSize )
397 pDev->DrawImage( aPnt, pImp->aSizeImage );
398 aPnt.X() += pImp->aSizeImage.GetSizePixel().Width();
399 Point aDrwPnt = aPnt;
400 aPnt.X() += PAINT_OFFSET;
401 aStr = GetMetricStr_Impl( pImp->aSize.Width() );
402 aStr.AppendAscii(" x ");
403 aStr += GetMetricStr_Impl( pImp->aSize.Height() );
404 pDev->DrawRect( Rectangle( aDrwPnt, rRect.BottomRight() ) );
405 pDev->DrawText( aPnt, aStr );
407 else
408 pDev->DrawRect( Rectangle( aPnt, rRect.BottomRight() ) );
410 else if ( pImp->bTable )
412 pDev->DrawRect( rRect );
413 pDev->DrawText( Point(
414 rRect.Left() + rRect.GetWidth() / 2 - pDev->GetTextWidth( pImp->aStr ) / 2,
415 aItemPos.Y() ), pImp->aStr );
417 else
419 // Empty display if neither size nor table position are available.
420 // Date/Time are no longer used (#65302#).
421 pDev->DrawRect( rRect );
424 pDev->SetLineColor( aOldLineColor );
425 pDev->SetFillColor( aOldFillColor );
428 // -----------------------------------------------------------------------
430 ULONG SvxPosSizeStatusBarControl::GetDefItemWidth(const StatusBar& rStb)
432 Image aTmpPosImage( ResId( RID_SVXBMP_POSITION, DIALOG_MGR() ) );
433 Image aTmpSizeImage( ResId( RID_SVXBMP_SIZE, DIALOG_MGR() ) );
435 ULONG nWidth=PAINT_OFFSET+aTmpPosImage.GetSizePixel().Width();
436 nWidth+=PAINT_OFFSET+aTmpSizeImage.GetSizePixel().Width();
437 nWidth+=2*(PAINT_OFFSET+rStb.GetTextWidth(String::CreateFromAscii("XXXX,XX / XXXX,XX")));
439 return nWidth;