public void RemoveSolutionItem (SolutionItem item) { string question = GettextCatalog.GetString ("Do you really want to remove project '{0}' from '{1}'?", item.Name, item.ParentFolder.Name); string secondaryText = GettextCatalog.GetString ("The Remove option remove the project from the solution, but it will not physically delete any file from disk."); SolutionEntityItem prj = item as SolutionEntityItem; if (prj == null) { if (MessageService.Confirm (question, AlertButton.Remove) && IdeApp.Workspace.RequestItemUnload (item)) RemoveItemFromSolution (prj); return; } AlertButton delete = new AlertButton (GettextCatalog.GetString ("Delete from Disk")); AlertButton result = MessageService.AskQuestion (question, secondaryText, delete, AlertButton.Cancel, AlertButton.Remove); if (result == delete) { if (!IdeApp.Workspace.RequestItemUnload (prj)) return; ConfirmProjectDeleteDialog dlg = new ConfirmProjectDeleteDialog (prj); if (MessageService.RunCustomDialog (dlg) == (int) Gtk.ResponseType.Ok) { // Remove the project before removing the files to avoid unnecessary events RemoveItemFromSolution (prj); List<FilePath> files = dlg.GetFilesToDelete (); dlg.Destroy (); using (IProgressMonitor monitor = new MessageDialogProgressMonitor (true)) { monitor.BeginTask (GettextCatalog.GetString ("Deleting Files..."), files.Count); foreach (FilePath file in files) { try { if (Directory.Exists (file)) FileService.DeleteDirectory (file); else FileService.DeleteFile (file); } catch (Exception ex) { monitor.ReportError (GettextCatalog.GetString ("The file or directory '{0}' could not be deleted.", file), ex); } monitor.Step (1); } monitor.EndTask (); } } else dlg.Destroy (); } else if (result == AlertButton.Remove && IdeApp.Workspace.RequestItemUnload (prj)) { RemoveItemFromSolution (prj); } }
/// <summary> /// Adds files to a project, potentially asking the user whether to move, copy or link the files. /// </summary> public IList<ProjectFile> AddFilesToProject (Project project, FilePath[] files, FilePath[] targetPaths, string buildAction) { Debug.Assert (project != null); Debug.Assert (files != null); Debug.Assert (targetPaths != null); Debug.Assert (files.Length == targetPaths.Length); AddAction action = AddAction.Copy; bool applyToAll = true; bool dialogShown = false; IProgressMonitor monitor = null; if (files.Length > 10) { monitor = new MessageDialogProgressMonitor (true); monitor.BeginTask (GettextCatalog.GetString("Adding files..."), files.Length); } var newFileList = new List<ProjectFile> (); //project.AddFile (string) does linear search for duplicate file, so instead we use this HashSet and //and add the ProjectFiles directly. With large project and many files, this should really help perf. //Also, this is a better check because we handle vpaths and links. //FIXME: it would be really nice if project.Files maintained these hashmaps var vpathsInProject = new HashSet<FilePath> (project.Files.Select (pf => pf.ProjectVirtualPath)); var filesInProject = new Dictionary<FilePath,ProjectFile> (); foreach (var pf in project.Files) filesInProject [pf.FilePath] = pf; using (monitor) { for (int i = 0; i < files.Length; i++) { FilePath file = files[i]; if (monitor != null) { monitor.Log.WriteLine (file); monitor.Step (1); } if (FileService.IsDirectory (file)) { //FIXME: warning about skipping? newFileList.Add (null); continue; } FilePath targetPath = targetPaths[i].CanonicalPath; Debug.Assert (targetPath.IsChildPathOf (project.BaseDirectory)); var vpath = targetPath.ToRelative (project.BaseDirectory); if (vpathsInProject.Contains (vpath)) { if (project.Files.GetFileWithVirtualPath (vpath).FilePath != file) MessageService.ShowWarning (GettextCatalog.GetString ( "There is a already a file or link in the project with the name '{0}'", vpath)); continue; } string fileBuildAction = buildAction; if (string.IsNullOrEmpty (buildAction)) fileBuildAction = project.GetDefaultBuildAction (targetPath); //files in the target directory get added directly in their current location without moving/copying if (file.CanonicalPath == targetPath) { AddFileToFolder (newFileList, vpathsInProject, filesInProject, file, fileBuildAction); continue; } //for files outside the project directory, we ask the user whether to move, copy or link AddExternalFileDialog addExternalDialog = null; if (!dialogShown || !applyToAll) { addExternalDialog = new AddExternalFileDialog (file); if (files.Length > 1) { addExternalDialog.ApplyToAll = applyToAll; addExternalDialog.ShowApplyAll = true; } if (file.IsChildPathOf (targetPath.ParentDirectory)) addExternalDialog.ShowKeepOption (file.ParentDirectory.ToRelative (targetPath.ParentDirectory)); else { if (action == AddAction.Keep) action = AddAction.Copy; addExternalDialog.SelectedAction = action; } } try { if (!dialogShown || !applyToAll) { if (MessageService.RunCustomDialog (addExternalDialog) == (int) Gtk.ResponseType.Cancel) { project.Files.AddRange (newFileList.Where (f => f != null)); return newFileList; } action = addExternalDialog.SelectedAction; applyToAll = addExternalDialog.ApplyToAll; dialogShown = true; } if (action == AddAction.Keep) { AddFileToFolder (newFileList, vpathsInProject, filesInProject, file, fileBuildAction); continue; } if (action == AddAction.Link) { ProjectFile pf = new ProjectFile (file, fileBuildAction) { Link = vpath }; vpathsInProject.Add (pf.ProjectVirtualPath); filesInProject [pf.FilePath] = pf; newFileList.Add (pf); continue; } try { if (!Directory.Exists (targetPath.ParentDirectory)) FileService.CreateDirectory (targetPath.ParentDirectory); if (MoveCopyFile (file, targetPath, action == AddAction.Move)) { var pf = new ProjectFile (targetPath, fileBuildAction); vpathsInProject.Add (pf.ProjectVirtualPath); filesInProject [pf.FilePath] = pf; newFileList.Add (pf); } else { newFileList.Add (null); } } catch (Exception ex) { MessageService.ShowException (ex, GettextCatalog.GetString ( "An error occurred while attempt to move/copy that file. Please check your permissions.")); newFileList.Add (null); } } finally { if (addExternalDialog != null) addExternalDialog.Destroy (); } } } project.Files.AddRange (newFileList.Where (f => f != null)); return newFileList; }
protected virtual void OnButton24Clicked (object sender, System.EventArgs e) { var dialog = new SelectFileDialog (GettextCatalog.GetString ("Add items to toolbox")) { SelectMultiple = true, TransientFor = this, }; dialog.AddFilter (null, "*.dll"); if (dialog.Run ()) { indexModified = true; // Add the new files to the index using (var monitor = new MessageDialogProgressMonitor (true, false, false, true)) { monitor.BeginTask (GettextCatalog.GetString ("Looking for components..."), dialog.SelectedFiles.Length); foreach (string s in dialog.SelectedFiles) { var cif = index.AddFile (s); monitor.Step (1); if (cif != null) { // Select all new items by default foreach (var it in cif.Components) currentItems.Add (it, it); } else MessageService.ShowWarning (GettextCatalog.GetString ("The file '{0}' does not contain any component.", s)); } } Fill (); } }
/// <summary> /// Adds files to a project, potentially asking the user whether to move, copy or link the files. /// </summary> public IList<ProjectFile> AddFilesToProject (Project project, FilePath[] files, FilePath[] targetPaths, string buildAction) { Debug.Assert (project != null); Debug.Assert (files != null); Debug.Assert (targetPaths != null); Debug.Assert (files.Length == targetPaths.Length); AddAction action = AddAction.Copy; bool applyToAll = true; bool dialogShown = false; bool supportsLinking = !(project is MonoDevelop.Projects.SharedAssetsProjects.SharedAssetsProject); var confirmReplaceFileMessage = new QuestionMessage (); if (files.Length > 1) { confirmReplaceFileMessage.AllowApplyToAll = true; confirmReplaceFileMessage.Buttons.Add (new AlertButton (GettextCatalog.GetString ("Skip"))); } confirmReplaceFileMessage.Buttons.Add (AlertButton.Cancel); confirmReplaceFileMessage.Buttons.Add (AlertButton.OverwriteFile); confirmReplaceFileMessage.DefaultButton = confirmReplaceFileMessage.Buttons.Count - 1; ProgressMonitor monitor = null; if (files.Length > 10) { monitor = new MessageDialogProgressMonitor (true); monitor.BeginTask (GettextCatalog.GetString("Adding files..."), files.Length); } var newFileList = new List<ProjectFile> (); //project.AddFile (string) does linear search for duplicate file, so instead we use this HashSet and //and add the ProjectFiles directly. With large project and many files, this should really help perf. //Also, this is a better check because we handle vpaths and links. //FIXME: it would be really nice if project.Files maintained these hashmaps var vpathsInProject = new Dictionary<FilePath, ProjectFile> (); var filesInProject = new Dictionary<FilePath,ProjectFile> (); foreach (var pf in project.Files) { filesInProject [pf.FilePath] = pf; vpathsInProject [pf.ProjectVirtualPath] = pf; } using (monitor) { for (int i = 0; i < files.Length; i++) { FilePath file = files[i]; if (monitor != null) { monitor.Log.WriteLine (file); monitor.Step (1); } if (FileService.IsDirectory (file)) { //FIXME: warning about skipping? newFileList.Add (null); continue; } FilePath targetPath = targetPaths[i].CanonicalPath; Debug.Assert (targetPath.IsChildPathOf (project.BaseDirectory)); ProjectFile vfile; var vpath = targetPath.ToRelative (project.BaseDirectory); if (vpathsInProject.TryGetValue (vpath, out vfile)) { if (vfile.IsLink) { MessageService.ShowWarning (GettextCatalog.GetString ( "There is already a link in the project with the name '{0}'", vpath)); continue; } else if (vfile.FilePath == file) { // File already exists in project. continue; } } string fileBuildAction = buildAction; if (string.IsNullOrEmpty (buildAction)) fileBuildAction = project.GetDefaultBuildAction (targetPath); //files in the target directory get added directly in their current location without moving/copying if (file.CanonicalPath == targetPath) { if (vfile != null) ShowFileExistsInProjectMessage (vpath); else AddFileToFolder (newFileList, vpathsInProject, filesInProject, file, fileBuildAction); continue; } //for files outside the project directory, we ask the user whether to move, copy or link AddExternalFileDialog addExternalDialog = null; if (!dialogShown || !applyToAll) { addExternalDialog = new AddExternalFileDialog (file); if (!supportsLinking) addExternalDialog.DisableLinkOption (); if (files.Length > 1) { addExternalDialog.ApplyToAll = applyToAll; addExternalDialog.ShowApplyAll = true; } if (file.IsChildPathOf (targetPath.ParentDirectory)) addExternalDialog.ShowKeepOption (file.ParentDirectory.ToRelative (targetPath.ParentDirectory)); else { if (action == AddAction.Keep) action = AddAction.Copy; addExternalDialog.SelectedAction = action; } } try { if (!dialogShown || !applyToAll) { int response = MessageService.RunCustomDialog (addExternalDialog); // A dialog emits DeleteEvent rather than Cancel in response to Escape being pressed if (response == (int) Gtk.ResponseType.Cancel || response == (int) Gtk.ResponseType.DeleteEvent) { project.Files.AddRange (newFileList.Where (f => f != null)); return newFileList; } action = addExternalDialog.SelectedAction; applyToAll = addExternalDialog.ApplyToAll; dialogShown = true; } if (action == AddAction.Keep) { if (vfile != null) ShowFileExistsInProjectMessage (vpath); else AddFileToFolder (newFileList, vpathsInProject, filesInProject, file, fileBuildAction); continue; } if (action == AddAction.Link) { if (vfile != null) { ShowFileExistsInProjectMessage (vpath); continue; } ProjectFile pf = new ProjectFile (file, fileBuildAction) { Link = vpath }; vpathsInProject [pf.ProjectVirtualPath] = pf; filesInProject [pf.FilePath] = pf; newFileList.Add (pf); continue; } try { if (!Directory.Exists (targetPath.ParentDirectory)) FileService.CreateDirectory (targetPath.ParentDirectory); bool? result = MoveCopyFile (file, targetPath, action == AddAction.Move, confirmReplaceFileMessage); if (result == true) { if (vfile == null) { var pf = new ProjectFile (targetPath, fileBuildAction); vpathsInProject [pf.ProjectVirtualPath] = pf; filesInProject [pf.FilePath] = pf; newFileList.Add (pf); } } else if (result == null) { project.Files.AddRange (newFileList.Where (f => f != null)); return newFileList; } else { newFileList.Add (null); } } catch (Exception ex) { MessageService.ShowError (GettextCatalog.GetString ( "An error occurred while attempt to move/copy that file. Please check your permissions."), ex); newFileList.Add (null); } } finally { if (addExternalDialog != null) { addExternalDialog.Destroy (); addExternalDialog.Dispose (); } } } } project.Files.AddRange (newFileList.Where (f => f != null)); return newFileList; }
/// <summary> /// Adds files to a project, potentially asking the user whether to move, copy or link the files. /// </summary> public IList<ProjectFile> AddFilesToProject (Project project, FilePath[] files, FilePath[] targetPaths, string buildAction) { Debug.Assert (project != null); Debug.Assert (files != null); Debug.Assert (targetPaths != null); Debug.Assert (files.Length == targetPaths.Length); int action = -1; IProgressMonitor monitor = null; if (files.Length > 10) { monitor = new MessageDialogProgressMonitor (true); monitor.BeginTask (GettextCatalog.GetString("Adding files..."), files.Length); } var newFileList = new List<ProjectFile> (); //project.AddFile (string) does linear search for duplicate file, so instead we use this HashSet and //and add the ProjectFiles directly. With large project and many files, this should really help perf. //Also, this is a better check because we handle vpaths and links. //FIXME: it would be really nice if project.Files maintained these hashmaps var vpathsInProject = new HashSet<FilePath> (project.Files.Select (pf => pf.ProjectVirtualPath)); var filesInProject = new Dictionary<FilePath,ProjectFile> (); foreach (var pf in project.Files) filesInProject [pf.FilePath] = pf; using (monitor) { for (int i = 0; i < files.Length; i++) { FilePath file = files[i]; if (monitor != null) { monitor.Log.WriteLine (file); monitor.Step (1); } if (FileService.IsDirectory (file)) { //FIXME: warning about skipping? newFileList.Add (null); continue; } FilePath targetPath = targetPaths[i].CanonicalPath; Debug.Assert (targetPath.IsChildPathOf (project.BaseDirectory)); var vpath = targetPath.ToRelative (project.BaseDirectory); if (vpathsInProject.Contains (vpath)) { MessageService.ShowWarning (GettextCatalog.GetString ( "There is a already a file or link in the project with the name '{0}'", vpath)); continue; } string fileBuildAction = buildAction; if (string.IsNullOrEmpty (buildAction)) fileBuildAction = project.GetDefaultBuildAction (file); //files in the target directory get added directly in their current location without moving/copying if (file.CanonicalPath == targetPath) { //FIXME: MD project system doesn't cope with duplicate includes - project save/load will remove the file ProjectFile pf; if (filesInProject.TryGetValue (targetPath, out pf)) { var link = pf.Link; MessageService.ShowWarning (GettextCatalog.GetString ( "The link '{0}' in the project already includes the file '{1}'", link, file)); continue; } pf = new ProjectFile (file, fileBuildAction); vpathsInProject.Add (pf.ProjectVirtualPath); filesInProject [pf.FilePath] = pf; newFileList.Add (pf); continue; } //for files outside the project directory, we ask the user whether to move, copy or link var md = new Gtk.MessageDialog ( IdeApp.Workbench.RootWindow, Gtk.DialogFlags.Modal | Gtk.DialogFlags.DestroyWithParent, Gtk.MessageType.Question, Gtk.ButtonsType.None, GettextCatalog.GetString ("The file {0} is outside the target directory. What would you like to do?", file)); try { Gtk.CheckButton remember = null; if (files.Length > 1) { remember = new Gtk.CheckButton (GettextCatalog.GetString ("Use the same action for all selected files.")); md.VBox.PackStart (remember, false, false, 0); } const int ACTION_LINK = 3; const int ACTION_COPY = 1; const int ACTION_MOVE = 2; md.AddButton (GettextCatalog.GetString ("_Link"), ACTION_LINK); md.AddButton (Gtk.Stock.Copy, ACTION_COPY); md.AddButton (GettextCatalog.GetString ("_Move"), ACTION_MOVE); md.AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel); md.VBox.ShowAll (); int ret = -1; if (action < 0) { ret = MessageService.RunCustomDialog (md); if (ret < 0) { project.Files.AddRange (newFileList.Where (f => f != null)); return newFileList; } if (remember != null && remember.Active) action = ret; } else { ret = action; } if (ret == ACTION_LINK) { //FIXME: MD project system doesn't cope with duplicate includes - project save/load will remove the file ProjectFile pf; if (filesInProject.TryGetValue (file, out pf)) { var link = pf.Link; MessageService.ShowWarning (GettextCatalog.GetString ( "The link '{0}' in the project already includes the file '{1}'", link, file)); continue; } pf = new ProjectFile (file, fileBuildAction) { Link = vpath }; vpathsInProject.Add (pf.ProjectVirtualPath); filesInProject [pf.FilePath] = pf; newFileList.Add (pf); continue; } try { if (!Directory.Exists (targetPath.ParentDirectory)) FileService.CreateDirectory (targetPath.ParentDirectory); if (MoveCopyFile (file, targetPath, ret == ACTION_MOVE)) { var pf = new ProjectFile (targetPath, fileBuildAction); vpathsInProject.Add (pf.ProjectVirtualPath); filesInProject [pf.FilePath] = pf; newFileList.Add (pf); } else { newFileList.Add (null); } } catch (Exception ex) { MessageService.ShowException (ex, GettextCatalog.GetString ( "An error occurred while attempt to move/copy that file. Please check your permissions.")); newFileList.Add (null); } } finally { md.Destroy (); } } } project.Files.AddRange (newFileList.Where (f => f != null)); return newFileList; }
/// <summary> /// Adds files to a project, potentially asking the user whether to move, copy or link the files. /// </summary> public IList<ProjectFile> AddFilesToProject (Project project, FilePath[] files, FilePath targetDirectory, string buildAction) { int action = -1; IProgressMonitor monitor = null; if (files.Length > 10) { monitor = new MessageDialogProgressMonitor (true); monitor.BeginTask (GettextCatalog.GetString("Adding files..."), files.Length); } var newFileList = new List<ProjectFile> (); using (monitor) { foreach (FilePath file in files) { if (monitor != null) { monitor.Log.WriteLine (file); monitor.Step (1); } if (FileService.IsDirectory (file)) { //FIXME: warning about skipping? newFileList.Add (null); continue; } //files in the project directory get added directly in their current location without moving/copying if (file.IsChildPathOf (project.BaseDirectory)) { newFileList.Add (project.AddFile (file, buildAction)); continue; } //for files outside the project directory, we ask the user whether to move, copy or link var md = new Gtk.MessageDialog ( IdeApp.Workbench.RootWindow, Gtk.DialogFlags.Modal | Gtk.DialogFlags.DestroyWithParent, Gtk.MessageType.Question, Gtk.ButtonsType.None, GettextCatalog.GetString ("The file {0} is outside the project directory. What would you like to do?", file)); try { Gtk.CheckButton remember = null; if (files.Length > 1) { remember = new Gtk.CheckButton (GettextCatalog.GetString ("Use the same action for all selected files.")); md.VBox.PackStart (remember, false, false, 0); } const int ACTION_LINK = 3; const int ACTION_COPY = 1; const int ACTION_MOVE = 2; md.AddButton (GettextCatalog.GetString ("_Link"), ACTION_LINK); md.AddButton (Gtk.Stock.Copy, ACTION_COPY); md.AddButton (GettextCatalog.GetString ("_Move"), ACTION_MOVE); md.AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel); md.VBox.ShowAll (); int ret = -1; if (action < 0) { ret = MessageService.RunCustomDialog (md); if (ret < 0) return newFileList; if (remember != null && remember.Active) action = ret; } else { ret = action; } var targetName = targetDirectory.Combine (file.FileName); if (ret == ACTION_LINK) { var pf = project.AddFile (file, buildAction); pf.Link = project.GetRelativeChildPath (targetName); newFileList.Add (pf); continue; } try { if (MoveCopyFile (file, targetName, ret == ACTION_MOVE)) newFileList.Add (project.AddFile (targetName, buildAction)); else newFileList.Add (null); } catch (Exception ex) { MessageService.ShowException (ex, GettextCatalog.GetString ( "An error occurred while attempt to move/copy that file. Please check your permissions.")); newFileList.Add (null); } } finally { md.Destroy (); } } } return newFileList; }