Example #1
0
#pragma warning disable VSTHRD100 // Avoid async void methods - ok as an event handler
        private async void Execute(object sender, EventArgs e)
#pragma warning restore VSTHRD100 // Avoid async void methods
        {
            System.Windows.Forms.Cursor previousCursor = System.Windows.Forms.Cursor.Current;
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;

            try
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                this.Logger?.RecordFeatureUsage(nameof(AnalyzeCurrentDocumentCommand));

                var dte = await Instance.AsyncPackage.GetServiceAsync <DTE, DTE>();

                var vs = new VisualStudioAbstraction(this.Logger, this.AsyncPackage, dte);

                var filePath = vs.GetActiveDocumentFilePath();

                // Ensure that the open document has been saved so get latest version
                var rdt = new RunningDocumentTable(Package);
                rdt.SaveFileIfDirty(filePath);

                RapidXamlDocumentCache.Invalidate(filePath);
                RapidXamlDocumentCache.TryUpdate(filePath);
            }
            catch (Exception exc)
            {
                this.Logger?.RecordException(exc);
            }
            finally
            {
                System.Windows.Forms.Cursor.Current = previousCursor;
            }
        }
#pragma warning disable CS0628 // New protected member declared in sealed class
        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress)
#pragma warning restore CS0628 // New protected member declared in sealed class
        {
            // When initialized asynchronously, the current thread may be a background thread at this point.
            // Do any initialization that requires the UI thread after switching to the UI thread.
            await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            try
            {
                await SharedRapidXamlPackage.InitializeAsync(cancellationToken, this);

                SharedRapidXamlPackage.Logger?.RecordNotice(StringRes.Info_LaunchVersionAnalysis.WithParams(CoreDetails.GetVersion()));
                SharedRapidXamlPackage.Logger?.RecordNotice(string.Empty);

                await FeedbackCommand.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                await MoveAllHardCodedStringsToResourceFileCommand.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                await this.SetUpRunningDocumentTableEventsAsync(cancellationToken);

                RapidXamlDocumentCache.Initialize(this, SharedRapidXamlPackage.Logger);

                Microsoft.VisualStudio.Shell.Events.SolutionEvents.OnAfterCloseSolution += this.HandleCloseSolution;
            }
            catch (Exception exc)
            {
                SharedRapidXamlPackage.Logger?.RecordException(exc);
            }
        }
Example #3
0
        public override void Execute(CancellationToken cancellationToken)
        {
            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(StringRes.UI_SetBindingModeToTwoWay);
            try
            {
                var lineNumber = this.Tag.Snapshot.GetLineNumberFromPosition(this.Tag.InsertPosition) + 1;

                if (!string.IsNullOrEmpty(this.Tag.ExistingBindingMode))
                {
                    vs.ReplaceInActiveDocOnLine(this.Tag.ExistingBindingMode, "Mode=TwoWay", lineNumber);
                }
                else
                {
                    vs.ReplaceInActiveDocOnLine("}", ", Mode=TwoWay}", lineNumber);
                }

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
Example #4
0
        public override void Execute(CancellationToken cancellationToken)
        {
            var resPath = this.GetResourceFilePath();

            if (resPath == null)
            {
                return;
            }

            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(StringRes.Info_UndoContextMoveStringToResourceFile);

            try
            {
                // If the resource file is open with unsaved changes VS will prompt about data being lost.
                this.AddResource(resPath, $"{this.Tag.UidValue}.{this.Tag.AttributeName}", this.Tag.Value);

                if (this.Tag.AttributeType == AttributeType.Inline)
                {
                    var currentAttribute = $"{this.Tag.AttributeName}=\"{this.Tag.Value}\"";

                    if (this.Tag.UidExists)
                    {
                        vs.RemoveInActiveDocOnLine(currentAttribute, this.Tag.GetDesignerLineNumber());
                    }
                    else
                    {
                        var uidTag = $"x:Uid=\"{this.Tag.UidValue}\"";
                        vs.ReplaceInActiveDocOnLine(currentAttribute, uidTag, this.Tag.GetDesignerLineNumber());
                    }
                }
                else if (this.Tag.AttributeType == AttributeType.Element)
                {
                    var currentAttribute = $"<{this.Tag.ElementName}.{this.Tag.AttributeName}>{this.Tag.Value}</{this.Tag.ElementName}.{this.Tag.AttributeName}>";

                    vs.RemoveInActiveDocOnLine(currentAttribute, this.Tag.GetDesignerLineNumber());

                    if (!this.Tag.UidExists)
                    {
                        var uidTag = $"<{this.Tag.ElementName} x:Uid=\"{this.Tag.UidValue}\"";
                        vs.ReplaceInActiveDocOnLineOrAbove($"<{this.Tag.ElementName}", uidTag, this.Tag.GetDesignerLineNumber());
                    }
                }
                else if (this.Tag.AttributeType == AttributeType.DefaultValue)
                {
                    var current     = $">{this.Tag.Value}</{this.Tag.ElementName}>";
                    var replaceWith = this.Tag.UidExists ? " />" : $" x:Uid=\"{this.Tag.UidValue}\" />";

                    vs.ReplaceInActiveDocOnLine(current, replaceWith, this.Tag.GetDesignerLineNumber());
                }

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
Example #5
0
 public override void Execute(CancellationToken cancellationToken)
 {
     this.Tag.SetAsHiddenInSettingsFile();
     this.Source.Refresh();
     RapidXamlDocumentCache.RemoveTags(this.Tag.FileName, this.ErrorCode);
     RapidXamlDocumentCache.Invalidate(this.Tag.FileName);
     RapidXamlDocumentCache.TryUpdate(this.Tag.FileName);
     TableDataSource.Instance.CleanErrors(this.Tag.FileName);
 }
        public override void Execute(CancellationToken cancellationToken)
        {
            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(this.UndoText);
            try
            {
                vs.ReplaceInActiveDocOnLine(this.Original, this.Replace, this.LineNo);

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
Example #7
0
        public override void Execute(CancellationToken cancellationToken)
        {
            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(StringRes.UI_AddMissingEvent);
            try
            {
                var lineNumber = this.Tag.Snapshot.GetLineNumberFromPosition(this.Tag.InsertPosition) + 1;

                string newName;

                if (this.Tag.ExistingName.ToLowerInvariant().Contains("checked"))
                {
                    if (this.Tag.ExistingIsChecked)
                    {
                        newName = this.Tag.ExistingName.Replace("Checked", "UnChecked").Replace("checked", "Unchecked");
                    }
                    else
                    {
                        newName = this.Tag.ExistingName.Replace("UnChecked", "Checked").Replace("unchecked", "checked");
                    }
                }
                else
                {
                    if (this.Tag.ExistingIsChecked)
                    {
                        newName = "OnCheckBoxUnchecked";
                    }
                    else
                    {
                        newName = "OnCheckBoxChecked";
                    }
                }

                var newEvent = this.Tag.ExistingIsChecked
                    ? $"Unchecked=\"{newName}\""
                    : $"Checked=\"{newName}\"";

                vs.ReplaceInActiveDocOnLine("<CheckBox", $"<CheckBox {newEvent} ", lineNumber);

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress)
        {
            // When initialized asynchronously, the current thread may be a background thread at this point.
            // Do any initialization that requires the UI thread after switching to the UI thread.
            await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            var rxtLogger = new RxtLogger();

            var config = new RxtSettings();

            var telemLogger = TelemetryAccessor.Create(rxtLogger, config.TelemetryKey);

            Logger = new RxtLoggerWithTelemtry(rxtLogger, telemLogger);

            try
            {
                // Set the ServiceProvider of CodeParserBase as it's needed to get settings
                CodeParserBase.ServiceProvider = this;
                Logger.RecordInfo(StringRes.Info_ProblemsInstructionsAndLink);
                Logger.RecordInfo(StringRes.Info_IntializingCommands.WithParams(CoreDetails.GetVersion()));

                await CreateViewCommand.InitializeAsync(this, Logger);

                await CopyToClipboardCommand.InitializeAsync(this, Logger);

                await SendToToolboxCommand.InitializeAsync(this, Logger);

                await OpenOptionsCommand.InitializeAsync(this, Logger);

                await SetDatacontextCommand.InitializeAsync(this, Logger);

                await MoveAllHardCodedStringsToResourceFileCommand.InitializeAsync(this, Logger);

                await RapidXamlDropHandlerProvider.InitializeAsync(this, Logger);

                await this.SetUpRunningDocumentTableEventsAsync(cancellationToken);

                RapidXamlDocumentCache.Initialize(this);
            }
            catch (Exception exc)
            {
                Logger.RecordException(exc);
                throw;  // Remove for launch. see issue #90
            }
        }
        public override void Execute(CancellationToken cancellationToken)
        {
            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(StringRes.Info_UndoContextAddTextBoxInputScope);
            try
            {
                var lineNumber = this.Tag.Snapshot.GetLineNumberFromPosition(this.Tag.InsertPosition) + 1;

                vs.ReplaceInActiveDocOnLine("<TextBox ", "<TextBox InputScope=\"Default\" ", lineNumber);

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
        public override void Execute(CancellationToken cancellationToken)
        {
            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(StringRes.UI_UndoContextAddEntryKeyboard);
            try
            {
                var lineNumber = this.Tag.Snapshot.GetLineNumberFromPosition(this.Tag.InsertPosition) + 1;

                vs.ReplaceInActiveDocOnLine("<Entry ", $"<Entry Keyboard=\"{this.KeyBoardName}\" ", lineNumber);

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
        public override void Execute(CancellationToken cancellationToken)
        {
            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(StringRes.UI_ChangeToMediaPlayerElement);
            try
            {
                var lineNumber = this.Tag.Snapshot.GetLineNumberFromPosition(this.Tag.InsertPosition) + 1;

                vs.ReplaceInActiveDocOnLine("<MediaElement", "<MediaPlayerElement", lineNumber);

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
Example #12
0
        public override void Execute(CancellationToken cancellationToken)
        {
            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(this.UndoOperationName);
            try
            {
                var lineNumber = this.Tag.Snapshot.GetLineNumberFromPosition(this.Tag.InsertPosition) + 1;

                string toInsert;
                if (this.Tag.GridNeedsExpanding)
                {
                    vs.RemoveInActiveDocOnLine(" />", lineNumber);

                    toInsert = $">{Environment.NewLine}{this.InjectedXaml}";

                    toInsert = toInsert.Replace("\n", "\n" + this.Tag.LeftPad);

                    string shortPad = this.Tag.LeftPad.EndsWith("\t")
                        ? this.Tag.LeftPad.Substring(0, this.Tag.LeftPad.Length - 1)
                        : this.Tag.LeftPad.Substring(0, this.Tag.LeftPad.Length - 4);

                    toInsert += $"{Environment.NewLine}{shortPad}</Grid>";
                }
                else
                {
                    toInsert = Environment.NewLine + this.InjectedXaml;
                    toInsert = toInsert.Replace("\n", "\n" + this.Tag.LeftPad);
                }

                vs.InsertAtEndOfLine(lineNumber, toInsert);

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
        public override void Execute(CancellationToken cancellationToken)
        {
            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(this.DisplayText);
            try
            {
                this.InnerExecute(vs, this.Tag, cancellationToken);

                foreach (var suppAction in this.Tag.SupplementaryActions)
                {
                    var sat = this.RepurposeTagForSupplementaryAction(this.Tag, suppAction);
                    this.InnerExecute(vs, sat, cancellationToken);
                }

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
Example #14
0
        public override void Execute(CancellationToken cancellationToken)
        {
            var vs = new VisualStudioTextManipulation(ProjectHelpers.Dte);

            vs.StartSingleUndoOperation(StringRes.Info_UndoContextAddRowDefinitions);

            try
            {
                var insert = string.Empty;

                const string def = "<RowDefinition Height=\"*\" />";

                var leftPad = this.Tag.LeftPad.Contains("\t") ? this.Tag.LeftPad + "\t" : this.Tag.LeftPad + "    ";

                for (var i = 0; i <= this.Tag.TotalDefsRequired - this.Tag.ExistingDefsCount; i++)
                {
                    insert += $"{Environment.NewLine}{leftPad}{def}";
                }

                var insertLine = this.Tag.Snapshot.GetLineNumberFromPosition(this.Tag.InsertPosition);

                if (!this.Tag.HasSomeDefinitions)
                {
                    insert = $"{Environment.NewLine}{this.Tag.LeftPad}<Grid.RowDefinitions>{insert}{Environment.NewLine}{this.Tag.LeftPad}</Grid.RowDefinitions>";

                    // Account for different reference position - end-of-start vs start-of-end
                    insertLine += 1;
                }

                vs.InsertAtEndOfLine(insertLine, insert);

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                vs.EndSingleUndoOperation();
            }
        }
Example #15
0
 public override void Execute(CancellationToken cancellationToken)
 {
     this.Tag.SetAsHiddenInSettingsFile();
     RapidXamlDocumentCache.RemoveTags(this.Tag.FileName, this.ErrorCode);
     this.Source.Refresh();
 }
        public override void Execute(CancellationToken cancellationToken)
        {
            var resPath = this.GetResourceFilePath();

            if (resPath == null)
            {
                return;
            }

            var vs = this.vstm ?? new VisualStudioTextManipulation(ProjectHelpers.Dte);

            var undo = vs.StartSingleUndoOperation(StringRes.UI_UndoContextMoveStringToResourceFile);

            try
            {
                if (this.Tag.ProjType == ProjectType.Uwp)
                {
                    // If the resource file is open with unsaved changes VS will prompt about data being lost.
                    this.AddResource(resPath, $"{this.Tag.UidValue}.{this.Tag.AttributeName}", this.Tag.Value);

                    if (this.Tag.AttributeType == AttributeType.Inline)
                    {
                        var currentAttribute = $"{this.Tag.AttributeName}=\"{this.Tag.Value}\"";

                        if (this.Tag.UidExists)
                        {
                            vs.RemoveInActiveDocOnLine(currentAttribute, this.Tag.GetDesignerLineNumber());
                        }
                        else
                        {
                            var uidTag = $"x:Uid=\"{this.Tag.UidValue}\"";
                            vs.ReplaceInActiveDocOnLine(currentAttribute, uidTag, this.Tag.GetDesignerLineNumber());
                        }
                    }
                    else if (this.Tag.AttributeType == AttributeType.Element)
                    {
                        var currentAttribute = $"<{this.Tag.ElementName}.{this.Tag.AttributeName}>{this.Tag.Value}</{this.Tag.ElementName}.{this.Tag.AttributeName}>";

                        vs.RemoveInActiveDocOnLine(currentAttribute, this.Tag.GetDesignerLineNumber());

                        if (!this.Tag.UidExists)
                        {
                            var uidTag = $"<{this.Tag.ElementName} x:Uid=\"{this.Tag.UidValue}\"";
                            vs.ReplaceInActiveDocOnLineOrAbove($"<{this.Tag.ElementName}", uidTag, this.Tag.GetDesignerLineNumber());
                        }
                    }
                    else if (this.Tag.AttributeType == AttributeType.DefaultValue)
                    {
                        var current     = $">{this.Tag.Value}</{this.Tag.ElementName}>";
                        var replaceWith = this.Tag.UidExists ? " />" : $" x:Uid=\"{this.Tag.UidValue}\" />";

                        vs.ReplaceInActiveDocOnLine(current, replaceWith, this.Tag.GetDesignerLineNumber());
                    }
                }
                else if (this.Tag.ProjType == ProjectType.Wpf)
                {
                    // TODO: ISSUE#163 Implement WPF resource creation
                    var resourceName = "NEED TO GENERATE THIS";
                    this.AddResource(resPath, resourceName, this.Tag.Value);

                    switch (this.Tag.AttributeType)
                    {
                    case AttributeType.Inline:
                        break;

                    case AttributeType.Element:
                        break;

                    case AttributeType.DefaultValue:
                        break;
                    }
                }
                else if (this.Tag.ProjType == ProjectType.XamarinForms)
                {
                    var resourceName = "NEED TO GENERATE THIS";
                    this.AddResource(resPath, resourceName, this.Tag.Value);

                    // TODO: ISSUE#163 Implement Xamarin.Forms resource creation
                    switch (this.Tag.AttributeType)
                    {
                    case AttributeType.Inline:
                        var currentAttribute   = $"{this.Tag.AttributeName}=\"{this.Tag.Value}\"";
                        var localizedAttribute = $"{this.Tag.AttributeName}=\"{{x:Static resources:{System.IO.Path.GetFileNameWithoutExtension(resPath)}.{resourceName}}}\"";

                        vs.ReplaceInActiveDocOnLine(currentAttribute, localizedAttribute, this.Tag.GetDesignerLineNumber());
                        break;

                    case AttributeType.Element:
                        break;

                    case AttributeType.DefaultValue:
                        break;
                    }
                }

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                if (undo)
                {
                    vs.EndSingleUndoOperation();
                }
            }
        }
#pragma warning disable CS0628 // New protected member declared in sealed class
        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress)
#pragma warning restore CS0628 // New protected member declared in sealed class
        {
            // When initialized asynchronously, the current thread may be a background thread at this point.
            // Do any initialization that requires the UI thread after switching to the UI thread.
            await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            try
            {
                await SharedRapidXamlPackage.InitializeAsync(cancellationToken, this);

                SharedRapidXamlPackage.Logger?.RecordNotice(StringRes.Info_LaunchVersionAnalysis.WithParams(CoreDetails.GetVersion()));
                SharedRapidXamlPackage.Logger?.RecordNotice(string.Empty);

                await FeedbackCommand.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                await MoveAllHardCodedStringsToResourceFileCommand.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                await AnalyzeCurrentDocumentCommand.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                await OpenAnalysisOptionsCommand.InitializeAsync(this, SharedRapidXamlPackage.Logger);

                await this.SetUpRunningDocumentTableEventsAsync(cancellationToken);

                RapidXamlDocumentCache.Initialize(this, SharedRapidXamlPackage.Logger);

                Microsoft.VisualStudio.Shell.Events.SolutionEvents.OnAfterCloseSolution += this.HandleCloseSolution;

                // Handle the ability to resolve assemblies when loading custom analyzers.
                // Hat-tip: https://weblog.west-wind.com/posts/2016/dec/12/loading-net-assemblies-out-of-seperate-folders
                AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs args) =>
                {
                    // Ignore missing resources
                    if (args.Name.Contains(".resources"))
                    {
                        return(null);
                    }

                    if (args.RequestingAssembly == null)
                    {
                        return(null);
                    }

                    // check for assemblies already loaded
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == args.Name);
                    if (assembly != null)
                    {
                        return(assembly);
                    }

                    // Try to load by filename - split out the filename of the full assembly name
                    // and append the base path of the original assembly (ie. look in the same dir)
                    string filename = args.Name.Split(',')[0] + ".dll".ToLower();

                    var asmFile = Path.Combine(Path.GetDirectoryName(args.RequestingAssembly.CodeBase), filename);

                    if (asmFile.StartsWith("file:\\"))
                    {
                        asmFile = asmFile.Substring(6);
                    }

                    try
                    {
                        return(Assembly.LoadFrom(asmFile));
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine(ex);
                        return(null);
                    }
                };

                // Track this so don't try and load CustomAnalyzers while VS is still starting up.
                RapidXamlAnalysisPackage.IsLoaded = true;

                RapidXamlAnalysisPackage.Options = (AnalysisOptionsGrid)this.GetDialogPage(typeof(AnalysisOptionsGrid));

                var ass = Assembly.GetExecutingAssembly().GetName();

                SharedRapidXamlPackage.Logger?.RecordFeatureUsage(StringRes.Info_PackageLoad.WithParams(ass.Name, ass.Version), quiet: true);
            }
            catch (Exception exc)
            {
                SharedRapidXamlPackage.Logger?.RecordException(exc);
            }
        }
Example #18
0
        public override void Execute(CancellationToken cancellationToken)
        {
            Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread();

            var resPath = this.GetResourceFilePath();

            if (resPath == null)
            {
                return;
            }

            var vs = this.vstm ?? new VisualStudioTextManipulation(ProjectHelpers.Dte);

            var undo = vs.StartSingleUndoOperation(StringRes.UI_UndoContextMoveStringToResourceFile);

            try
            {
                if (this.Tag.ProjType == ProjectType.Uwp)
                {
                    // If the resource file is open with unsaved changes VS will prompt about data being lost.
                    this.AddResource(resPath, $"{this.Tag.UidValue}.{this.Tag.AttributeName}", this.Tag.Value);

                    if (this.Tag.AttributeType == AttributeType.Inline)
                    {
                        var currentAttribute = $"{this.Tag.AttributeName}=\"{this.Tag.Value}\"";

                        if (this.Tag.UidExists)
                        {
                            vs.RemoveInActiveDocOnLine(currentAttribute, this.Tag.GetDesignerLineNumber());
                        }
                        else
                        {
                            var uidTag = $"x:Uid=\"{this.Tag.UidValue}\"";
                            vs.ReplaceInActiveDocOnLine(currentAttribute, uidTag, this.Tag.GetDesignerLineNumber());
                        }
                    }
                    else if (this.Tag.AttributeType == AttributeType.Element)
                    {
                        var currentAttribute = $"<{this.Tag.ElementName}.{this.Tag.AttributeName}>{this.Tag.Value}</{this.Tag.ElementName}.{this.Tag.AttributeName}>";

                        vs.RemoveInActiveDocOnLine(currentAttribute, this.Tag.GetDesignerLineNumber());

                        if (!this.Tag.UidExists)
                        {
                            var uidTag = $"<{this.Tag.ElementName} x:Uid=\"{this.Tag.UidValue}\"";
                            vs.ReplaceInActiveDocOnLineOrAbove($"<{this.Tag.ElementName}", uidTag, this.Tag.GetDesignerLineNumber());
                        }
                    }
                    else if (this.Tag.AttributeType == AttributeType.DefaultValue)
                    {
                        var current     = $">{this.Tag.Value}</{this.Tag.ElementName}>";
                        var replaceWith = this.Tag.UidExists ? " />" : $" x:Uid=\"{this.Tag.UidValue}\" />";

                        vs.ReplaceInActiveDocOnLine(current, replaceWith, this.Tag.GetDesignerLineNumber());
                    }
                }
                else if (this.Tag.ProjType == ProjectType.Wpf ||
                         this.Tag.ProjType == ProjectType.XamarinForms)
                {
                    var resourceName = $"{Path.GetFileNameWithoutExtension(this.Tag.FileName)}{this.Tag.Value}".RemoveNonAlphaNumerics();
                    this.AddResource(resPath, resourceName, this.Tag.Value);

                    var resourceNs = this.GetResourceFileNamespace(resPath);

                    // TODO: Issue#410 determine if XMLNS already exists based on resfile folder
                    // TODO: Issue#410 convert this to be based on BuiltInAnalyzer so can check for existing xmlns aliases
                    var xmlns       = "properties";
                    var xmlnsExists = true;

                    var newAttribute = $"{this.Tag.AttributeName}=\"{{x:Static {xmlns}:{Path.GetFileNameWithoutExtension(resPath)}.{resourceName}}}\"";

                    switch (this.Tag.AttributeType)
                    {
                    case AttributeType.Inline:
                        var currentAttribute = $"{this.Tag.AttributeName}=\"{this.Tag.Value}\"";
                        vs.ReplaceInActiveDocOnLine(currentAttribute, newAttribute, this.Tag.GetDesignerLineNumber());
                        break;

                    case AttributeType.Element:
                        var currentElementAttribute = $"<{this.Tag.ElementName}.{this.Tag.AttributeName}>{this.Tag.Value}</{this.Tag.ElementName}.{this.Tag.AttributeName}>";
                        vs.RemoveInActiveDocOnLine(currentElementAttribute, this.Tag.GetDesignerLineNumber());

                        var newXaml = $"<{this.Tag.ElementName} {newAttribute}";
                        vs.ReplaceInActiveDocOnLineOrAbove($"<{this.Tag.ElementName}", newXaml, this.Tag.GetDesignerLineNumber());
                        break;

                    case AttributeType.DefaultValue:
                        var current     = $">{this.Tag.Value}</{this.Tag.ElementName}>";
                        var replaceWith = $" {newAttribute} />";
                        vs.ReplaceInActiveDocOnLine(current, replaceWith, this.Tag.GetDesignerLineNumber());
                        break;
                    }

                    if (!xmlnsExists)
                    {
                        vs.AddXmlnsAliasToActiveDoc(xmlns, $"clr-namespace:{resourceNs}");
                    }
                }
                ////else if (this.Tag.ProjType == ProjectType.XamarinForms)
                ////{
                ////    var resourceName = "NEED TO GENERATE THIS";
                ////    this.AddResource(resPath, resourceName, this.Tag.Value);

                ////    // TODO: ISSUE#163 Implement Xamarin.Forms resource creation
                ////    switch (this.Tag.AttributeType)
                ////    {
                ////        case AttributeType.Inline:
                ////            var currentAttribute = $"{this.Tag.AttributeName}=\"{this.Tag.Value}\"";
                ////            var localizedAttribute = $"{this.Tag.AttributeName}=\"{{x:Static resources:{System.IO.Path.GetFileNameWithoutExtension(resPath)}.{resourceName}}}\"";

                ////            vs.ReplaceInActiveDocOnLine(currentAttribute, localizedAttribute, this.Tag.GetDesignerLineNumber());
                ////            break;
                ////        case AttributeType.Element:
                ////            break;
                ////        case AttributeType.DefaultValue:
                ////            break;
                ////    }
                ////}

                RapidXamlDocumentCache.TryUpdate(this.File);
            }
            finally
            {
                if (undo)
                {
                    vs.EndSingleUndoOperation();
                }
            }
        }
Example #19
0
#pragma warning disable VSTHRD100 // Avoid async void methods - Allowed as called from event handler.
        private async void Execute(object sender, EventArgs e)
#pragma warning restore VSTHRD100 // Avoid async void methods
        {
            System.Windows.Forms.Cursor previousCursor = System.Windows.Forms.Cursor.Current;
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;

            try
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                this.Logger?.RecordFeatureUsage(nameof(MoveAllHardCodedStringsToResourceFileCommand));

                var dte = await Instance.AsyncPackage.GetServiceAsync <DTE, DTE>();

                var vs = new VisualStudioAbstraction(this.Logger, this.AsyncPackage, dte);

                var filePath = vs.GetActiveDocumentFilePath();

                // Ensure that the open document has been saved or modifications may go wrong
                var rdt = new RunningDocumentTable(Package);
                rdt.SaveFileIfDirty(filePath);

                // Do this as don't have direct snapshot access and want any changes to be processed before making changes
                RapidXamlDocumentCache.TryUpdate(filePath);

                var tags = RapidXamlDocumentCache.ErrorListTags(filePath)
                           .OfType <HardCodedStringTag>()
                           .OrderByDescending(t => t.Span.Start);

                var referenceUids = new Dictionary <Guid, string>();

                vs.StartSingleUndoOperation(StringRes.UI_UndoContextMoveStringsToResourceFile);

                try
                {
                    foreach (var tag in tags)
                    {
                        if (!tag.UidExists && referenceUids.ContainsKey(tag.ElementGuid))
                        {
                            tag.UidExists = true;
                            tag.UidValue  = referenceUids[tag.ElementGuid];
                        }

                        // pass in vs so have the same reference for tracking undo actions
                        var action = new HardCodedStringAction(filePath, null, tag, vs);
                        action.Execute(new CancellationTokenSource().Token);

                        if (tag.UidExists == false && tag.ElementGuid != Guid.Empty && !referenceUids.ContainsKey(tag.ElementGuid))
                        {
                            referenceUids.Add(tag.ElementGuid, tag.UidValue);
                        }
                    }
                }
                finally
                {
                    vs.EndSingleUndoOperation();
                }

                // Update again to force reflecting the changes that were just made.
                RapidXamlDocumentCache.TryUpdate(filePath);
            }
            catch (Exception exc)
            {
                this.Logger?.RecordException(exc);
                throw;
            }
            finally
            {
                System.Windows.Forms.Cursor.Current = previousCursor;
            }
        }