/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svx.hxx" // include --------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include #include #include "svx/pszctrl.hxx" #define PAINT_OFFSET 5 #include #include #include "svx/dlgutil.hxx" #include "stbctrls.h" #include #include #ifndef _UNOTOOLS_PROCESSFACTORY_HXX #include #endif // ----------------------------------------------------------------------- /* [Beschreibung] Funktion, mit der ein metrischer Wert in textueller Darstellung umgewandelt wird. nVal ist hier der metrische Wert in der Einheit eUnit. [Querverweise] */ String SvxPosSizeStatusBarControl::GetMetricStr_Impl( long nVal ) { // Applikations-Metrik besorgen und setzen FieldUnit eOutUnit = SfxModule::GetModuleFieldUnit( getFrameInterface() ); FieldUnit eInUnit = FUNIT_100TH_MM; String sMetric; const sal_Unicode cSep = Application::GetSettings().GetLocaleDataWrapper().getNumDecimalSep().GetChar(0); sal_Int64 nConvVal = MetricField::ConvertValue( nVal * 100, 0L, 0, eInUnit, eOutUnit ); if ( nConvVal < 0 && ( nConvVal / 100 == 0 ) ) sMetric += '-'; sMetric += String::CreateFromInt64( nConvVal / 100 ); if( FUNIT_NONE != eOutUnit ) { sMetric += cSep; sal_Int64 nFract = nConvVal % 100; if ( nFract < 0 ) nFract *= -1; if ( nFract < 10 ) sMetric += '0'; sMetric += String::CreateFromInt64( nFract ); } return sMetric; } // ----------------------------------------------------------------------- SFX_IMPL_STATUSBAR_CONTROL(SvxPosSizeStatusBarControl, SvxSizeItem); // class FunctionPopup_Impl ---------------------------------------------- class FunctionPopup_Impl : public PopupMenu { public: FunctionPopup_Impl( sal_uInt16 nCheck ); sal_uInt16 GetSelected() const { return nSelected; } private: sal_uInt16 nSelected; virtual void Select(); }; // ----------------------------------------------------------------------- FunctionPopup_Impl::FunctionPopup_Impl( sal_uInt16 nCheck ) : PopupMenu( ResId( RID_SVXMNU_PSZ_FUNC, DIALOG_MGR() ) ), nSelected( 0 ) { if (nCheck) CheckItem( nCheck ); } // ----------------------------------------------------------------------- void FunctionPopup_Impl::Select() { nSelected = GetCurItemId(); } // struct SvxPosSizeStatusBarControl_Impl -------------------------------- struct SvxPosSizeStatusBarControl_Impl /* [Beschreibung] Diese Implementations-Struktur der Klasse SvxPosSizeStatusBarControl dient der Entkopplung von Änderungen vom exportierten Interface sowie der Verringerung von extern sichtbaren Symbolen. Eine Instanz existiert pro SvxPosSizeStatusBarControl-Instanz für deren Laufzeit. */ { Point aPos; // gültig, wenn eine Position angezeigt wird Size aSize; // gültig, wenn eine Größe angezeigt wird String aStr; // gültig, wenn ein Text angezeigt wird sal_Bool bPos; // show position? sal_Bool bSize; // show size? sal_Bool bTable; // Tabellenindex anzeigen? sal_Bool bHasMenu; // Calc Popup-Menü anzeigen? sal_uInt16 nFunction; // selektierte Calc Funktion Image aPosImage; // Image für die Positionsanzeige Image aSizeImage; // Image für die Größenanzeige }; // class SvxPosSizeStatusBarControl ------------------------------------------ /* [Beschreibung] Ctor(): Anlegen einer Impl-Klassen-Instanz, Default die Zeitanzeige enablen, Images für die Position und Größe laden. */ #define STR_POSITION ".uno:Position" #define STR_TABLECELL ".uno:StateTableCell" #define STR_FUNC ".uno:StatusBarFunc" SvxPosSizeStatusBarControl::SvxPosSizeStatusBarControl( sal_uInt16 _nSlotId, sal_uInt16 _nId, StatusBar& rStb ) : SfxStatusBarControl( _nSlotId, _nId, rStb ), pImp( new SvxPosSizeStatusBarControl_Impl ) { pImp->bPos = sal_False; pImp->bSize = sal_False; pImp->bTable = sal_False; pImp->bHasMenu = sal_False; pImp->nFunction = 0; sal_Bool bHC = GetStatusBar().GetSettings().GetStyleSettings().GetHighContrastMode(); pImp->aPosImage = Image( SVX_RES( bHC ? RID_SVXBMP_POSITION_H : RID_SVXBMP_POSITION ) ); pImp->aSizeImage = Image( SVX_RES( bHC ? RID_SVXBMP_SIZE_H : RID_SVXBMP_SIZE ) ); addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STR_POSITION ))); // SID_ATTR_POSITION addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STR_TABLECELL ))); // SID_TABLE_CELL addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STR_FUNC ))); // SID_PSZ_FUNCTION } // ----------------------------------------------------------------------- /* [Beschreibung] Dtor(): Pointer auf die Impl-Klasse löschen, damit der Timer gestoppt wird. */ SvxPosSizeStatusBarControl::~SvxPosSizeStatusBarControl() { delete pImp; } // ----------------------------------------------------------------------- /* [Beschreibung] SID_PSZ_FUNCTION aktiviert das Popup-Menü für Calc, ansonsten: Statusbenachrichtigung; Je nach Item-Typ wird eine bestimmte Anzeige enabled, die anderen disabled. NULL/Void SfxPointItem SvxSizeItem SfxStringItem ------------------------------------------------------------------------ Zeit sal_True sal_False sal_False FALSE Position sal_False FALSE Größe FALSE TRUE FALSE Text sal_False sal_False TRUE Ein anderes Item bewirkt einen Assert, die Zeitanzeige wird enabled. */ void SvxPosSizeStatusBarControl::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState ) { // da Kombi-Controller, immer die aktuelle Id als HelpId setzen // gecachten HelpText vorher löschen GetStatusBar().SetHelpText( GetId(), String() ); switch ( nSID ) { case SID_ATTR_POSITION : GetStatusBar().SetHelpId( GetId(), STR_POSITION ); break; case SID_TABLE_CELL: GetStatusBar().SetHelpId( GetId(), STR_TABLECELL ); break; case SID_PSZ_FUNCTION: GetStatusBar().SetHelpId( GetId(), STR_FUNC ); break; default: break; } if ( nSID == SID_PSZ_FUNCTION ) { if ( eState == SFX_ITEM_AVAILABLE ) { pImp->bHasMenu = sal_True; if ( pState && pState->ISA(SfxUInt16Item) ) pImp->nFunction = ((const SfxUInt16Item*)pState)->GetValue(); } else pImp->bHasMenu = sal_False; } else if ( SFX_ITEM_AVAILABLE != eState ) { // #i34458# don't switch to empty display before an empty state was // notified for all display types if ( nSID == SID_TABLE_CELL ) pImp->bTable = sal_False; else if ( nSID == SID_ATTR_POSITION ) pImp->bPos = sal_False; else if ( nSID == GetSlotId() ) // controller is registered for SID_ATTR_SIZE pImp->bSize = sal_False; else { DBG_ERRORFILE("unknown slot id"); } } else if ( pState->ISA( SfxPointItem ) ) { // Position anzeigen pImp->aPos = ( (SfxPointItem*)pState )->GetValue(); pImp->bPos = sal_True; pImp->bTable = sal_False; } else if ( pState->ISA( SvxSizeItem ) ) { // Größe anzeigen pImp->aSize = ( (SvxSizeItem*)pState )->GetSize(); pImp->bSize = sal_True; pImp->bTable = sal_False; } else if ( pState->ISA( SfxStringItem ) ) { // String anzeigen (Tabellen-Zelle oder anderes) pImp->aStr = ( (SfxStringItem*)pState )->GetValue(); pImp->bTable = sal_True; pImp->bPos = sal_False; pImp->bSize = sal_False; } else { DBG_ERRORFILE( "invalid item type" ); // trotzdem Datum und Zeit anzeigen pImp->bPos = sal_False; pImp->bSize = sal_False; pImp->bTable = sal_False; } if ( GetStatusBar().AreItemsVisible() ) GetStatusBar().SetItemData( GetId(), 0 ); // nur Strings auch als Text an der StatusBar setzen, damit Tip-Hilfe // funktioniert, wenn der Text zu lang ist. String aText; if ( pImp->bTable ) aText = pImp->aStr; GetStatusBar().SetItemText( GetId(), aText ); } // ----------------------------------------------------------------------- /* [Beschreibung] Popup-Menü ausführen, wenn per Status enabled */ void SvxPosSizeStatusBarControl::Command( const CommandEvent& rCEvt ) { if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU && pImp->bHasMenu ) { sal_uInt16 nSelect = pImp->nFunction; if (!nSelect) nSelect = PSZ_FUNC_NONE; FunctionPopup_Impl aMenu( nSelect ); if ( aMenu.Execute( &GetStatusBar(), rCEvt.GetMousePosPixel() ) ) { nSelect = aMenu.GetSelected(); if (nSelect) { if (nSelect == PSZ_FUNC_NONE) nSelect = 0; ::com::sun::star::uno::Any a; SfxUInt16Item aItem( SID_PSZ_FUNCTION, nSelect ); ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs( 1 ); aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusBarFunc" )); aItem.QueryValue( a ); aArgs[0].Value = a; execute( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StatusBarFunc" )), aArgs ); // GetBindings().GetDispatcher()->Execute( SID_PSZ_FUNCTION, SFX_CALLMODE_RECORD, &aItem, 0L ); } } } else SfxStatusBarControl::Command( rCEvt ); } // ----------------------------------------------------------------------- /* [Beschreibung] Je nach enableden Anzeigentyp, wird der Wert angezeigt. Vorher wird das Rectangle übermalt (gelöscht). */ void SvxPosSizeStatusBarControl::Paint( const UserDrawEvent& rUsrEvt ) { OutputDevice* pDev = rUsrEvt.GetDevice(); DBG_ASSERT( pDev, "no OutputDevice on UserDrawEvent" ); const Rectangle& rRect = rUsrEvt.GetRect(); StatusBar& rBar = GetStatusBar(); Point aItemPos = rBar.GetItemTextPos( GetId() ); Color aOldLineColor = pDev->GetLineColor(); Color aOldFillColor = pDev->GetFillColor(); pDev->SetLineColor(); pDev->SetFillColor( pDev->GetBackground().GetColor() ); if ( pImp->bPos || pImp->bSize ) { // Position für Size-Anzeige berechnen long nSizePosX = rRect.Left() + rRect.GetWidth() / 2 + PAINT_OFFSET; // Position zeichnen Point aPnt = rRect.TopLeft(); aPnt.Y() = aItemPos.Y(); aPnt.X() += PAINT_OFFSET; pDev->DrawImage( aPnt, pImp->aPosImage ); aPnt.X() += pImp->aPosImage.GetSizePixel().Width(); aPnt.X() += PAINT_OFFSET; String aStr = GetMetricStr_Impl( pImp->aPos.X()); aStr.AppendAscii(" / "); aStr += GetMetricStr_Impl( pImp->aPos.Y()); pDev->DrawRect( Rectangle( aPnt, Point( nSizePosX, rRect.Bottom() ) ) ); pDev->DrawText( aPnt, aStr ); // falls verfügbar, Größe zeichnen aPnt.X() = nSizePosX; if ( pImp->bSize ) { pDev->DrawImage( aPnt, pImp->aSizeImage ); aPnt.X() += pImp->aSizeImage.GetSizePixel().Width(); Point aDrwPnt = aPnt; aPnt.X() += PAINT_OFFSET; aStr = GetMetricStr_Impl( pImp->aSize.Width() ); aStr.AppendAscii(" x "); aStr += GetMetricStr_Impl( pImp->aSize.Height() ); pDev->DrawRect( Rectangle( aDrwPnt, rRect.BottomRight() ) ); pDev->DrawText( aPnt, aStr ); } else pDev->DrawRect( Rectangle( aPnt, rRect.BottomRight() ) ); } else if ( pImp->bTable ) { pDev->DrawRect( rRect ); pDev->DrawText( Point( rRect.Left() + rRect.GetWidth() / 2 - pDev->GetTextWidth( pImp->aStr ) / 2, aItemPos.Y() ), pImp->aStr ); } else { // Empty display if neither size nor table position are available. // Date/Time are no longer used (#65302#). pDev->DrawRect( rRect ); } pDev->SetLineColor( aOldLineColor ); pDev->SetFillColor( aOldFillColor ); } // ----------------------------------------------------------------------- sal_uIntPtr SvxPosSizeStatusBarControl::GetDefItemWidth(const StatusBar& rStb) { Image aTmpPosImage( ResId( RID_SVXBMP_POSITION, DIALOG_MGR() ) ); Image aTmpSizeImage( ResId( RID_SVXBMP_SIZE, DIALOG_MGR() ) ); sal_uIntPtr nWidth=PAINT_OFFSET+aTmpPosImage.GetSizePixel().Width(); nWidth+=PAINT_OFFSET+aTmpSizeImage.GetSizePixel().Width(); nWidth+=2*(PAINT_OFFSET+rStb.GetTextWidth(String::CreateFromAscii("XXXX,XX / XXXX,XX"))); return nWidth; } /* vim: set noet sw=4 ts=4: */