/// <summary>
        /// Repositions the specified item into the specified base.
        /// </summary>
        /// <param name="itemToMove">The item to move.</param>
        /// <param name="baseItem">The base item.</param>
        private void RepositionItemIntoBase(BaseCodeItem itemToMove, ICodeItemParent baseItem)
        {
            if (itemToMove == baseItem) return;

            bool padWithNewLine = _insertBlankLinePaddingLogic.ShouldInstanceBeFollowedByBlankLine(itemToMove);
            int cursorOffset;
            var text = GetTextAndRemoveItem(itemToMove, out cursorOffset);

            baseItem.RefreshCachedPositionAndName();
            var baseInsertPoint = baseItem.InsertPoint;
            var pastePoint = baseInsertPoint.CreateEditPoint();

            pastePoint.Insert(text);
            pastePoint.Insert(Environment.NewLine);
            if (padWithNewLine)
            {
                pastePoint.Insert(Environment.NewLine);
            }

            pastePoint.EndOfLine();
            baseInsertPoint.SmartFormat(pastePoint);

            if (cursorOffset >= 0)
            {
                baseInsertPoint.Parent.Selection.MoveToAbsoluteOffset(baseInsertPoint.AbsoluteCharOffset + cursorOffset);
            }

            itemToMove.RefreshCachedPositionAndName();
            baseItem.RefreshCachedPositionAndName();
        }
        /// <summary>
        /// Gets the text and removes the specified item.
        /// </summary>
        /// <param name="itemToRemove">The item to remove.</param>
        /// <param name="cursorOffset">
        /// The cursor's offset within the item being removed, otherwise -1.
        /// </param>
        private static string GetTextAndRemoveItem(BaseCodeItem itemToRemove, out int cursorOffset)
        {
            // Refresh the code item and capture its end points.
            itemToRemove.RefreshCachedPositionAndName();
            var removeStartPoint = itemToRemove.StartPoint;
            var removeEndPoint = itemToRemove.EndPoint;

            // Determine the cursor's offset if within the item being removed.
            var cursorAbsoluteOffset = removeStartPoint.Parent.Selection.ActivePoint.AbsoluteCharOffset;
            if (cursorAbsoluteOffset >= removeStartPoint.AbsoluteCharOffset && cursorAbsoluteOffset <= removeEndPoint.AbsoluteCharOffset)
            {
                cursorOffset = cursorAbsoluteOffset - removeStartPoint.AbsoluteCharOffset;
            }
            else
            {
                cursorOffset = -1;
            }

            // Capture the text.
            var text = removeStartPoint.GetText(removeEndPoint);

            // Remove the text and cleanup whitespace.
            removeStartPoint.Delete(removeEndPoint);
            removeStartPoint.DeleteWhitespace(vsWhitespaceOptions.vsWhitespaceOptionsVertical);

            return text;
        }
        /// <summary>
        /// Repositions the specified item below the specified base.
        /// </summary>
        /// <param name="itemToMove">The item to move.</param>
        /// <param name="baseItem">The base item.</param>
        private void RepositionItemBelowBase(BaseCodeItem itemToMove, BaseCodeItem baseItem)
        {
            if (itemToMove == baseItem) return;

            bool separateWithNewLine = ShouldBeSeparatedByNewLine(baseItem, itemToMove);
            int cursorOffset;
            var text = GetTextAndRemoveItem(itemToMove, out cursorOffset);

            baseItem.RefreshCachedPositionAndName();
            var baseEndPoint = baseItem.EndPoint;
            var pastePoint = baseEndPoint.CreateEditPoint();

            pastePoint.Insert(Environment.NewLine);
            if (separateWithNewLine)
            {
                pastePoint.Insert(Environment.NewLine);
            }

            var formatPoint = pastePoint.CreateEditPoint();
            var insertPoint = pastePoint.CreateEditPoint();

            pastePoint.Insert(text);

            formatPoint.EndOfLine();
            baseEndPoint.SmartFormat(formatPoint);

            if (cursorOffset >= 0)
            {
                insertPoint.Parent.Selection.MoveToAbsoluteOffset(insertPoint.AbsoluteCharOffset + cursorOffset);
            }

            itemToMove.RefreshCachedPositionAndName();
            baseItem.RefreshCachedPositionAndName();
        }
        /// <summary>
        /// Attempts to select the text of the specified code item.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="codeItem">The code item.</param>
        internal static void SelectCodeItem(Document document, BaseCodeItem codeItem)
        {
            var textDocument = document.GetTextDocument();
            if (textDocument == null) return;

            try
            {
                codeItem.RefreshCachedPositionAndName();
                textDocument.Selection.MoveToPoint(codeItem.StartPoint, false);
                textDocument.Selection.MoveToPoint(codeItem.EndPoint, true);

                textDocument.Selection.SwapAnchor();
            }
            catch (Exception)
            {
                // Select operation may fail if element is no longer available.
            }
            finally
            {
                // Always set focus within the code editor window.
                document.Activate();
            }
        }
 /// <summary>
 /// Moves the specified item into the specified base.
 /// </summary>
 /// <param name="itemToMove">The item to move.</param>
 /// <param name="baseItem">The base item.</param>
 internal void MoveItemIntoBase(BaseCodeItem itemToMove, ICodeItemParent baseItem)
 {
     _undoTransactionHelper.Run(() => RepositionItemIntoBase(itemToMove, baseItem));
 }
        /// <summary>
        /// Attempts to get the type component string based on the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <returns>The type component of the partial image name, otherwise null.</returns>
        private static string GetTypeComponentString(BaseCodeItem codeItem)
        {
            switch (codeItem.Kind)
            {
                case KindCodeItem.Class: return "Class";
                case KindCodeItem.Constructor: return "MethodConstructor";
                case KindCodeItem.Delegate: return "Delegate";
                case KindCodeItem.Destructor: return "MethodDestructor";
                case KindCodeItem.Enum: return "Enum";
                case KindCodeItem.Event: return "Event";
                case KindCodeItem.Field:
                    var codeItemField = (CodeItemField)codeItem;
                    if (codeItemField.IsEnumItem) return "EnumItem";
                    if (codeItemField.IsConstant) return "Constant";
                    return "Field";

                case KindCodeItem.Interface: return "Interface";
                case KindCodeItem.Method: return "Method";
                case KindCodeItem.Indexer:
                case KindCodeItem.Property: return "Property";
                case KindCodeItem.Region: return "Region";
                case KindCodeItem.Struct: return "Structure";
                default: return null;
            }
        }
        /// <summary>
        /// Attempts to move the cursor to the specified code item.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="codeItem">The code item.</param>
        /// <param name="centerOnWhole">True if the whole element should be used for centering.</param>
        internal static void MoveToCodeItem(Document document, BaseCodeItem codeItem, bool centerOnWhole)
        {
            var textDocument = document.GetTextDocument();
            if (textDocument == null) return;

            try
            {
                object viewRangeEnd = null;
                TextPoint navigatePoint = null;

                codeItem.RefreshCachedPositionAndName();
                textDocument.Selection.MoveToPoint(codeItem.StartPoint, false);

                if (centerOnWhole)
                {
                    viewRangeEnd = codeItem.EndPoint;
                }

                var codeItemElement = codeItem as BaseCodeItemElement;
                if (codeItemElement != null)
                {
                    navigatePoint = codeItemElement.CodeElement.GetStartPoint(vsCMPart.vsCMPartNavigate);
                }

                textDocument.Selection.AnchorPoint.TryToShow(vsPaneShowHow.vsPaneShowCentered, viewRangeEnd);

                if (navigatePoint != null)
                {
                    textDocument.Selection.MoveToPoint(navigatePoint, false);
                }
                else
                {
                    textDocument.Selection.FindText(codeItem.Name, (int)vsFindOptions.vsFindOptionsMatchInHiddenText);
                    textDocument.Selection.MoveToPoint(textDocument.Selection.AnchorPoint, false);
                }
            }
            catch (Exception)
            {
                // Move operation may fail if element is no longer available.
            }
            finally
            {
                // Always set focus within the code editor window.
                document.Activate();
            }
        }
Beispiel #8
0
        /// <summary>
        /// Determines if the specified item is an ancestor of the specified base.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="baseItem">The base item.</param>
        /// <returns>True if item is an ancestor of the specified base, otherwise false.</returns>
        private static bool IsItemAncestorOfBase(BaseCodeItem item, BaseCodeItem baseItem)
        {
            var itemAsParent = item as ICodeItemParent;
            if (itemAsParent == null)
            {
                return false;
            }

            return itemAsParent.Children.Contains(baseItem) ||
                   itemAsParent.Children.Any(x => IsItemAncestorOfBase(x, baseItem));
        }
Beispiel #9
0
        /// <summary>
        /// Jumps to the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        private void JumpToCodeItem(BaseCodeItem codeItem)
        {
            var viewModel = ViewModel;
            if (codeItem == null || viewModel == null || codeItem.StartOffset <= 0) return;

            Dispatcher.BeginInvoke(
                new Action(() => TextDocumentHelper.MoveToCodeItem(viewModel.Document, codeItem, Settings.Default.Digging_CenterOnWhole)));
        }
        /// <summary>
        /// Composes a region based on the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <returns>A region.</returns>
        private CodeItemRegion ComposeRegionForCodeItem(BaseCodeItem codeItem)
        {
            if (codeItem == null) return null;

            var setting = MemberTypeSettingHelper.LookupByKind(codeItem.Kind);
            if (setting == null) return null;

            var regionName = string.Empty;

            if (Settings.Default.Reorganizing_RegionsIncludeAccessLevel)
            {
                var element = codeItem as BaseCodeItemElement;
                if (element != null)
                {
                    var accessModifier = CodeElementHelper.GetAccessModifierKeyword(element.Access);
                    if (accessModifier != null)
                    {
                        regionName = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(accessModifier) + " ";
                    }
                }
            }

            regionName += setting.EffectiveName;

            return new CodeItemRegion { Name = regionName };
        }
Beispiel #11
0
        /// <summary>
        /// Determines the drop position for the specified drag event and the drop target.
        /// </summary>
        /// <param name="e">
        /// The <see cref="System.Windows.DragEventArgs" /> instance containing the event data.
        /// </param>
        /// <param name="targetItem">The target item.</param>
        /// <param name="targetElement">The target element.</param>
        /// <returns>The drop position.</returns>
        private static DropPosition GetDropPosition(DragEventArgs e, BaseCodeItem targetItem, TreeViewItem targetElement)
        {
            var header = targetElement.Template.FindName("PART_HeaderBorder", targetElement) as FrameworkElement;
            var targetHeight = header?.ActualHeight ?? targetElement.ActualHeight;
            var dropPoint = e.GetPosition(targetElement);
            bool canDropOn = targetItem is ICodeItemParent;

            if (canDropOn)
            {
                bool isTopThird = dropPoint.Y <= targetHeight / 3;
                bool isBottomThird = dropPoint.Y > targetHeight * 2 / 3;

                return isTopThird ? DropPosition.Above : (isBottomThird ? DropPosition.Below : DropPosition.On);
            }

            bool isTopHalf = dropPoint.Y <= targetHeight / 2;

            return isTopHalf ? DropPosition.Above : DropPosition.Below;
        }
 /// <summary>
 /// Determines if the specified code item belongs in the specified region.
 /// </summary>
 /// <param name="codeItem">The code item.</param>
 /// <param name="region">The region.</param>
 /// <returns>True if the specified code item belongs in the specified region, otherwise false.</returns>
 private bool CodeItemBelongsInRegion(BaseCodeItem codeItem, CodeItemRegion region)
 {
     return codeItem != null && _regionComparerByName.Equals(region, ComposeRegionForCodeItem(codeItem));
 }
Beispiel #13
0
        /// <summary>
        /// Shows a context menu for the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <param name="point">The point where the context menu should be shown.</param>
        private void ShowContextMenu(BaseCodeItem codeItem, Point point)
        {
            var viewModel = ViewModel;
            if (codeItem == null || viewModel == null) return;

            var menuCommandService = viewModel.Package.MenuCommandService;
            if (menuCommandService != null)
            {
                var contextMenuCommandID = new CommandID(GuidList.GuidCodeMaidContextSpadeBaseGroup, PkgCmdIDList.MenuIDCodeMaidContextSpade);

                viewModel.SelectedItem = codeItem;
                menuCommandService.ShowContextMenu(contextMenuCommandID, (int)point.X, (int)point.Y);
                viewModel.SelectedItem = null;
            }
        }
        /// <summary>
        /// Attempts to build an image URI from the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        /// <returns>The built URI, otherwise null.</returns>
        private string BuildImageURIString(BaseCodeItem codeItem)
        {
            string typeComponent = GetTypeComponentString(codeItem);
            string accessComponent = GetAccessString(codeItem as BaseCodeItemElement);

            if (typeComponent == null) return null;

            string uriString = string.Format("/SteveCadwallader.CodeMaid;component/UI/ToolWindows/Spade/Images/{0}/{1}{2}.png", ImagePath, typeComponent, accessComponent);

            return uriString;
        }
 /// <summary>
 /// Determines if the two specified items should be separated by a newline.
 /// </summary>
 /// <param name="firstItem">The first item.</param>
 /// <param name="secondItem">The second item.</param>
 /// <returns>True if the items should be separated by a newline, otherwise false.</returns>
 private bool ShouldBeSeparatedByNewLine(BaseCodeItem firstItem, BaseCodeItem secondItem)
 {
     return _insertBlankLinePaddingLogic.ShouldInstanceBeFollowedByBlankLine(firstItem) ||
            _insertBlankLinePaddingLogic.ShouldInstanceBePrecededByBlankLine(secondItem);
 }
Beispiel #16
0
        /// <summary>
        /// Selects the specified code item.
        /// </summary>
        /// <param name="codeItem">The code item.</param>
        private void SelectCodeItem(BaseCodeItem codeItem)
        {
            var viewModel = ViewModel;
            if (codeItem == null || viewModel == null || codeItem.StartOffset <= 0) return;

            Dispatcher.BeginInvoke(
                new Action(() => TextDocumentHelper.SelectCodeItem(viewModel.Document, codeItem)));
        }
 /// <summary>
 /// Moves the specified item below the specified base.
 /// </summary>
 /// <param name="itemToMove">The item to move.</param>
 /// <param name="baseItem">The base item.</param>
 internal void MoveItemBelowBase(BaseCodeItem itemToMove, BaseCodeItem baseItem)
 {
     _undoTransactionHelper.Run(() => RepositionItemBelowBase(itemToMove, baseItem));
 }
 /// <summary>
 /// Determines if the specified item is a candidate for deletion.
 /// </summary>
 /// <param name="codeItem">The code item.</param>
 /// <returns>True if the code item can be deleted, otherwise false.</returns>
 private static bool IsDeletable(BaseCodeItem codeItem)
 {
     return !(codeItem is CodeItemRegion) || !((CodeItemRegion)codeItem).IsPseudoGroup;
 }