diff options
Diffstat (limited to 'framework/source/services/license.cxx')
-rw-r--r-- | framework/source/services/license.cxx | 631 |
1 files changed, 631 insertions, 0 deletions
diff --git a/framework/source/services/license.cxx b/framework/source/services/license.cxx new file mode 100644 index 000000000000..18f3e21bf67d --- /dev/null +++ b/framework/source/services/license.cxx @@ -0,0 +1,631 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <services/license.hxx> +#include <threadhelp/resetableguard.hxx> +#include <macros/debug.hxx> +#include <services.h> + +// local header for UI implementation +#include "services/licensedlg.hxx" +#include "classes/resource.hrc" + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/util/XChangesBatch.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/lang/XComponent.hpp> + + +//_________________________________________________________________________________________________________________ +// includes of other projects +//_________________________________________________________________________________________________________________ + +#include <rtl/ustrbuf.hxx> +#include <rtl/strbuf.hxx> +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> +#include <unotools/bootstrap.hxx> +#include <osl/file.hxx> +#include <svtools/xtextedt.hxx> +#include <vcl/svapp.hxx> +#include <comphelper/processfactory.hxx> +#include <tools/date.hxx> +#include <tools/time.hxx> +#include <tools/datetime.hxx> +#include <osl/file.hxx> +#include <osl/time.h> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ +using namespace utl; +using namespace ::osl ; +using namespace ::cppu ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::beans ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::util ; +using namespace ::com::sun::star::frame ; + +//_________________________________________________________________________________________________________________ +// non exported const +//_________________________________________________________________________________________________________________ + +// license file name +static const char *szLicensePath = "/share/readme"; +#ifdef UNX +static const char *szUNXLicenseName = "/LICENSE"; +static const char *szUNXLicenseExt = ""; +#elif defined(WNT) || defined(OS2) +static const char *szWNTLicenseName = "/license"; +static const char *szWNTLicenseExt = ".txt"; +#endif + +//_________________________________________________________________________________________________________________ +// non exported definitions +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +License::License( const Reference< XMultiServiceFactory >& xFactory ) + // Init baseclasses first + // Attention: + // Don't change order of initialization! + // ThreadHelpBase is a struct with a mutex as member. We can't use a mutex as member, while + // we must garant right initialization and a valid value of this! First initialize + // baseclasses and then members. And we need the mutex for other baseclasses !!! + : ThreadHelpBase ( &Application::GetSolarMutex() ) + , OWeakObject ( ) + // Init member + , m_xFactory ( xFactory ) + , m_bTerminate ( sal_False ) +{ +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +License::~License() +{ +} + +//***************************************************************************************************************** +// XInterface, XTypeProvider, XServiceInfo +//***************************************************************************************************************** + +DEFINE_XINTERFACE_4 ( License , + OWeakObject , + DIRECT_INTERFACE(XTypeProvider ), + DIRECT_INTERFACE(XServiceInfo ), + DIRECT_INTERFACE(XJob ), + DIRECT_INTERFACE(XCloseable ) + ) + +DEFINE_XTYPEPROVIDER_4 ( License , + XTypeProvider , + XServiceInfo , + XJob , + XCloseable + ) + +DEFINE_XSERVICEINFO_MULTISERVICE ( License, + OWeakObject , + SERVICENAME_LICENSE , + IMPLEMENTATIONNAME_LICENSE + ) + +DEFINE_INIT_SERVICE ( License, + { + } + ) + + +#if 0 +IMPL_STATIC_LINK_NOINSTANCE( License, Terminate, void*, EMPTYARG ) +{ + /* + Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); + Reference< XDesktop > xDesktop(xFactory->createInstance( + ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY); + if (xDesktop.is()) + xDesktop->terminate(); + */ + /* + _exit(0); + */ + return 0; +} +#endif + +static DateTime _oslDateTimeToDateTime(const oslDateTime& aDateTime) +{ + return DateTime( + Date(aDateTime.Day, aDateTime.Month, aDateTime.Year), + Time(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds)); +} + +static ::rtl::OUString _makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_False) +{ + ::rtl::OStringBuffer aDateTimeString; + aDateTimeString.append((sal_Int32)aDateTime.GetYear()); + aDateTimeString.append("-"); + if (aDateTime.GetMonth()<10) aDateTimeString.append("0"); + aDateTimeString.append((sal_Int32)aDateTime.GetMonth()); + aDateTimeString.append("-"); + if (aDateTime.GetDay()<10) aDateTimeString.append("0"); + aDateTimeString.append((sal_Int32)aDateTime.GetDay()); + aDateTimeString.append("T"); + if (aDateTime.GetHour()<10) aDateTimeString.append("0"); + aDateTimeString.append((sal_Int32)aDateTime.GetHour()); + aDateTimeString.append(":"); + if (aDateTime.GetMin()<10) aDateTimeString.append("0"); + aDateTimeString.append((sal_Int32)aDateTime.GetMin()); + aDateTimeString.append(":"); + if (aDateTime.GetSec()<10) aDateTimeString.append("0"); + aDateTimeString.append((sal_Int32)aDateTime.GetSec()); + if (bUTC) aDateTimeString.append("Z"); + + return OStringToOUString(aDateTimeString.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); +} + +static sal_Bool _parseDateTime(const ::rtl::OUString& aString, DateTime& aDateTime) +{ + // take apart a canonical literal xsd:dateTime string + //CCYY-MM-DDThh:mm:ss(Z) + + ::rtl::OUString aDateTimeString = aString.trim(); + + // check length + if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20) + return sal_False; + + sal_Int32 nDateLength = 10; + sal_Int32 nTimeLength = 8; + + ::rtl::OUString aDateTimeSep = ::rtl::OUString::createFromAscii("T"); + ::rtl::OUString aDateSep = ::rtl::OUString::createFromAscii("-"); + ::rtl::OUString aTimeSep = ::rtl::OUString::createFromAscii(":"); + ::rtl::OUString aUTCString = ::rtl::OUString::createFromAscii("Z"); + + ::rtl::OUString aDateString = aDateTimeString.copy(0, nDateLength); + ::rtl::OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength); + + sal_Int32 nIndex = 0; + sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32(); + sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32(); + sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32(); + nIndex = 0; + sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32(); + sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32(); + sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32(); + + Date tmpDate((USHORT)nDay, (USHORT)nMonth, (USHORT)nYear); + Time tmpTime(nHour, nMinute, nSecond); + DateTime tmpDateTime(tmpDate, tmpTime); + if (aString.indexOf(aUTCString) < 0) + tmpDateTime.ConvertToUTC(); + + aDateTime = tmpDateTime; + return sal_True; +} + +static ::rtl::OUString _getCurrentDateString() +{ + ::rtl::OUString aString; + return _makeDateTimeString(DateTime()); +} + +// execution of license check... +css::uno::Any SAL_CALL License::execute(const css::uno::Sequence< css::beans::NamedValue >& ) + throw( css::lang::IllegalArgumentException, css::uno::Exception) +{ + // return value + Any aRet; aRet <<= sal_False; + + try + { + ::rtl::OUString aBaseInstallPath; + Bootstrap::PathStatus aBaseLocateResult = + Bootstrap::locateBaseInstallation(aBaseInstallPath); + if (aBaseLocateResult != Bootstrap::PATH_EXISTS) + { + // base install noit found + // prepare termination + // m_bTerminate = sal_True; + // Application::PostUserEvent( STATIC_LINK( 0, License, Terminate ) ); + aRet <<= sal_False; + return aRet; + } + // determine the filename of the license to show + ::rtl::OUString aLangString; + ::com::sun::star::lang::Locale aLocale; + ::rtl::OString aMgrName = ::rtl::OString("fwe"); + AllSettings aSettings(Application::GetSettings()); + aLocale = aSettings.GetUILocale(); + ResMgr* pResMgr = ResMgr::SearchCreateResMgr(aMgrName, aLocale); + + aLangString = aLocale.Language; + if ( aLocale.Country.getLength() != 0 ) + { + aLangString += ::rtl::OUString::createFromAscii("-"); + aLangString += aLocale.Country; + if ( aLocale.Variant.getLength() != 0 ) + { + aLangString += ::rtl::OUString::createFromAscii("-"); + aLangString += aLocale.Variant; + } + } +#if defined(WNT) || defined(OS2) + ::rtl::OUString aLicensePath = + aBaseInstallPath + ::rtl::OUString::createFromAscii(szLicensePath) + + ::rtl::OUString::createFromAscii(szWNTLicenseName) + + ::rtl::OUString::createFromAscii("_") + + aLangString + + ::rtl::OUString::createFromAscii(szWNTLicenseExt); +#else + ::rtl::OUString aLicensePath = + aBaseInstallPath + ::rtl::OUString::createFromAscii(szLicensePath) + + ::rtl::OUString::createFromAscii(szUNXLicenseName) + + ::rtl::OUString::createFromAscii("_") + + aLangString + + ::rtl::OUString::createFromAscii(szUNXLicenseExt); +#endif + // check if we need to show the license at all + // open org.openoffice.Setup/Office/ooLicenseAcceptDate + ::rtl::OUString sConfigSrvc = SERVICENAME_CFGPROVIDER; + ::rtl::OUString sAccessSrvc = ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"); + ::rtl::OUString sReadSrvc = SERVICENAME_CFGREADACCESS; + + // get configuration provider + Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >( + m_xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW); + Sequence< Any > theArgs(1); + NamedValue v; + v.Name = ::rtl::OUString::createFromAscii("NodePath"); + v.Value <<= ::rtl::OUString::createFromAscii("org.openoffice.Setup/Office"); + theArgs[0] <<= v; + Reference< XPropertySet > pset = Reference< XPropertySet >( + theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW); + + // if we find a date there, compare it to baseinstall license date + ::rtl::OUString aAcceptDate; + if (pset->getPropertyValue(::rtl::OUString::createFromAscii("ooLicenseAcceptDate")) >>= aAcceptDate) + { + // get LicenseFileDate from base install + ::rtl::OUString aLicenseURL = aLicensePath; + /* + if (FileBase::getFileURLFromSystemPath(aLicensePath, aLicenseURL) != FileBase::E_None) + return makeAny(sal_False); + */ + DirectoryItem aDirItem; + if (DirectoryItem::get(aLicenseURL, aDirItem) != FileBase::E_None) + return makeAny(sal_False); + FileStatus aStatus(FileStatusMask_All); + if (aDirItem.getFileStatus(aStatus) != FileBase::E_None) + return makeAny(sal_False); + TimeValue aTimeVal = aStatus.getModifyTime(); + oslDateTime aDateTimeVal; + if (!osl_getDateTimeFromTimeValue(&aTimeVal, &aDateTimeVal)) + return makeAny(sal_False); + + // compare dates + DateTime aLicenseDateTime = _oslDateTimeToDateTime(aDateTimeVal); + DateTime aAcceptDateTime; + if (!_parseDateTime(aAcceptDate, aAcceptDateTime)) + return makeAny(sal_False); + + if ( aAcceptDateTime > aLicenseDateTime ) + return makeAny(sal_True); + } + // prepare to show + // display license dialog + LicenseDialog* pDialog = new LicenseDialog(aLicensePath, pResMgr); + sal_Bool bAgreed = (pDialog->Execute() == 1); + delete pDialog; + + if (bAgreed) { + + // write org.openoffice.Setup/ooLicenseAcceptDate + aAcceptDate = _getCurrentDateString(); + pset->setPropertyValue(::rtl::OUString::createFromAscii("ooLicenseAcceptDate"), makeAny(aAcceptDate)); + Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges(); + + // enable quickstarter + sal_Bool bQuickstart( sal_True ); + sal_Bool bAutostart( sal_True ); + Sequence< Any > aSeq( 2 ); + aSeq[0] <<= bQuickstart; + aSeq[1] <<= bAutostart; + + Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance( + ::rtl::OUString::createFromAscii( "com.sun.star.office.Quickstart" )),UNO_QUERY ); + if ( xQuickstart.is() ) + xQuickstart->initialize( aSeq ); + + aRet <<= sal_True; + } + else + { + // license was not accepted + // prepare termination + // m_bTerminate = sal_True; + // Application::PostUserEvent( STATIC_LINK( 0, License, Terminate ) ); + aRet <<= sal_False; + } + } + catch (RuntimeException&) + { + // license could not be verified + aRet <<= sal_False; + } + return aRet; +} + +void SAL_CALL License::close(sal_Bool /*bDeliverOwnership*/) throw (css::util::CloseVetoException) +{ + if (!m_bTerminate) + throw CloseVetoException(); +} +void SAL_CALL License::addCloseListener(const css::uno::Reference< css::util::XCloseListener >&) + throw (css::uno::RuntimeException) +{ +} +void SAL_CALL License::removeCloseListener(const css::uno::Reference< css::util::XCloseListener >&) + throw (css::uno::RuntimeException) +{ +} + + +//************************************************************************ +// License Dialog +//************************************************************************ + +LicenseDialog::LicenseDialog(const ::rtl::OUString & aLicensePath, ResMgr *pResMgr) : + ModalDialog(NULL, ResId(DLG_LICENSE, *pResMgr)), + aLicenseML(this, ResId(ML_LICENSE, *pResMgr)), + aInfo1FT(this, ResId(FT_INFO1, *pResMgr)), + aInfo2FT(this, ResId(FT_INFO2, *pResMgr)), + aInfo3FT(this, ResId(FT_INFO3, *pResMgr)), + aInfo2_1FT(this, ResId(FT_INFO2_1, *pResMgr)), + aInfo3_1FT(this, ResId(FT_INFO3_1, *pResMgr)), + aFixedLine(this, ResId(FL_DIVIDE, *pResMgr)), + aPBPageDown(this, ResId(PB_PAGEDOWN, *pResMgr)), + aPBDecline( this, ResId(PB_DECLINE, *pResMgr) ), + aPBAccept( this, ResId(PB_ACCEPT, *pResMgr) ), + aArrow(this, ResId(IMG_ARROW, *pResMgr)), + aStrAccept( ResId(LICENSE_ACCEPT, *pResMgr) ), + aStrNotAccept( ResId(LICENSE_NOTACCEPT, *pResMgr) ), + bEndReached(FALSE) +{ + FreeResource(); + + aLicenseML.SetEndReachedHdl( LINK(this, LicenseDialog, EndReachedHdl) ); + aLicenseML.SetScrolledHdl( LINK(this, LicenseDialog, ScrolledHdl) ); + + aPBPageDown.SetClickHdl( LINK(this, LicenseDialog, PageDownHdl) ); + aPBDecline.SetClickHdl( LINK(this, LicenseDialog, DeclineBtnHdl) ); + aPBAccept.SetClickHdl( LINK(this, LicenseDialog, AcceptBtnHdl) ); + + // We want a automatic repeating page down button + WinBits aStyle = aPBPageDown.GetStyle(); + aStyle |= WB_REPEAT; + aPBPageDown.SetStyle( aStyle ); + + String aText = aInfo2FT.GetText(); + aText.SearchAndReplaceAll( UniString::CreateFromAscii("%PAGEDOWN"), aPBPageDown.GetText() ); + aInfo2FT.SetText( aText ); + + aPBDecline.SetText( aStrNotAccept ); + aPBAccept.SetText( aStrAccept ); + + aPBAccept.Disable(); + + // load license text + File aLicenseFile(aLicensePath); + if ( aLicenseFile.open(OpenFlag_Read) == FileBase::E_None) + { + DirectoryItem d; + DirectoryItem::get(aLicensePath, d); + FileStatus fs(FileStatusMask_FileSize); + d.getFileStatus(fs); + sal_uInt64 nBytesRead = 0; + sal_uInt64 nPosition = 0; + sal_uInt32 nBytes = (sal_uInt32)fs.getFileSize(); + sal_Char *pBuffer = new sal_Char[nBytes]; + // FileBase RC r = FileBase::E_None; + while (aLicenseFile.read(pBuffer+nPosition, nBytes-nPosition, nBytesRead) == FileBase::E_None + && nPosition + nBytesRead < nBytes) + { + nPosition += nBytesRead; + } + ::rtl::OUString aLicenseString(pBuffer, nBytes, RTL_TEXTENCODING_UTF8, + OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE); + delete[] pBuffer; + aLicenseML.SetText(aLicenseString); + } + +} + +LicenseDialog::~LicenseDialog() +{ +} + +IMPL_LINK( LicenseDialog, PageDownHdl, PushButton *, EMPTYARG ) +{ + aLicenseML.ScrollDown( SCROLL_PAGEDOWN ); + return 0; +} + +IMPL_LINK( LicenseDialog, EndReachedHdl, LicenseView *, EMPTYARG ) +{ + bEndReached = TRUE; + + EnableControls(); + + return 0; +} + +IMPL_LINK( LicenseDialog, ScrolledHdl, LicenseView *, EMPTYARG ) +{ + EnableControls(); + + return 0; +} + +IMPL_LINK( LicenseDialog, DeclineBtnHdl, PushButton *, EMPTYARG ) +{ + EndDialog(0); + return 0; +} +IMPL_LINK( LicenseDialog, AcceptBtnHdl, PushButton *, EMPTYARG ) +{ + EndDialog(1); + return 0; +} + + +void LicenseDialog::EnableControls() +{ + if( !bEndReached && + ( aLicenseML.IsEndReached() || !aLicenseML.GetText().Len() ) ) + bEndReached = TRUE; + + if ( bEndReached ) + { + Point aPos( aInfo1FT.GetPosPixel().X(), + aInfo3_1FT.GetPosPixel().Y() ); + aArrow.SetPosPixel( aPos ); + aPBAccept.Enable(); + } + else + { + Point aPos( aInfo1FT.GetPosPixel().X(), + aInfo2_1FT.GetPosPixel().Y() ); + aArrow.SetPosPixel( aPos ); + aPBAccept.Disable(); + } + + if ( aLicenseML.IsEndReached() ) + aPBPageDown.Disable(); + else + aPBPageDown.Enable(); + +} + + +LicenseView::LicenseView( Window* pParent, const ResId& rResId ) + : MultiLineEdit( pParent, rResId ) +{ + SetLeftMargin( 5 ); + + mbEndReached = IsEndReached(); + + StartListening( *GetTextEngine() ); +} + +LicenseView::~LicenseView() +{ + maEndReachedHdl = Link(); + maScrolledHdl = Link(); + + EndListeningAll(); +} + +void LicenseView::ScrollDown( ScrollType eScroll ) +{ + ScrollBar* pScroll = GetVScrollBar(); + + if ( pScroll ) + pScroll->DoScrollAction( eScroll ); +} + +BOOL LicenseView::IsEndReached() const +{ + BOOL bEndReached; + + ExtTextView* pView = GetTextView(); + ExtTextEngine* pEdit = GetTextEngine(); + ULONG nHeight = pEdit->GetTextHeight(); + Size aOutSize = pView->GetWindow()->GetOutputSizePixel(); + Point aBottom( 0, aOutSize.Height() ); + + if ( (ULONG) pView->GetDocPos( aBottom ).Y() >= nHeight - 1 ) + bEndReached = TRUE; + else + bEndReached = FALSE; + + return bEndReached; +} + +void LicenseView::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + if ( rHint.IsA( TYPE(TextHint) ) ) + { + BOOL bLastVal = EndReached(); + ULONG nId = ((const TextHint&)rHint).GetId(); + + if ( nId == TEXT_HINT_PARAINSERTED ) + { + if ( bLastVal ) + mbEndReached = IsEndReached(); + } + else if ( nId == TEXT_HINT_VIEWSCROLLED ) + { + if ( ! mbEndReached ) + mbEndReached = IsEndReached(); + maScrolledHdl.Call( this ); + } + + if ( EndReached() && !bLastVal ) + { + maEndReachedHdl.Call( this ); + } + } +} + +} // namespace framework + |