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