@@ -404,69 +404,89 @@ def __init__(self, parent):
404404
405405 def onCreatePortable (self , evt ):
406406 if not self .portableDirectoryEdit .Value :
407- # Translators: The message displayed when the user has not specified a destination directory
408- # in the Create Portable NVDA dialog.
409- gui .messageBox (_ ("Please specify a directory in which to create the portable copy." ),
410- _ ("Error" ),
411- wx .OK | wx .ICON_ERROR )
412- return
413- if not os .path .isabs (self .portableDirectoryEdit .Value ):
414407 gui .messageBox (
415- # Translators: The message displayed when the user has not specified an absolute destination directory
416- # in the Create Portable NVDA dialog.
417- _ ("Please specify an absolute path (including drive letter) in which to create the portable copy." ),
418- # Translators: The message title displayed
419- # when the user has not specified an absolute destination directory
408+ # Translators: The message displayed when the user has not specified a destination directory
420409 # in the Create Portable NVDA dialog.
410+ _ ("Please specify a directory in which to create the portable copy." ),
411+ # Translators: the title of an error dialog.
421412 _ ("Error" ),
422413 wx .OK | wx .ICON_ERROR
423414 )
424415 return
425- drv = os .path .splitdrive (self .portableDirectoryEdit .Value )[0 ]
426- if drv and not os .path .isdir (drv ):
427- # Translators: The message displayed when the user specifies an invalid destination drive
428- # in the Create Portable NVDA dialog.
429- gui .messageBox (_ ("Invalid drive %s" )% drv ,
416+ expandedPortableDirectory = os .path .expandvars (self .portableDirectoryEdit .Value )
417+ if not os .path .isabs (expandedPortableDirectory ):
418+ gui .messageBox (
419+ _ (
420+ # Translators: The message displayed when the user has not specified an absolute destination directory
421+ # in the Create Portable NVDA dialog.
422+ "Please specify the absolute path where the portable copy should be created. "
423+ "It may include system variables (%temp%, %homepath%, etc.)."
424+ ),
425+ # Translators: The message title displayed when the user has not specified an absolute
426+ # destination directory in the Create Portable NVDA dialog.
430427 _ ("Error" ),
431- wx .OK | wx .ICON_ERROR )
428+ wx .OK | wx .ICON_ERROR
429+ )
432430 return
431+ # We used to separate out the drive letter, check it, and present an error if it was not
432+ # its own directory, as a secondary check of path absoluteness.
433+ # But if os.path.isabs is convinced, we should just add the drive letter if missing, and carry on. (#14681)
434+ expandedPortableDirectory = os .path .abspath (expandedPortableDirectory )
433435 self .Hide ()
434- doCreatePortable (self .portableDirectoryEdit .Value ,self .copyUserConfigCheckbox .Value ,False ,self .startAfterCreateCheckbox .Value )
436+ doCreatePortable (
437+ expandedPortableDirectory ,
438+ self .copyUserConfigCheckbox .Value ,
439+ False ,
440+ self .startAfterCreateCheckbox .Value
441+ )
435442 self .Destroy ()
436443
437444 def onCancel (self , evt ):
438445 self .Destroy ()
439446
440- def doCreatePortable (portableDirectory ,copyUserConfig = False ,silent = False ,startAfterCreate = False ):
441- d = gui .IndeterminateProgressDialog (gui .mainFrame ,
442- # Translators: The title of the dialog presented while a portable copy of NVDA is bieng created.
447+ def doCreatePortable (
448+ portableDirectory : str ,
449+ copyUserConfig : bool = False ,
450+ silent : bool = False ,
451+ startAfterCreate : bool = False
452+ ) -> None :
453+ d = gui .IndeterminateProgressDialog (
454+ gui .mainFrame ,
455+ # Translators: The title of the dialog presented while a portable copy of NVDA is being created.
443456 _ ("Creating Portable Copy" ),
444- # Translators: The message displayed while a portable copy of NVDA is bieng created.
445- _ ("Please wait while a portable copy of NVDA is created." ))
457+ # Translators: The message displayed while a portable copy of NVDA is being created.
458+ _ ("Please wait while a portable copy of NVDA is created." )
459+ )
446460 try :
447- gui .ExecAndPump (installer .createPortableCopy ,portableDirectory ,copyUserConfig )
461+ gui .ExecAndPump (installer .createPortableCopy , portableDirectory , copyUserConfig )
448462 except Exception as e :
449- log .error ("Failed to create portable copy" ,exc_info = True )
463+ log .error ("Failed to create portable copy" , exc_info = True )
450464 d .done ()
451- if isinstance (e ,installer .RetriableFailure ):
465+ if isinstance (e , installer .RetriableFailure ):
452466 # Translators: a message dialog asking to retry or cancel when NVDA portable copy creation fails
453- message = _ ("NVDA is unable to remove or overwrite a file." )
467+ message = _ ("NVDA is unable to remove or overwrite a file." )
454468 # Translators: the title of a retry cancel dialog when NVDA portable copy creation fails
455- title = _ ("File in Use" )
456- if winUser .MessageBox (None ,message ,title ,winUser .MB_RETRYCANCEL )== winUser .IDRETRY :
457- return doCreatePortable (portableDirectory ,copyUserConfig ,silent ,startAfterCreate )
458- # Translators: The message displayed when an error occurs while creating a portable copy of NVDA.
459- # %s will be replaced with the specific error message.
460- gui .messageBox (_ ("Failed to create portable copy: %s" )% e ,
469+ title = _ ("File in Use" )
470+ if winUser .MessageBox (None , message , title , winUser .MB_RETRYCANCEL ) == winUser .IDRETRY :
471+ return doCreatePortable (portableDirectory , copyUserConfig , silent , startAfterCreate )
472+ gui .messageBox (
473+ # Translators: The message displayed when an error occurs while creating a portable copy of NVDA.
474+ # {error} will be replaced with the specific error message.
475+ _ ("Failed to create portable copy: {error}." ).format (error = e ),
476+ # Translators: Title of an error dialog shown when an error occurs while creating a portable copy of NVDA.
461477 _ ("Error" ),
462- wx .OK | wx .ICON_ERROR )
478+ wx .OK | wx .ICON_ERROR
479+ )
463480 return
464481 d .done ()
465482 if not silent :
466- # Translators: The message displayed when a portable copy of NVDA has been successfully created.
467- # %s will be replaced with the destination directory.
468- gui .messageBox (_ ("Successfully created a portable copy of NVDA at %s" )% portableDirectory ,
469- _ ("Success" ))
483+ gui .messageBox (
484+ # Translators: The message displayed when a portable copy of NVDA has been successfully created.
485+ # {dir} will be replaced with the destination directory.
486+ _ ("Successfully created a portable copy of NVDA at {dir}" ).format (dir = portableDirectory ),
487+ # Translators: Title of a dialog shown when a portable copy of NVDA is created.
488+ _ ("Success" )
489+ )
470490 if silent or startAfterCreate :
471491 newNVDA = None
472492 if startAfterCreate :
0 commit comments