Skip to content

Commit

Permalink
Closes #5041
Browse files Browse the repository at this point in the history
  • Loading branch information
mansellan committed Jul 17, 2019
1 parent b9ccf14 commit 5a424ee
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 119 deletions.
Expand Up @@ -386,8 +386,7 @@ private void ExecuteRemoveCommand(object param)
public ImportCommand ImportCommand { get; set; }
public ExportCommand ExportCommand { get; set; }
public ExportAllCommand ExportAllCommand { get; set; }
// public ExcludeCommand ExcludeCommand { get; set; }
public OpenCommand DeleteCommand { get; set; } // TODO
public DeleteCommand DeleteCommand { get; set; }
public CommandBase RemoveCommand { get; }
public PrintCommand PrintCommand { get; set; }
public AddRemoveReferencesCommand AddRemoveReferencesCommand { get; set; }
Expand Down
86 changes: 82 additions & 4 deletions Rubberduck.Core/UI/CodeExplorer/Commands/DeleteCommand.cs
@@ -1,20 +1,98 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Rubberduck.Interaction;
using Rubberduck.Navigation.CodeExplorer;
using Rubberduck.VBEditor.ComManagement;
using Rubberduck.VBEditor.SafeComWrappers;
using Rubberduck.VBEditor.SafeComWrappers.Abstract;

namespace Rubberduck.UI.CodeExplorer.Commands
{
public class DeleteCommand : CodeExplorerCommandBase
{
public DeleteCommand()
private readonly RemoveCommand _removeCommand;
private readonly IProjectsRepository _projectsRepository;
private readonly IMessageBox _messageBox;
private readonly IVBE _vbe;

public DeleteCommand(RemoveCommand removeCommand, IProjectsRepository projectsRepository, IMessageBox messageBox, IVBE vbe)
{
// TODO
_removeCommand = removeCommand;
_projectsRepository = projectsRepository;
_messageBox = messageBox;
_vbe = vbe;

AddToCanExecuteEvaluation(SpecialEvaluateCanExecute);
}

private bool SpecialEvaluateCanExecute(object parameter)
{
return _vbe.Kind == VBEKind.Standalone &&
_removeCommand.CanExecute(parameter);
}

protected override void OnExecute(object parameter)
{
// TODO
if (!(parameter is CodeExplorerComponentViewModel node) || node.Declaration is null)
{
return;
}

var qualifiedModuleName = node.Declaration.QualifiedName.QualifiedModuleName;
var component = _projectsRepository.Component(qualifiedModuleName);
if (component is null)
{
return;
}

// Permanent operation, prompt for confirm
var message = string.Format(Resources.CodeExplorer.CodeExplorerUI.ConfirmBeforeDelete_Prompt, qualifiedModuleName.Name);
if (!_messageBox.ConfirmYesNo(message, Resources.CodeExplorer.CodeExplorerUI.ConfirmBeforeDelete_Caption))
{
return;
}

// Have to build the file list *before* removing the component!
var files = new List<string>();
for (short i = 1; i <= component.FileCount; i++)
{
var fileName = component.GetFileName(i);
if (fileName != null) // Unsaved components have a null filename for some reason
{
files.Add(component.GetFileName(i));
}
}

if (!_removeCommand.RemoveComponent(qualifiedModuleName, false))
{
return; // Remove was cancelled or failed
}

var failedDeletions = new List<string>();
foreach (var file in files)
{
try
{
File.Delete(file);
}
catch (Exception exception)
{
Logger.Error(exception, "Failed to delete file");
failedDeletions.Add(file);
}
}

// Let the user know if there are any component files left on disk
if (failedDeletions.Any())
{
message = string.Format(Resources.CodeExplorer.CodeExplorerUI.DeleteFailed_Message, string.Join(Environment.NewLine, failedDeletions));
_messageBox.NotifyWarn(message, Resources.CodeExplorer.CodeExplorerUI.DeleteFailed_Caption);
}

}

public override IEnumerable<Type> ApplicableNodeTypes => new List<Type>(); // TODO!!
public override IEnumerable<Type> ApplicableNodeTypes => new List<Type> { typeof(CodeExplorerComponentViewModel) };
}
}
59 changes: 0 additions & 59 deletions Rubberduck.Core/UI/CodeExplorer/Commands/ExcludeCommand.cs

This file was deleted.

45 changes: 29 additions & 16 deletions Rubberduck.Core/UI/CodeExplorer/Commands/ExportCommand.cs
Expand Up @@ -14,30 +14,47 @@ namespace Rubberduck.UI.CodeExplorer.Commands
{
public class ExportCommand : CommandBase
{
private static readonly Dictionary<ComponentType, string> ExportableFileExtensions = new Dictionary<ComponentType, string>
private static readonly Dictionary<ComponentType, string> VBAExportableFileExtensions = new Dictionary<ComponentType, string>
{
{ ComponentType.StandardModule, ".bas" },
{ ComponentType.ClassModule, ".cls" },
{ ComponentType.Document, ".cls" },
{ ComponentType.UserForm, ".frm" }
{ ComponentType.UserForm, ".frm" }
};

private static readonly Dictionary<ComponentType, string> VB6ExportableFileExtensions = new Dictionary<ComponentType, string>
{
{ ComponentType.StandardModule, ".bas" },
{ ComponentType.ClassModule, ".cls" },
{ ComponentType.VBForm, ".frm" },
{ ComponentType.MDIForm, ".frm" },
{ ComponentType.UserControl, ".ctl" },
{ ComponentType.DocObject, ".dob" },
{ ComponentType.ActiveXDesigner, ".dsr" },
{ ComponentType.PropPage, ".pag" },
{ ComponentType.ResFile, ".res" },
};

private readonly IFileSystemBrowserFactory _dialogFactory;
private readonly IVBE _vbe;
private readonly Dictionary<ComponentType, string> _ExportableFileExtensions;

public ExportCommand(IFileSystemBrowserFactory dialogFactory, IMessageBox messageBox, IProjectsRepository projectsRepository, IVBE vbe)
public ExportCommand(IFileSystemBrowserFactory dialogFactory, IMessageBox messageBox, IProjectsProvider projectsProvider, IVBE vbe)
{
_dialogFactory = dialogFactory;
_vbe = vbe;
MessageBox = messageBox;
ProjectsRepository = projectsRepository;
ProjectsProvider = projectsProvider;

_ExportableFileExtensions =
vbe.Kind == VBEKind.Hosted
? VBAExportableFileExtensions
: VB6ExportableFileExtensions;

AddToCanExecuteEvaluation(SpecialEvaluateCanExecute);
}

protected IMessageBox MessageBox { get; }
protected IProjectsRepository ProjectsRepository { get; }

protected IProjectsProvider ProjectsProvider { get; }
private bool SpecialEvaluateCanExecute(object parameter)
{
if (!(parameter is CodeExplorerComponentViewModel node) ||
Expand All @@ -46,13 +63,9 @@ private bool SpecialEvaluateCanExecute(object parameter)
return false;
}

if (_vbe.Kind != VBEKind.Hosted)
{
return false;
}

var componentType = node.Declaration.QualifiedName.QualifiedModuleName.ComponentType;
return ExportableFileExtensions.Select(s => s.Key).Contains(componentType);

return _ExportableFileExtensions.Select(s => s.Key).Contains(componentType);
}

protected override void OnExecute(object parameter)
Expand All @@ -68,7 +81,7 @@ protected override void OnExecute(object parameter)

public bool PromptFileNameAndExport(QualifiedModuleName qualifiedModule)
{
if (!ExportableFileExtensions.TryGetValue(qualifiedModule.ComponentType, out var extension))
if (!_ExportableFileExtensions.TryGetValue(qualifiedModule.ComponentType, out var extension))
{
return false;
}
Expand All @@ -84,7 +97,7 @@ public bool PromptFileNameAndExport(QualifiedModuleName qualifiedModule)
return false;
}

var component = ProjectsRepository.Component(qualifiedModule);
var component = ProjectsProvider.Component(qualifiedModule);
try
{
component.Export(dialog.FileName);
Expand Down
5 changes: 0 additions & 5 deletions Rubberduck.Core/UI/CodeExplorer/Commands/PrintCommand.cs
Expand Up @@ -37,15 +37,10 @@ private bool SpecialEvaluateCanExecute(object parameter)
try
{
var component = _projectsProvider.Component(node.Declaration.QualifiedName.QualifiedModuleName);
if (component is null)
{
return false;
}
using (var codeModule = component.CodeModule)
{
return codeModule.CountOfLines != 0;
}

}
catch (COMException)
{
Expand Down
72 changes: 45 additions & 27 deletions Rubberduck.Core/UI/CodeExplorer/Commands/RemoveCommand.cs
Expand Up @@ -3,6 +3,7 @@
using Rubberduck.Navigation.CodeExplorer;
using Rubberduck.Resources.CodeExplorer;
using Rubberduck.UI.Command;
using Rubberduck.VBEditor;
using Rubberduck.VBEditor.ComManagement;
using Rubberduck.VBEditor.SafeComWrappers;
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
Expand All @@ -16,7 +17,7 @@ public class RemoveCommand : CommandBase
private readonly IMessageBox _messageBox;
private readonly IVBE _vbe;

public RemoveCommand(ExportCommand exportCommand, IProjectsRepository projectsRepository, IMessageBox messageBox, IVBE vbe)
public RemoveCommand(ExportCommand exportCommand, IProjectsRepository projectsRepository, IMessageBox messageBox, IVBE vbe)
{
_exportCommand = exportCommand;
_projectsRepository = projectsRepository;
Expand All @@ -28,10 +29,10 @@ public RemoveCommand(ExportCommand exportCommand, IProjectsRepository projectsRe

private bool SpecialEvaluateCanExecute(object parameter)
{
return _vbe.Kind == VBEKind.Standalone ||
_exportCommand.CanExecute(parameter) &&
((CodeExplorerComponentViewModel)parameter).Declaration.QualifiedName.QualifiedModuleName.ComponentType != ComponentType.Document;
}
return _exportCommand.CanExecute(parameter) &&
parameter is CodeExplorerComponentViewModel viewModel &&
viewModel.Declaration.QualifiedName.QualifiedModuleName.ComponentType != ComponentType.Document;
}

protected override void OnExecute(object parameter)
{
Expand All @@ -42,31 +43,16 @@ protected override void OnExecute(object parameter)
return;
}

var qualifiedModuleName = node.Declaration.QualifiedName.QualifiedModuleName;
var projectId = qualifiedModuleName.ProjectId;
var projectType = _projectsRepository.Project(projectId).Type;
RemoveComponent(node.Declaration.QualifiedModuleName);
}

if (projectType == ProjectType.HostProject) // Prompt for export for VBA only
public bool RemoveComponent(QualifiedModuleName qualifiedModuleName, bool promptToExport = true)
{
if (promptToExport && !TryExport(qualifiedModuleName))
{
var message = string.Format(CodeExplorerUI.ExportBeforeRemove_Prompt, node.Name);

switch(_messageBox.Confirm(message, CodeExplorerUI.ExportBeforeRemove_Caption, ConfirmationOutcome.Yes))
{
case ConfirmationOutcome.Yes:
if (!_exportCommand.PromptFileNameAndExport(qualifiedModuleName))
{
return; // Don't remove if export was cancelled
}
break;

case ConfirmationOutcome.Cancel:
return;

case ConfirmationOutcome.No:
break;
}
return false;
}

// No file export or file successfully exported--now remove it
try
{
Expand All @@ -75,7 +61,39 @@ protected override void OnExecute(object parameter)
catch (Exception ex)
{
_messageBox.NotifyWarn(ex.Message, string.Format(CodeExplorerUI.RemoveError_Caption, qualifiedModuleName.ComponentName));
return false;
}

return true;
}

private bool TryExport(QualifiedModuleName qualifiedModuleName)
{
var projectId = qualifiedModuleName.ProjectId;
var projectType = _projectsRepository.Project(projectId).Type;
var component = _projectsRepository.Component(qualifiedModuleName);

if (projectType == ProjectType.HostProject && component.IsSaved)
{
return true; // File already up-to-date
}

var message = string.Format(CodeExplorerUI.ExportBeforeRemove_Prompt, qualifiedModuleName.Name);

switch (_messageBox.Confirm(message, CodeExplorerUI.ExportBeforeRemove_Caption, ConfirmationOutcome.Yes))
{
case ConfirmationOutcome.No:
return true;

case ConfirmationOutcome.Yes:
if (_exportCommand.PromptFileNameAndExport(qualifiedModuleName))
{
return true;
}
break;
}

return false; // Export cancelled or failed
}
}
}

0 comments on commit 5a424ee

Please sign in to comment.