merge the formfield patch from ooo-build
[ooovba.git] / framework / source / services / license.cxx
blobc34d7908d121e5d4b32f0b0cbf5b0561a9ddccaf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: license.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 //_________________________________________________________________________________________________________________
35 // my own includes
36 //_________________________________________________________________________________________________________________
37 #include <services/license.hxx>
38 #include <threadhelp/resetableguard.hxx>
39 #include <macros/debug.hxx>
40 #include <services.h>
42 // local header for UI implementation
43 #include "services/licensedlg.hxx"
44 #include "classes/resource.hrc"
46 //_________________________________________________________________________________________________________________
47 // interface includes
48 //_________________________________________________________________________________________________________________
50 #include <com/sun/star/frame/XDesktop.hpp>
51 #include <com/sun/star/lang/XInitialization.hpp>
52 #include <com/sun/star/beans/XPropertySet.hpp>
53 #include <com/sun/star/uno/Any.hxx>
54 #include <com/sun/star/util/XChangesBatch.hpp>
55 #include <com/sun/star/beans/NamedValue.hpp>
56 #include <com/sun/star/lang/XComponent.hpp>
59 //_________________________________________________________________________________________________________________
60 // includes of other projects
61 //_________________________________________________________________________________________________________________
63 #include <rtl/ustrbuf.hxx>
64 #include <rtl/strbuf.hxx>
65 #include <rtl/ustring.hxx>
66 #include <rtl/string.hxx>
67 #include <unotools/bootstrap.hxx>
68 #include <osl/file.hxx>
69 #include <svtools/xtextedt.hxx>
70 #include <vcl/svapp.hxx>
71 #include <comphelper/processfactory.hxx>
72 #include <tools/date.hxx>
73 #include <tools/time.hxx>
74 #include <tools/datetime.hxx>
75 #include <osl/file.hxx>
76 #include <osl/time.h>
78 //_________________________________________________________________________________________________________________
79 // namespace
80 //_________________________________________________________________________________________________________________
82 namespace framework{
83 using namespace utl;
84 using namespace ::osl ;
85 using namespace ::cppu ;
86 using namespace ::com::sun::star::uno ;
87 using namespace ::com::sun::star::beans ;
88 using namespace ::com::sun::star::lang ;
89 using namespace ::com::sun::star::util ;
90 using namespace ::com::sun::star::frame ;
92 //_________________________________________________________________________________________________________________
93 // non exported const
94 //_________________________________________________________________________________________________________________
96 // license file name
97 static const char *szLicensePath = "/share/readme";
98 #ifdef UNX
99 static const char *szUNXLicenseName = "/LICENSE";
100 static const char *szUNXLicenseExt = "";
101 #elif defined(WNT) || defined(OS2)
102 static const char *szWNTLicenseName = "/license";
103 static const char *szWNTLicenseExt = ".txt";
104 #endif
106 //_________________________________________________________________________________________________________________
107 // non exported definitions
108 //_________________________________________________________________________________________________________________
110 //_________________________________________________________________________________________________________________
111 // declarations
112 //_________________________________________________________________________________________________________________
114 //*****************************************************************************************************************
115 // constructor
116 //*****************************************************************************************************************
117 License::License( const Reference< XMultiServiceFactory >& xFactory )
118 // Init baseclasses first
119 // Attention:
120 // Don't change order of initialization!
121 // ThreadHelpBase is a struct with a mutex as member. We can't use a mutex as member, while
122 // we must garant right initialization and a valid value of this! First initialize
123 // baseclasses and then members. And we need the mutex for other baseclasses !!!
124 : ThreadHelpBase ( &Application::GetSolarMutex() )
125 , OWeakObject ( )
126 // Init member
127 , m_xFactory ( xFactory )
128 , m_bTerminate ( sal_False )
132 //*****************************************************************************************************************
133 // destructor
134 //*****************************************************************************************************************
135 License::~License()
139 //*****************************************************************************************************************
140 // XInterface, XTypeProvider, XServiceInfo
141 //*****************************************************************************************************************
143 DEFINE_XINTERFACE_4 ( License ,
144 OWeakObject ,
145 DIRECT_INTERFACE(XTypeProvider ),
146 DIRECT_INTERFACE(XServiceInfo ),
147 DIRECT_INTERFACE(XJob ),
148 DIRECT_INTERFACE(XCloseable )
151 DEFINE_XTYPEPROVIDER_4 ( License ,
152 XTypeProvider ,
153 XServiceInfo ,
154 XJob ,
155 XCloseable
158 DEFINE_XSERVICEINFO_MULTISERVICE ( License,
159 OWeakObject ,
160 SERVICENAME_LICENSE ,
161 IMPLEMENTATIONNAME_LICENSE
164 DEFINE_INIT_SERVICE ( License,
170 #if 0
171 IMPL_STATIC_LINK_NOINSTANCE( License, Terminate, void*, EMPTYARG )
174 Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
175 Reference< XDesktop > xDesktop(xFactory->createInstance(
176 ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY);
177 if (xDesktop.is())
178 xDesktop->terminate();
181 _exit(0);
183 return 0;
185 #endif
187 static DateTime _oslDateTimeToDateTime(const oslDateTime& aDateTime)
189 return DateTime(
190 Date(aDateTime.Day, aDateTime.Month, aDateTime.Year),
191 Time(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds));
194 static ::rtl::OUString _makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_False)
196 ::rtl::OStringBuffer aDateTimeString;
197 aDateTimeString.append((sal_Int32)aDateTime.GetYear());
198 aDateTimeString.append("-");
199 if (aDateTime.GetMonth()<10) aDateTimeString.append("0");
200 aDateTimeString.append((sal_Int32)aDateTime.GetMonth());
201 aDateTimeString.append("-");
202 if (aDateTime.GetDay()<10) aDateTimeString.append("0");
203 aDateTimeString.append((sal_Int32)aDateTime.GetDay());
204 aDateTimeString.append("T");
205 if (aDateTime.GetHour()<10) aDateTimeString.append("0");
206 aDateTimeString.append((sal_Int32)aDateTime.GetHour());
207 aDateTimeString.append(":");
208 if (aDateTime.GetMin()<10) aDateTimeString.append("0");
209 aDateTimeString.append((sal_Int32)aDateTime.GetMin());
210 aDateTimeString.append(":");
211 if (aDateTime.GetSec()<10) aDateTimeString.append("0");
212 aDateTimeString.append((sal_Int32)aDateTime.GetSec());
213 if (bUTC) aDateTimeString.append("Z");
215 return OStringToOUString(aDateTimeString.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
218 static sal_Bool _parseDateTime(const ::rtl::OUString& aString, DateTime& aDateTime)
220 // take apart a canonical literal xsd:dateTime string
221 //CCYY-MM-DDThh:mm:ss(Z)
223 ::rtl::OUString aDateTimeString = aString.trim();
225 // check length
226 if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
227 return sal_False;
229 sal_Int32 nDateLength = 10;
230 sal_Int32 nTimeLength = 8;
232 ::rtl::OUString aDateTimeSep = ::rtl::OUString::createFromAscii("T");
233 ::rtl::OUString aDateSep = ::rtl::OUString::createFromAscii("-");
234 ::rtl::OUString aTimeSep = ::rtl::OUString::createFromAscii(":");
235 ::rtl::OUString aUTCString = ::rtl::OUString::createFromAscii("Z");
237 ::rtl::OUString aDateString = aDateTimeString.copy(0, nDateLength);
238 ::rtl::OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength);
240 sal_Int32 nIndex = 0;
241 sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32();
242 sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32();
243 sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32();
244 nIndex = 0;
245 sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32();
246 sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32();
247 sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32();
249 Date tmpDate((USHORT)nDay, (USHORT)nMonth, (USHORT)nYear);
250 Time tmpTime(nHour, nMinute, nSecond);
251 DateTime tmpDateTime(tmpDate, tmpTime);
252 if (aString.indexOf(aUTCString) < 0)
253 tmpDateTime.ConvertToUTC();
255 aDateTime = tmpDateTime;
256 return sal_True;
259 static ::rtl::OUString _getCurrentDateString()
261 ::rtl::OUString aString;
262 return _makeDateTimeString(DateTime());
265 // execution of license check...
266 css::uno::Any SAL_CALL License::execute(const css::uno::Sequence< css::beans::NamedValue >& )
267 throw( css::lang::IllegalArgumentException, css::uno::Exception)
269 // return value
270 Any aRet; aRet <<= sal_False;
274 ::rtl::OUString aBaseInstallPath;
275 Bootstrap::PathStatus aBaseLocateResult =
276 Bootstrap::locateBaseInstallation(aBaseInstallPath);
277 if (aBaseLocateResult != Bootstrap::PATH_EXISTS)
279 // base install noit found
280 // prepare termination
281 // m_bTerminate = sal_True;
282 // Application::PostUserEvent( STATIC_LINK( 0, License, Terminate ) );
283 aRet <<= sal_False;
284 return aRet;
286 // determine the filename of the license to show
287 ::rtl::OUString aLangString;
288 ::com::sun::star::lang::Locale aLocale;
289 ::rtl::OString aMgrName = ::rtl::OString("fwe");
290 AllSettings aSettings(Application::GetSettings());
291 aLocale = aSettings.GetUILocale();
292 ResMgr* pResMgr = ResMgr::SearchCreateResMgr(aMgrName, aLocale);
294 aLangString = aLocale.Language;
295 if ( aLocale.Country.getLength() != 0 )
297 aLangString += ::rtl::OUString::createFromAscii("-");
298 aLangString += aLocale.Country;
299 if ( aLocale.Variant.getLength() != 0 )
301 aLangString += ::rtl::OUString::createFromAscii("-");
302 aLangString += aLocale.Variant;
305 #if defined(WNT) || defined(OS2)
306 ::rtl::OUString aLicensePath =
307 aBaseInstallPath + ::rtl::OUString::createFromAscii(szLicensePath)
308 + ::rtl::OUString::createFromAscii(szWNTLicenseName)
309 + ::rtl::OUString::createFromAscii("_")
310 + aLangString
311 + ::rtl::OUString::createFromAscii(szWNTLicenseExt);
312 #else
313 ::rtl::OUString aLicensePath =
314 aBaseInstallPath + ::rtl::OUString::createFromAscii(szLicensePath)
315 + ::rtl::OUString::createFromAscii(szUNXLicenseName)
316 + ::rtl::OUString::createFromAscii("_")
317 + aLangString
318 + ::rtl::OUString::createFromAscii(szUNXLicenseExt);
319 #endif
320 // check if we need to show the license at all
321 // open org.openoffice.Setup/Office/ooLicenseAcceptDate
322 ::rtl::OUString sConfigSrvc = SERVICENAME_CFGPROVIDER;
323 ::rtl::OUString sAccessSrvc = ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
324 ::rtl::OUString sReadSrvc = SERVICENAME_CFGREADACCESS;
326 // get configuration provider
327 Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
328 m_xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
329 Sequence< Any > theArgs(1);
330 NamedValue v;
331 v.Name = ::rtl::OUString::createFromAscii("NodePath");
332 v.Value <<= ::rtl::OUString::createFromAscii("org.openoffice.Setup/Office");
333 theArgs[0] <<= v;
334 Reference< XPropertySet > pset = Reference< XPropertySet >(
335 theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
337 // if we find a date there, compare it to baseinstall license date
338 ::rtl::OUString aAcceptDate;
339 if (pset->getPropertyValue(::rtl::OUString::createFromAscii("ooLicenseAcceptDate")) >>= aAcceptDate)
341 // get LicenseFileDate from base install
342 ::rtl::OUString aLicenseURL = aLicensePath;
344 if (FileBase::getFileURLFromSystemPath(aLicensePath, aLicenseURL) != FileBase::E_None)
345 return makeAny(sal_False);
347 DirectoryItem aDirItem;
348 if (DirectoryItem::get(aLicenseURL, aDirItem) != FileBase::E_None)
349 return makeAny(sal_False);
350 FileStatus aStatus(FileStatusMask_All);
351 if (aDirItem.getFileStatus(aStatus) != FileBase::E_None)
352 return makeAny(sal_False);
353 TimeValue aTimeVal = aStatus.getModifyTime();
354 oslDateTime aDateTimeVal;
355 if (!osl_getDateTimeFromTimeValue(&aTimeVal, &aDateTimeVal))
356 return makeAny(sal_False);
358 // compare dates
359 DateTime aLicenseDateTime = _oslDateTimeToDateTime(aDateTimeVal);
360 DateTime aAcceptDateTime;
361 if (!_parseDateTime(aAcceptDate, aAcceptDateTime))
362 return makeAny(sal_False);
364 if ( aAcceptDateTime > aLicenseDateTime )
365 return makeAny(sal_True);
367 // prepare to show
368 // display license dialog
369 LicenseDialog* pDialog = new LicenseDialog(aLicensePath, pResMgr);
370 sal_Bool bAgreed = (pDialog->Execute() == 1);
371 delete pDialog;
373 if (bAgreed) {
375 // write org.openoffice.Setup/ooLicenseAcceptDate
376 aAcceptDate = _getCurrentDateString();
377 pset->setPropertyValue(::rtl::OUString::createFromAscii("ooLicenseAcceptDate"), makeAny(aAcceptDate));
378 Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges();
380 // enable quickstarter
381 sal_Bool bQuickstart( sal_True );
382 sal_Bool bAutostart( sal_True );
383 Sequence< Any > aSeq( 2 );
384 aSeq[0] <<= bQuickstart;
385 aSeq[1] <<= bAutostart;
387 Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
388 ::rtl::OUString::createFromAscii( "com.sun.star.office.Quickstart" )),UNO_QUERY );
389 if ( xQuickstart.is() )
390 xQuickstart->initialize( aSeq );
392 aRet <<= sal_True;
394 else
396 // license was not accepted
397 // prepare termination
398 // m_bTerminate = sal_True;
399 // Application::PostUserEvent( STATIC_LINK( 0, License, Terminate ) );
400 aRet <<= sal_False;
403 catch (RuntimeException&)
405 // license could not be verified
406 aRet <<= sal_False;
408 return aRet;
411 void SAL_CALL License::close(sal_Bool /*bDeliverOwnership*/) throw (css::util::CloseVetoException)
413 if (!m_bTerminate)
414 throw CloseVetoException();
416 void SAL_CALL License::addCloseListener(const css::uno::Reference< css::util::XCloseListener >&)
417 throw (css::uno::RuntimeException)
420 void SAL_CALL License::removeCloseListener(const css::uno::Reference< css::util::XCloseListener >&)
421 throw (css::uno::RuntimeException)
426 //************************************************************************
427 // License Dialog
428 //************************************************************************
430 LicenseDialog::LicenseDialog(const ::rtl::OUString & aLicensePath, ResMgr *pResMgr) :
431 ModalDialog(NULL, ResId(DLG_LICENSE, *pResMgr)),
432 aLicenseML(this, ResId(ML_LICENSE, *pResMgr)),
433 aInfo1FT(this, ResId(FT_INFO1, *pResMgr)),
434 aInfo2FT(this, ResId(FT_INFO2, *pResMgr)),
435 aInfo3FT(this, ResId(FT_INFO3, *pResMgr)),
436 aInfo2_1FT(this, ResId(FT_INFO2_1, *pResMgr)),
437 aInfo3_1FT(this, ResId(FT_INFO3_1, *pResMgr)),
438 aFixedLine(this, ResId(FL_DIVIDE, *pResMgr)),
439 aPBPageDown(this, ResId(PB_PAGEDOWN, *pResMgr)),
440 aPBDecline( this, ResId(PB_DECLINE, *pResMgr) ),
441 aPBAccept( this, ResId(PB_ACCEPT, *pResMgr) ),
442 aArrow(this, ResId(IMG_ARROW, *pResMgr)),
443 aStrAccept( ResId(LICENSE_ACCEPT, *pResMgr) ),
444 aStrNotAccept( ResId(LICENSE_NOTACCEPT, *pResMgr) ),
445 bEndReached(FALSE)
447 FreeResource();
449 aLicenseML.SetEndReachedHdl( LINK(this, LicenseDialog, EndReachedHdl) );
450 aLicenseML.SetScrolledHdl( LINK(this, LicenseDialog, ScrolledHdl) );
452 aPBPageDown.SetClickHdl( LINK(this, LicenseDialog, PageDownHdl) );
453 aPBDecline.SetClickHdl( LINK(this, LicenseDialog, DeclineBtnHdl) );
454 aPBAccept.SetClickHdl( LINK(this, LicenseDialog, AcceptBtnHdl) );
456 // We want a automatic repeating page down button
457 WinBits aStyle = aPBPageDown.GetStyle();
458 aStyle |= WB_REPEAT;
459 aPBPageDown.SetStyle( aStyle );
461 String aText = aInfo2FT.GetText();
462 aText.SearchAndReplaceAll( UniString::CreateFromAscii("%PAGEDOWN"), aPBPageDown.GetText() );
463 aInfo2FT.SetText( aText );
465 aPBDecline.SetText( aStrNotAccept );
466 aPBAccept.SetText( aStrAccept );
468 aPBAccept.Disable();
470 // load license text
471 File aLicenseFile(aLicensePath);
472 if ( aLicenseFile.open(OpenFlag_Read) == FileBase::E_None)
474 DirectoryItem d;
475 DirectoryItem::get(aLicensePath, d);
476 FileStatus fs(FileStatusMask_FileSize);
477 d.getFileStatus(fs);
478 sal_uInt64 nBytesRead = 0;
479 sal_uInt64 nPosition = 0;
480 sal_uInt32 nBytes = (sal_uInt32)fs.getFileSize();
481 sal_Char *pBuffer = new sal_Char[nBytes];
482 // FileBase RC r = FileBase::E_None;
483 while (aLicenseFile.read(pBuffer+nPosition, nBytes-nPosition, nBytesRead) == FileBase::E_None
484 && nPosition + nBytesRead < nBytes)
486 nPosition += nBytesRead;
488 ::rtl::OUString aLicenseString(pBuffer, nBytes, RTL_TEXTENCODING_UTF8,
489 OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE);
490 delete[] pBuffer;
491 aLicenseML.SetText(aLicenseString);
496 LicenseDialog::~LicenseDialog()
500 IMPL_LINK( LicenseDialog, PageDownHdl, PushButton *, EMPTYARG )
502 aLicenseML.ScrollDown( SCROLL_PAGEDOWN );
503 return 0;
506 IMPL_LINK( LicenseDialog, EndReachedHdl, LicenseView *, EMPTYARG )
508 bEndReached = TRUE;
510 EnableControls();
512 return 0;
515 IMPL_LINK( LicenseDialog, ScrolledHdl, LicenseView *, EMPTYARG )
517 EnableControls();
519 return 0;
522 IMPL_LINK( LicenseDialog, DeclineBtnHdl, PushButton *, EMPTYARG )
524 EndDialog(0);
525 return 0;
527 IMPL_LINK( LicenseDialog, AcceptBtnHdl, PushButton *, EMPTYARG )
529 EndDialog(1);
530 return 0;
534 void LicenseDialog::EnableControls()
536 if( !bEndReached &&
537 ( aLicenseML.IsEndReached() || !aLicenseML.GetText().Len() ) )
538 bEndReached = TRUE;
540 if ( bEndReached )
542 Point aPos( aInfo1FT.GetPosPixel().X(),
543 aInfo3_1FT.GetPosPixel().Y() );
544 aArrow.SetPosPixel( aPos );
545 aPBAccept.Enable();
547 else
549 Point aPos( aInfo1FT.GetPosPixel().X(),
550 aInfo2_1FT.GetPosPixel().Y() );
551 aArrow.SetPosPixel( aPos );
552 aPBAccept.Disable();
555 if ( aLicenseML.IsEndReached() )
556 aPBPageDown.Disable();
557 else
558 aPBPageDown.Enable();
563 LicenseView::LicenseView( Window* pParent, const ResId& rResId )
564 : MultiLineEdit( pParent, rResId )
566 SetLeftMargin( 5 );
568 mbEndReached = IsEndReached();
570 StartListening( *GetTextEngine() );
573 LicenseView::~LicenseView()
575 maEndReachedHdl = Link();
576 maScrolledHdl = Link();
578 EndListeningAll();
581 void LicenseView::ScrollDown( ScrollType eScroll )
583 ScrollBar* pScroll = GetVScrollBar();
585 if ( pScroll )
586 pScroll->DoScrollAction( eScroll );
589 BOOL LicenseView::IsEndReached() const
591 BOOL bEndReached;
593 ExtTextView* pView = GetTextView();
594 ExtTextEngine* pEdit = GetTextEngine();
595 ULONG nHeight = pEdit->GetTextHeight();
596 Size aOutSize = pView->GetWindow()->GetOutputSizePixel();
597 Point aBottom( 0, aOutSize.Height() );
599 if ( (ULONG) pView->GetDocPos( aBottom ).Y() >= nHeight - 1 )
600 bEndReached = TRUE;
601 else
602 bEndReached = FALSE;
604 return bEndReached;
607 void LicenseView::Notify( SfxBroadcaster&, const SfxHint& rHint )
609 if ( rHint.IsA( TYPE(TextHint) ) )
611 BOOL bLastVal = EndReached();
612 ULONG nId = ((const TextHint&)rHint).GetId();
614 if ( nId == TEXT_HINT_PARAINSERTED )
616 if ( bLastVal )
617 mbEndReached = IsEndReached();
619 else if ( nId == TEXT_HINT_VIEWSCROLLED )
621 if ( ! mbEndReached )
622 mbEndReached = IsEndReached();
623 maScrolledHdl.Call( this );
626 if ( EndReached() && !bLastVal )
628 maEndReachedHdl.Call( this );
633 } // namespace framework