/// ------------------------------------------------------------------------------------ public override void RenameAnnotatedFile(string newPath) { var oldPfsxFile = Path.ChangeExtension(PathToAnnotatedFile, ".pfsx"); base.RenameAnnotatedFile(newPath); AnnotationFileHelper.ChangeMediaFileName(PathToAnnotatedFile, GetPathToAssociatedMediaFile()); if (!File.Exists(oldPfsxFile)) { return; } var newPfsxFile = Path.ChangeExtension(PathToAnnotatedFile, ".pfsx"); File.Move(oldPfsxFile, newPfsxFile); if (_oralAnnotationFile != null) { _oralAnnotationFile.RenameAnnotatedFile(GetSuggestedPathToOralAnnotationFile()); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// The reason this is separate from the Id property is: 1) You're not supposed to do /// anything non-trivial in property accessors (like renaming folders) and 2) It may /// fail, and needs a way to indicate that to the caller. /// /// NB: at the moment, all the change is done immediately, so a Save() is needed to /// keep things consistent. We could imagine just making the change pending until /// the next Save. /// </summary> /// <returns>true if the change was possible and occurred</returns> /// ------------------------------------------------------------------------------------ public virtual bool TryChangeIdAndSave(string newId, out string failureMessage) { failureMessage = null; Save(); newId = newId.Trim(); if (_id == newId) { return(true); } if (newId == string.Empty) { failureMessage = NoIdSaveFailureMessage; return(false); } var parent = Directory.GetParent(FolderPath).FullName; string newFolderPath = Path.Combine(parent, newId); if (Directory.Exists(newFolderPath)) { failureMessage = string.Format(AlreadyExistsSaveFailureMessage, Id, newId); return(false); } try { //todo... need a way to make this all one big all or nothing transaction. As it is, some things can be //renamed and then we run into a snag, and we're left in a bad, inconsistent state. // for now, at least check for the very common situation where the rename of the // directory itself will fail, and find that out *before* we do the file renamings if (!CanPerformRename()) { failureMessage = LocalizationManager.GetString("CommonToMultipleViews.ChangeIdFailureMsg", "Something is holding onto that folder or a file in it, so it cannot be renamed. You can try restarting this program, or restarting the computer.", "Message displayed when attempt failed to change a session id or a person's name (i.e. id)"); return(false); } foreach (var file in Directory.GetFiles(FolderPath)) { var name = Path.GetFileName(file); if (name.ToLower().StartsWith(Id.ToLower())) // to be conservative, let's only trigger if it starts with the id { //todo: do a case-insensitive replacement //todo... this could over-replace var newFileName = Path.Combine(FolderPath, name.Replace(Id, newId)); File.Move(file, newFileName); if (Path.GetExtension(newFileName) == Settings.Default.AnnotationFileExtension) { // If the file just renamed is an annotation file (i.e. .eaf) then we // need to make sure the annotation file is updated internally so it's // pointing to the renamed media file. This fixes SP-399. var newMediaFileName = newFileName.Replace( AnnotationFileHelper.kAnnotationsEafFileSuffix, string.Empty); AnnotationFileHelper.ChangeMediaFileName(newFileName, newMediaFileName); } else if (Directory.Exists(file + Settings.Default.OralAnnotationsFolderSuffix)) { Directory.Move(file + Settings.Default.OralAnnotationsFolderSuffix, newFileName + Settings.Default.OralAnnotationsFolderSuffix); } } } Directory.Move(FolderPath, newFolderPath); } catch (Exception e) { failureMessage = ExceptionHelper.GetAllExceptionMessages(e); return(false); } var oldId = _id; _id = newId; Save(); if (IdChangedNotificationReceiver != null) { IdChangedNotificationReceiver(this, oldId, newId); } return(true); }