-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat: Add Yes/No to all for batch asset import #3052
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
02d59bc
4d51fd4
ca106b1
d84e797
dbf5ca2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,13 +1,10 @@ | ||||||
| // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) | ||||||
| // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. | ||||||
| using System; | ||||||
| using System.Collections.Generic; | ||||||
| using System.Collections.Specialized; | ||||||
| using System.IO; | ||||||
| using System.Linq; | ||||||
| using System.Threading; | ||||||
| using System.Threading.Tasks; | ||||||
| using System.Threading.Tasks.Dataflow; | ||||||
| using Stride.Core; | ||||||
| using Stride.Core.Annotations; | ||||||
| using Stride.Core.Assets.Analysis; | ||||||
| using Stride.Core.Assets.Editor.Components.AddAssets; | ||||||
| using Stride.Core.Assets.Editor.Components.Properties; | ||||||
|
|
@@ -19,8 +16,6 @@ | |||||
| using Stride.Core.Assets.Editor.ViewModel.Progress; | ||||||
| using Stride.Core.Assets.Templates; | ||||||
| using Stride.Core.Assets.Tracking; | ||||||
| using Stride.Core; | ||||||
| using Stride.Core.Annotations; | ||||||
| using Stride.Core.Diagnostics; | ||||||
| using Stride.Core.Extensions; | ||||||
| using Stride.Core.IO; | ||||||
|
|
@@ -30,9 +25,9 @@ | |||||
| using Stride.Core.Presentation.Dirtiables; | ||||||
| using Stride.Core.Presentation.Interop; | ||||||
| using Stride.Core.Presentation.Services; | ||||||
| using Stride.Core.Translation; | ||||||
| using Stride.Core.Presentation.ViewModels; | ||||||
| using System.Collections; | ||||||
| using Stride.Core.Presentation.Windows; | ||||||
| using Stride.Core.Translation; | ||||||
|
|
||||||
| namespace Stride.Core.Assets.Editor.ViewModel | ||||||
| { | ||||||
|
|
@@ -587,39 +582,103 @@ [new FilePickerFilter("") { Patterns = [file.GetFileExtension()]}], | |||||
|
|
||||||
| private async Task<List<AssetViewModel>> InvokeAddAssetTemplate(LoggerResult logger, string name, DirectoryBaseViewModel directory, TemplateAssetDescription templateDescription, [CanBeNull] IList<UFile> files, PropertyContainer? customParameters) | ||||||
| { | ||||||
| List<AssetViewModel> newAssets = new List<AssetViewModel>(); | ||||||
| const int DialogClosed = 0; | ||||||
| const int DialogYes = 1; | ||||||
| const int DialogNo = 2; | ||||||
| const int DialogYesToAll = 3; | ||||||
| const int DialogNoToAll = 4; | ||||||
|
|
||||||
| var newAssets = new List<AssetViewModel>(); | ||||||
| IReadOnlyList<DialogButtonInfo> copyPromptButtons = DialogHelper.CreateButtons(files is not null && files.Count > 1 ? | ||||||
| [ | ||||||
| Tr._p("Button", "Yes"), | ||||||
| Tr._p("Button", "No"), | ||||||
| Tr._p("Button", "Yes to all"), | ||||||
| Tr._p("Button", "No to all") | ||||||
| ] | ||||||
| : | ||||||
| [ | ||||||
| Tr._p("Button", "Yes"), | ||||||
| Tr._p("Button", "No") | ||||||
| ], 1, 2); | ||||||
|
|
||||||
| IReadOnlyList<DialogButtonInfo> overwritePromptButtons = DialogHelper.CreateButtons(files is not null && files.Count > 1 ? | ||||||
| [ | ||||||
| Tr._p("Button", "Yes"), | ||||||
| Tr._p("Button", "No"), | ||||||
| Tr._p("Button", "Yes to all") | ||||||
| ] | ||||||
| : | ||||||
| [ | ||||||
| Tr._p("Button", "Yes"), | ||||||
| Tr._p("Button", "No") | ||||||
| ], 1, 2); | ||||||
|
|
||||||
| var yesToAll = false; | ||||||
| var overwriteAll = false; | ||||||
| var finalPath = string.Empty; | ||||||
|
|
||||||
| if (files is not null) | ||||||
| { | ||||||
| for (int i = 0; i < files.Count; i++) | ||||||
| for (var i = 0; i < files.Count; i++) | ||||||
| { | ||||||
| var file = files[i]; | ||||||
| bool inResourceFolder = directory.Package.Package.ResourceFolders.Any(x => file.FullPath.StartsWith(x.FullPath, StringComparison.Ordinal)); | ||||||
| var inResourceFolder = directory.Package.Package.ResourceFolders.Any(x => file.FullPath.StartsWith(x.FullPath, StringComparison.Ordinal)); | ||||||
|
|
||||||
| if (inResourceFolder) | ||||||
| { | ||||||
| continue; | ||||||
| } | ||||||
|
|
||||||
| if (!yesToAll) | ||||||
| { | ||||||
| var message = Tr._p("Message", "Source file '{0}' is not inside of your project's resource folders, do you want to copy it?").ToFormat(file.FullPath); | ||||||
|
|
||||||
| var message = Tr._p("Message", "Source file '{0}' is not inside of your project's resource folders, do you want to copy it?").ToFormat(file.FullPath); | ||||||
| var copyResult = await Dialogs.MessageBoxAsync(message, copyPromptButtons, MessageBoxImage.Warning); | ||||||
|
|
||||||
| var copyResult = await Dialogs.MessageBoxAsync(message, MessageBoxButton.YesNo, MessageBoxImage.Warning); | ||||||
| if (copyResult is DialogClosed or DialogNo) | ||||||
| { | ||||||
| continue; | ||||||
| } | ||||||
|
|
||||||
| if (copyResult != MessageBoxResult.Yes) | ||||||
| continue; | ||||||
| if (copyResult is DialogNoToAll) | ||||||
| { | ||||||
| break; | ||||||
| } | ||||||
|
|
||||||
| if (copyResult is DialogYesToAll) | ||||||
| { | ||||||
| yesToAll = true; | ||||||
| } | ||||||
|
|
||||||
| string finalPath = await GetAssetCopyDirectory(directory, file); | ||||||
| if (copyResult is DialogYes or DialogYesToAll) | ||||||
| { | ||||||
| finalPath = await GetAssetCopyDirectory(directory, file); | ||||||
| } | ||||||
| } | ||||||
| else | ||||||
| { | ||||||
| // If "Yes to all" we're going to assume they want to use the same directory as the initial file. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a valid assumption? It sounds like it would flatten any hierarchy during the copy.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be misunderstanding, but I believe this assumption is valid as this is consistent with the current behavior. If you select No to the default location, and specify a directory in the window that pops up, it puts it right where you tell it to without sub folder generation vs saying Yes to the default, which puts it in Resources/subfolder |
||||||
| finalPath = Path.Combine(Path.GetDirectoryName(finalPath), file.GetFileName()); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not opposed to the change personally, my only hang up is that the rest of Stride uses Path.Combine. I could not find any uses of Path.Join in the code base, so I'm hesitant to deviate from that consistency.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Path.Join is newer, faster, and likely exhibits behavior closer to coder intentions. The primary difference between the two is:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While @ds5678 remark is valid, let's keep Path.Combine for now. We can explore Path.Join as a separate cleanup task throughout the whole codebase. |
||||||
| } | ||||||
|
|
||||||
| try | ||||||
| { | ||||||
| Directory.CreateDirectory(Path.GetDirectoryName(finalPath)); | ||||||
| if (File.Exists(finalPath)) | ||||||
| { | ||||||
| message = Tr._p("Message", "The file '{0}' already exists, it will get overwritten if you continue, do you really want to proceed?").ToFormat(finalPath); | ||||||
| if (!overwriteAll) | ||||||
| { | ||||||
| var message = Tr._p("Message", "The file '{0}' already exists, it will get overwritten if you continue, do you really want to proceed?").ToFormat(finalPath); | ||||||
|
|
||||||
| copyResult = await Dialogs.MessageBoxAsync(message, MessageBoxButton.YesNo, MessageBoxImage.Warning); | ||||||
| var copyResult = await Dialogs.MessageBoxAsync(message, overwritePromptButtons, MessageBoxImage.Warning); | ||||||
|
|
||||||
| // Abort if the user says no or closes the prompt | ||||||
| if (copyResult != MessageBoxResult.Yes) | ||||||
| { | ||||||
| return newAssets; | ||||||
| overwriteAll = copyResult is DialogYesToAll; | ||||||
|
|
||||||
| if (copyResult is DialogClosed or DialogNo) | ||||||
| { | ||||||
| return newAssets; | ||||||
| } | ||||||
| } | ||||||
| File.Copy(file.FullPath, finalPath, true); | ||||||
| } | ||||||
|
|
@@ -632,7 +691,7 @@ private async Task<List<AssetViewModel>> InvokeAddAssetTemplate(LoggerResult log | |||||
| } | ||||||
| catch (Exception ex) | ||||||
| { | ||||||
| message = Tr._p("Message", $"An error occurred while copying the asset to the resources folder : {ex.Message}"); | ||||||
| var message = Tr._p("Message", $"An error occurred while copying the asset to the resources folder : {ex.Message}"); | ||||||
| await Dialogs.MessageBoxAsync(message, MessageBoxButton.OK, MessageBoxImage.Error); | ||||||
| return newAssets; | ||||||
| } | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would produce mildly undesirable behavior when the user reaches the last file, by including the "to all" buttons.