1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 32*cdf0e10cSrcweir #include <stdio.h> 33*cdf0e10cSrcweir #endif 34*cdf0e10cSrcweir #include <sal/alloca.h> 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include <tools/prex.h> 37*cdf0e10cSrcweir #include <X11/Xlib.h> 38*cdf0e10cSrcweir #include <unx/XIM.h> 39*cdf0e10cSrcweir #include <tools/postx.h> 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include <unx/salunx.h> 42*cdf0e10cSrcweir #include <unx/i18n_status.hxx> 43*cdf0e10cSrcweir #include <unx/i18n_ic.hxx> 44*cdf0e10cSrcweir #include <unx/saldisp.hxx> 45*cdf0e10cSrcweir #include <unx/salframe.h> 46*cdf0e10cSrcweir #include <unx/saldata.hxx> 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir #include <vcl/wrkwin.hxx> 49*cdf0e10cSrcweir #include <vcl/fixed.hxx> 50*cdf0e10cSrcweir #include <vcl/menubtn.hxx> 51*cdf0e10cSrcweir #include <vcl/menu.hxx> 52*cdf0e10cSrcweir #include <vcl/svapp.hxx> 53*cdf0e10cSrcweir #include <vcl/sysdata.hxx> 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir #include <svdata.hxx> 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir using namespace vcl; 58*cdf0e10cSrcweir using namespace rtl; 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir namespace vcl { 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir class StatusWindow : public WorkWindow 63*cdf0e10cSrcweir { 64*cdf0e10cSrcweir protected: 65*cdf0e10cSrcweir StatusWindow( WinBits nWinBits ); 66*cdf0e10cSrcweir public: 67*cdf0e10cSrcweir virtual ~StatusWindow(); 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir virtual void setPosition( SalFrame* ); 70*cdf0e10cSrcweir virtual void setText( const String & ) = 0; 71*cdf0e10cSrcweir virtual String getText() const = 0; 72*cdf0e10cSrcweir virtual void show( bool bShow, I18NStatus::ShowReason eReason ) = 0; 73*cdf0e10cSrcweir virtual void toggle( bool bOn ) = 0; 74*cdf0e10cSrcweir }; 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir StatusWindow::StatusWindow( WinBits nWinBits ) : 79*cdf0e10cSrcweir WorkWindow( NULL, nWinBits ) 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir StatusWindow::~StatusWindow() {} 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir void StatusWindow::setPosition( SalFrame* ) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir } 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir // -------------------------------------------------------------------------- 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir namespace vcl { 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir class XIMStatusWindow : public StatusWindow 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir FixedText m_aStatusText; 96*cdf0e10cSrcweir SalFrame* m_pLastParent; 97*cdf0e10cSrcweir Size m_aWindowSize; 98*cdf0e10cSrcweir bool m_bAnchoredAtRight; 99*cdf0e10cSrcweir // true if the right edge (instead of the left edge) should stay at a 100*cdf0e10cSrcweir // fixed position when re-sizing the window 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir // for delayed showing 103*cdf0e10cSrcweir bool m_bDelayedShow; 104*cdf0e10cSrcweir I18NStatus::ShowReason m_eDelayedReason; 105*cdf0e10cSrcweir sal_uLong m_nDelayedEvent; 106*cdf0e10cSrcweir // for toggling 107*cdf0e10cSrcweir bool m_bOn; 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir Point updatePosition(); 110*cdf0e10cSrcweir void layout(); 111*cdf0e10cSrcweir bool checkLastParent() const; 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir DECL_LINK( DelayedShowHdl, void* ); 114*cdf0e10cSrcweir public: 115*cdf0e10cSrcweir XIMStatusWindow( bool bOn ); 116*cdf0e10cSrcweir virtual ~XIMStatusWindow(); 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir virtual void setPosition( SalFrame* ); 119*cdf0e10cSrcweir virtual void setText( const String & ); 120*cdf0e10cSrcweir virtual String getText() const; 121*cdf0e10cSrcweir virtual void show( bool bShow, I18NStatus::ShowReason eReason ); 122*cdf0e10cSrcweir virtual void toggle( bool bOn ); 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir // overload WorkWindow::DataChanged 125*cdf0e10cSrcweir virtual void DataChanged( const DataChangedEvent& rEvt ); 126*cdf0e10cSrcweir }; 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir XIMStatusWindow::XIMStatusWindow( bool bOn ) : 131*cdf0e10cSrcweir StatusWindow( WB_BORDER | WB_SYSTEMFLOATWIN | WB_TOOLTIPWIN ), 132*cdf0e10cSrcweir m_aStatusText( this, 0 ), 133*cdf0e10cSrcweir m_pLastParent( NULL ), 134*cdf0e10cSrcweir m_bAnchoredAtRight( false ), 135*cdf0e10cSrcweir m_bDelayedShow( false ), 136*cdf0e10cSrcweir m_eDelayedReason( I18NStatus::contextmap ), 137*cdf0e10cSrcweir m_nDelayedEvent( 0 ), 138*cdf0e10cSrcweir m_bOn( bOn ) 139*cdf0e10cSrcweir { 140*cdf0e10cSrcweir layout(); 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir XIMStatusWindow::~XIMStatusWindow() 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir if( m_nDelayedEvent ) 146*cdf0e10cSrcweir Application::RemoveUserEvent( m_nDelayedEvent ); 147*cdf0e10cSrcweir } 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir void XIMStatusWindow::toggle( bool bOn ) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir m_bOn = bOn; 152*cdf0e10cSrcweir show( bOn, I18NStatus::contextmap ); 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir void XIMStatusWindow::layout() 156*cdf0e10cSrcweir { 157*cdf0e10cSrcweir m_aWindowSize.Width() = m_aStatusText.GetTextWidth( m_aStatusText.GetText() )+8; 158*cdf0e10cSrcweir Font aFont( m_aStatusText.GetFont() ); 159*cdf0e10cSrcweir m_aWindowSize.Height() = aFont.GetHeight()+10; 160*cdf0e10cSrcweir m_aWindowSize = LogicToPixel( m_aWindowSize ); 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir Size aControlSize( m_aWindowSize ); 163*cdf0e10cSrcweir aControlSize.Width() -= 4; 164*cdf0e10cSrcweir aControlSize.Height() -= 4; 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir m_aStatusText.SetPosSizePixel( Point( 1, 1 ), aControlSize ); 167*cdf0e10cSrcweir m_aStatusText.SetFont( aFont ); 168*cdf0e10cSrcweir m_aStatusText.Show( sal_True ); 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir if (m_bAnchoredAtRight && IsVisible()) 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir SalFrame* pFrame = (SalFrame*)GetSystemData()->pSalFrame; 173*cdf0e10cSrcweir long nDelta = pFrame->maGeometry.nWidth - m_aWindowSize.Width(); 174*cdf0e10cSrcweir pFrame->SetPosSize( pFrame->maGeometry.nX + nDelta, 175*cdf0e10cSrcweir pFrame->maGeometry.nY, 176*cdf0e10cSrcweir m_aWindowSize.Width(), 177*cdf0e10cSrcweir m_aWindowSize.Height(), 178*cdf0e10cSrcweir SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y | SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir else 181*cdf0e10cSrcweir SetOutputSizePixel( m_aWindowSize ); 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir bool XIMStatusWindow::checkLastParent() const 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir if( m_pLastParent ) 187*cdf0e10cSrcweir { 188*cdf0e10cSrcweir const std::list< SalFrame* >& rFrames = GetX11SalData()->GetDisplay()->getFrames(); 189*cdf0e10cSrcweir for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it ) 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir if( *it == m_pLastParent ) 192*cdf0e10cSrcweir return true; 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir return false; 196*cdf0e10cSrcweir } 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir void XIMStatusWindow::DataChanged( const DataChangedEvent& ) 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir m_aStatusText.SetSettings( GetSettings() ); 201*cdf0e10cSrcweir layout(); 202*cdf0e10cSrcweir } 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir Point XIMStatusWindow::updatePosition() 205*cdf0e10cSrcweir { 206*cdf0e10cSrcweir Point aRet; 207*cdf0e10cSrcweir if( checkLastParent() ) 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir const SystemEnvData* pParentEnvData = m_pLastParent->GetSystemData(); 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir SalExtTextInputPosEvent aPosEvent; 212*cdf0e10cSrcweir m_pLastParent->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvent ); 213*cdf0e10cSrcweir int x, y; 214*cdf0e10cSrcweir XLIB_Window aChild; 215*cdf0e10cSrcweir XTranslateCoordinates( (Display*)pParentEnvData->pDisplay, 216*cdf0e10cSrcweir (XLIB_Window)pParentEnvData->aShellWindow, 217*cdf0e10cSrcweir GetX11SalData()->GetDisplay()->GetRootWindow( GetX11SalData()->GetDisplay()->GetDefaultScreenNumber() ), 218*cdf0e10cSrcweir 0, 0, 219*cdf0e10cSrcweir &x, &y, 220*cdf0e10cSrcweir &aChild ); 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir // TODO: Currently, place the status window to the (physical) left of 223*cdf0e10cSrcweir // the cursor iff in vertical mode (assuming that the columns in 224*cdf0e10cSrcweir // vertical mode are always written from right to left, this causes the 225*cdf0e10cSrcweir // status window to keep out of the text already written). This 226*cdf0e10cSrcweir // heuristic would break if there is ever a vertical mode in which the 227*cdf0e10cSrcweir // columns are written from left to right. Also, more elaborate 228*cdf0e10cSrcweir // positioning for (both horizontal and vertical) left-to-right and 229*cdf0e10cSrcweir // right-to-left text would be possible. 230*cdf0e10cSrcweir bool bLeft = aPosEvent.mbVertical; 231*cdf0e10cSrcweir // true if status window is to the left of the cursor 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir int const nGap = 4; // between cursor and status window 234*cdf0e10cSrcweir if (aPosEvent.mbVertical) 235*cdf0e10cSrcweir { 236*cdf0e10cSrcweir aRet.X() = x + aPosEvent.mnX + (bLeft 237*cdf0e10cSrcweir ? -m_aWindowSize.Width() - nGap 238*cdf0e10cSrcweir : aPosEvent.mnHeight + nGap); 239*cdf0e10cSrcweir aRet.Y() = y + aPosEvent.mnY; 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir else 242*cdf0e10cSrcweir { 243*cdf0e10cSrcweir aRet.X() = x + aPosEvent.mnX + (bLeft ? -m_aWindowSize.Width() : 0); 244*cdf0e10cSrcweir aRet.Y() = y + aPosEvent.mnY+aPosEvent.mnHeight + nGap; 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir m_bAnchoredAtRight = bLeft; 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir return aRet; 250*cdf0e10cSrcweir } 251*cdf0e10cSrcweir 252*cdf0e10cSrcweir void XIMStatusWindow::setPosition( SalFrame* pParent ) 253*cdf0e10cSrcweir { 254*cdf0e10cSrcweir if( pParent ) 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir if( pParent != m_pLastParent ) 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir setText( String() ); 259*cdf0e10cSrcweir m_pLastParent = pParent; 260*cdf0e10cSrcweir Show( sal_False, SHOW_NOACTIVATE ); 261*cdf0e10cSrcweir } 262*cdf0e10cSrcweir if( IsVisible() ) 263*cdf0e10cSrcweir { 264*cdf0e10cSrcweir const SystemEnvData* pEnvData = GetSystemData(); 265*cdf0e10cSrcweir SalFrame* pStatusFrame = (SalFrame*)pEnvData->pSalFrame; 266*cdf0e10cSrcweir Point aPoint = updatePosition(); 267*cdf0e10cSrcweir pStatusFrame->SetPosSize( aPoint.X(), aPoint.Y(), m_aWindowSize.Width(), m_aWindowSize.Height(), SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y | SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); 268*cdf0e10cSrcweir } 269*cdf0e10cSrcweir } 270*cdf0e10cSrcweir } 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir IMPL_LINK( XIMStatusWindow, DelayedShowHdl, void*, EMPTYARG ) 273*cdf0e10cSrcweir { 274*cdf0e10cSrcweir m_nDelayedEvent = 0; 275*cdf0e10cSrcweir const SystemEnvData* pData = GetSystemData(); 276*cdf0e10cSrcweir SalFrame* pStatusFrame = (SalFrame*)pData->pSalFrame; 277*cdf0e10cSrcweir if( m_bDelayedShow ) 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir Size aControlSize( m_aWindowSize.Width()-4, m_aWindowSize.Height()-4 ); 280*cdf0e10cSrcweir m_aStatusText.SetPosSizePixel( Point( 1, 1 ), aControlSize ); 281*cdf0e10cSrcweir Point aPoint = updatePosition(); 282*cdf0e10cSrcweir pStatusFrame->SetPosSize( aPoint.X(), aPoint.Y(), m_aWindowSize.Width(), m_aWindowSize.Height(), SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y | SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir Show( m_bDelayedShow && m_bOn, SHOW_NOACTIVATE ); 285*cdf0e10cSrcweir if( m_bDelayedShow ) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir XRaiseWindow( (Display*)pData->pDisplay, 288*cdf0e10cSrcweir (XLIB_Window)pData->aShellWindow ); 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir return 0; 291*cdf0e10cSrcweir } 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir void XIMStatusWindow::show( bool bShow, I18NStatus::ShowReason eReason ) 294*cdf0e10cSrcweir { 295*cdf0e10cSrcweir if( bShow && ! m_aStatusText.GetText().Len() ) 296*cdf0e10cSrcweir bShow = false; 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir m_bDelayedShow = bShow; 299*cdf0e10cSrcweir m_eDelayedReason = eReason; 300*cdf0e10cSrcweir if( ! m_nDelayedEvent ) 301*cdf0e10cSrcweir m_nDelayedEvent = Application::PostUserEvent( LINK( this, XIMStatusWindow, DelayedShowHdl ) ); 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir void XIMStatusWindow::setText( const String& rText ) 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir m_aStatusText.SetText( rText ); 307*cdf0e10cSrcweir m_aWindowSize.Width() = m_aStatusText.GetTextWidth( rText )+8; 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir String XIMStatusWindow::getText() const 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir return m_aStatusText.GetText(); 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir // -------------------------------------------------------------------------- 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir namespace vcl { 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir class IIIMPStatusWindow : public StatusWindow 320*cdf0e10cSrcweir { 321*cdf0e10cSrcweir MenuButton m_aStatusBtn; 322*cdf0e10cSrcweir PopupMenu m_aMenu; 323*cdf0e10cSrcweir SalFrame* m_pResetFocus; 324*cdf0e10cSrcweir bool m_bShow; 325*cdf0e10cSrcweir bool m_bOn; 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir DECL_LINK( SelectHdl, MenuButton* ); 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir void show(); 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir public: 332*cdf0e10cSrcweir IIIMPStatusWindow( SalFrame* pParent, bool bOn ); // for initial position 333*cdf0e10cSrcweir virtual ~IIIMPStatusWindow(); 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir virtual void setText( const String & ); 336*cdf0e10cSrcweir virtual String getText() const; 337*cdf0e10cSrcweir virtual void show( bool bShow, I18NStatus::ShowReason eReason ); 338*cdf0e10cSrcweir virtual void toggle( bool bOn ); 339*cdf0e10cSrcweir void layout(); 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir // overload Window focus handler 342*cdf0e10cSrcweir virtual void GetFocus(); 343*cdf0e10cSrcweir // overload WorkWindow::DataChanged 344*cdf0e10cSrcweir virtual void DataChanged( const DataChangedEvent& rEvt ); 345*cdf0e10cSrcweir }; 346*cdf0e10cSrcweir 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir IIIMPStatusWindow::IIIMPStatusWindow( SalFrame* pParent, bool bOn ) : 350*cdf0e10cSrcweir StatusWindow( WB_MOVEABLE ), 351*cdf0e10cSrcweir m_aStatusBtn( this, WB_BORDER ), 352*cdf0e10cSrcweir m_pResetFocus( pParent ), 353*cdf0e10cSrcweir m_bShow( true ), 354*cdf0e10cSrcweir m_bOn( bOn ) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir SetText( String( RTL_CONSTASCII_USTRINGPARAM( "IME Status" ) ) ); 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir layout(); 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir m_aStatusBtn.SetSelectHdl( LINK( this, IIIMPStatusWindow, SelectHdl ) ); 361*cdf0e10cSrcweir m_aStatusBtn.SetPopupMenu( &m_aMenu ); 362*cdf0e10cSrcweir m_aStatusBtn.Show( sal_True ); 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir const ::std::vector< I18NStatus::ChoiceData >& rChoices( I18NStatus::get().getChoices() ); 365*cdf0e10cSrcweir int i = 1; 366*cdf0e10cSrcweir for( ::std::vector< I18NStatus::ChoiceData >::const_iterator it = rChoices.begin(); it != rChoices.end(); ++it, i++ ) 367*cdf0e10cSrcweir m_aMenu.InsertItem( i, it->aString ); 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir if( pParent ) 370*cdf0e10cSrcweir { 371*cdf0e10cSrcweir const SystemEnvData* pEnvData = GetSystemData(); 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir const SalFrameGeometry& rGeom( pParent->GetUnmirroredGeometry() ); 374*cdf0e10cSrcweir int nDistance = rGeom.nTopDecoration; 375*cdf0e10cSrcweir if( nDistance < 20 ) 376*cdf0e10cSrcweir nDistance = 20; 377*cdf0e10cSrcweir XMoveWindow( (Display*)pEnvData->pDisplay, 378*cdf0e10cSrcweir (XLIB_Window)pEnvData->aShellWindow, 379*cdf0e10cSrcweir rGeom.nX, 380*cdf0e10cSrcweir rGeom.nY + rGeom.nHeight + nDistance 381*cdf0e10cSrcweir ); 382*cdf0e10cSrcweir } 383*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 384*cdf0e10cSrcweir else 385*cdf0e10cSrcweir fprintf( stderr, "Warning: could not reposition status window since no frame\n" ); 386*cdf0e10cSrcweir #endif 387*cdf0e10cSrcweir EnableAlwaysOnTop( sal_True ); 388*cdf0e10cSrcweir } 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir IIIMPStatusWindow::~IIIMPStatusWindow() 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir } 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir void IIIMPStatusWindow::layout() 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir Font aFont( m_aStatusBtn.GetFont() ); 397*cdf0e10cSrcweir Size aSize( 15*aFont.GetHeight(), aFont.GetHeight()+14 ); 398*cdf0e10cSrcweir aSize = m_aStatusBtn.LogicToPixel( aSize ); 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir m_aStatusBtn.SetPosSizePixel( Point( 0, 0 ), aSize ); 401*cdf0e10cSrcweir SetOutputSizePixel( aSize ); 402*cdf0e10cSrcweir if( IsVisible() ) 403*cdf0e10cSrcweir Invalidate(); 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir void IIIMPStatusWindow::DataChanged( const DataChangedEvent& ) 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir m_aStatusBtn.SetSettings( GetSettings() ); 409*cdf0e10cSrcweir layout(); 410*cdf0e10cSrcweir } 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir void IIIMPStatusWindow::setText( const String& rText ) 413*cdf0e10cSrcweir { 414*cdf0e10cSrcweir m_aStatusBtn.SetText( rText ); 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir String IIIMPStatusWindow::getText() const 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir return m_aStatusBtn.GetText(); 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir void IIIMPStatusWindow::show( bool bShow, I18NStatus::ShowReason eReason ) 423*cdf0e10cSrcweir { 424*cdf0e10cSrcweir // hide IIIMPStatusWindow only in presentations 425*cdf0e10cSrcweir if( ! bShow 426*cdf0e10cSrcweir && eReason != I18NStatus::presentation 427*cdf0e10cSrcweir ) 428*cdf0e10cSrcweir return; 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir m_bShow = bShow; 431*cdf0e10cSrcweir show(); 432*cdf0e10cSrcweir } 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir void IIIMPStatusWindow::toggle( bool bOn ) 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir if (bOn != m_bOn) 437*cdf0e10cSrcweir { 438*cdf0e10cSrcweir m_bOn = bOn; 439*cdf0e10cSrcweir show(); 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir } 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir void IIIMPStatusWindow::show() 444*cdf0e10cSrcweir { 445*cdf0e10cSrcweir if (m_bOn && m_bShow && !IsVisible()) 446*cdf0e10cSrcweir m_pResetFocus = I18NStatus::get().getParent(); 447*cdf0e10cSrcweir Show(m_bOn && m_bShow); 448*cdf0e10cSrcweir } 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir void IIIMPStatusWindow::GetFocus() 451*cdf0e10cSrcweir { 452*cdf0e10cSrcweir /* 453*cdf0e10cSrcweir * this is here just to put the focus back to the application 454*cdf0e10cSrcweir * window at startup on clickToFocus WMs 455*cdf0e10cSrcweir */ 456*cdf0e10cSrcweir WorkWindow::GetFocus(); 457*cdf0e10cSrcweir if( m_pResetFocus ) 458*cdf0e10cSrcweir { 459*cdf0e10cSrcweir /* 460*cdf0e10cSrcweir * look if reset focus still exists 461*cdf0e10cSrcweir * since reset focus really is an internal hack there should 462*cdf0e10cSrcweir * not be a method to be called in SalFrame destructor 463*cdf0e10cSrcweir */ 464*cdf0e10cSrcweir const std::list< SalFrame* >& rFrames = GetX11SalData()->GetDisplay()->getFrames(); 465*cdf0e10cSrcweir std::list< SalFrame* >::const_iterator it; 466*cdf0e10cSrcweir for( it = rFrames.begin(); it != rFrames.end() && *it != m_pResetFocus; ++it ) 467*cdf0e10cSrcweir ; 468*cdf0e10cSrcweir if( it != rFrames.end() ) 469*cdf0e10cSrcweir { 470*cdf0e10cSrcweir const SystemEnvData* pParentEnvData = m_pResetFocus->GetSystemData(); 471*cdf0e10cSrcweir SalXLib* pXLib = GetX11SalData()->GetDisplay()->GetXLib(); 472*cdf0e10cSrcweir pXLib->PushXErrorLevel( true ); 473*cdf0e10cSrcweir XSetInputFocus( (Display*)pParentEnvData->pDisplay, 474*cdf0e10cSrcweir (XLIB_Window)pParentEnvData->aShellWindow, 475*cdf0e10cSrcweir RevertToNone, 476*cdf0e10cSrcweir CurrentTime 477*cdf0e10cSrcweir ); 478*cdf0e10cSrcweir XSync( (Display*)pParentEnvData->pDisplay, False ); 479*cdf0e10cSrcweir pXLib->PopXErrorLevel(); 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir m_pResetFocus = NULL; 482*cdf0e10cSrcweir } 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir // -------------------------------------------------------------------------- 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir IMPL_LINK( IIIMPStatusWindow, SelectHdl, MenuButton*, pBtn ) 488*cdf0e10cSrcweir { 489*cdf0e10cSrcweir if( pBtn == & m_aStatusBtn ) 490*cdf0e10cSrcweir { 491*cdf0e10cSrcweir const ::std::vector< I18NStatus::ChoiceData >& rChoices( I18NStatus::get().getChoices() ); 492*cdf0e10cSrcweir unsigned int nIndex = m_aStatusBtn.GetCurItemId()-1; 493*cdf0e10cSrcweir if( nIndex < rChoices.size() ) 494*cdf0e10cSrcweir { 495*cdf0e10cSrcweir XSetICValues( static_cast<X11SalFrame*>(I18NStatus::get().getParent())->getInputContext()->GetContext(), 496*cdf0e10cSrcweir XNUnicodeCharacterSubset, 497*cdf0e10cSrcweir rChoices[nIndex].pData, 498*cdf0e10cSrcweir NULL); 499*cdf0e10cSrcweir // FIXME: get rid of X11SalFrame 500*cdf0e10cSrcweir X11SalFrame* pParent = static_cast<X11SalFrame*>(I18NStatus::get().getParent()); 501*cdf0e10cSrcweir if( pParent && pParent->isMapped() ) 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir const SystemEnvData* pEnv = pParent->GetSystemData(); 504*cdf0e10cSrcweir SalXLib* pXLib = GetX11SalData()->GetDisplay()->GetXLib(); 505*cdf0e10cSrcweir pXLib->PushXErrorLevel( true ); 506*cdf0e10cSrcweir XSetInputFocus( (Display*)pEnv->pDisplay, 507*cdf0e10cSrcweir (XLIB_Window)pEnv->aShellWindow, 508*cdf0e10cSrcweir RevertToNone, 509*cdf0e10cSrcweir CurrentTime 510*cdf0e10cSrcweir ); 511*cdf0e10cSrcweir XSync( (Display*)pEnv->pDisplay, False ); 512*cdf0e10cSrcweir pXLib->PopXErrorLevel(); 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir return 0; 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir /* 520*cdf0e10cSrcweir * I18NStatus 521*cdf0e10cSrcweir */ 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir I18NStatus* I18NStatus::pInstance = NULL; 524*cdf0e10cSrcweir 525*cdf0e10cSrcweir I18NStatus& I18NStatus::get() 526*cdf0e10cSrcweir { 527*cdf0e10cSrcweir if( ! pInstance ) 528*cdf0e10cSrcweir pInstance = new I18NStatus(); 529*cdf0e10cSrcweir return *pInstance; 530*cdf0e10cSrcweir } 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir // -------------------------------------------------------------------------- 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir bool I18NStatus::exists() 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir return pInstance != NULL; 537*cdf0e10cSrcweir } 538*cdf0e10cSrcweir 539*cdf0e10cSrcweir // -------------------------------------------------------------------------- 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir void I18NStatus::free() 542*cdf0e10cSrcweir { 543*cdf0e10cSrcweir if( pInstance ) 544*cdf0e10cSrcweir delete pInstance, pInstance = NULL; 545*cdf0e10cSrcweir } 546*cdf0e10cSrcweir 547*cdf0e10cSrcweir // -------------------------------------------------------------------------- 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir I18NStatus::I18NStatus() : 550*cdf0e10cSrcweir m_pParent( NULL ), 551*cdf0e10cSrcweir m_pStatusWindow( NULL ) 552*cdf0e10cSrcweir { 553*cdf0e10cSrcweir } 554*cdf0e10cSrcweir 555*cdf0e10cSrcweir // -------------------------------------------------------------------------- 556*cdf0e10cSrcweir 557*cdf0e10cSrcweir I18NStatus::~I18NStatus() 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir if( m_pStatusWindow ) 560*cdf0e10cSrcweir delete m_pStatusWindow, m_pStatusWindow = NULL; 561*cdf0e10cSrcweir if( pInstance == this ) 562*cdf0e10cSrcweir pInstance = NULL; 563*cdf0e10cSrcweir } 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir // -------------------------------------------------------------------------- 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir void I18NStatus::setParent( SalFrame* pParent ) 568*cdf0e10cSrcweir { 569*cdf0e10cSrcweir m_pParent = pParent; 570*cdf0e10cSrcweir if( ! m_pStatusWindow ) 571*cdf0e10cSrcweir { 572*cdf0e10cSrcweir bool bIIIMPmode = m_aChoices.begin() != m_aChoices.end(); 573*cdf0e10cSrcweir if( bIIIMPmode ) 574*cdf0e10cSrcweir m_pStatusWindow = new IIIMPStatusWindow( pParent, 575*cdf0e10cSrcweir getStatusWindowMode() ); 576*cdf0e10cSrcweir else 577*cdf0e10cSrcweir m_pStatusWindow = new XIMStatusWindow( getStatusWindowMode() ); 578*cdf0e10cSrcweir setStatusText( m_aCurrentIM ); 579*cdf0e10cSrcweir } 580*cdf0e10cSrcweir m_pStatusWindow->setPosition( m_pParent ); 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir // -------------------------------------------------------------------------- 584*cdf0e10cSrcweir 585*cdf0e10cSrcweir void I18NStatus::show( bool bShow, ShowReason eReason ) 586*cdf0e10cSrcweir { 587*cdf0e10cSrcweir if( m_pStatusWindow ) 588*cdf0e10cSrcweir { 589*cdf0e10cSrcweir m_pStatusWindow->setPosition( m_pParent ); 590*cdf0e10cSrcweir m_pStatusWindow->show( bShow, eReason ); 591*cdf0e10cSrcweir } 592*cdf0e10cSrcweir } 593*cdf0e10cSrcweir 594*cdf0e10cSrcweir // -------------------------------------------------------------------------- 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir void I18NStatus::setStatusText( const String& rText ) 597*cdf0e10cSrcweir { 598*cdf0e10cSrcweir if( m_pStatusWindow ) 599*cdf0e10cSrcweir { 600*cdf0e10cSrcweir /* 601*cdf0e10cSrcweir * #93614# convert fullwidth ASCII forms to ascii 602*cdf0e10cSrcweir */ 603*cdf0e10cSrcweir int nChars = rText.Len()+1; 604*cdf0e10cSrcweir sal_Unicode* pBuffer = (sal_Unicode*)alloca( nChars*sizeof( sal_Unicode ) ); 605*cdf0e10cSrcweir const sal_Unicode* pCopy = rText.GetBuffer(); 606*cdf0e10cSrcweir for( int i = 0; i < nChars; i++ ) 607*cdf0e10cSrcweir { 608*cdf0e10cSrcweir if( pCopy[i] >=0xff00 && pCopy[i] <= 0xff5f ) 609*cdf0e10cSrcweir pBuffer[i] = (pCopy[i] & 0xff) + 0x20; 610*cdf0e10cSrcweir else 611*cdf0e10cSrcweir pBuffer[i] = pCopy[i]; 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir String aText( pBuffer ); 614*cdf0e10cSrcweir m_pStatusWindow->setText( aText ); 615*cdf0e10cSrcweir m_pStatusWindow->setPosition( m_pParent ); 616*cdf0e10cSrcweir 617*cdf0e10cSrcweir bool bVisible = true; 618*cdf0e10cSrcweir if( m_pParent ) 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir long w, h; 621*cdf0e10cSrcweir m_pParent->GetClientSize( w, h ); 622*cdf0e10cSrcweir if( w == 0 || h == 0 ) 623*cdf0e10cSrcweir { 624*cdf0e10cSrcweir bVisible = false; 625*cdf0e10cSrcweir } 626*cdf0e10cSrcweir } 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir m_pStatusWindow->show( bVisible, contextmap ); 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir // -------------------------------------------------------------------------- 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir void I18NStatus::changeIM( const String& rIM ) 635*cdf0e10cSrcweir { 636*cdf0e10cSrcweir m_aCurrentIM = rIM; 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir // -------------------------------------------------------------------------- 640*cdf0e10cSrcweir 641*cdf0e10cSrcweir String I18NStatus::getStatusText() const 642*cdf0e10cSrcweir { 643*cdf0e10cSrcweir return m_pStatusWindow ? m_pStatusWindow->getText() : String(); 644*cdf0e10cSrcweir } 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir // -------------------------------------------------------------------------- 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir void I18NStatus::clearChoices() 649*cdf0e10cSrcweir { 650*cdf0e10cSrcweir m_aChoices.clear(); 651*cdf0e10cSrcweir } 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir // -------------------------------------------------------------------------- 654*cdf0e10cSrcweir 655*cdf0e10cSrcweir void I18NStatus::addChoice( const String& rChoice, void* pData ) 656*cdf0e10cSrcweir { 657*cdf0e10cSrcweir ChoiceData aData; 658*cdf0e10cSrcweir aData.pData = pData; 659*cdf0e10cSrcweir aData.aString = rChoice; 660*cdf0e10cSrcweir m_aChoices.push_back( aData ); 661*cdf0e10cSrcweir } 662*cdf0e10cSrcweir 663*cdf0e10cSrcweir // -------------------------------------------------------------------------- 664*cdf0e10cSrcweir 665*cdf0e10cSrcweir void I18NStatus::toTop() const 666*cdf0e10cSrcweir { 667*cdf0e10cSrcweir if( m_pStatusWindow ) 668*cdf0e10cSrcweir { 669*cdf0e10cSrcweir const SystemEnvData* pData = m_pStatusWindow->GetSystemData(); 670*cdf0e10cSrcweir XRaiseWindow( (Display*)pData->pDisplay, 671*cdf0e10cSrcweir (XLIB_Window)pData->aShellWindow ); 672*cdf0e10cSrcweir } 673*cdf0e10cSrcweir } 674*cdf0e10cSrcweir 675*cdf0e10cSrcweir // -------------------------------------------------------------------------- 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir SalFrame* I18NStatus::getStatusFrame() const 678*cdf0e10cSrcweir { 679*cdf0e10cSrcweir SalFrame* pRet = NULL; 680*cdf0e10cSrcweir if( m_pStatusWindow ) 681*cdf0e10cSrcweir { 682*cdf0e10cSrcweir const SystemEnvData* pData = m_pStatusWindow->GetSystemData(); 683*cdf0e10cSrcweir pRet = (SalFrame*)pData->pSalFrame; 684*cdf0e10cSrcweir } 685*cdf0e10cSrcweir return pRet; 686*cdf0e10cSrcweir } 687*cdf0e10cSrcweir 688*cdf0e10cSrcweir bool I18NStatus::canToggleStatusWindow() const 689*cdf0e10cSrcweir { 690*cdf0e10cSrcweir return true; 691*cdf0e10cSrcweir } 692*cdf0e10cSrcweir 693*cdf0e10cSrcweir void I18NStatus::toggleStatusWindow() 694*cdf0e10cSrcweir { 695*cdf0e10cSrcweir if (m_pStatusWindow != 0) 696*cdf0e10cSrcweir m_pStatusWindow->toggle(getStatusWindowMode()); 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir 699*cdf0e10cSrcweir bool I18NStatus::getStatusWindowMode() 700*cdf0e10cSrcweir { 701*cdf0e10cSrcweir switch (ImplGetSVData()->maAppData.meShowImeStatusWindow) 702*cdf0e10cSrcweir { 703*cdf0e10cSrcweir default: // ImplSVAppData::ImeStatusWindowMode_UNKNOWN 704*cdf0e10cSrcweir return Application::GetShowImeStatusWindowDefault(); 705*cdf0e10cSrcweir case ImplSVAppData::ImeStatusWindowMode_HIDE: 706*cdf0e10cSrcweir return false; 707*cdf0e10cSrcweir case ImplSVAppData::ImeStatusWindowMode_SHOW: 708*cdf0e10cSrcweir return true; 709*cdf0e10cSrcweir } 710*cdf0e10cSrcweir } 711*cdf0e10cSrcweir 712*cdf0e10cSrcweir /* 713*cdf0e10cSrcweir * X11ImeStatus 714*cdf0e10cSrcweir */ 715*cdf0e10cSrcweir X11ImeStatus::~X11ImeStatus() 716*cdf0e10cSrcweir { 717*cdf0e10cSrcweir vcl::I18NStatus::free(); 718*cdf0e10cSrcweir } 719*cdf0e10cSrcweir 720*cdf0e10cSrcweir bool X11ImeStatus::canToggle() 721*cdf0e10cSrcweir { 722*cdf0e10cSrcweir return vcl::I18NStatus::get().canToggleStatusWindow(); 723*cdf0e10cSrcweir } 724*cdf0e10cSrcweir 725*cdf0e10cSrcweir void X11ImeStatus::toggle() 726*cdf0e10cSrcweir { 727*cdf0e10cSrcweir vcl::I18NStatus::get().toggleStatusWindow(); 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir 730*cdf0e10cSrcweir SalI18NImeStatus* X11SalInstance::CreateI18NImeStatus() 731*cdf0e10cSrcweir { 732*cdf0e10cSrcweir return new X11ImeStatus(); 733*cdf0e10cSrcweir } 734