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