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