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 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_desktop.hxx" 26 27 #include <migration.hxx> 28 #include "wizard.hxx" 29 #include "wizard.hrc" 30 #include "pages.hxx" 31 #include "app.hxx" 32 33 #include <rtl/ustring.hxx> 34 #include <rtl/ustrbuf.hxx> 35 #include <rtl/string.hxx> 36 #include <rtl/strbuf.hxx> 37 #include <rtl/bootstrap.hxx> 38 39 #include <comphelper/processfactory.hxx> 40 #include <tools/date.hxx> 41 #include <tools/time.hxx> 42 #include <tools/datetime.hxx> 43 #include <osl/file.hxx> 44 #include <osl/time.h> 45 #include <osl/module.hxx> 46 #include <unotools/bootstrap.hxx> 47 #include <vcl/msgbox.hxx> 48 49 #include <com/sun/star/uno/Any.hxx> 50 #include <com/sun/star/uno/Sequence.hxx> 51 #include <com/sun/star/beans/NamedValue.hpp> 52 #include <com/sun/star/beans/XPropertySet.hpp> 53 #include <com/sun/star/beans/XPropertyState.hpp> 54 #include <com/sun/star/frame/XDesktop.hpp> 55 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 56 #include <com/sun/star/lang/XInitialization.hpp> 57 #include <com/sun/star/lang/XComponent.hpp> 58 #include <com/sun/star/util/XChangesBatch.hpp> 59 #include <com/sun/star/container/XNameReplace.hpp> 60 #include <com/sun/star/awt/WindowDescriptor.hpp> 61 #include <com/sun/star/awt/WindowAttribute.hpp> 62 63 using namespace svt; 64 using namespace rtl; 65 using namespace osl; 66 using namespace utl; 67 using namespace com::sun::star; 68 using namespace com::sun::star::uno; 69 using namespace com::sun::star::lang; 70 using namespace com::sun::star::beans; 71 using namespace com::sun::star::util; 72 using namespace com::sun::star::container; 73 74 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) 75 76 namespace desktop 77 { 78 79 const FirstStartWizard::WizardState FirstStartWizard::STATE_WELCOME = 0; 80 const FirstStartWizard::WizardState FirstStartWizard::STATE_LICENSE = 1; 81 const FirstStartWizard::WizardState FirstStartWizard::STATE_MIGRATION = 2; 82 const FirstStartWizard::WizardState FirstStartWizard::STATE_USER = 3; 83 const FirstStartWizard::WizardState FirstStartWizard::STATE_UPDATE_CHECK = 4; 84 const FirstStartWizard::WizardState FirstStartWizard::STATE_REGISTRATION = 5; 85 86 static sal_Int32 getBuildId() 87 { 88 ::rtl::OUString aDefault; 89 ::rtl::OUString aBuildIdData = utl::Bootstrap::getBuildIdData( aDefault ); 90 sal_Int32 nBuildId( 0 ); 91 sal_Int32 nIndex1 = aBuildIdData.indexOf(':'); 92 sal_Int32 nIndex2 = aBuildIdData.indexOf(')'); 93 if (( nIndex1 > 0 ) && ( nIndex2 > 0 ) && ( nIndex2-1 > nIndex1+1 )) 94 { 95 ::rtl::OUString aBuildId = aBuildIdData.copy( nIndex1+1, nIndex2-nIndex1-1 ); 96 nBuildId = aBuildId.toInt32(); 97 } 98 return nBuildId; 99 } 100 101 WizardResId::WizardResId( sal_uInt16 nId ) : 102 ResId( nId, *FirstStartWizard::GetResManager() ) 103 { 104 } 105 106 ResMgr *FirstStartWizard::pResMgr = 0; 107 108 ResMgr *FirstStartWizard::GetResManager() 109 { 110 if ( !FirstStartWizard::pResMgr ) 111 FirstStartWizard::pResMgr = ResMgr::CreateResMgr( "dkt"); 112 return FirstStartWizard::pResMgr; 113 } 114 115 FirstStartWizard::FirstStartWizard( Window* pParent, sal_Bool bLicenseNeedsAcceptance, const rtl::OUString &rLicensePath ) 116 :RoadmapWizard( pParent, 117 WizardResId(DLG_FIRSTSTART_WIZARD), 118 WZB_NEXT|WZB_PREVIOUS|WZB_FINISH|WZB_CANCEL|WZB_HELP) 119 ,m_bOverride(sal_False) 120 , m_lastState( STATE_WELCOME ) 121 ,m_aDefaultPath(0) 122 ,m_aMigrationPath(0) 123 ,m_bDone(sal_False) 124 ,m_bLicenseNeedsAcceptance( bLicenseNeedsAcceptance ) 125 ,m_bLicenseWasAccepted(sal_False) 126 ,m_bAutomaticUpdChk(sal_True) 127 ,m_aThrobber(this, WizardResId(CTRL_THROBBER)) 128 ,m_aLicensePath( rLicensePath ) 129 { 130 FreeResource(); 131 132 Size aTPSize(TP_WIDTH, TP_HEIGHT); 133 SetPageSizePixel(LogicToPixel(aTPSize, MAP_APPFONT)); 134 135 //set help id 136 m_pPrevPage->SetHelpId(HID_FIRSTSTART_PREV); 137 m_pNextPage->SetHelpId(HID_FIRSTSTART_NEXT); 138 m_pCancel->SetHelpId(HID_FIRSTSTART_CANCEL); 139 m_pFinish->SetHelpId(HID_FIRSTSTART_FINISH); 140 m_pHelp->Hide(); 141 m_pHelp->Disable(); 142 143 // save button lables 144 m_sNext = m_pNextPage->GetText(); 145 m_sCancel = m_pCancel->GetText(); 146 147 // save cancel click handler 148 m_lnkCancel = m_pCancel->GetClickHdl(); 149 150 m_aDefaultPath = defineWizardPagesDependingFromContext(); 151 activatePath(m_aDefaultPath, sal_True); 152 153 ActivatePage(); 154 155 // set text of finish putton: 156 m_pFinish->SetText(String(WizardResId(STR_FINISH))); 157 // disable "finish button" 158 enableButtons(WZB_FINISH, sal_False); 159 defaultButton(WZB_NEXT); 160 } 161 162 void FirstStartWizard::DisableButtonsWhileMigration() 163 { 164 enableButtons(0xff, sal_False); 165 } 166 167 ::svt::RoadmapWizardTypes::PathId FirstStartWizard::defineWizardPagesDependingFromContext() 168 { 169 ::svt::RoadmapWizardTypes::PathId aDefaultPath = 0; 170 171 sal_Bool bPage_Migration = sal_True; 172 sal_Bool bPage_UpdateCheck = sal_True; 173 174 bPage_Migration = Migration::checkMigration(); 175 bPage_UpdateCheck = showOnlineUpdatePage(); 176 177 WizardPath aPath; 178 aPath.push_back(STATE_WELCOME); 179 if (bPage_Migration) 180 { 181 aPath.push_back(STATE_MIGRATION); 182 } 183 aPath.push_back(STATE_USER); 184 m_lastState = STATE_USER; 185 if (bPage_UpdateCheck) 186 { 187 aPath.push_back(STATE_UPDATE_CHECK); 188 m_lastState = STATE_UPDATE_CHECK; 189 } 190 191 declarePath(aDefaultPath, aPath); 192 193 // a) If license must be accepted by the user, all direct links 194 // to wizard tab pages must be disabled. Because such pages 195 // should be accessible only in case license was accepted ! 196 // b) But if no license should be shown at all ... 197 // such direct links can be enabled by default. 198 sal_Bool bAllowDirectLink = true; 199 200 enableState(STATE_USER, bAllowDirectLink); 201 if (bPage_Migration) 202 enableState(STATE_MIGRATION, bAllowDirectLink); 203 if (bPage_UpdateCheck) 204 enableState(STATE_UPDATE_CHECK, bAllowDirectLink); 205 206 return aDefaultPath; 207 } 208 209 // catch F1 and disable help 210 long FirstStartWizard::PreNotify( NotifyEvent& rNEvt ) 211 { 212 if( rNEvt.GetType() == EVENT_KEYINPUT ) 213 { 214 const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode(); 215 if( rKey.GetCode() == KEY_F1 && ! rKey.GetModifier() ) 216 return sal_True; 217 } 218 return RoadmapWizard::PreNotify(rNEvt); 219 } 220 221 222 void FirstStartWizard::enterState(WizardState _nState) 223 { 224 RoadmapWizard::enterState(_nState); 225 // default state 226 // all on 227 enableButtons(0xff, sal_True); 228 // finish off 229 enableButtons(WZB_FINISH, sal_False); 230 // default text 231 m_pCancel->SetText(m_sCancel); 232 m_pCancel->SetClickHdl(m_lnkCancel); 233 m_pNextPage->SetText(m_sNext); 234 235 // default 236 defaultButton(WZB_NEXT); 237 238 // specialized state 239 switch (_nState) 240 { 241 case STATE_WELCOME: 242 enableButtons(WZB_PREVIOUS, sal_False); 243 break; 244 case STATE_LICENSE: 245 m_pCancel->SetText(String(WizardResId(STR_LICENSE_DECLINE))); 246 m_pNextPage->SetText(String(WizardResId(STR_LICENSE_ACCEPT))); 247 enableButtons(WZB_NEXT, sal_False); 248 // attach warning dialog to cancel/decline button 249 m_pCancel->SetClickHdl( LINK(this, FirstStartWizard, DeclineHdl) ); 250 break; 251 } 252 if ( _nState == m_lastState ) 253 { 254 enableButtons(WZB_NEXT, sal_False); 255 enableButtons(WZB_FINISH, sal_True); 256 defaultButton(WZB_FINISH); 257 } 258 } 259 260 IMPL_LINK( FirstStartWizard, DeclineHdl, PushButton *, EMPTYARG ) 261 { 262 QueryBox aBox(this, WizardResId(QB_ASK_DECLINE)); 263 sal_Int32 ret = aBox.Execute(); 264 if ( ret == BUTTON_OK || ret == BUTTON_YES) 265 { 266 Close(); 267 return sal_False; 268 } 269 else 270 return sal_True; 271 } 272 273 274 TabPage* FirstStartWizard::createPage(WizardState _nState) 275 { 276 TabPage *pTabPage = 0; 277 switch (_nState) 278 { 279 case STATE_WELCOME: 280 pTabPage = new WelcomePage(this, WizardResId(TP_WELCOME), m_bLicenseNeedsAcceptance); 281 break; 282 case STATE_MIGRATION: 283 pTabPage = new MigrationPage(this, WizardResId(TP_MIGRATION), m_aThrobber); 284 break; 285 case STATE_USER: 286 pTabPage = new UserPage(this, WizardResId(TP_USER)); 287 break; 288 case STATE_UPDATE_CHECK: 289 pTabPage = new UpdateCheckPage(this, WizardResId(TP_UPDATE_CHECK)); 290 break; 291 } 292 pTabPage->Show(); 293 294 return pTabPage; 295 } 296 297 String FirstStartWizard::getStateDisplayName( WizardState _nState ) const 298 { 299 String sName; 300 switch(_nState) 301 { 302 case STATE_WELCOME: 303 sName = String(WizardResId(STR_STATE_WELCOME)); 304 break; 305 case STATE_MIGRATION: 306 sName = String(WizardResId(STR_STATE_MIGRATION)); 307 break; 308 case STATE_USER: 309 sName = String(WizardResId(STR_STATE_USER)); 310 break; 311 case STATE_UPDATE_CHECK: 312 sName = String(WizardResId(STR_STATE_UPDATE_CHECK)); 313 break; 314 } 315 return sName; 316 } 317 318 sal_Bool FirstStartWizard::prepareLeaveCurrentState( CommitPageReason _eReason ) 319 { 320 // the license acceptance is handled here, because it needs to change the state 321 // of the roadmap wizard which the page implementation does not know. 322 if ( 323 (_eReason == eTravelForward) && 324 (getCurrentState() == STATE_LICENSE ) && 325 (m_bLicenseWasAccepted == sal_False ) 326 ) 327 { 328 if (Migration::checkMigration()) 329 enableState(FirstStartWizard::STATE_MIGRATION, sal_True); 330 if ( showOnlineUpdatePage() ) 331 enableState(FirstStartWizard::STATE_UPDATE_CHECK, sal_True); 332 enableState(FirstStartWizard::STATE_USER, sal_True); 333 enableState(FirstStartWizard::STATE_REGISTRATION, sal_True); 334 335 storeAcceptDate(); 336 m_bLicenseWasAccepted = sal_True; 337 } 338 339 return svt::RoadmapWizard::prepareLeaveCurrentState(_eReason); 340 } 341 342 sal_Bool FirstStartWizard::leaveState(WizardState) 343 { 344 if (( getCurrentState() == STATE_MIGRATION ) && m_bLicenseWasAccepted ) 345 { 346 // Store accept date and patch level now as it has been 347 // overwritten by the migration process! 348 storeAcceptDate(); 349 setPatchLevel(); 350 } 351 352 return sal_True; 353 } 354 355 sal_Bool FirstStartWizard::onFinish() 356 { 357 return svt::RoadmapWizard::onFinish(); 358 } 359 360 short FirstStartWizard::Execute() 361 { 362 return svt::RoadmapWizard::Execute(); 363 } 364 365 static OUString _makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_False) 366 { 367 OStringBuffer aDateTimeString; 368 aDateTimeString.append((sal_Int32)aDateTime.GetYear()); 369 aDateTimeString.append("-"); 370 if (aDateTime.GetMonth()<10) aDateTimeString.append("0"); 371 aDateTimeString.append((sal_Int32)aDateTime.GetMonth()); 372 aDateTimeString.append("-"); 373 if (aDateTime.GetDay()<10) aDateTimeString.append("0"); 374 aDateTimeString.append((sal_Int32)aDateTime.GetDay()); 375 aDateTimeString.append("T"); 376 if (aDateTime.GetHour()<10) aDateTimeString.append("0"); 377 aDateTimeString.append((sal_Int32)aDateTime.GetHour()); 378 aDateTimeString.append(":"); 379 if (aDateTime.GetMin()<10) aDateTimeString.append("0"); 380 aDateTimeString.append((sal_Int32)aDateTime.GetMin()); 381 aDateTimeString.append(":"); 382 if (aDateTime.GetSec()<10) aDateTimeString.append("0"); 383 aDateTimeString.append((sal_Int32)aDateTime.GetSec()); 384 if (bUTC) aDateTimeString.append("Z"); 385 386 return OStringToOUString(aDateTimeString.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); 387 } 388 389 static OUString _getCurrentDateString() 390 { 391 OUString aString; 392 return _makeDateTimeString(DateTime()); 393 } 394 395 396 static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) ); 397 static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) ); 398 static const OUString sReadSrvc ( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ); 399 400 void FirstStartWizard::storeAcceptDate() 401 { 402 403 try { 404 Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); 405 // get configuration provider 406 Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >( 407 xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW); 408 Sequence< Any > theArgs(1); 409 NamedValue v(OUString::createFromAscii("NodePath"), 410 makeAny(OUString::createFromAscii("org.openoffice.Setup/Office"))); 411 theArgs[0] <<= v; 412 Reference< XPropertySet > pset = Reference< XPropertySet >( 413 theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW); 414 Any result = pset->getPropertyValue(OUString::createFromAscii("LicenseAcceptDate")); 415 416 OUString aAcceptDate = _getCurrentDateString(); 417 pset->setPropertyValue(OUString::createFromAscii("LicenseAcceptDate"), makeAny(aAcceptDate)); 418 Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges(); 419 420 // since the license is accepted the local user registry can be cleaned if required 421 cleanOldOfficeRegKeys(); 422 } catch (const Exception&) 423 { 424 } 425 426 } 427 428 void FirstStartWizard::setPatchLevel() 429 { 430 try { 431 Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); 432 // get configuration provider 433 Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >( 434 xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW); 435 Sequence< Any > theArgs(1); 436 NamedValue v(OUString::createFromAscii("NodePath"), 437 makeAny(OUString::createFromAscii("org.openoffice.Office.Common/Help/Registration"))); 438 theArgs[0] <<= v; 439 Reference< XPropertySet > pset = Reference< XPropertySet >( 440 theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW); 441 Any result = pset->getPropertyValue(OUString::createFromAscii("ReminderDate")); 442 443 OUString aPatchLevel( RTL_CONSTASCII_USTRINGPARAM( "Patch" )); 444 aPatchLevel += OUString::valueOf( getBuildId(), 10 ); 445 pset->setPropertyValue(OUString::createFromAscii("ReminderDate"), makeAny(aPatchLevel)); 446 Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges(); 447 } catch (const Exception&) 448 { 449 } 450 } 451 452 #ifdef WNT 453 typedef int ( __stdcall * CleanCurUserRegProc ) ( wchar_t* ); 454 #endif 455 456 void FirstStartWizard::cleanOldOfficeRegKeys() 457 { 458 #ifdef WNT 459 // after the wizard is completed clean OOo1.1.x entries in the current user registry if required 460 // issue i47658 461 462 OUString aBaseLocationPath; 463 OUString aSharedLocationPath; 464 OUString aInstallMode; 465 466 ::utl::Bootstrap::PathStatus aBaseLocateResult = 467 ::utl::Bootstrap::locateBaseInstallation( aBaseLocationPath ); 468 ::utl::Bootstrap::PathStatus aSharedLocateResult = 469 ::utl::Bootstrap::locateSharedData( aSharedLocationPath ); 470 aInstallMode = ::utl::Bootstrap::getAllUsersValue( ::rtl::OUString() ); 471 472 // TODO: replace the checking for install mode 473 if ( aBaseLocateResult == ::utl::Bootstrap::PATH_EXISTS && aSharedLocateResult == ::utl::Bootstrap::PATH_EXISTS 474 && aInstallMode.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1" ) ) ) ) 475 { 476 ::rtl::OUString aDeregCompletePath = 477 aBaseLocationPath + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/regcleanold.dll" ) ); 478 ::rtl::OUString aExecCompletePath = 479 aSharedLocationPath + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/regdeinstall/userdeinst.exe" ) ); 480 481 osl::Module aCleanModule( aDeregCompletePath ); 482 CleanCurUserRegProc pNativeProc = ( CleanCurUserRegProc )( 483 aCleanModule.getFunctionSymbol( 484 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CleanCurUserOldSystemRegistry" ) ) ) ); 485 486 if( pNativeProc!=NULL ) 487 { 488 ::rtl::OUString aExecCompleteSysPath; 489 if ( osl::File::getSystemPathFromFileURL( aExecCompletePath, aExecCompleteSysPath ) == FileBase::E_None 490 && aExecCompleteSysPath.getLength() ) 491 { 492 ( *pNativeProc )( (wchar_t*)( aExecCompleteSysPath.getStr() ) ); 493 } 494 } 495 } 496 #endif 497 } 498 499 sal_Bool FirstStartWizard::showOnlineUpdatePage() 500 { 501 try { 502 Reference < XNameReplace > xUpdateAccess; 503 Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); 504 505 xUpdateAccess = Reference < XNameReplace >( 506 xFactory->createInstance( UNISTRING( "com.sun.star.setup.UpdateCheckConfig" ) ), UNO_QUERY_THROW ); 507 508 if ( xUpdateAccess.is() ) 509 { 510 sal_Bool bAutoUpdChk = sal_False; 511 Any result = xUpdateAccess->getByName( UNISTRING( "AutoCheckEnabled" ) ); 512 result >>= bAutoUpdChk; 513 if ( bAutoUpdChk == sal_False ) 514 return sal_True; 515 else 516 return sal_False; 517 } 518 } catch (const Exception&) 519 { 520 } 521 return sal_False; 522 } 523 524 } 525