Пример #1
0
        public RepositoryDiff(MainWindow mainWindow, FooSyncEngine foo, SyncGroup syncGroup)
        {
            InitializeComponent();

            _actionBoxes = new Dictionary<Guid, ComboBox>();
            _mainWindow = mainWindow;
            _foo = foo;
            _syncGroup = syncGroup;
            _repoStates = null;
            _trees = null;
            _changeSet = null;
            _diffData = null;

            _updatingActionBox = new Dictionary<Guid, bool>();
        }
Пример #2
0
        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;
                }
            ));
        }