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