private static void HandleDropForSource(DragDropEffects result) { System.Diagnostics.Debug.WriteLine($"HandleDropForSource: {result}"); dropInfo?.UpdateTargetContainerAndIndex(); if (result.HasFlag(DragDropEffects.Move)) { ToolWindowHistory.SaveStateAndPause(); foreach (var sourceItem in dragInfo.SourceItems) { var sourceCol = sourceItem.Parent; var idx = sourceCol.Items.IndexOf(sourceItem); if (Equals(sourceCol, dropInfo?.TargetContainer) && idx < dropInfo.InsertIndex) { dropInfo.InsertIndex--; } sourceItem.Parent.Items.RemoveAt(idx); } } if (dropInfo?.TargetItem != null) { HandleDropForTarget(result); } if (result.HasFlag(DragDropEffects.Move)) { ToolWindowHistory.Resume(); } }
public static void HandleDropForTarget(DragDropEffects result, DragEventArgs e = null) { System.Diagnostics.Debug.WriteLine($"HandleDropForTarget: {dropInfo.TargetItem.Item}"); IEnumerable <CmdBase> data = DropInfo.ExtractDropData(dragInfo, e); if (dropInfo.CanAcceptData(data) && (result.HasFlag(DragDropEffects.Move) || result.HasFlag(DragDropEffects.Copy))) { var idx = dropInfo.InsertIndex; if (result.HasFlag(DragDropEffects.Copy)) { data = data.Select(cmd => cmd.Copy()); } var dataList = data.ToList(); var souldDeselctItem = dropInfo.InsertPosition.HasFlag(DropInfo.RelativInsertPosition.IntoTargetItem) && dropInfo.TargetItem.Item is CmdContainer con && !con.IsExpanded; if (dataList.Count > 0) { ToolWindowHistory.SaveState(); } foreach (var sourceItem in dataList) { if (souldDeselctItem) { sourceItem.IsSelected = false; } dropInfo.TargetContainer.Insert(idx++, sourceItem); } var focusItem = dragInfo?.DirectSourceItem ?? dataList.FirstOrDefault(); var selectItemCommand = dropInfo.TargetItem.ParentTreeView.SelectItemCommand; if (souldDeselctItem) { selectItemCommand.SafeExecute(dropInfo.TargetItem.Item); } else if (selectItemCommand.SafeExecute(focusItem)) { foreach (var sourceItem in dataList) { sourceItem.IsSelected = true; } } } else { if (e != null) { e.Effects = DragDropEffects.None; } } dropInfo?.DropTargetAdorner?.Detach(); dropInfo = null; }
private void UpdateCommandsForProjectOnDispatcher(IVsHierarchy project, bool onlyIfVcsSupportEnabled) { Logger.Info($"Dispatching update commands function call"); JoinableTaskFactory.RunAsync(async delegate { // git branch and merge might lead to a race condition here. // If a branch is checkout where the json file differs, the // filewatcher will trigger an event which is dispatched here. // However, while the function call is queued VS may reopen the // solution due to changes. This will ultimately result in a // null ref exception because the project object is unloaded. // UpdateCommandsForProject() will skip such projects because // their guid is empty. await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (onlyIfVcsSupportEnabled && !IsVcsSupportEnabled) { return; } Logger.Info($"Dispatched update commands function call for project '{project.GetDisplayName()}'"); if (project.GetGuid() == Guid.Empty) { Logger.Info($"Race condition might occurred while dispatching update commands function call. Project is already unloaded."); } ToolWindowHistory.SaveState(); UpdateCommandsForProject(project); }); }
private void VsHelper_ProjectRenamed(object sender, VisualStudioHelper.ProjectAfterRenameEventArgs e) { Logger.Info($"VS-Event: Project '{e.OldProjectName}' renamed to '{e.Project.GetName()}'."); fileStorage.RenameProject(e.Project, e.OldProjectDir, e.OldProjectName, () => { ToolWindowHistory.SaveState(); UpdateCommandsForProject(e.Project); }); ToolWindowViewModel.RenameProject(e.Project); }
private void VsHelper_ProjectAdded(object sender, VisualStudioHelper.ProjectAfterOpenEventArgs e) { Logger.Info($"VS-Event: Project '{e.Project.GetName()}' added. (IsLoadProcess={e.IsLoadProcess}, IsSolutionOpenProcess={e.IsSolutionOpenProcess})"); if (e.IsSolutionOpenProcess) { return; } ToolWindowHistory.SaveState(); UpdateCommandsForProject(e.Project); fileStorage.AddProject(e.Project); }
private void OptionPage_VcsSupportChanged(object sender, bool enabled) { if (!enabled) { return; } ToolWindowHistory.SaveState(); foreach (var projectName in vsHelper.GetSupportedProjects()) { UpdateCommandsForProject(projectName); } }
private void FileStorage_FileStorageChanged(object sender, FileStorageChangedEventArgs e) { // This event is triggered on non-main thread! Logger.Info($"Dispatching update commands function call"); JoinableTaskFactory.RunAsync(async delegate { // git branch and merge might lead to a race condition here. // If a branch is checkout where the json file differs, the // filewatcher will trigger an event which is dispatched here. // However, while the function call is queued VS may reopen the // solution due to changes. This will ultimately result in a // null ref exception because the project object is unloaded. // UpdateCommandsForProject() will skip such projects because // their guid is empty. await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (!IsVcsSupportEnabled) { return; } ToolWindowHistory.SaveState(); IEnumerable <IVsHierarchy> projects; if (e.IsSolutionWide) { Logger.Info($"Dispatched update commands function calls for the solution."); projects = vsHelper.GetSupportedProjects(); } else { Logger.Info($"Dispatched update commands function call for project '{e.Project.GetDisplayName()}'"); projects = new[] { e.Project }; } foreach (var project in projects) { if (project.GetGuid() == Guid.Empty) { Logger.Info($"Race condition might occurred while dispatching update commands function call. Project is already unloaded."); } UpdateCommandsForProject(project); } }); }