public void InspectWorkingThread() { _trees = new Dictionary<Guid, FooTree>(); _repoStates = new List<RepositoryStateCollection>(); Progress.ValueChanged += new RoutedPropertyChangedEventHandler<double>((object sender, RoutedPropertyChangedEventArgs<double> args) => { _mainWindow.TaskbarItemInfo.ProgressValue = args.NewValue / 100; } ); // // Get RepositoryStateCollection and FooTree for each URL in the sync group. // foreach (FooSyncUrl url in _syncGroup.URLs) { RepositoryStateCollection currentStateColl; NetClient client; FooTree tree; Dispatcher.Invoke(new Action(() => { _mainWindow.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Indeterminate; Progress.IsIndeterminate = true; ProgressText.Text = "Getting Repository State..."; DetailText1.Text = url.NaturalFormat; DetailText2.Text = string.Empty; } )); if (url.IsLocal) { try { currentStateColl = new RepositoryStateCollection(Path.Combine(url.LocalPath, FooSyncEngine.RepoStateFileName)); } catch (FileNotFoundException) { currentStateColl = new RepositoryStateCollection(); } catch (DirectoryNotFoundException ex) { MessageBox.Show(string.Format("Something's wrong: {0}\nI can't continue!", ex.Message), "Directory Not Found", MessageBoxButton.OK, MessageBoxImage.Error); throw; } DateTime last = DateTime.Now; tree = new FooTree( MainWindow.Foo, url.LocalPath, FooSyncEngine.PrepareExceptions(_syncGroup.IgnorePatterns.OfType<IIgnorePattern>().ToList()), new Progress((current, total, path) => { if ((DateTime.Now - last).Milliseconds > ProgressUpdateRateMsecs) { last = DateTime.Now; Dispatcher.Invoke(new Action(() => { _mainWindow.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Indeterminate; Progress.IsIndeterminate = true; ProgressText.Text = "Enumerating Files..."; DetailText1.Text = string.Format("{0} files so far", current); DetailText2.Text = Path.Combine(url.LocalPath, Path.GetDirectoryName(path)); } )); } } )); if (currentStateColl.Repositories.Count == 0) { currentStateColl.AddRepository(tree, currentStateColl.RepositoryID); } } else { try { client = new NetClient(MainWindow.Foo, url.Host, url.Port, "WRFDEV", "WRFDEV", url.AbsolutePath.Substring(1)); currentStateColl = client.GetState(); DateTime last = DateTime.Now; tree = client.GetTree(new Progress((current, total, path) => { if ((DateTime.Now - last).Milliseconds > ProgressUpdateRateMsecs) { last = DateTime.Now; Dispatcher.Invoke(new Action(() => { _mainWindow.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Indeterminate; Progress.IsIndeterminate = true; ProgressText.Text = "Enumerating Files..."; DetailText1.Text = string.Format("{0} files so far", current); DetailText2.Text = Path.GetDirectoryName(path); } )); } } )); } catch (Exception ex) { Dispatcher.Invoke(new Action(() => { _mainWindow.TaskbarItemInfo.ProgressValue = 1.0; _mainWindow.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Error; } )); MessageBox.Show(string.Format("Error: {0} ({1})", ex.Message, ex.GetType().Name), "Error Getting Remote Repository", MessageBoxButton.OK, MessageBoxImage.Error); currentStateColl = null; tree = null; } } if (currentStateColl != null && tree != null) { _repoStates.Add(currentStateColl); _trees.Add(currentStateColl.RepositoryID, tree); } } // // We want to operate on the oldest repository state collection, so get that one now. // RepositoryStateCollection bestStateColl = _repoStates.OrderBy(s => s.Modified).First(); // // Now update all of them to have information on any trees they don't yet have. // This updates their Modified property, hence why newestStateColl is figured out first. // foreach (RepositoryStateCollection stateColl in _repoStates) { foreach (KeyValuePair<Guid, FooTree> treePair in _trees) { if (!stateColl.Repositories.Any(statePair => statePair.Key == treePair.Key)) { stateColl.AddRepository(treePair.Value, treePair.Key); } } } // // Diff! // Dispatcher.Invoke(new Action(() => { _mainWindow.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Normal; Progress.IsIndeterminate = false; ProgressText.Text = "Inspecting Files..."; } )); DateTime lastUpdate = DateTime.Now; _changeSet = _foo.Inspect(bestStateColl, _trees, new Progress((current, total, name) => { if ((DateTime.Now - lastUpdate).Milliseconds > ProgressUpdateRateMsecs) { lastUpdate = DateTime.Now; Dispatcher.Invoke(new Action(() => { Progress.Maximum = total; Progress.Value = current; DetailText1.Text = string.Format("{0:##0.00}%", (double)current / total * 100); DetailText2.Text = name; _mainWindow.TaskbarItemInfo.ProgressValue = (double)current / total; } )); } } )); _changeSet.SetDefaultActions(_trees); // // Convert the changeset into data structures for display. // DictionaryItemPickerConverter converter = new DictionaryItemPickerConverter(); IEnumerable<string> fileOperations = EnumMethods.GetEnumDescriptions(typeof(FileOperation)); //foreach (KeyValuePair<Guid, FooTree> pair in trees) IEnumerator<KeyValuePair<Guid, FooTree>> treeEnum = _trees.GetEnumerator(); for (int i = 0; treeEnum.MoveNext(); i++) { FooSyncUrl url = treeEnum.Current.Value.Base; Guid repoId = treeEnum.Current.Key; Dispatcher.Invoke(new Action(() => { ((GridView)DiffGrid.View).Columns.Add(new GridViewColumn() { Header = string.Format(" {0} ", url.IsLocal ? url.LocalPath : url.ToString()), DisplayMemberBinding = new Binding() { Converter = converter, ConverterParameter = repoId, Path = new PropertyPath("CombinedStatus"), }, }); ActionsPanel.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto }); Label header = new Label(); header.Content = string.Format(" {0} ", url.IsLocal ? url.LocalPath : url.ToString()); ActionsPanel.Children.Add(header); Grid.SetRow(header, 0); Grid.SetColumn(header, i + 1); ComboBox actionBox = new ComboBox(); actionBox.ItemsSource = fileOperations; actionBox.SelectionChanged += new SelectionChangedEventHandler(actionBox_SelectionChanged); _updatingActionBox.Add(repoId, false); actionBox.Tag = repoId; ActionsPanel.Children.Add(actionBox); Grid.SetRow(actionBox, 1); Grid.SetColumn(actionBox, i + 1); _actionBoxes.Add(repoId, actionBox); } )); } _diffData = new RepositoryDiffData(); foreach (string filename in _changeSet) { RepositoryDiffDataItem item = new RepositoryDiffDataItem(); item.Filename = filename; if (_changeSet[filename].ConflictStatus != ConflictStatus.NoConflict) { item.State = RepositoryDiffDataItem.ConflictState; } else { FooChangeSetElem changeElem = _changeSet[filename]; if (changeElem.ChangeStatus.Any(e => e.Value == ChangeStatus.New)) { item.State = RepositoryDiffDataItem.AddedState; } else if (changeElem.ChangeStatus.Any(e => e.Value == ChangeStatus.Deleted)) { item.State = RepositoryDiffDataItem.DeletedState; } else if (changeElem.ChangeStatus.Any(e => e.Value == ChangeStatus.Changed)) { item.State = RepositoryDiffDataItem.ChangedState; } } foreach (Guid repoId in _changeSet.RepositoryIDs) { item.ChangeStatus.Add(repoId, _changeSet[filename].ChangeStatus[repoId]); item.FileOperation.Add(repoId, _changeSet[filename].FileOperation[repoId]); } _diffData.Add(item); } // // Display // Dispatcher.Invoke(new Action(() => { _mainWindow.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.None; ProgressView.Visibility = Visibility.Collapsed; DiffGrid.ItemsSource = _diffData; DiffGrid.Visibility = Visibility.Visible; ActionsPanel.Visibility = Visibility.Visible; } )); }
/// <summary> /// Handle a Repository State request /// /// Gets a path from the stream, then writes a return code, the size of the state data, /// and then invokes RepositoryState.Write (which writes the same way it does to a file). /// </summary> private void HandleStateRequest() { var repoName = _reader.ReadString(); var repo = _config.Repositories[repoName]; if (repo == null || !Directory.Exists(repo.Path)) { _writer.Write(RetCode.BadPath); return; } if (repo.Users.Count(u => u.Name == _userName || u.Name == AnonymousUsername) == 0) { _writer.Write(RetCode.BadAuth); return; } var stateFile = Path.Combine( repo.Path, FooSyncEngine.RepoStateFileName ); if (!File.Exists(stateFile)) { RepositoryStateCollection state = new RepositoryStateCollection(); state.AddRepository(new FooTree(_foo, repo.Path), state.RepositoryID); state.Write(stateFile); } _writer.Write(RetCode.Success); using (var statestream = new FileStream(stateFile, FileMode.Open)) { _writer.Write(statestream.Length); statestream.CopyTo(_stream); } }