예제 #1
0
        public void OpenGroup(DocumentGroup group)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            if (group == null)
            {
                return;
            }

            if (group.Positions != null)
            {
                using (var stream = new VsOleStream())
                {
                    stream.Write(group.Positions, 0, group.Positions.Length);
                    stream.Seek(0, SeekOrigin.Begin);

                    var hr = DocumentWindowMgr.ReopenDocumentWindows(stream);
                    if (hr != VSConstants.S_OK)
                    {
                        Debug.Assert(false, "ReopenDocumentWindows", String.Empty, hr);
                    }
                }
            }

            try
            {
                var missingFiles = new List <string>();
                var openFiles    = Package.Environment.GetDocumentFiles();
                foreach (var file in group.Files)
                {
                    if (File.Exists(file))
                    {
                        if (!openFiles.Any(f => string.Compare(f, file, true) == 0))
                        {
                            OpenFile(file);
                        }
                    }
                    else
                    {
                        missingFiles.Add(file);
                    }
                }

                if (missingFiles.Count > 0)
                {
                    MessageBox.Show("The following files could not be found and were not restored:\n\n"
                                    + String.Join("\n", missingFiles), "SaveAllTheTabs");
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Windows for the solution were restored, but an error occurred while opening external files.\n\n" + nameof(OpenGroup), ex.ToString());
            }
        }
예제 #2
0
        public void CloseGroup(DocumentGroup group)
        {
            if (group?.Files == null)
            {
                return;
            }

            var documents = from d in Package.Environment.GetDocuments()
                            where @group.Files.Contains(d.FullName)
                            select d;

            documents.CloseAll();
        }
예제 #3
0
        public void SetGroupSlot(DocumentGroup group, int slot)
        {
            if (group == null || group.Slot == slot)
            {
                return;
            }

            var resident = Groups.FindBySlot(slot);

            group.Slot = slot;

            if (resident != null)
            {
                resident.Slot = null;
            }
        }
예제 #4
0
        private void TrySetSlot(DocumentGroup group, int?slot)
        {
            if (!slot.HasValue || !(slot <= SlotMax) || group.Slot == slot)
            {
                return;
            }

            // Find out if there is an existing item in the desired slot
            var resident = Groups.FindBySlot((int)slot);

            if (resident != null)
            {
                resident.Slot = null;
            }

            group.Slot = slot;
        }
예제 #5
0
        private List <DocumentGroup> LoadGroupsForSolution()
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            var solution = SolutionName;
            List <DocumentGroup> groups = new List <DocumentGroup>();

            if (string.IsNullOrWhiteSpace(solution))
            {
                return(groups);
            }

            try
            {
                var settingsMgr = new ShellSettingsManager(ServiceProvider);
                var store       = settingsMgr.GetReadOnlySettingsStore(SettingsScope.UserSettings);

                string projectKeyHash   = GetHashString(solution);
                string projectGroupsKey = string.Format(ProjectGroupsKeyPlaceholder, projectKeyHash);

                if (!store.CollectionExists(projectGroupsKey))
                {
                    // try load tabs from older versions
                    var propertyName = String.Format(SavedTabsStoragePropertyFormat, solution);
                    if (store.PropertyExists(StorageCollectionPath, propertyName))
                    {
                        var tabs = store.GetString(StorageCollectionPath, propertyName);
                        groups = JsonConvert.DeserializeObject <List <DocumentGroup> >(tabs);
                    }

                    return(groups);
                }

                var groupProperties = store.GetPropertyNamesAndValues(projectGroupsKey);
                foreach (var groupProperty in groupProperties)
                {
                    DocumentGroup group = JsonConvert.DeserializeObject <DocumentGroup>(groupProperty.Value.ToString());
                    groups.Add(group);
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, nameof(LoadGroupsForSolution), ex.ToString());
            }

            return(groups);
        }
예제 #6
0
        public void RestoreGroup(DocumentGroup group)
        {
            if (group == null)
            {
                return;
            }

            var windows = Package.Environment.GetDocumentWindows();

            if (!IsUndoGroup(group.Name) && windows.Any())
            {
                SaveUndoGroup();
            }

            Package.Environment.Documents.CloseAll();

            OpenGroup(group);
        }
예제 #7
0
        public void RemoveGroup(DocumentGroup group, bool confirm = true)
        {
            if (group == null)
            {
                return;
            }

            if (confirm)
            {
                var window = new ConfirmDeleteTabsWindow(group.Name);
                if (window.ShowDialog() == false)
                {
                    return;
                }
            }

            SaveUndoGroup(group);
            Groups.Remove(group);
        }
예제 #8
0
        public void OpenGroup(DocumentGroup group)
        {
            if (group == null)
            {
                return;
            }

            using (var stream = new VsOleStream())
            {
                stream.Write(group.Positions, 0, group.Positions.Length);
                stream.Seek(0, SeekOrigin.Begin);

                var hr = DocumentWindowMgr.ReopenDocumentWindows(stream);
                if (hr != VSConstants.S_OK)
                {
                    Debug.Assert(false, "ReopenDocumentWindows", String.Empty, hr);
                }
            }
        }
예제 #9
0
        private static void StartEditing(ListView list, ListViewItem item, DocumentGroup group, Action <TextBox, bool> endEditingFn)
        {
            var edit = item.FindDescendant <TextBox>();

            var visibility = Observable.FromEventPattern <DependencyPropertyChangedEventArgs>(edit, "IsVisibleChanged");

            var disposables = new CompositeDisposable();

            visibility.Where(re => re.EventArgs.NewValue as bool? == false)
            .Take(1)
            .Subscribe(re => disposables.Dispose());

            visibility.Where(ivc => ivc.EventArgs.NewValue as bool? == true)
            .Take(1)
            .Subscribe(re =>
            {
                edit.SelectionStart  = 0;
                edit.SelectionLength = edit.Text.Length;
                edit.Focus();
            });

            disposables.Add(Observable.FromEventPattern <RoutedEventArgs>(edit, "LostFocus")
                            .Take(1)
                            .Subscribe(re => endEditingFn(edit, false)));

            disposables.Add(Observable.FromEventPattern <KeyEventArgs>(edit, "PreviewKeyUp")
                            .Where(re => re.EventArgs.Key == Key.Escape || re.EventArgs.Key == Key.Enter)
                            .Take(1)
                            .Subscribe(re =>
            {
                re.EventArgs.Handled = true;
                endEditingFn(edit, re.EventArgs.Key == Key.Escape);
            }));

            disposables.Add(Observable.FromEventPattern <MouseEventArgs>(list, "MouseLeftButtonDown")
                            .Take(1)
                            .Subscribe(re => endEditingFn(edit, false)));

            group.StartEditing();
        }
예제 #10
0
        public void RestoreGroup(DocumentGroup group)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            if (group == null)
            {
                return;
            }

            var windows = Package.Environment.GetDocumentWindows();

            if (!IsUndoGroup(group.Name) && windows.Any())
            {
                SaveUndoGroup();
            }

            if (windows.Any())
            {
                windows.CloseAll();
            }

            OpenGroup(group);
        }
예제 #11
0
        private void SaveUndoGroup(DocumentGroup group)
        {
            var undo = Groups.FindByName(UndoGroupName);

            if (undo == null)
            {
                undo = new DocumentGroup
                {
                    Name        = UndoGroupName,
                    Description = group.Description,
                    Files       = group.Files,
                    Positions   = group.Positions
                };

                Groups.Insert(0, undo);
            }
            else
            {
                undo.Description = group.Description;
                undo.Files       = group.Files;
                undo.Positions   = group.Positions;
            }
        }
예제 #12
0
        public void MoveGroup(DocumentGroup group, int delta)
        {
            if (group == null || group.IsBuiltIn)
            {
                return;
            }

            var index    = Groups.IndexOf(group);
            var newIndex = index + delta;

            if (newIndex < 0 || newIndex >= Groups.Count)
            {
                return;
            }

            var resident = Groups[newIndex];

            if (resident?.IsBuiltIn == true)
            {
                return;
            }

            Groups.Move(index, newIndex);
        }
예제 #13
0
        public void SaveGroup(string name, int?slot = null)
        {
            if (DocumentWindowMgr == null)
            {
                Debug.Assert(false, "IVsUIShellDocumentWindowMgr", String.Empty, 0);
                return;
            }

            if (!Package.Environment.GetDocumentWindows().Any())
            {
                return;
            }

            var isBuiltIn = IsBuiltInGroup(name);

            if (isBuiltIn)
            {
                slot = null;
            }

            var group = Groups.FindByName(name);

            var files = new DocumentFilesHashSet(Package.Environment.GetDocumentFiles().OrderBy(Path.GetFileName));

            //var bps = Package.Environment.GetMatchingBreakpoints(files, StringComparer.OrdinalIgnoreCase));

            using (var stream = new VsOleStream())
            {
                var hr = DocumentWindowMgr.SaveDocumentWindowPositions(0, stream);
                if (hr != VSConstants.S_OK)
                {
                    Debug.Assert(false, "SaveDocumentWindowPositions", String.Empty, hr);

                    if (group != null)
                    {
                        Groups.Remove(group);
                    }
                    return;
                }
                stream.Seek(0, SeekOrigin.Begin);

                var documents = String.Join(", ", files.Select(Path.GetFileName));

                if (group == null)
                {
                    group = new DocumentGroup
                    {
                        Name        = name,
                        Description = documents,
                        Files       = files,
                        Positions   = stream.ToArray()
                    };

                    TrySetSlot(group, slot);
                    if (isBuiltIn)
                    {
                        Groups.Insert(0, group);
                    }
                    else
                    {
                        Groups.Add(group);
                    }
                }
                else
                {
                    SaveUndoGroup(group);

                    group.Description = documents;
                    group.Files       = files;
                    group.Positions   = stream.ToArray();

                    TrySetSlot(group, slot);
                }
            }
        }