1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23 // MARKER(update_precomp.py): autogen include statement, do not remove
24 #include "precompiled_desktop.hxx"
25
26 #include <osl/file.hxx>
27 #include <rtl/bootstrap.hxx>
28 #include <rtl/ustring.hxx>
29 #include <tools/datetime.hxx>
30 #include <unotools/configmgr.hxx>
31
32 #include <comphelper/processfactory.hxx>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/beans/NamedValue.hpp>
35 #include <com/sun/star/util/XChangesBatch.hpp>
36
37 #include "app.hxx"
38
39 using ::rtl::OUString;
40 using namespace ::desktop;
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::beans;
43
44 static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
45 static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
46
47 /* Path of the license. */
GetLicensePath()48 OUString Desktop::GetLicensePath()
49 {
50 // license file name
51 static const char *szLicensePath = "/share/readme";
52 #if defined(WNT) || defined(OS2)
53 static const char *szWNTLicenseName = "/license";
54 static const char *szWNTLicenseExt = ".txt";
55 #else
56 static const char *szUNXLicenseName = "/LICENSE";
57 static const char *szUNXLicenseExt = "";
58 #endif
59 static OUString aLicensePath;
60
61 if (aLicensePath.getLength() > 0)
62 return aLicensePath;
63
64 OUString aBaseInstallPath(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR"));
65 rtl::Bootstrap::expandMacros(aBaseInstallPath);
66
67 // determine the filename of the license to show
68 OUString aLangString;
69 ::com::sun::star::lang::Locale aLocale;
70 OString aMgrName = OString("dkt");
71
72 AllSettings aSettings(Application::GetSettings());
73 aLocale = aSettings.GetUILocale();
74 ResMgr* pLocalResMgr = ResMgr::SearchCreateResMgr( aMgrName.getStr(), aLocale);
75
76 aLangString = aLocale.Language;
77 if ( aLocale.Country.getLength() != 0 )
78 {
79 aLangString += OUString::createFromAscii("-");
80 aLangString += aLocale.Country;
81 if ( aLocale.Variant.getLength() != 0 )
82 {
83 aLangString += OUString::createFromAscii("-");
84 aLangString += aLocale.Variant;
85 }
86 }
87 #if defined(WNT) || defined(OS2)
88 aLicensePath =
89 aBaseInstallPath + OUString::createFromAscii(szLicensePath)
90 + OUString::createFromAscii(szWNTLicenseName)
91 + OUString::createFromAscii("_")
92 + aLangString
93 + OUString::createFromAscii(szWNTLicenseExt);
94 #else
95 aLicensePath =
96 aBaseInstallPath + OUString::createFromAscii(szLicensePath)
97 + OUString::createFromAscii(szUNXLicenseName)
98 + OUString::createFromAscii("_")
99 + aLangString
100 + OUString::createFromAscii(szUNXLicenseExt);
101 #endif
102 delete pLocalResMgr;
103 return aLicensePath;
104 }
105
106 /* Check if we need to accept license. */
LicenseNeedsAcceptance()107 sal_Bool Desktop::LicenseNeedsAcceptance()
108 {
109 // permissive licences like ALv2 don't need end user license approval
110 return sal_False;
111 }
112
113 /* Local function - get access to the configuration */
impl_getConfigurationAccess(const OUString & rPath)114 static Reference< XPropertySet > impl_getConfigurationAccess( const OUString& rPath )
115 {
116 Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
117
118 // get configuration provider
119 Reference< XMultiServiceFactory > xConfigProvider = Reference< XMultiServiceFactory >(
120 xFactory->createInstance( sConfigSrvc ), UNO_QUERY_THROW );
121
122 Sequence< Any > aArgs( 1 );
123 NamedValue aValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "NodePath" ) ), makeAny( rPath ) );
124 aArgs[0] <<= aValue;
125 return Reference< XPropertySet >(
126 xConfigProvider->createInstanceWithArguments( sAccessSrvc, aArgs ), UNO_QUERY_THROW );
127 }
128
129 /* Local function - was the wizard completed already? */
impl_isFirstStart()130 static sal_Bool impl_isFirstStart()
131 {
132 try {
133 Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
134
135 Any result = xPSet->getPropertyValue(OUString::createFromAscii("FirstStartWizardCompleted"));
136 sal_Bool bCompleted = sal_False;
137 if ((result >>= bCompleted) && bCompleted)
138 return sal_False; // wizard was already completed
139 else
140 return sal_True;
141 } catch (const Exception&)
142 {
143 return sal_True;
144 }
145 }
146
147 /* Local function - convert oslDateTime to tools DateTime */
impl_oslDateTimeToDateTime(const oslDateTime & aDateTime)148 static DateTime impl_oslDateTimeToDateTime(const oslDateTime& aDateTime)
149 {
150 return DateTime(
151 Date(aDateTime.Day, aDateTime.Month, aDateTime.Year),
152 Time(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds));
153 }
154
155 /* Local function - get DateTime from a string */
impl_parseDateTime(const OUString & aString,DateTime & aDateTime)156 static sal_Bool impl_parseDateTime(const OUString& aString, DateTime& aDateTime)
157 {
158 // take apart a canonical literal xsd:dateTime string
159 //CCYY-MM-DDThh:mm:ss(Z)
160
161 OUString aDateTimeString = aString.trim();
162
163 // check length
164 if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
165 return sal_False;
166
167 sal_Int32 nDateLength = 10;
168 sal_Int32 nTimeLength = 8;
169
170 OUString aDateTimeSep = OUString::createFromAscii("T");
171 OUString aDateSep = OUString::createFromAscii("-");
172 OUString aTimeSep = OUString::createFromAscii(":");
173 OUString aUTCString = OUString::createFromAscii("Z");
174
175 OUString aDateString = aDateTimeString.copy(0, nDateLength);
176 OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength);
177
178 sal_Int32 nIndex = 0;
179 sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32();
180 sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32();
181 sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32();
182 nIndex = 0;
183 sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32();
184 sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32();
185 sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32();
186
187 Date tmpDate((sal_uInt16)nDay, (sal_uInt16)nMonth, (sal_uInt16)nYear);
188 Time tmpTime(nHour, nMinute, nSecond);
189 DateTime tmpDateTime(tmpDate, tmpTime);
190 if (aString.indexOf(aUTCString) < 0)
191 tmpDateTime.ConvertToUTC();
192
193 aDateTime = tmpDateTime;
194 return sal_True;
195 }
196
197 /* Local function - was the license accepted already? */
impl_isLicenseAccepted()198 static sal_Bool impl_isLicenseAccepted()
199 {
200 // If no license will be shown ... it must not be accepted.
201 // So it was accepted "hardly" by the outside installer.
202 // But if the configuration entry "HideEula" will be removed afterwards ..
203 // we have to show the license page again and user has to accept it here .-)
204 if ( ! Desktop::LicenseNeedsAcceptance() )
205 return sal_True;
206
207 try
208 {
209 Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
210
211 Any result = xPSet->getPropertyValue(OUString::createFromAscii("LicenseAcceptDate"));
212
213 OUString aAcceptDate;
214 if (result >>= aAcceptDate)
215 {
216 // compare to date of license file
217 OUString aLicenseURL = Desktop::GetLicensePath();
218 osl::DirectoryItem aDirItem;
219 if (osl::DirectoryItem::get(aLicenseURL, aDirItem) != osl::FileBase::E_None)
220 return sal_False;
221 osl::FileStatus aStatus(FileStatusMask_All);
222 if (aDirItem.getFileStatus(aStatus) != osl::FileBase::E_None)
223 return sal_False;
224 TimeValue aTimeVal = aStatus.getModifyTime();
225 oslDateTime aDateTimeVal;
226 if (!osl_getDateTimeFromTimeValue(&aTimeVal, &aDateTimeVal))
227 return sal_False;
228
229 // compare dates
230 DateTime aLicenseDateTime = impl_oslDateTimeToDateTime(aDateTimeVal);
231 DateTime aAcceptDateTime;
232 if (!impl_parseDateTime(aAcceptDate, aAcceptDateTime))
233 return sal_False;
234
235 if ( aAcceptDateTime > aLicenseDateTime )
236 return sal_True;
237 }
238 return sal_False;
239 } catch (const Exception&)
240 {
241 return sal_False;
242 }
243 }
244
245 /* Check if we need the first start wizard. */
IsFirstStartWizardNeeded()246 sal_Bool Desktop::IsFirstStartWizardNeeded()
247 {
248 return impl_isFirstStart() || !impl_isLicenseAccepted();
249 }
250
FinishFirstStart()251 void Desktop::FinishFirstStart()
252 {
253 #if 0 // most platforms no longer benefit from the quickstarter, TODO: are the other benefits worth it?
254 #ifndef OS2 // cannot enable quickstart on first startup, see shutdownicon.cxx comments.
255 EnableQuickstart();
256 #endif
257 #endif
258
259 try {
260 Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
261 // get configuration provider
262 Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
263 xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
264 Sequence< Any > theArgs(1);
265 NamedValue v(OUString::createFromAscii("NodePath"),
266 makeAny(OUString::createFromAscii("org.openoffice.Setup/Office")));
267 theArgs[0] <<= v;
268 Reference< XPropertySet > pset = Reference< XPropertySet >(
269 theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
270 pset->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("FirstStartWizardCompleted")), makeAny(sal_True));
271 Reference< util::XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges();
272 } catch (const uno::Exception&) {
273 // ignore the exception as it is not critical enough to prevent office from starting
274 }
275 }
276
EnableQuickstart()277 void Desktop::EnableQuickstart()
278 {
279 sal_Bool bQuickstart( sal_True );
280 sal_Bool bAutostart( sal_True );
281 Sequence< Any > aSeq( 2 );
282 aSeq[0] <<= bQuickstart;
283 aSeq[1] <<= bAutostart;
284
285 Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
286 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.office.Quickstart"))), UNO_QUERY );
287 if ( xQuickstart.is() )
288 xQuickstart->initialize( aSeq );
289 }
290
DoRestartActionsIfNecessary(sal_Bool bQuickStart)291 void Desktop::DoRestartActionsIfNecessary( sal_Bool bQuickStart )
292 {
293 if ( bQuickStart )
294 {
295 try
296 {
297 Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
298
299 OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "OfficeRestartInProgress" ) );
300 Any aRestart = xPSet->getPropertyValue( sPropName );
301 sal_Bool bRestart = sal_False;
302 if ( ( aRestart >>= bRestart ) && bRestart )
303 {
304 xPSet->setPropertyValue( sPropName, makeAny( sal_False ) );
305 Reference< util::XChangesBatch >( xPSet, UNO_QUERY_THROW )->commitChanges();
306
307 Sequence< Any > aSeq( 2 );
308 aSeq[0] <<= sal_True;
309 aSeq[1] <<= sal_True;
310
311 Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
312 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.Quickstart" ) ) ),UNO_QUERY_THROW );
313 xQuickstart->initialize( aSeq );
314 }
315 }
316 catch( uno::Exception& )
317 {
318 // this is no critical operation so it should not prevent office from starting
319 }
320 }
321 }
322
SetRestartState()323 void Desktop::SetRestartState()
324 {
325 try
326 {
327 Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) );
328 OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "OfficeRestartInProgress" ) );
329 xPSet->setPropertyValue( sPropName, makeAny( sal_True ) );
330 Reference< util::XChangesBatch >( xPSet, UNO_QUERY_THROW )->commitChanges();
331 }
332 catch( uno::Exception& )
333 {
334 // this is no critical operation, ignore the exception
335 }
336
337 }
338