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