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