1*2722ceddSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*2722ceddSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*2722ceddSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*2722ceddSAndrew Rist * distributed with this work for additional information 6*2722ceddSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*2722ceddSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*2722ceddSAndrew Rist * "License"); you may not use this file except in compliance 9*2722ceddSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*2722ceddSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*2722ceddSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*2722ceddSAndrew Rist * software distributed under the License is distributed on an 15*2722ceddSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*2722ceddSAndrew Rist * KIND, either express or implied. See the License for the 17*2722ceddSAndrew Rist * specific language governing permissions and limitations 18*2722ceddSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*2722ceddSAndrew Rist *************************************************************/ 21*2722ceddSAndrew Rist 22*2722ceddSAndrew 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 64cdf0e10cSrcweir OUString aBaseInstallPath(RTL_CONSTASCII_USTRINGPARAM("$BRAND_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 { 109cdf0e10cSrcweir // Don't show a license 110cdf0e10cSrcweir return sal_False; 111cdf0e10cSrcweir /* 112cdf0e10cSrcweir sal_Bool bShowLicense = sal_True; 113cdf0e10cSrcweir sal_Int32 nOpenSourceContext = 0; 114cdf0e10cSrcweir try 115cdf0e10cSrcweir { 116cdf0e10cSrcweir ::utl::ConfigManager::GetDirectConfigProperty( 117cdf0e10cSrcweir ::utl::ConfigManager::OPENSOURCECONTEXT ) >>= nOpenSourceContext; 118cdf0e10cSrcweir } 119cdf0e10cSrcweir catch( const ::com::sun::star::uno::Exception& ) {} 120cdf0e10cSrcweir 121cdf0e10cSrcweir // open source needs no license 122cdf0e10cSrcweir if ( nOpenSourceContext > 0 ) 123cdf0e10cSrcweir bShowLicense = sal_False; 124cdf0e10cSrcweir 125cdf0e10cSrcweir return bShowLicense; 126cdf0e10cSrcweir */ 127cdf0e10cSrcweir } 128cdf0e10cSrcweir 129cdf0e10cSrcweir /* Local function - get access to the configuration */ 130cdf0e10cSrcweir static Reference< XPropertySet > impl_getConfigurationAccess( const OUString& rPath ) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); 133cdf0e10cSrcweir 134cdf0e10cSrcweir // get configuration provider 135cdf0e10cSrcweir Reference< XMultiServiceFactory > xConfigProvider = Reference< XMultiServiceFactory >( 136cdf0e10cSrcweir xFactory->createInstance( sConfigSrvc ), UNO_QUERY_THROW ); 137cdf0e10cSrcweir 138cdf0e10cSrcweir Sequence< Any > aArgs( 1 ); 139cdf0e10cSrcweir NamedValue aValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "NodePath" ) ), makeAny( rPath ) ); 140cdf0e10cSrcweir aArgs[0] <<= aValue; 141cdf0e10cSrcweir return Reference< XPropertySet >( 142cdf0e10cSrcweir xConfigProvider->createInstanceWithArguments( sAccessSrvc, aArgs ), UNO_QUERY_THROW ); 143cdf0e10cSrcweir } 144cdf0e10cSrcweir 145cdf0e10cSrcweir /* Local function - was the wizard completed already? */ 146cdf0e10cSrcweir static sal_Bool impl_isFirstStart() 147cdf0e10cSrcweir { 148cdf0e10cSrcweir try { 149cdf0e10cSrcweir Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) ); 150cdf0e10cSrcweir 151cdf0e10cSrcweir Any result = xPSet->getPropertyValue(OUString::createFromAscii("FirstStartWizardCompleted")); 152cdf0e10cSrcweir sal_Bool bCompleted = sal_False; 153cdf0e10cSrcweir if ((result >>= bCompleted) && bCompleted) 154cdf0e10cSrcweir return sal_False; // wizard was already completed 155cdf0e10cSrcweir else 156cdf0e10cSrcweir return sal_True; 157cdf0e10cSrcweir } catch (const Exception&) 158cdf0e10cSrcweir { 159cdf0e10cSrcweir return sal_True; 160cdf0e10cSrcweir } 161cdf0e10cSrcweir } 162cdf0e10cSrcweir 163cdf0e10cSrcweir /* Local function - convert oslDateTime to tools DateTime */ 164cdf0e10cSrcweir static DateTime impl_oslDateTimeToDateTime(const oslDateTime& aDateTime) 165cdf0e10cSrcweir { 166cdf0e10cSrcweir return DateTime( 167cdf0e10cSrcweir Date(aDateTime.Day, aDateTime.Month, aDateTime.Year), 168cdf0e10cSrcweir Time(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds)); 169cdf0e10cSrcweir } 170cdf0e10cSrcweir 171cdf0e10cSrcweir /* Local function - get DateTime from a string */ 172cdf0e10cSrcweir static sal_Bool impl_parseDateTime(const OUString& aString, DateTime& aDateTime) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir // take apart a canonical literal xsd:dateTime string 175cdf0e10cSrcweir //CCYY-MM-DDThh:mm:ss(Z) 176cdf0e10cSrcweir 177cdf0e10cSrcweir OUString aDateTimeString = aString.trim(); 178cdf0e10cSrcweir 179cdf0e10cSrcweir // check length 180cdf0e10cSrcweir if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20) 181cdf0e10cSrcweir return sal_False; 182cdf0e10cSrcweir 183cdf0e10cSrcweir sal_Int32 nDateLength = 10; 184cdf0e10cSrcweir sal_Int32 nTimeLength = 8; 185cdf0e10cSrcweir 186cdf0e10cSrcweir OUString aDateTimeSep = OUString::createFromAscii("T"); 187cdf0e10cSrcweir OUString aDateSep = OUString::createFromAscii("-"); 188cdf0e10cSrcweir OUString aTimeSep = OUString::createFromAscii(":"); 189cdf0e10cSrcweir OUString aUTCString = OUString::createFromAscii("Z"); 190cdf0e10cSrcweir 191cdf0e10cSrcweir OUString aDateString = aDateTimeString.copy(0, nDateLength); 192cdf0e10cSrcweir OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength); 193cdf0e10cSrcweir 194cdf0e10cSrcweir sal_Int32 nIndex = 0; 195cdf0e10cSrcweir sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32(); 196cdf0e10cSrcweir sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32(); 197cdf0e10cSrcweir sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32(); 198cdf0e10cSrcweir nIndex = 0; 199cdf0e10cSrcweir sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32(); 200cdf0e10cSrcweir sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32(); 201cdf0e10cSrcweir sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32(); 202cdf0e10cSrcweir 203cdf0e10cSrcweir Date tmpDate((sal_uInt16)nDay, (sal_uInt16)nMonth, (sal_uInt16)nYear); 204cdf0e10cSrcweir Time tmpTime(nHour, nMinute, nSecond); 205cdf0e10cSrcweir DateTime tmpDateTime(tmpDate, tmpTime); 206cdf0e10cSrcweir if (aString.indexOf(aUTCString) < 0) 207cdf0e10cSrcweir tmpDateTime.ConvertToUTC(); 208cdf0e10cSrcweir 209cdf0e10cSrcweir aDateTime = tmpDateTime; 210cdf0e10cSrcweir return sal_True; 211cdf0e10cSrcweir } 212cdf0e10cSrcweir 213cdf0e10cSrcweir /* Local function - was the license accepted already? */ 214cdf0e10cSrcweir static sal_Bool impl_isLicenseAccepted() 215cdf0e10cSrcweir { 216cdf0e10cSrcweir // If no license will be shown ... it must not be accepted. 217cdf0e10cSrcweir // So it was accepted "hardly" by the outside installer. 218cdf0e10cSrcweir // But if the configuration entry "HideEula" will be removed afterwards .. 219cdf0e10cSrcweir // we have to show the licese page again and user has to accept it here .-) 220cdf0e10cSrcweir if ( ! Desktop::LicenseNeedsAcceptance() ) 221cdf0e10cSrcweir return sal_True; 222cdf0e10cSrcweir 223cdf0e10cSrcweir try 224cdf0e10cSrcweir { 225cdf0e10cSrcweir Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) ); 226cdf0e10cSrcweir 227cdf0e10cSrcweir Any result = xPSet->getPropertyValue(OUString::createFromAscii("LicenseAcceptDate")); 228cdf0e10cSrcweir 229cdf0e10cSrcweir OUString aAcceptDate; 230cdf0e10cSrcweir if (result >>= aAcceptDate) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir // compare to date of license file 233cdf0e10cSrcweir OUString aLicenseURL = Desktop::GetLicensePath(); 234cdf0e10cSrcweir osl::DirectoryItem aDirItem; 235cdf0e10cSrcweir if (osl::DirectoryItem::get(aLicenseURL, aDirItem) != osl::FileBase::E_None) 236cdf0e10cSrcweir return sal_False; 237cdf0e10cSrcweir osl::FileStatus aStatus(FileStatusMask_All); 238cdf0e10cSrcweir if (aDirItem.getFileStatus(aStatus) != osl::FileBase::E_None) 239cdf0e10cSrcweir return sal_False; 240cdf0e10cSrcweir TimeValue aTimeVal = aStatus.getModifyTime(); 241cdf0e10cSrcweir oslDateTime aDateTimeVal; 242cdf0e10cSrcweir if (!osl_getDateTimeFromTimeValue(&aTimeVal, &aDateTimeVal)) 243cdf0e10cSrcweir return sal_False; 244cdf0e10cSrcweir 245cdf0e10cSrcweir // compare dates 246cdf0e10cSrcweir DateTime aLicenseDateTime = impl_oslDateTimeToDateTime(aDateTimeVal); 247cdf0e10cSrcweir DateTime aAcceptDateTime; 248cdf0e10cSrcweir if (!impl_parseDateTime(aAcceptDate, aAcceptDateTime)) 249cdf0e10cSrcweir return sal_False; 250cdf0e10cSrcweir 251cdf0e10cSrcweir if ( aAcceptDateTime > aLicenseDateTime ) 252cdf0e10cSrcweir return sal_True; 253cdf0e10cSrcweir } 254cdf0e10cSrcweir return sal_False; 255cdf0e10cSrcweir } catch (const Exception&) 256cdf0e10cSrcweir { 257cdf0e10cSrcweir return sal_False; 258cdf0e10cSrcweir } 259cdf0e10cSrcweir } 260cdf0e10cSrcweir 261cdf0e10cSrcweir /* Check if we need the first start wizard. */ 262cdf0e10cSrcweir sal_Bool Desktop::IsFirstStartWizardNeeded() 263cdf0e10cSrcweir { 264cdf0e10cSrcweir return impl_isFirstStart() || !impl_isLicenseAccepted(); 265cdf0e10cSrcweir } 266cdf0e10cSrcweir 267cdf0e10cSrcweir void Desktop::DoRestartActionsIfNecessary( sal_Bool bQuickStart ) 268cdf0e10cSrcweir { 269cdf0e10cSrcweir if ( bQuickStart ) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir try 272cdf0e10cSrcweir { 273cdf0e10cSrcweir Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) ); 274cdf0e10cSrcweir 275cdf0e10cSrcweir OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "OfficeRestartInProgress" ) ); 276cdf0e10cSrcweir Any aRestart = xPSet->getPropertyValue( sPropName ); 277cdf0e10cSrcweir sal_Bool bRestart = sal_False; 278cdf0e10cSrcweir if ( ( aRestart >>= bRestart ) && bRestart ) 279cdf0e10cSrcweir { 280cdf0e10cSrcweir xPSet->setPropertyValue( sPropName, makeAny( sal_False ) ); 281cdf0e10cSrcweir Reference< util::XChangesBatch >( xPSet, UNO_QUERY_THROW )->commitChanges(); 282cdf0e10cSrcweir 283cdf0e10cSrcweir Sequence< Any > aSeq( 2 ); 284cdf0e10cSrcweir aSeq[0] <<= sal_True; 285cdf0e10cSrcweir aSeq[1] <<= sal_True; 286cdf0e10cSrcweir 287cdf0e10cSrcweir Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance( 288cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.office.Quickstart" ) ) ),UNO_QUERY_THROW ); 289cdf0e10cSrcweir xQuickstart->initialize( aSeq ); 290cdf0e10cSrcweir } 291cdf0e10cSrcweir } 292cdf0e10cSrcweir catch( uno::Exception& ) 293cdf0e10cSrcweir { 294cdf0e10cSrcweir // this is no critical operation so it should not prevent office from starting 295cdf0e10cSrcweir } 296cdf0e10cSrcweir } 297cdf0e10cSrcweir } 298cdf0e10cSrcweir 299cdf0e10cSrcweir void Desktop::SetRestartState() 300cdf0e10cSrcweir { 301cdf0e10cSrcweir try 302cdf0e10cSrcweir { 303cdf0e10cSrcweir Reference< XPropertySet > xPSet = impl_getConfigurationAccess( OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Setup/Office" ) ) ); 304cdf0e10cSrcweir OUString sPropName( RTL_CONSTASCII_USTRINGPARAM( "OfficeRestartInProgress" ) ); 305cdf0e10cSrcweir xPSet->setPropertyValue( sPropName, makeAny( sal_True ) ); 306cdf0e10cSrcweir Reference< util::XChangesBatch >( xPSet, UNO_QUERY_THROW )->commitChanges(); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir catch( uno::Exception& ) 309cdf0e10cSrcweir { 310cdf0e10cSrcweir // this is no critical operation, ignore the exception 311cdf0e10cSrcweir } 312cdf0e10cSrcweir 313cdf0e10cSrcweir } 314cdf0e10cSrcweir 315