PageVersionExport.xaml.vb 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. Public Class PageVersionExport
  2. Private CurrentVer As String = ""
  3. Private Sub PageVersionExport_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
  4. Reload()
  5. End Sub
  6. Public ItemVersion As MyListItem
  7. Public Sub Reload()
  8. AniControlEnabled += 1
  9. If CurrentVer <> PageVersionLeft.Version.Path Then
  10. '说明切换到另一个版本了,所有的绝对路径都要重置,否则爆炸
  11. CurrentPath = ""
  12. Selected = New List(Of String)
  13. CurrentVer = PageVersionLeft.Version.Path
  14. End If
  15. TbExportName.ShowValidateResult = True
  16. TbExportName.ValidateRules = New ObjectModel.Collection(Of Validate) From {New ValidateFileName() With {.AllowNull = True}}
  17. TbExportName.Validate()
  18. TbExportName.HintText = PageVersionLeft.Version.Name
  19. TbExportDesc.HintText = PageVersionLeft.Version.Info
  20. PanDisplayItem.Children.Clear()
  21. ItemVersion = PageSelectRight.McVersionListItem(PageVersionLeft.Version.Load())
  22. ItemVersion.IsHitTestVisible = False
  23. If Not String.IsNullOrEmpty(CustomLogo) Then ItemVersion.Logo = CustomLogo
  24. PanDisplayItem.Children.Add(ItemVersion)
  25. ItemVersion.Title = If(String.IsNullOrWhiteSpace(TbExportName.Text), PageVersionLeft.Version.Name, TbExportName.Text)
  26. ItemVersion.Info = If(String.IsNullOrWhiteSpace(TbExportDesc.Text), PageVersionLeft.Version.Info, TbExportDesc.Text)
  27. #If BETA Then
  28. CheckIncludePCL.IsEnabled = True
  29. #Else
  30. CheckIncludePCL.IsEnabled = False
  31. TbHint.Text = "你可以在此勾选需要包含进整合包的文件或文件夹,其他文件或文件夹在高级选项添加。" & vbCrLf & "你当前的 PCL 不是正式版,有二次分发的限制,因此整合包不能包含 PCL 程序。"
  32. #End If
  33. CheckIncludeSetup.IsEnabled = CheckIncludePCL.IsEnabled
  34. ReloadFileList(CurrentPath)
  35. AniControlEnabled -= 1
  36. End Sub
  37. #Region "文件列表"
  38. ''' <summary>
  39. ''' 当前所在的文件夹。注意是绝对路径!以 \ 结尾。
  40. ''' </summary>
  41. Private CurrentPath As String = ""
  42. Private Sub ReloadFileList(Optional NewPath As String = "")
  43. If String.IsNullOrWhiteSpace(NewPath) Then NewPath = PageVersionLeft.Version.Path
  44. Dim tb As TextBlock = PanFileList.Children(0)
  45. PanFileList.Children.Clear()
  46. PanFileList.Children.Add(tb)
  47. If NewPath <> PageVersionLeft.Version.Path Then
  48. Dim listItem As New MyListItem With {.Title = "返回上一级目录", .Tag = "..", .Height = 35, .Type = MyListItem.CheckType.Clickable}
  49. AddHandler listItem.Click, AddressOf ListItem_Click
  50. PanFileList.Children.Add(listItem)
  51. End If
  52. Dim fileCount As Integer = 0
  53. For Each d In Directory.EnumerateDirectories(NewPath)
  54. If Directory.EnumerateFileSystemEntries(d).Count = 0 Then Continue For
  55. d = GetFolderNameFromPath(d)
  56. If IsVerRedundant(NewPath & d) OrElse IsMustExport(d) Then Continue For
  57. Dim title As String = ""
  58. Dim listItem As New MyListItem
  59. If Titles.TryGetValue(d, title) Then 'title 作为引用类型传入
  60. listItem.Title = title
  61. listItem.Info = d
  62. Else
  63. listItem.Title = d
  64. End If
  65. '图标按钮
  66. Dim btnSwap As New MyIconButton
  67. btnSwap.Logo = Logo.IconButtonRight
  68. btnSwap.LogoScale = 1.0
  69. btnSwap.Tag = d
  70. AddHandler btnSwap.Click, AddressOf BtnSwap_Click
  71. listItem.Buttons = {btnSwap}
  72. listItem.Type = MyListItem.CheckType.CheckBox
  73. listItem.Height = 35
  74. listItem.Logo = Logo.IconButtonOpen
  75. listItem.Tag = d & "\"
  76. Select Case IsSelected(NewPath & d & "\")
  77. Case 1
  78. listItem.Half = True
  79. Case 2
  80. listItem.Checked = True
  81. End Select
  82. AddHandler listItem.Click, AddressOf ListItem_Click
  83. PanFileList.Children.Add(listItem)
  84. fileCount += 1
  85. Next
  86. For Each f In Directory.EnumerateFiles(NewPath)
  87. f = GetFileNameFromPath(f)
  88. If IsVerRedundant(NewPath & f) OrElse IsMustExport(f) Then Continue For
  89. Dim title As String = ""
  90. Dim listItem As New MyListItem
  91. If Titles.TryGetValue(f, title) Then 'title 作为引用类型传入
  92. listItem.Title = title
  93. listItem.Info = f
  94. Else
  95. listItem.Title = f
  96. End If
  97. listItem.Type = MyListItem.CheckType.CheckBox
  98. listItem.Height = 35
  99. listItem.Tag = f
  100. listItem.Checked = (IsSelected(NewPath & f) = 2)
  101. AddHandler listItem.Click, AddressOf ListItem_Click
  102. PanFileList.Children.Add(listItem)
  103. fileCount += 1
  104. Next
  105. CurrentPath = NewPath
  106. CardMore.Title = If(NewPath = PageVersionLeft.Version.Path, "高级选项", $"高级选项 ({NewPath.Replace(PageVersionLeft.Version.Path, "").TrimEnd("\")})")
  107. End Sub
  108. Private Titles As New Dictionary(Of String, String) From {
  109. {"saves", "存档"},
  110. {"resourcepacks", "资源包"},
  111. {"config", "Mod 配置"},
  112. {"shaderpacks", "光影包"},
  113. {"options.txt", "游戏配置"},
  114. {"servers.dat", "服务器列表"}
  115. }
  116. Private Sub BtnSwap_Click(sender As MyIconButton, e As Object)
  117. Dim actualPath As String = CurrentPath & sender.Tag & "\"
  118. 'Dim relative As String = actualPath.Replace(PageVersionLeft.Version.Path, "")
  119. If Not Directory.Exists(actualPath) Then
  120. Hint($"找不到目录:{actualPath}", HintType.Critical)
  121. Exit Sub
  122. End If
  123. ReloadFileList(actualPath)
  124. End Sub
  125. ''' <summary>
  126. ''' 选中的文件列表,绝对路径。
  127. ''' </summary>
  128. Private Selected As New List(Of String)
  129. Private Sub SelectedChange(IsAdd As Boolean, TargetPath As String)
  130. If File.Exists(TargetPath) Then
  131. If IsAdd Then Selected.Add(TargetPath) Else Selected.Remove(TargetPath)
  132. Exit Sub
  133. End If
  134. If Directory.Exists(TargetPath) Then
  135. For Each d In Directory.EnumerateDirectories(TargetPath)
  136. SelectedChange(IsAdd, d)
  137. Next
  138. For Each f In Directory.EnumerateFiles(TargetPath)
  139. If IsAdd Then Selected.Add(f) Else Selected.Remove(f)
  140. Next
  141. End If
  142. Selected = Selected.Distinct().ToList()
  143. End Sub
  144. ''' <summary>
  145. ''' 获取 TargetPath 是否选中。
  146. ''' </summary>
  147. ''' <returns>全部未选中为 0,部分选中为 1,全部选中为 2。</returns>
  148. Private Function IsSelected(TargetPath As String, Optional AllowEmpty As Boolean = False) As Integer
  149. If File.Exists(TargetPath) Then
  150. Return If(Selected.Contains(TargetPath), 2, 0)
  151. End If
  152. If Directory.Exists(TargetPath) Then
  153. Dim di As New DirectoryInfo(TargetPath)
  154. If di.GetDirectories.Length + di.GetFiles.Length = 0 Then Return If(AllowEmpty, 2, 0)
  155. '如果有一个文件不在列表,则 hasExclude = True
  156. Dim hasExclude As Boolean = False
  157. '如果有一个文件在列表,则 hasTrue = True
  158. Dim hasInclude As Boolean = False
  159. For Each d In Directory.EnumerateDirectories(TargetPath)
  160. If Directory.EnumerateFileSystemEntries(d).Count = 0 Then Continue For
  161. Select Case IsSelected(d, True)
  162. Case 0
  163. hasExclude = True
  164. Case 1
  165. Return 1
  166. Case 2
  167. hasInclude = True
  168. End Select
  169. If hasInclude AndAlso hasExclude Then Return 1 '如果有文件在、有文件不在列表中,可以断定部分选中
  170. Next
  171. For Each f In Directory.EnumerateFiles(TargetPath)
  172. If Selected.Contains(f) Then hasInclude = True Else hasExclude = True
  173. If hasInclude AndAlso hasExclude Then Return 1 '如果有文件在、有文件不在列表中,可以断定部分选中
  174. Next
  175. If hasExclude AndAlso Not hasInclude Then Return 0
  176. If hasInclude AndAlso Not hasExclude Then Return 2
  177. End If
  178. Return 0
  179. End Function
  180. Private Sub ListItem_Click(sender As MyListItem, e As Object)
  181. If sender.Tag = ".." Then '回到上一级目录
  182. ReloadFileList(GetPathFromFullPath(CurrentPath))
  183. Exit Sub
  184. End If
  185. SelectedChange(Not sender.Checked, '非常难绷的逻辑,很难描述清楚,自己打断点看 Checked 属性值吧……
  186. CurrentPath & sender.Tag)
  187. End Sub
  188. 'Private ReadOnly Property Saves As List(Of String)
  189. ' Get
  190. ' If Directory.Exists(PageVersionLeft.Version.Path & "saves\") Then
  191. ' Return Directory.EnumerateDirectories(PageVersionLeft.Version.Path & "saves\").ToList
  192. ' End If
  193. ' Return New List(Of String)
  194. ' End Get
  195. 'End Property
  196. '复选框与高级选项同步
  197. Private Sub PanCommonFiles_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles PanCommonFiles.MouseLeftButtonUp
  198. For Each c In PanCommonFiles.Children
  199. If TypeOf c IsNot MyCheckBox Then Continue For
  200. If String.IsNullOrEmpty(c.Tag) Then Continue For
  201. For Each l In PanFileList.Children
  202. If TypeOf l Is MyListItem Then
  203. If l.Tag.Replace("\", "") = c.Tag Then
  204. l.Checked = c.Checked
  205. SelectedChange(c.Checked, PageVersionLeft.Version.Path & c.Tag)
  206. End If
  207. End If
  208. Next
  209. Next
  210. End Sub
  211. '高级选项与复选框同步
  212. Private Sub PanFileList_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles PanFileList.MouseLeftButtonUp
  213. For Each c In PanCommonFiles.Children
  214. If TypeOf c Is MyCheckBox Then
  215. c.Checked = (IsSelected(PageVersionLeft.Version.Path & c.Tag) = 2)
  216. End If
  217. Next
  218. End Sub
  219. #End Region
  220. #Region "整合包信息 & 预览栏"
  221. Private Sub TbExportName_TextChanged(sender As MyTextBox, e As TextChangedEventArgs) Handles TbExportName.TextChanged
  222. If String.IsNullOrEmpty(TbExportName.ValidateResult) Then
  223. ItemVersion.Title = If(String.IsNullOrWhiteSpace(sender.Text), PageVersionLeft.Version.Name, sender.Text)
  224. End If
  225. End Sub
  226. Private Sub TbExportDesc_TextChanged(sender As MyTextBox, e As TextChangedEventArgs) Handles TbExportDesc.TextChanged
  227. ItemVersion.Info = If(String.IsNullOrWhiteSpace(sender.Text), PageVersionLeft.Version.Info, sender.Text)
  228. End Sub
  229. Private CustomLogoVal As String
  230. ''' <summary>
  231. ''' 自定义 Logo 的路径。
  232. ''' </summary>
  233. Public Property CustomLogo() As String
  234. Get
  235. Return CustomLogoVal
  236. End Get
  237. Set(value As String)
  238. If AniControlEnabled <> 0 Then Exit Property
  239. CustomLogoVal = value
  240. ItemVersion.Logo = value
  241. Reload()
  242. End Set
  243. End Property
  244. Private Sub ComboDisplayLogo_SelectionChanged(sender As MyComboBox, e As SelectionChangedEventArgs) Handles ComboDisplayLogo.SelectionChanged
  245. If Not AniControlEnabled = 0 Then Exit Sub
  246. '选择 自定义 时修改图片
  247. If ComboDisplayLogo.SelectedItem Is ItemDisplayLogoCustom Then
  248. Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif", "选择图片")
  249. If String.IsNullOrWhiteSpace(FileName) Then Exit Sub
  250. CustomLogo = FileName
  251. Else
  252. CustomLogo = sender.SelectedItem.Tag
  253. End If
  254. End Sub
  255. #End Region
  256. #Region "基本信息"
  257. Private Sub CheckIncludePCL_Change(sender As Object, user As Boolean) Handles CheckIncludePCL.Change
  258. CheckIncludeSetup.IsEnabled = CheckIncludePCL.IsEnabled
  259. End Sub
  260. #End Region
  261. #Region "导出"
  262. 'Private Sub ComboExportType_Change(sender As ComboBox, e As SelectionChangedEventArgs) Handles ComboExportType.SelectionChanged
  263. ' If AniControlEnabled <> 0 Then Exit Sub
  264. ' Type = sender.SelectedIndex
  265. ' Select Case Type
  266. ' Case ModpackType.Modrinth
  267. ' If IncludePCL() Then 'TODO:修改这里的条件
  268. ' If GridCompressed IsNot Nothing Then GridCompressed.Visibility = Visibility.Visible
  269. ' If GridModrinth IsNot Nothing Then GridModrinth.Visibility = Visibility.Collapsed
  270. ' Else
  271. ' If GridCompressed IsNot Nothing Then GridCompressed.Visibility = Visibility.Collapsed
  272. ' If GridModrinth IsNot Nothing Then GridModrinth.Visibility = Visibility.Visible
  273. ' End If
  274. ' End Select
  275. ' CardExport.TriggerForceResize()
  276. 'End Sub
  277. Private Sub BtnExportExport_Click() Handles BtnExportExport.Click
  278. Dim savePath As String = SelectAs(
  279. "选择导出位置", $"整合包 - {If(String.IsNullOrWhiteSpace(TbExportName.Text), PageVersionLeft.Version.Name, TbExportName.Text)}" & If(CheckIncludePCL.Checked, ".zip", ".mrpack"),
  280. If(CheckIncludePCL.Checked, "整合包文件(*.zip)|*.zip", "Modrinth 整合包(*.mrpack)|*.mrpack"))
  281. If String.IsNullOrEmpty(savePath) Then Exit Sub
  282. '获取需要包含的文件
  283. Dim contains As List(Of String) = Selected
  284. For Each c In PanCommonFiles.Children
  285. If TypeOf c IsNot MyCheckBox Then Continue For
  286. If String.IsNullOrEmpty(c.Tag) Then Continue For
  287. If c.Checked Then contains.Add(PageVersionLeft.Version.Path & c.Tag)
  288. Next
  289. ModpackExport(New ExportOptions(PageVersionLeft.Version, savePath, CheckIncludePCL.Checked, contains.Distinct.ToArray,
  290. PCLSetupGlobal:=CheckIncludeSetup.Checked, Name:=TbExportName.Text, VerID:=TbExportVersion.Text))
  291. End Sub
  292. #End Region
  293. End Class