xref: /aoo42x/main/vcl/unx/generic/app/i18n_status.cxx (revision c82f2877)
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