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