@@ -184,11 +184,8 @@ public static class FPM
184184 ? Path . Combine ( Path . GetPathRoot ( AppDomain . CurrentDomain . BaseDirectory ) , "Flashpoint" )
185185 : Path . GetFullPath ( Path . Combine ( Directory . GetCurrentDirectory ( ) , ".." ) ) ;
186186
187- // Flag to control how operation window will function
188- // 0 is for adding/removing components
189- // 1 is for updating components
190- public static int OperateMode { get ; set ; } = 0 ;
191-
187+ // Controls whether components are being updated instead of added or removed
188+ public static bool UpdateMode { get ; set ; } = false ;
192189 // Controls whether the update tab is selected at launch
193190 public static bool OpenUpdateTab { get ; set ; } = false ;
194191 // Controls which component (if any) will be automatically downloaded at launch
@@ -266,40 +263,27 @@ public static TreeNode AddNodeToList(XmlNode child, TreeNodeCollection parent)
266263
267264 listNode . Text = component . Title ;
268265 listNode . Name = component . ID ;
266+ listNode . Tag = component ;
269267
270- if ( component . Required )
271- {
272- listNode . ForeColor = Color . FromArgb ( 255 , 96 , 96 , 96 ) ;
273- }
274-
275- listNode . Tag = component ;
268+ if ( component . Required ) listNode . ForeColor = Color . FromArgb ( 255 , 96 , 96 , 96 ) ;
276269 }
277270 else if ( child . Name == "category" )
278271 {
279272 var category = new Category ( child ) ;
280273
281274 listNode . Text = category . Title ;
282275 listNode . Name = category . ID ;
276+ listNode . Tag = category ;
283277
284- if ( category . Required )
285- {
286- listNode . ForeColor = Color . FromArgb ( 255 , 96 , 96 , 96 ) ;
287- }
288-
289- listNode . Tag = category ;
278+ if ( category . Required ) listNode . ForeColor = Color . FromArgb ( 255 , 96 , 96 , 96 ) ;
290279 }
291280
292281 parent . Add ( listNode ) ;
293-
294- // Initialize checkbox
295- // (the Checked attribute needs to be explicitly set or else the checkbox won't appear)
296- listNode . Checked = false ;
297-
298282 return listNode ;
299283 }
300284
301- // Refreshes tracker objects with up-to-date information
302- public static void SyncManager ( bool updateLists = false )
285+ // Refreshes component lists and tracker objects with up-to-date information
286+ public static void SyncManager ( )
303287 {
304288 ComponentTracker . Downloaded . Clear ( ) ;
305289 ComponentTracker . ToUpdate . Clear ( ) ;
@@ -309,20 +293,86 @@ public static void SyncManager(bool updateLists = false)
309293 if ( node . Tag . GetType ( ) . ToString ( ) . EndsWith ( "Component" ) )
310294 {
311295 var component = node . Tag as Component ;
312- string infoPath = Path . Combine ( SourcePath , "Components" , $ "{ component . ID } .txt") ;
313296
314- if ( File . Exists ( infoPath ) )
297+ if ( File . Exists ( Path . Combine ( SourcePath , "Components" , $ " { component . ID } .txt" ) ) )
315298 {
316299 ComponentTracker . Downloaded . Add ( component ) ;
317- if ( updateLists ) node . Checked = true ;
300+ node . Checked = true ;
301+ }
302+ else
303+ {
304+ node . Checked = false ;
318305 }
319306 }
320307 } ) ;
321308
322- if ( updateLists )
309+ Main . UpdateList . Items . Clear ( ) ;
310+ Main . UpdateButton . Text = "Install updates" ;
311+
312+ long totalSizeChange = 0 ;
313+
314+ void AddToQueue ( Component component , long oldSize )
315+ {
316+ long sizeChange = component . Size - oldSize ;
317+ totalSizeChange += sizeChange ;
318+
319+ string displayedSize = GetFormattedBytes ( sizeChange ) ;
320+ if ( displayedSize [ 0 ] != '-' ) displayedSize = "+" + displayedSize ;
321+
322+ var item = new ListViewItem ( ) ;
323+ item . Text = component . Title ;
324+ item . SubItems . Add ( component . Description ) ;
325+ item . SubItems . Add ( component . LastUpdated ) ;
326+ item . SubItems . Add ( displayedSize ) ;
327+ Main . UpdateList . Items . Add ( item ) ;
328+
329+ ComponentTracker . ToUpdate . Add ( component ) ;
330+ }
331+
332+ IterateXML ( XmlTree . GetElementsByTagName ( "list" ) [ 0 ] . ChildNodes , node =>
333+ {
334+ if ( node . Name != "component" ) return ;
335+
336+ var component = new Component ( node ) ;
337+
338+ bool update = false ;
339+ long oldSize = 0 ;
340+
341+ if ( ComponentTracker . Downloaded . Any ( item => item . ID == component . ID ) )
342+ {
343+ string infoFile = Path . Combine ( SourcePath , "Components" , $ "{ component . ID } .txt") ;
344+ string [ ] componentData = File . ReadLines ( infoFile ) . First ( ) . Split ( ' ' ) ;
345+
346+ update = componentData [ 0 ] != component . Hash ;
347+ oldSize = long . Parse ( componentData [ 1 ] ) ;
348+ }
349+ else if ( component . ID . StartsWith ( "required" ) )
350+ {
351+ update = true ;
352+ }
353+
354+ if ( update )
355+ {
356+ AddToQueue ( component , oldSize ) ;
357+
358+ foreach ( string dependID in component . Depends )
359+ {
360+ if ( ! ComponentTracker . Downloaded . Any ( item => item . ID == dependID ) )
361+ {
362+ var query = Main . ComponentList . Nodes . Find ( dependID , true ) ;
363+ if ( query . Length > 0 ) AddToQueue ( query [ 0 ] . Tag as Component , 0 ) ;
364+ }
365+ }
366+ }
367+ } ) ;
368+
369+ if ( ComponentTracker . ToUpdate . Count > 0 )
370+ {
371+ Main . UpdateButton . Enabled = true ;
372+ Main . UpdateButton . Text += $ " ({ GetFormattedBytes ( totalSizeChange ) } )";
373+ }
374+ else
323375 {
324- Main . UpdateList . Items . Clear ( ) ;
325- Main . UpdateButton . Text = "Install updates" ;
326376 Main . UpdateButton . Enabled = false ;
327377 }
328378
@@ -339,11 +389,11 @@ public static void DeleteFileAndDirectories(string file)
339389
340390 string folder = Path . GetDirectoryName ( file ) ;
341391
342- while ( folder != SourcePath )
392+ while ( folder != Directory . GetParent ( SourcePath ) . ToString ( ) )
343393 {
344394 if ( Directory . Exists ( folder ) && ! Directory . EnumerateFileSystemEntries ( folder ) . Any ( ) )
345395 {
346- Directory . Delete ( folder , false ) ;
396+ Directory . Delete ( folder ) ;
347397 }
348398 else break ;
349399
@@ -383,14 +433,14 @@ public static void VerifySourcePath()
383433 }
384434
385435 // Checks if any dependencies were not marked for download by the user, and marks them accordingly
386- public static bool CheckDependencies ( TreeView sourceTree )
436+ public static bool CheckDependencies ( )
387437 {
388438 List < string > requiredDepends = new List < string > ( ) ;
389439 List < string > persistDepends = new List < string > ( ) ;
390440 List < string > missingDepends = new List < string > ( ) ;
391441
392442 // First, fill out a list of dependencies
393- IterateList ( sourceTree . Nodes , node =>
443+ IterateList ( Main . ComponentList . Nodes , node =>
394444 {
395445 if ( node . Checked && node . Tag . GetType ( ) . ToString ( ) . EndsWith ( "Component" ) )
396446 {
@@ -409,7 +459,7 @@ public static bool CheckDependencies(TreeView sourceTree)
409459 } ) ;
410460
411461 // Then make sure they're all marked for installation
412- IterateList ( sourceTree . Nodes , node =>
462+ IterateList ( Main . ComponentList . Nodes , node =>
413463 {
414464 if ( node . Tag . GetType ( ) . ToString ( ) . EndsWith ( "Component" ) )
415465 {
0 commit comments