1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sfx2.hxx"
30 
31 #include "imestatuswindow.hxx"
32 
33 #include <sfx2/app.hxx>
34 #include <sfx2/sfxsids.hrc>
35 
36 #include "com/sun/star/beans/PropertyState.hpp"
37 #include "com/sun/star/beans/PropertyValue.hpp"
38 #include "com/sun/star/beans/XPropertySet.hpp"
39 #include "com/sun/star/lang/DisposedException.hpp"
40 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
41 #include "com/sun/star/uno/Any.hxx"
42 #include "com/sun/star/uno/Exception.hpp"
43 #include "com/sun/star/uno/Reference.hxx"
44 #include "com/sun/star/uno/RuntimeException.hpp"
45 #include "com/sun/star/uno/Sequence.hxx"
46 #include "com/sun/star/util/XChangesBatch.hpp"
47 #include "osl/diagnose.h"
48 #include "osl/mutex.hxx"
49 #include "rtl/ustring.h"
50 #include "rtl/ustring.hxx"
51 #include "sal/types.h"
52 #include "vcl/svapp.hxx"
53 #include "vos/mutex.hxx"
54 
55 namespace css = com::sun::star;
56 
57 using sfx2::appl::ImeStatusWindow;
58 
59 ImeStatusWindow::ImeStatusWindow(
60     css::uno::Reference< css::lang::XMultiServiceFactory > const &
61         rServiceFactory):
62     m_xServiceFactory(rServiceFactory),
63     m_bDisposed(false)
64 {}
65 
66 void ImeStatusWindow::init()
67 {
68     if (Application::CanToggleImeStatusWindow())
69         try
70         {
71             sal_Bool bShow = sal_Bool();
72             if (getConfig()->getPropertyValue(
73                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
74                                       "ShowStatusWindow")))
75                 >>= bShow)
76                 Application::ShowImeStatusWindow(bShow);
77         }
78         catch (css::uno::Exception &)
79         {
80             OSL_ENSURE(false, "com.sun.star.uno.Exception");
81             // Degrade gracefully and use the VCL-supplied default if no
82             // configuration is available.
83         }
84 }
85 
86 bool ImeStatusWindow::isShowing()
87 {
88     try
89     {
90         sal_Bool bShow = sal_Bool();
91         if (getConfig()->getPropertyValue(
92                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowStatusWindow")))
93             >>= bShow)
94             return bShow;
95     }
96     catch (css::uno::Exception &)
97     {
98         OSL_ENSURE(false, "com.sun.star.uno.Exception");
99         // Degrade gracefully and use the VCL-supplied default if no
100         // configuration is available.
101     }
102     return Application::GetShowImeStatusWindowDefault();
103 }
104 
105 void ImeStatusWindow::show(bool bShow)
106 {
107     try
108     {
109         css::uno::Reference< css::beans::XPropertySet > xConfig(getConfig());
110         xConfig->setPropertyValue(
111             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowStatusWindow")),
112             css::uno::makeAny(static_cast< sal_Bool >(bShow)));
113         css::uno::Reference< css::util::XChangesBatch > xCommit(
114             xConfig, css::uno::UNO_QUERY);
115         // Degrade gracefully by not saving the settings permanently:
116         if (xCommit.is())
117             xCommit->commitChanges();
118         // Alternatively, setting the VCL status could be done even if updating
119         // the configuration failed:
120         Application::ShowImeStatusWindow(bShow);
121     }
122     catch (css::uno::Exception &)
123     {
124         OSL_ENSURE(false, "com.sun.star.uno.Exception");
125     }
126 }
127 
128 bool ImeStatusWindow::canToggle() const
129 {
130     return Application::CanToggleImeStatusWindow();
131 }
132 
133 ImeStatusWindow::~ImeStatusWindow()
134 {
135     if (m_xConfig.is())
136         // We should never get here, but just in case...
137         try
138         {
139             m_xConfig->removePropertyChangeListener(
140                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowStatusWindow")),
141                 this);
142         }
143         catch (css::uno::Exception &)
144         {
145             OSL_ENSURE(false, "com.sun.star.uno.RuntimeException");
146         }
147 }
148 
149 void SAL_CALL ImeStatusWindow::disposing(css::lang::EventObject const & )
150     throw (css::uno::RuntimeException)
151 {
152     osl::MutexGuard aGuard(m_aMutex);
153     m_xConfig = 0;
154     m_bDisposed = true;
155 }
156 
157 void SAL_CALL
158 ImeStatusWindow::propertyChange(css::beans::PropertyChangeEvent const & )
159     throw (css::uno::RuntimeException)
160 {
161     vos::OGuard aGuard(Application::GetSolarMutex());
162     SfxApplication* pApp = SfxApplication::Get();
163     if (pApp)
164 	pApp->Invalidate(SID_SHOW_IME_STATUS_WINDOW);
165 }
166 
167 css::uno::Reference< css::beans::XPropertySet > ImeStatusWindow::getConfig()
168 {
169     css::uno::Reference< css::beans::XPropertySet > xConfig;
170     bool bAdd = false;
171     {
172         osl::MutexGuard aGuard(m_aMutex);
173         if (!m_xConfig.is())
174         {
175             if (m_bDisposed)
176                 throw css::lang::DisposedException();
177             if (!m_xServiceFactory.is())
178                 throw css::uno::RuntimeException(
179                     rtl::OUString(
180                         RTL_CONSTASCII_USTRINGPARAM(
181                             "null comphelper::getProcessServiceFactory")),
182                     0);
183             css::uno::Reference< css::lang::XMultiServiceFactory > xProvider(
184                 m_xServiceFactory->createInstance(
185                     rtl::OUString(
186                         RTL_CONSTASCII_USTRINGPARAM(
187                           "com.sun.star.configuration.ConfigurationProvider"))),
188                 css::uno::UNO_QUERY);
189             if (!xProvider.is())
190                 throw css::uno::RuntimeException(
191                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
192                                       "null com.sun.star.configuration."
193                                       "ConfigurationProvider")),
194                     0);
195             css::beans::PropertyValue aArg(
196                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")), -1,
197                 css::uno::makeAny(
198                     rtl::OUString(
199                         RTL_CONSTASCII_USTRINGPARAM(
200                             "/org.openoffice.Office.Common/I18N/InputMethod"))),
201                 css::beans::PropertyState_DIRECT_VALUE);
202             css::uno::Sequence< css::uno::Any > aArgs(1);
203             aArgs[0] <<= aArg;
204             m_xConfig
205                 = css::uno::Reference< css::beans::XPropertySet >(
206                     xProvider->createInstanceWithArguments(
207                         rtl::OUString(
208                             RTL_CONSTASCII_USTRINGPARAM(
209                        "com.sun.star.configuration.ConfigurationUpdateAccess")),
210                         aArgs),
211                     css::uno::UNO_QUERY);
212             if (!m_xConfig.is())
213                 throw css::uno::RuntimeException(
214                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
215                                       "null com.sun.star.configuration."
216                                       "ConfigurationUpdateAccess")),
217                     0);
218             bAdd = true;
219         }
220         xConfig = m_xConfig;
221     }
222     if (bAdd)
223         // Exceptions here could be handled individually, to support graceful
224         // degradation (no update notification mechanism in this case---but also
225         // no dispose notifications):
226         xConfig->addPropertyChangeListener(
227             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowStatusWindow")),
228             this);
229     return xConfig;
230 }
231 
232