Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez <lluis@novell.com>2009-08-11 18:47:31 +0400
committerLluis Sanchez <lluis@novell.com>2009-08-11 18:47:31 +0400
commit7f9ed19fc609bfd7799e38d69cb7f89655fa2e5f (patch)
tree3970fb4df99e9b6694f63b0a6c479f6b59e2bde4 /main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks
parentb73651b980c8ad02dffee7f77f27b7e0343f6c19 (diff)
* Makefile.am:
* MonoDevelop.Ide.csproj: * MonoDevelop.Ide.Gui\Ide.cs: * MonoDevelop.Ide\Services.cs: * MonoDevelop.Ide.Tasks\Task.cs: * MonoDevelop.Ide.Gui\Document.cs: * MonoDevelop.Ide.Tasks\UserTask.cs: * MonoDevelop.Ide.Tasks\TaskStore.cs: * MonoDevelop.Ide.Tasks\TaskService.cs: * MonoDevelop.Ide.Tasks\UserTasksView.cs: * MonoDevelop.Ide.Gui\ProjectOperations.cs: * MonoDevelop.Ide.Gui.Pads\ErrorListPad.cs: * MonoDevelop.Ide.Tasks\CommentTasksView.cs: Reimplemented the task service. It should now be more efficient. svn path=/trunk/monodevelop/; revision=139707
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs192
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/Task.cs298
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs544
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskStore.cs342
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/UserTask.cs80
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/UserTasksView.cs53
6 files changed, 774 insertions, 735 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs
index 20914d8797..8a893dd20f 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/CommentTasksView.cs
@@ -37,6 +37,9 @@ using MonoDevelop.Projects;
using MonoDevelop.Ide;
using MonoDevelop.Ide.Gui;
using MonoDevelop.Core.Gui;
+using MonoDevelop.Projects.Text;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Projects.Dom;
namespace MonoDevelop.Ide.Tasks
{
@@ -56,16 +59,32 @@ namespace MonoDevelop.Ide.Tasks
MonoDevelop.Ide.Gui.Components.PadTreeView view;
ListStore store;
- Hashtable tasks = new Hashtable ();
Gdk.Color highPrioColor, normalPrioColor, lowPrioColor;
Menu menu;
Dictionary<ToggleAction, int> columnsActions = new Dictionary<ToggleAction, int> ();
Clipboard clipboard;
+
+ TaskStore comments = new TaskStore ();
+ Dictionary<string, TaskPriority> priorities = new Dictionary<string, TaskPriority> ();
public CommentTasksView ()
{
+ }
+
+ void CreateView ()
+ {
+ if (view != null)
+ return;
+
+ ReloadPriorities ();
+
+ ProjectDomService.CommentTasksChanged += OnCommentTasksChanged;
+ ProjectDomService.SpecialCommentTagsChanged += OnCommentTagsChanged;
+ IdeApp.Workspace.WorkspaceItemLoaded += OnWorkspaceItemLoaded;
+ IdeApp.Workspace.WorkspaceItemUnloaded += OnWorkspaceItemUnloaded;
+
highPrioColor = StringToColor ((string)PropertyService.Get ("Monodevelop.UserTasksHighPrioColor", ""));
normalPrioColor = StringToColor ((string)PropertyService.Get ("Monodevelop.UserTasksNormalPrioColor", ""));
lowPrioColor = StringToColor ((string)PropertyService.Get ("Monodevelop.UserTasksLowPrioColor", ""));
@@ -110,15 +129,15 @@ namespace MonoDevelop.Ide.Tasks
LoadColumnsVisibility ();
- Services.TaskService.TaskAdded += (TaskEventHandler) DispatchService.GuiDispatch (new TaskEventHandler (GeneratedTaskAdded));
- Services.TaskService.TaskRemoved += (TaskEventHandler) DispatchService.GuiDispatch (new TaskEventHandler (GeneratedTaskRemoved));
+ comments.TasksAdded += (TaskEventHandler) DispatchService.GuiDispatch (new TaskEventHandler (GeneratedTaskAdded));
+ comments.TasksRemoved += (TaskEventHandler) DispatchService.GuiDispatch (new TaskEventHandler (GeneratedTaskRemoved));
PropertyService.PropertyChanged += (EventHandler<PropertyChangedEventArgs>) DispatchService.GuiDispatch (new EventHandler<PropertyChangedEventArgs> (OnPropertyUpdated));
CreateMenu ();
// Initialize with existing tags.
- foreach (Task t in Services.TaskService.CommentTasks)
+ foreach (Task t in comments)
AddGeneratedTask (t);
}
@@ -146,53 +165,127 @@ namespace MonoDevelop.Ide.Tasks
view.Columns[(int)Columns.Path].Visible);
PropertyService.Set ("Monodevelop.CommentTasksColumns", columns);
}
+
+ void OnWorkspaceItemLoaded (object sender, WorkspaceItemEventArgs e)
+ {
+ comments.BeginTaskUpdates ();
+ try {
+ Solution sol = e.Item as Solution;
+ if (sol != null) {
+ // Load all tags that are stored in pidb files
+ foreach (Project p in sol.GetAllProjects ()) {
+ ProjectDom pContext = ProjectDomService.GetProjectDom (p);
+ if (pContext == null)
+ continue;
+ foreach (ProjectFile file in p.Files) {
+ IList<Tag> tags = pContext.GetSpecialComments (file.Name);
+ if (tags !=null)
+ UpdateCommentTags (sol, file.Name, tags);
+ }
+ }
+ }
+ }
+ finally {
+ comments.EndTaskUpdates ();
+ }
+ }
+
+ void OnWorkspaceItemUnloaded (object sender, WorkspaceItemEventArgs e)
+ {
+ comments.RemoveItemTasks (e.Item, true);
+ }
- void GeneratedTaskAdded (object sender, TaskEventArgs e)
+ void OnCommentTasksChanged (object sender, CommentTasksChangedEventArgs e)
+ {
+ if (e.Project != null)
+ UpdateCommentTags (e.Project, e.FileName, e.TagComments);
+ }
+
+ void OnCommentTagsChanged (object sender, EventArgs e)
{
- foreach (Task t in e.Tasks) {
- if (t.TaskType == TaskType.Comment)
- AddGeneratedTask (t);
+ ReloadPriorities ();
+ }
+
+ void UpdateCommentTags (IWorkspaceObject wob, FilePath fileName, IEnumerable<Tag> tagComments)
+ {
+ if (fileName == FilePath.Null)
+ return;
+
+ fileName = fileName.FullPath;
+
+ List<Task> newTasks = new List<Task> ();
+ if (tagComments != null) {
+ foreach (Tag tag in tagComments) {
+ if (!priorities.ContainsKey (tag.Key))
+ continue;
+ Task t = new Task (fileName,
+ tag.Key + tag.Text,
+ tag.Region.Start.Column - 1,
+ tag.Region.Start.Line,
+ TaskSeverity.Information,
+ priorities[tag.Key],
+ wob);
+ newTasks.Add (t);
+ }
+ }
+
+ List<Task> oldTasks = new List<Task> (comments.GetFileTasks (fileName));
+
+ for (int i = 0; i < newTasks.Count; ++i) {
+ for (int j = 0; j < oldTasks.Count; ++j) {
+ if (oldTasks[j] != null &&
+ newTasks[i].Line == oldTasks[j].Line &&
+ newTasks[i].Column == oldTasks[j].Column &&
+ newTasks[i].Description == oldTasks[j].Description &&
+ newTasks[i].Priority == oldTasks[j].Priority)
+ {
+ newTasks.RemoveAt (i);
+ oldTasks.RemoveAt (j);
+ i--;
+ break;
+ }
+ }
+ }
+
+ comments.BeginTaskUpdates ();
+ try {
+ comments.AddRange (newTasks);
+ comments.RemoveRange (oldTasks);
+ } finally {
+ comments.EndTaskUpdates ();
}
}
+
+ void ReloadPriorities ()
+ {
+ priorities.Clear ();
+ foreach (CommentTag tag in ProjectDomService.SpecialCommentTags)
+ priorities.Add (tag.Tag, (TaskPriority) tag.Priority);
+ }
+
+ void GeneratedTaskAdded (object sender, TaskEventArgs e)
+ {
+ foreach (Task t in e.Tasks)
+ AddGeneratedTask (t);
+ }
void AddGeneratedTask (Task t)
{
- if (tasks.Contains (t)) return;
-
- tasks [t] = t;
-
- string tmpPath = t.FileName;
+ FilePath tmpPath = t.FileName;
if (t.WorkspaceObject != null)
- tmpPath = FileService.AbsoluteToRelativePath (t.WorkspaceObject.BaseDirectory, t.FileName);
-
- string fileName = tmpPath;
- string path = tmpPath;
+ tmpPath = tmpPath.ToRelative (t.WorkspaceObject.BaseDirectory);
- try {
- fileName = Path.GetFileName (tmpPath);
- } catch (Exception) {}
-
- try {
- path = Path.GetDirectoryName (tmpPath);
- } catch (Exception) {}
-
- store.AppendValues (t.Line, t.Description, fileName, path, t, GetColorByPriority (t.Priority), (int)Pango.Weight.Bold);
+ store.AppendValues (t.Line, t.Description, tmpPath.FileName, tmpPath.ParentDirectory.FileName, t, GetColorByPriority (t.Priority), (int)Pango.Weight.Bold);
}
void GeneratedTaskRemoved (object sender, TaskEventArgs e)
{
- foreach (Task t in e.Tasks) {
- if (t.TaskType == TaskType.Comment)
- RemoveGeneratedTask (t);
- }
+ foreach (Task t in e.Tasks)
+ RemoveGeneratedTask (t);
}
void RemoveGeneratedTask (Task t)
{
- if (!tasks.Contains (t)) return;
-
- tasks[t] = null;
-
TreeIter iter = FindTask (store, t);
if (!iter.Equals (TreeIter.Zero))
store.Remove (ref iter);
@@ -201,17 +294,16 @@ namespace MonoDevelop.Ide.Tasks
static TreeIter FindTask (ListStore store, Task task)
{
TreeIter iter;
- store.GetIterFirst (out iter);
- Task t = store.GetValue (iter, (int)Columns.Task) as Task;
- if (t != null && t == task) {
- return iter;
- }
- while (store.IterNext (ref iter)) {
- t = store.GetValue (iter, (int)Columns.Task) as Task;
- if (t != null && t == task) {
+ if (!store.GetIterFirst (out iter))
+ return TreeIter.Zero;
+
+ do {
+ Task t = store.GetValue (iter, (int)Columns.Task) as Task;
+ if (t == task)
return iter;
- }
}
+ while (store.IterNext (ref iter));
+
return TreeIter.Zero;
}
@@ -362,7 +454,7 @@ namespace MonoDevelop.Ide.Tasks
doc.TextEditor.JumpTo (task.Line, task.Column);
line = line.Substring (0, index);
doc.TextEditor.ReplaceLine (task.Line, line);
- IdeApp.Services.TaskService.Remove (task);
+ comments.Remove (task);
}
}
}
@@ -470,8 +562,16 @@ namespace MonoDevelop.Ide.Tasks
}
#region ITaskListView members
- TreeView ITaskListView.Content { get { return view; } }
- ToolItem[] ITaskListView.ToolBarItems { get { return null; } }
+ TreeView ITaskListView.Content {
+ get {
+ CreateView ();
+ return view;
+ }
+ }
+
+ ToolItem[] ITaskListView.ToolBarItems {
+ get { return null; }
+ }
#endregion
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/Task.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/Task.cs
index 26ccbf1899..ba7dac4a17 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/Task.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/Task.cs
@@ -1,22 +1,29 @@
-// Task.cs
-//
-// This file was derived from a file from #Develop.
-//
-// Copyright (C) 2001-2007 Mike Krüger <mkrueger@novell.com>
//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
+// Task.cs
//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Author:
+// Lluis Sanchez Gual <lluis@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
using System;
using System.Collections;
@@ -27,181 +34,186 @@ using MonoDevelop.Ide.Gui;
using MonoDevelop.Ide.Gui.Components;
using MonoDevelop.Ide.Gui.Pads.ProjectPad;
using MonoDevelop.Core;
+using MonoDevelop.Core.Serialization;
namespace MonoDevelop.Ide.Tasks
{
- public enum TaskType {
- Error,
- Warning,
- Message,
- SearchResult,
- Comment
- }
-
- public class Task
+ public class Task
{
+ [ItemProperty]
+ FilePath file;
+
+ [ItemProperty (DefaultValue = 0)]
+ int line;
+
+ [ItemProperty (DefaultValue = 0)]
+ int column;
+
+ [ItemProperty (DefaultValue = "")]
+ string description = string.Empty;
+
+ [ItemProperty (DefaultValue = "")]
+ string code = string.Empty;
+
+ [ItemProperty (DefaultValue = TaskPriority.Normal)]
TaskPriority priority = TaskPriority.Normal;
- string description;
- FilePath fileName;
- TaskType type;
- int line;
- int column;
-
- int savedLine = -1;
- string errorNumber;
+ [ItemProperty (DefaultValue = TaskSeverity.Information)]
+ TaskSeverity severity = TaskSeverity.Information;
+
+ [ItemProperty (DefaultValue = false)]
+ bool completed;
+
object owner;
+ IWorkspaceObject parentObject;
+ internal int SavedLine;
+
+ public Task (FilePath file, string description, int column, int line, TaskSeverity severity)
+ : this (file, description, column, line, severity, TaskPriority.Normal, null, null)
+ {
+ }
+
+ public Task (FilePath file, string description, int column, int line, TaskSeverity severity, TaskPriority priority)
+ : this (file, description, column, line, severity, priority, null, null)
+ {
+ }
- public override string ToString ()
+ public Task (FilePath file, string description, int column, int line, TaskSeverity severity, TaskPriority priority, IWorkspaceObject parent)
+ : this (file, description, column, line, severity, priority, parent, null)
{
- return String.Format ("[Task:File={0}, Line={1}, Column={2}, Type={3}, Priority={4}, Description={5}]",
- fileName,
- line,
- column,
- type,
- Enum.GetName (typeof (TaskPriority), priority),
- description);
}
- public IWorkspaceObject WorkspaceObject {
- get {
- return owner as IWorkspaceObject;
- }
+ public Task (FilePath file, string description, int column, int line, TaskSeverity severity, TaskPriority priority, IWorkspaceObject parent, object owner)
+ {
+ this.file = file;
+ this.description = description;
+ this.column = column;
+ this.line = line;
+ this.severity = severity;
+ this.priority = priority;
+ this.owner = owner;
+ this.parentObject = parent;
+ }
+
+ public Task ()
+ {
+
+ }
+
+ public Task (BuildError error)
+ : this (error, null)
+ {
}
- public TaskPriority Priority
+ public Task (BuildError error, object owner)
{
- get { return priority; }
- set { priority = value; }
+ parentObject = error.SourceTarget;
+ file = error.FileName;
+ description = error.ErrorText;
+ column = error.Column;
+ line = error.Line;
+ if (!string.IsNullOrEmpty (error.ErrorNumber))
+ description += " (" + error.ErrorNumber + ")";
+ if (error.IsWarning)
+ severity = error.ErrorNumber == "COMMENT" ? TaskSeverity.Information : TaskSeverity.Warning;
+ else
+ severity = TaskSeverity.Error;
+ priority = TaskPriority.Normal;
+ code = error.ErrorNumber;
}
- /// <value>
- /// Used for temporarly line changes (e.g. editing a file) to set back to a default
- /// value when not saving the file and reverting the changes.
- /// </value>
- internal int SavedLine {
+ public int Column {
get {
- return savedLine;
- }
- set {
- this.savedLine = value;
+ return column;
}
}
- public int Line {
+ public bool Completed {
get {
- return line;
+ return completed;
}
set {
- this.line = value;
+ completed = value;
}
}
-
- public int Column {
+
+ public string Description {
get {
- return column;
+ return description;
}
set {
- this.column = value;
+ description = value;
}
}
- public string Description {
+ public string Code {
get {
- return description;
+ return code;
}
}
public FilePath FileName {
get {
- return fileName;
+ return file;
}
- set {
- fileName = !value.IsNullOrEmpty ? value.FullPath : value;
+ internal set {
+ file = value;
}
}
- public TaskType TaskType {
+ public int Line {
get {
- return type;
+ return line;
}
- }
-
- public string ErrorNumber {
- get {
- return errorNumber;
+ internal set {
+ line = value;
}
}
-
- public object OwnerItem {
+
+ public object Owner {
get {
return owner;
}
- set {
+ internal set {
owner = value;
}
}
-// public Task (string fileName, string description, int column, int line)
-// {
-// if (fileName != null)
-// type = TaskType.SearchResult;
-// else
-// type = TaskType.Comment;
-// this.fileName = fileName;
-// this.description = description.Trim();
-// this.column = column;
-// this.line = line;
-// }
-
- public Task (FilePath fileName, string description, int column, int line, TaskType type, Project project)
- : this (fileName, description, column, line, type)
- {
- owner = project;
- }
-
- public Task (FilePath fileName, string description, int column, int line, TaskType type, Project project, TaskPriority priority)
- : this (fileName, description, column, line, type, priority)
- {
- owner = project;
- }
-
- public Task (FilePath fileName, string description, int column, int line, TaskType type, TaskPriority priority)
- : this (fileName, description, column, line, type)
- {
- this.priority = priority;
+ public IWorkspaceObject WorkspaceObject {
+ get {
+ return parentObject;
+ }
+ set {
+ if (parentObject != null)
+ throw new InvalidOperationException ("Owner already set");
+ parentObject = value;
+ }
}
- public Task (FilePath fileName, string description, int column, int line, TaskType type)
- {
- this.type = type;
- this.description = description.Trim();
- this.column = column;
- this.line = line;
- FileName = fileName;
+ public TaskPriority Priority {
+ get {
+ return priority;
+ }
+ set {
+ priority = value;
+ }
}
- public Task (BuildError error)
- {
- owner = error.SourceTarget;
- type = error.IsWarning ? error.ErrorNumber == "COMMENT" ? TaskType.Message : TaskType.Warning : TaskType.Error;
- column = error.Column;
- line = error.Line;
- description = error.ErrorText;
- if (error.ErrorNumber != String.Empty && error.ErrorNumber != null)
- description += "(" + error.ErrorNumber + ")";
- FileName = error.FileName;
- errorNumber = error.ErrorNumber;
+ public TaskSeverity Severity {
+ get {
+ return severity;
+ }
}
+
public virtual void JumpToPosition()
{
- if (!fileName.IsNullOrEmpty) {
- IdeApp.Workbench.OpenDocument (fileName, Math.Max (1, line), Math.Max (1, column), true);
- } else if (owner != null) {
+ if (!file.IsNullOrEmpty) {
+ IdeApp.Workbench.OpenDocument (file, Math.Max (1, line), Math.Max (1, column), true);
+ } else if (parentObject != null) {
Pad pad = IdeApp.Workbench.GetPad<ProjectSolutionPad> ();
ProjectSolutionPad spad = pad.Content as ProjectSolutionPad;
- ITreeNavigator nav = spad.TreeView.GetNodeAtObject (owner, true);
+ ITreeNavigator nav = spad.TreeView.GetNodeAtObject (parentObject, true);
if (nav != null) {
nav.ExpandToNode ();
nav.Selected = true;
@@ -209,5 +221,31 @@ namespace MonoDevelop.Ide.Tasks
}
}
}
+
+ public bool BelongsToItem (IWorkspaceObject item, bool checkHierarchy)
+ {
+ if (!checkHierarchy)
+ return item == parentObject;
+
+ IWorkspaceObject cit = parentObject;
+ do {
+ if (cit == item)
+ return true;
+ if (cit is SolutionItem) {
+ SolutionItem si = (SolutionItem) cit;
+ if (si.ParentFolder != null)
+ cit = si.ParentFolder;
+ else
+ cit = si.ParentSolution;
+ }
+ else if (cit is WorkspaceItem) {
+ cit = ((WorkspaceItem)cit).ParentWorkspace;
+ }
+ else
+ cit = null;
+ } while (cit != null);
+
+ return false;
+ }
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs
index a8ce033094..e428f42b60 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskService.cs
@@ -1,32 +1,37 @@
-// TaskService.cs
-//
-// This file was derived from a file from #Develop.
-//
-// Copyright (C) 2001-2007 Mike Krüger <mkrueger@novell.com>
//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
+// TaskService.cs
//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Author:
+// Lluis Sanchez Gual <lluis@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
using System;
using System.IO;
using System.Collections.Generic;
-using System.Runtime.Serialization;
using System.Xml.Serialization;
using MonoDevelop.Core.Gui;
using MonoDevelop.Core;
-using MonoDevelop.Ide.Gui.Pads;
+using MonoDevelop.Core.Serialization;
using MonoDevelop.Projects;
using MonoDevelop.Projects.Dom;
using MonoDevelop.Projects.Dom.Parser;
@@ -34,473 +39,90 @@ using MonoDevelop.Ide.Gui;
namespace MonoDevelop.Ide.Tasks
{
- public class TaskService : GuiSyncObject
+ public enum TaskSeverity
{
- List<Task> tasks = new List<Task> ();
- Dictionary<TaskType, int> taskCount = new Dictionary<TaskType, int> ();
- Dictionary<string, TaskPriority> priorities = new Dictionary<string, TaskPriority> ();
- Dictionary<object,List<UserTask>> userTasks = new Dictionary<object,List<UserTask>> ();
+ Error,
+ Warning,
+ Information,
+ Comment
+ }
+
+ public static class TaskService
+ {
+ static TaskStore errors = new TaskStore ();
+ static TaskStore userTasks = new TaskStore ();
- public TaskService ()
+ static TaskService ()
{
- ReloadPriories ();
-
- IdeApp.Workspace.WorkspaceItemLoaded += ProjectServiceSolutionOpened;
- IdeApp.Workspace.WorkspaceItemUnloaded += ProjectServiceSolutionClosed;
- IdeApp.Workspace.FileRenamedInProject += new ProjectFileRenamedEventHandler (ProjectFileRenamed);
- IdeApp.Workspace.FileRemovedFromProject += new ProjectFileEventHandler (ProjectFileRemoved);
-
- ProjectDomService.CommentTasksChanged += OnCommentTasksChanged;
- ProjectDomService.SpecialCommentTagsChanged += OnCommentTagsChanged;
-
- MonoDevelop.Projects.Text.TextFileService.CommitCountChanges += delegate (object sender, MonoDevelop.Projects.Text.TextFileEventArgs args) {
- foreach (Task task in this.Tasks) {
- if (String.IsNullOrEmpty (task.FileName))
- continue;
- if (Path.GetFullPath (task.FileName) == Path.GetFullPath (args.TextFile.Name)) {
- task.SavedLine = -1;
- }
- }
- };
-
- MonoDevelop.Projects.Text.TextFileService.ResetCountChanges += delegate (object sender, MonoDevelop.Projects.Text.TextFileEventArgs args) {
- List<Task> tasks = new List<Task> ();
- foreach (Task task in this.Tasks) {
- if (String.IsNullOrEmpty (task.FileName))
- continue;
- if (Path.GetFullPath (task.FileName) == Path.GetFullPath (args.TextFile.Name)) {
- if (task.SavedLine != -1) {
- task.Line = task.SavedLine;
- task.SavedLine = -1;
- tasks.Add (task);
- }
- }
- }
- OnTaskChanged (new TaskEventArgs (tasks));
- };
-
- MonoDevelop.Projects.Text.TextFileService.LineCountChanged += delegate (object sender, MonoDevelop.Projects.Text.LineCountEventArgs args) {
- if (args.TextFile == null || String.IsNullOrEmpty (args.TextFile.Name))
- return;
- List<Task> tasks = new List<Task>();
- foreach (Task task in this.Tasks) {
- if (String.IsNullOrEmpty (task.FileName))
- continue;
- if (Path.GetFullPath (task.FileName) == Path.GetFullPath (args.TextFile.Name) && task.Line - 1 > args.LineNumber || (task.Line - 1 == args.LineNumber && task.Column - 1 >= args.Column)) {
- if (task.SavedLine == -1)
- task.SavedLine = task.Line;
- task.Line += args.LineCount;
- tasks.Add (task);
-
- }
- }
- OnTaskChanged (new TaskEventArgs (tasks));
- };
-
- this.tasks = new List<Task> ();
- }
-
- void ProjectServiceSolutionOpened (object sender, WorkspaceItemEventArgs e)
- {
- Solution sol = e.Item as Solution;
- if (sol != null) {
- // Load all tags that are stored in pidb files
- foreach (Project p in sol.GetAllProjects ()) {
- ProjectDom pContext = ProjectDomService.GetProjectDom (p);
- if (pContext == null)
- continue;
- foreach (ProjectFile file in p.Files) {
- IList<Tag> tags = pContext.GetSpecialComments (file.Name);
- if (tags !=null)
- UpdateCommentTags (sol, file.Name, tags);
- }
- }
- }
-
- List<UserTask> utasks = new List<UserTask> ();
- userTasks [e.Item] = utasks;
-
- // Load User Tasks from xml file
- string fileToLoad = GetUserTasksFilename (e.Item);
- if (File.Exists (fileToLoad))
- {
- try
- {
- XmlSerializer serializer = new XmlSerializer (utasks.GetType ());
- Stream stream = new FileStream (fileToLoad, FileMode.Open, FileAccess.Read, FileShare.None);
- utasks.AddRange ((IEnumerable<UserTask>)serializer.Deserialize (stream));
- stream.Close ();
- if (utasks.Count > 0 && UserTasksChanged != null)
- UserTasksChanged (this, EventArgs.Empty);
- }
- catch (Exception ex)
- {
- LoggingService.LogWarning ("Could not load user tasks: " + fileToLoad, ex);
- }
- }
- }
-
- void ProjectServiceSolutionClosed (object sender, WorkspaceItemEventArgs e)
- {
- // Save UserTasks to xml file
- string fileToSave = GetUserTasksFilename (e.Item);
- try {
- List<UserTask> utasks;
- if (userTasks.TryGetValue (e.Item, out utasks)) {
- XmlSerializer serializer = new XmlSerializer (utasks.GetType ());
- using (Stream stream = new FileStream (fileToSave, FileMode.Create, FileAccess.Write, FileShare.None)) {
- serializer.Serialize (stream, utasks);
- }
- }
- } catch (Exception ex) {
- LoggingService.LogWarning ("Could not save user tasks: " + fileToSave, ex);
- }
-
- // Remove solution tasks
-
- List<Task> ttasks = FindTasks (e.Item);
- if (ttasks.Count > 0) {
- foreach (Task t in ttasks) {
- tasks.Remove (t);
- taskCount [t.TaskType]--;
- }
-
- OnTaskRemoved (new TaskEventArgs (ttasks.ToArray ()));
- }
-
- userTasks.Remove (e.Item);
- if (UserTasksChanged != null)
- UserTasksChanged (this, EventArgs.Empty);
+ IdeApp.Workspace.WorkspaceItemLoaded += OnWorkspaceItemLoaded;
+ IdeApp.Workspace.WorkspaceItemUnloaded += OnWorkspaceItemUnloaded;
}
- List<Task> FindTasks (object owner)
- {
- List<Task> ts = new List<Task> ();
- WorkspaceItem it = owner as WorkspaceItem;
- foreach (Task t in tasks) {
- if (t.OwnerItem == owner)
- ts.Add (t);
- else if (it != null && t.WorkspaceObject != null && it.ContainsItem (t.WorkspaceObject))
- ts.Add (t);
- }
- return ts;
+ public static TaskStore Errors {
+ get { return errors; }
}
- void OnCommentTagsChanged (object sender, EventArgs e)
- {
- ReloadPriories ();
- // update priorities
-/* TODO:
-
- foreach (Project p in IdeApp.Workspace.GetAllProjects ())
- {
- IProjectParserContext pContext = IdeApp.Workspace.ParserDatabase.GetProjectParserContext (p);
- foreach (ProjectFile file in p.Files)
- {
- TagCollection tags = pContext.GetFileSpecialComments (file.Name);
- if (tags !=null)
- UpdateCommentTags (p.ParentSolution, file.Name, tags);
- }
- }*/
+ public static TaskStore UserTasks {
+ get { return userTasks; }
}
-
- void ProjectFileRemoved (object sender, ProjectFileEventArgs e)
+
+ static void OnWorkspaceItemLoaded (object sender, WorkspaceItemEventArgs e)
{
- foreach (Task curTask in new List<Task> (Tasks)) {
- if (curTask.FileName == e.ProjectFile.FilePath)
- Remove (curTask);
+ string fileToLoad = GetUserTasksFilename (e.Item);
+
+ userTasks.BeginTaskUpdates ();
+ try {
+ // Load User Tasks from xml file
+ if (File.Exists (fileToLoad)) {
+ XmlDataSerializer serializer = new XmlDataSerializer (new DataContext ());
+ List<Task> ts = (List<Task>) serializer.Deserialize (fileToLoad, typeof(List<Task>));
+ foreach (Task t in ts) {
+ t.WorkspaceObject = e.Item;
+ userTasks.Add (t);
+ }
+ }
}
- }
-
- void ProjectFileRenamed (object sender, ProjectFileRenamedEventArgs e)
- {
- List<Task> ctasks = new List<Task> (Tasks);
- foreach (Task curTask in ctasks) {
- if (curTask.FileName == e.OldName) {
- Remove (curTask);
- curTask.FileName = e.NewName;
- Add (curTask);
- }
+ catch (Exception ex) {
+ LoggingService.LogWarning ("Could not load user tasks: " + fileToLoad, ex);
}
- }
-
- [AsyncDispatch]
- void OnCommentTasksChanged (object sender, CommentTasksChangedEventArgs e)
- {
- if (e.Project != null)
- UpdateCommentTags (e.Project.ParentSolution, e.FileName, e.TagComments);
- }
-
- public void ClearExceptCommentTasks ()
- {
- List<Task> tlist = new List<Task> ();
- foreach (Task t in Tasks) {
- if (t.TaskType != TaskType.Comment)
- tlist.Add (t);
+ finally {
+ userTasks.EndTaskUpdates ();
}
- foreach (Task t in tlist)
- InternalRemove (t);
-
- OnTaskRemoved (new TaskEventArgs (tlist.ToArray ()));
}
- string GetUserTasksFilename (WorkspaceItem item)
+ static void OnWorkspaceItemUnloaded (object sender, WorkspaceItemEventArgs e)
{
- string combineFilename = item.FileName;
- string combinePath = Path.GetDirectoryName (combineFilename);
- string userTasksFilename = Path.Combine(combinePath, Path.GetFileNameWithoutExtension(combineFilename) + ".usertasks");
- return userTasksFilename;
- }
-
- void ReloadPriories ()
- {
- priorities.Clear ();
- foreach (CommentTag tag in ProjectDomService.SpecialCommentTags)
- priorities.Add (tag.Tag, (TaskPriority) tag.Priority);
- }
-
- public int TaskCount {
- get {
- return tasks.Count - GetCount (TaskType.Comment);
- }
- }
-
- public List<Task> Tasks {
- get {
- List<Task> retTasks = new List<Task> ();
- foreach (Task task in tasks) {
- if (task.TaskType != TaskType.Comment)
- retTasks.Add (task);
- }
- return retTasks;
- }
- }
-
- public List<Task> CommentTasks {
- get {
- List<Task> retTasks = new List<Task> ();
- foreach (Task task in tasks) {
- if (task.TaskType == TaskType.Comment) {
- retTasks.Add (task);
- }
- }
- return retTasks;
- }
- }
-
- public List<UserTask> UserTasks {
- get {
- List<UserTask> retTasks = new List<UserTask> ();
- foreach (List<UserTask> tt in userTasks.Values)
- retTasks.AddRange (tt);
- return retTasks;
- }
- }
-
- int GetCount (TaskType type)
- {
- if (!taskCount.ContainsKey (type)) {
- return 0;
- }
- return taskCount[type];
- }
-
- public int ErrorsCount {
- get {
- return GetCount (TaskType.Error);
- }
- }
-
- public int WarningsCount {
- get {
- return GetCount (TaskType.Warning);
- }
- }
-
- public int MessagesCount {
- get {
- return GetCount (TaskType.Message);
- }
- }
-
- public bool SomethingWentWrong {
- get {
- return GetCount (TaskType.Error) + GetCount (TaskType.Warning) > 0;
- }
- }
-
- public bool HasCriticalErrors (bool treatWarningsAsErrors)
- {
- if (treatWarningsAsErrors) {
- return SomethingWentWrong;
- } else {
- return GetCount (TaskType.Error) > 0;
- }
- }
-
- public void Add (Task task)
- {
- AddInternal (task);
- OnTaskAdded (new TaskEventArgs (new Task[] {task}));
- }
-
- public void AddRange (IEnumerable<Task> tasks)
- {
- foreach (Task task in tasks) {
- AddInternal (task);
- }
- OnTaskAdded (new TaskEventArgs (tasks));
- }
-
- void AddInternal (Task task)
- {
- object owner = task.OwnerItem;
- if (owner == null)
- owner = task.OwnerItem = this;
+ // Save UserTasks to xml file
+ SaveUserTasks (e.Item);
- if (owner is SolutionItem)
- owner = ((SolutionItem)owner).ParentSolution;
+ // Remove solution tasks
- tasks.Add (task);
- int count;
- if (!taskCount.TryGetValue (task.TaskType, out count))
- taskCount[task.TaskType] = 1;
- else
- taskCount[task.TaskType] = count + 1;
- }
-
-/* public void AddUserTasksRange (IEnumerable<UserTask> tasks)
- {
- userTasks.AddRange (tasks);
- if (UserTasksChanged != null)
- UserTasksChanged (this, EventArgs.Empty);
+ errors.RemoveItemTasks (e.Item, true);
+ userTasks.RemoveItemTasks (e.Item, true);
}
-*/
- public void Remove (Task task)
+ static FilePath GetUserTasksFilename (WorkspaceItem item)
{
- if (InternalRemove (task))
- OnTaskRemoved (new TaskEventArgs (new Task[] {task}));
+ FilePath combinePath = item.FileName.ParentDirectory;
+ return combinePath.Combine (item.FileName.FileNameWithoutExtension + ".usertasks");
}
- bool InternalRemove (Task task)
- {
- if (tasks.Remove (task)) {
- taskCount[task.TaskType]--;
- return true;
- }
- return false;
- }
-
- public void UpdateCommentTags (Solution sol, FilePath fileName, IEnumerable<MonoDevelop.Projects.Dom.Tag> tagComments)
+ internal static void SaveUserTasks (IWorkspaceObject item)
{
- if (fileName == FilePath.Null) {
- return;
- }
-
- List<Task> newTasks = new List<Task> ();
- if (tagComments != null) {
- foreach (MonoDevelop.Projects.Dom.Tag tag in tagComments) {
- if (!priorities.ContainsKey (tag.Key))
- continue;
- Task t = new Task (fileName,
- tag.Key + tag.Text,
- tag.Region.Start.Column - 1,
- tag.Region.Start.Line,
- TaskType.Comment, priorities[tag.Key]);
- t.OwnerItem = sol;
- newTasks.Add (t);
+ string fileToSave = GetUserTasksFilename ((WorkspaceItem)item);
+ try {
+ List<Task> utasks = new List<Task> (userTasks.GetItemTasks (item, true));
+ if (utasks.Count == 0) {
+ if (File.Exists (fileToSave))
+ File.Delete (fileToSave);
+ } else {
+ XmlDataSerializer serializer = new XmlDataSerializer (new DataContext ());
+ serializer.Serialize (fileToSave, utasks);
}
- }
- List<Task> oldTasks = new List<Task> ();
-
- fileName = fileName.FullPath;
- foreach (Task task in CommentTasks) {
- if (task.FileName == fileName)
- oldTasks.Add (task);
- }
-
- for (int i = 0; i < newTasks.Count; ++i) {
- for (int j = 0; j < oldTasks.Count; ++j) {
- if (oldTasks[j] != null &&
- newTasks[i].Line == oldTasks[j].Line &&
- newTasks[i].Column == oldTasks[j].Column &&
- newTasks[i].Description == oldTasks[j].Description &&
- newTasks[i].Priority == oldTasks[j].Priority)
- {
- newTasks[i] = null;
- oldTasks[j] = null;
- break;
- }
- }
- }
-
- foreach (Task task in newTasks) {
- if (task != null) {
- Add (task);
- }
- }
-
- foreach (Task task in oldTasks) {
- if (task != null) {
- Remove (task);
- }
- }
- }
-
- public void ShowErrors ()
- {
- DispatchService.GuiDispatch (new MessageHandler (ShowErrorsCallback));
- }
-
- void ShowErrorsCallback ()
- {
- Pad pad = IdeApp.Workbench.GetPad<ErrorListPad> ();
- if (pad != null)
- pad.BringToFront ();
- }
-
- protected void OnTaskAdded (TaskEventArgs e)
- {
- if (TaskAdded != null) {
- TaskAdded (this, e);
- }
- }
-
- protected void OnTaskRemoved (TaskEventArgs e)
- {
- if (TaskRemoved != null) {
- TaskRemoved (this, e);
- }
- }
-
- protected void OnTaskChanged (TaskEventArgs e)
- {
- if (TaskChanged != null) {
- TaskChanged (this, e);
+ } catch (Exception ex) {
+ LoggingService.LogWarning ("Could not save user tasks: " + fileToSave, ex);
}
}
-
- public event TaskEventHandler TaskAdded;
- public event TaskEventHandler TaskRemoved;
- public event TaskEventHandler TaskChanged;
- public event EventHandler UserTasksChanged;
- }
-
- public delegate void TaskEventHandler (object sender, TaskEventArgs e);
-
- public class TaskEventArgs : EventArgs
- {
- IEnumerable<Task> tasks;
-
- public TaskEventArgs (IEnumerable<Task> tasks)
- {
- this.tasks = tasks;
- }
-
- public IEnumerable<Task> Tasks
- {
- get { return tasks; }
- }
}
}
+
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskStore.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskStore.cs
new file mode 100644
index 0000000000..6b1ba49ba4
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/TaskStore.cs
@@ -0,0 +1,342 @@
+//
+// TaskStore.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3074
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using MonoDevelop.Ide.Gui;
+
+namespace MonoDevelop.Ide.Tasks
+{
+ public class TaskStore: IEnumerable<Task>
+ {
+ int taskUpdateCount;
+ List<Task> tasks = new List<Task> ();
+ Dictionary<FilePath,Task[]> taskIndex = new Dictionary<FilePath, Task[]> ();
+
+ public event TaskEventHandler TasksAdded;
+ public event TaskEventHandler TasksRemoved;
+ public event TaskEventHandler TasksChanged;
+
+ List<Task> tasksAdded;
+ List<Task> tasksRemoved;
+
+ public TaskStore ()
+ {
+ IdeApp.Workspace.FileRenamedInProject += ProjectFileRenamed;
+ IdeApp.Workspace.FileRemovedFromProject += ProjectFileRemoved;
+
+ MonoDevelop.Projects.Text.TextFileService.CommitCountChanges += delegate (object sender, MonoDevelop.Projects.Text.TextFileEventArgs args) {
+ foreach (Task task in GetFileTasks (args.TextFile.Name.FullPath))
+ task.SavedLine = -1;
+ };
+
+ MonoDevelop.Projects.Text.TextFileService.ResetCountChanges += delegate (object sender, MonoDevelop.Projects.Text.TextFileEventArgs args) {
+ Task[] ctasks = GetFileTasks (args.TextFile.Name.FullPath);
+ foreach (Task task in ctasks) {
+ if (task.SavedLine != -1) {
+ task.Line = task.SavedLine;
+ task.SavedLine = -1;
+ }
+ }
+ NotifyTasksChanged (ctasks);
+ };
+
+ MonoDevelop.Projects.Text.TextFileService.LineCountChanged += delegate (object sender, MonoDevelop.Projects.Text.LineCountEventArgs args) {
+ if (args.TextFile == null || args.TextFile.Name.IsNullOrEmpty)
+ return;
+ Task[] ctasks = GetFileTasks (args.TextFile.Name.FullPath);
+ foreach (Task task in ctasks) {
+ if (task.Line - 1 > args.LineNumber || (task.Line - 1 == args.LineNumber && task.Column - 1 >= args.Column)) {
+ if (task.SavedLine == -1)
+ task.SavedLine = task.Line;
+ task.Line += args.LineCount;
+ }
+ }
+ NotifyTasksChanged (ctasks);
+ };
+ }
+
+ public void Add (Task task)
+ {
+ tasks.Add (task);
+ OnTaskAdded (task);
+ }
+
+ public void AddRange (IEnumerable<Task> newTasks)
+ {
+ BeginTaskUpdates ();
+ try {
+ foreach (Task t in newTasks) {
+ tasks.Add (t);
+ OnTaskAdded (t);
+ }
+ } finally {
+ EndTaskUpdates ();
+ }
+ }
+
+ public void RemoveRange (IEnumerable<Task> tasks)
+ {
+ BeginTaskUpdates ();
+ try {
+ foreach (Task t in tasks) {
+ if (this.tasks.Remove (t))
+ OnTaskRemoved (t);
+ }
+ } finally {
+ EndTaskUpdates ();
+ }
+ }
+
+ public void RemoveItemTasks (IWorkspaceObject parent)
+ {
+ RemoveRange (new List<Task> (GetItemTasks (parent)));
+ }
+
+ public void RemoveItemTasks (IWorkspaceObject parent, bool checkHierarchy)
+ {
+ RemoveRange (new List<Task> (GetItemTasks (parent, checkHierarchy)));
+ }
+
+ public void RemoveFileTasks (FilePath file)
+ {
+ RemoveRange (new List<Task> (GetFileTasks (file)));
+ }
+
+ public void Remove (Task task)
+ {
+ if (tasks.Remove (task))
+ OnTaskRemoved (task);
+ }
+
+ public void Clear ()
+ {
+ List<Task> toRemove = tasks;
+ tasks = new List<Task> ();
+ foreach (Task t in toRemove)
+ OnTaskRemoved (t);
+ }
+
+ public void ClearByOwner (object owner)
+ {
+ List<Task> toRemove = new List<Task> (GetOwnerTasks (owner));
+ foreach (Task t in toRemove)
+ Remove (t);
+ }
+
+ public IEnumerator<Task> GetEnumerator ()
+ {
+ return tasks.GetEnumerator ();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return ((IEnumerable)tasks).GetEnumerator ();
+ }
+
+ public IEnumerable<Task> GetOwnerTasks (object owner)
+ {
+ foreach (Task t in tasks) {
+ if (t.Owner == owner)
+ yield return t;
+ }
+ }
+
+ public Task[] GetFileTasks (FilePath file)
+ {
+ Task[] ta;
+ if (taskIndex.TryGetValue (file, out ta))
+ return ta;
+ else
+ return new Task [0];
+ }
+
+ public IEnumerable<Task> GetItemTasks (IWorkspaceObject parent)
+ {
+ return GetItemTasks (parent, true);
+ }
+
+ public IEnumerable<Task> GetItemTasks (IWorkspaceObject parent, bool checkHierarchy)
+ {
+ foreach (Task t in tasks) {
+ if (t.BelongsToItem (parent, checkHierarchy))
+ yield return t;
+ }
+ }
+
+ public void BeginTaskUpdates ()
+ {
+ if (taskUpdateCount++ != 0)
+ return;
+ tasksAdded = new List<Task> ();
+ tasksRemoved = new List<Task> ();
+ }
+
+ public void EndTaskUpdates ()
+ {
+ if (--taskUpdateCount != 0)
+ return;
+ List<Task> oldAdded = tasksAdded;
+ List<Task> oldRemoved = tasksRemoved;
+ tasksAdded = null;
+ tasksRemoved = null;
+ if (oldRemoved.Count > 0)
+ NotifyTasksRemoved (oldRemoved);
+ if (oldAdded.Count > 0)
+ NotifyTasksAdded (oldAdded);
+ }
+
+ void NotifyTasksAdded (IEnumerable<Task> ts)
+ {
+ try {
+ if (TasksAdded != null)
+ TasksAdded (null, new TaskEventArgs (ts));
+ } catch (Exception ex) {
+ LoggingService.LogError ("Error while notifying task changes", ex);
+ }
+ }
+
+ void NotifyTasksChanged (IEnumerable<Task> ts)
+ {
+ try {
+ if (TasksChanged != null)
+ TasksChanged (null, new TaskEventArgs (ts));
+ } catch (Exception ex) {
+ LoggingService.LogError ("Error while notifying task changes", ex);
+ }
+ }
+
+ void NotifyTasksRemoved (IEnumerable<Task> ts)
+ {
+ try {
+ if (TasksRemoved != null)
+ TasksRemoved (null, new TaskEventArgs (ts));
+ } catch (Exception ex) {
+ LoggingService.LogError ("Error while notifying task changes", ex);
+ }
+ }
+
+ internal void OnTaskAdded (Task t)
+ {
+ if (t.FileName != FilePath.Null) {
+ Task[] ta;
+ if (taskIndex.TryGetValue (t.FileName, out ta)) {
+ Array.Resize (ref ta, ta.Length + 1);
+ ta [ta.Length - 1] = t;
+ } else {
+ ta = new Task [] { t };
+ }
+ taskIndex [t.FileName] = ta;
+ }
+ if (tasksAdded != null)
+ tasksAdded.Add (t);
+ else
+ NotifyTasksAdded (new Task [] { t });
+ }
+
+ internal void OnTaskRemoved (Task t)
+ {
+ if (t.FileName != FilePath.Null) {
+ Task[] ta;
+ if (taskIndex.TryGetValue (t.FileName, out ta)) {
+ if (ta.Length == 1) {
+ if (ta [0] == t)
+ taskIndex.Remove (t.FileName);
+ } else {
+ int i = Array.IndexOf (ta, t);
+ if (i != -1) {
+ Task[] newTa = new Task [ta.Length - 1];
+ Array.Copy (ta, 0, newTa, 0, i);
+ Array.Copy (ta, i+1, newTa, i, ta.Length - i - 1);
+ taskIndex [t.FileName] = ta;
+ }
+ }
+ }
+ }
+ if (tasksRemoved != null)
+ tasksRemoved.Add (t);
+ else
+ NotifyTasksRemoved (new Task [] { t });
+ }
+
+ void ProjectFileRemoved (object sender, ProjectFileEventArgs e)
+ {
+ BeginTaskUpdates ();
+ try {
+ foreach (Task curTask in new List<Task> (GetFileTasks (e.ProjectFile.FilePath))) {
+ Remove (curTask);
+ }
+ } finally {
+ EndTaskUpdates ();
+ }
+ }
+
+ void ProjectFileRenamed (object sender, ProjectFileRenamedEventArgs e)
+ {
+ BeginTaskUpdates ();
+ try {
+ Task[] ctasks = GetFileTasks (e.OldName);
+ foreach (Task curTask in ctasks)
+ curTask.FileName = e.NewName;
+ taskIndex.Remove (e.OldName);
+ taskIndex [e.NewName] = ctasks;
+ tasksAdded.AddRange (ctasks);
+ tasksRemoved.AddRange (ctasks);
+ } finally {
+ EndTaskUpdates ();
+ }
+ }
+ }
+
+ public delegate void TaskEventHandler (object sender, TaskEventArgs e);
+
+ public class TaskEventArgs : EventArgs
+ {
+ IEnumerable<Task> tasks;
+
+ public TaskEventArgs (IEnumerable<Task> tasks)
+ {
+ this.tasks = tasks;
+ }
+
+ public IEnumerable<Task> Tasks
+ {
+ get { return tasks; }
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/UserTask.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/UserTask.cs
deleted file mode 100644
index 40c53b34c5..0000000000
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/UserTask.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// UserTask.cs
-//
-// Author:
-// David Makovský <yakeen@sannyas-on.net>
-//
-// Copyright (C) 2006 David Makovský
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Xml.Serialization;
-using MonoDevelop.Core;
-using MonoDevelop.Projects;
-
-namespace MonoDevelop.Ide.Tasks
-{
- public class UserTask
- {
- TaskPriority priority = TaskPriority.Normal;
- bool completed = false;
- string description;
- Solution solution;
-
- public TaskPriority Priority
- {
- get { return priority; }
- set { priority = value; }
- }
-
- public bool Completed
- {
- get { return completed; }
- set { completed = value; }
- }
-
- public string Description
- {
- get { return description; }
- set { description = value; }
- }
-
- [System.Xml.Serialization.XmlIgnoreAttribute]
- public Solution Solution {
- get {
- return solution;
- }
- internal set {
- solution = value;
- }
- }
-
- public override string ToString ()
- {
- return String.Format ("[UserTask: Priority={0}, Completed={1}, Description={2}]",
- Enum.GetName (typeof (TaskPriority), priority),
- completed, description);
- }
- }
-}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/UserTasksView.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/UserTasksView.cs
index 74f69d5779..9c702f4162 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/UserTasksView.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Tasks/UserTasksView.cs
@@ -58,6 +58,7 @@ namespace MonoDevelop.Ide.Tasks
MonoDevelop.Ide.Gui.Components.PadTreeView view;
ListStore store;
+ CellRendererText cellRendDesc;
Gdk.Color highPrioColor, normalPrioColor, lowPrioColor;
@@ -65,11 +66,11 @@ namespace MonoDevelop.Ide.Tasks
Clipboard clipboard;
bool solutionLoaded = false;
+ bool updating;
string[] priorities = { GettextCatalog.GetString ("High"), GettextCatalog.GetString ("Normal"), GettextCatalog.GetString ("Low")};
public UserTasksView ()
{
-
highPrioColor = StringToColor ((string)PropertyService.Get ("Monodevelop.UserTasksHighPrioColor", ""));
normalPrioColor = StringToColor ((string)PropertyService.Get ("Monodevelop.UserTasksNormalPrioColor", ""));
lowPrioColor = StringToColor ((string)PropertyService.Get ("Monodevelop.UserTasksLowPrioColor", ""));
@@ -78,7 +79,7 @@ namespace MonoDevelop.Ide.Tasks
typeof (string), // priority
typeof (bool), // completed
typeof (string), // desc
- typeof (UserTask), // user task
+ typeof (Task), // user task
typeof (Gdk.Color), // foreground color
typeof (int)); // font style
@@ -111,7 +112,7 @@ namespace MonoDevelop.Ide.Tasks
col.Clickable = true;
col.Clicked += new EventHandler (UserTaskCompletedResort);
- CellRendererText cellRendDesc = view.TextRenderer;
+ cellRendDesc = view.TextRenderer;
cellRendDesc.Editable = true;
cellRendDesc.Edited += new EditedHandler (UserTaskDescEdited);
col = view.AppendColumn (GettextCatalog.GetString ("Description"), cellRendDesc, "text", Columns.Description, "strikethrough", Columns.Completed, "foreground-gdk", Columns.Foreground, "weight", Columns.Bold);
@@ -129,13 +130,16 @@ namespace MonoDevelop.Ide.Tasks
delButton.Clicked += new EventHandler (DeleteUserTaskClicked);
delButton.SetTooltip (tips, GettextCatalog.GetString ("Delete Task"), GettextCatalog.GetString ("Delete Task"));
- Services.TaskService.UserTasksChanged += (EventHandler) DispatchService.GuiDispatch (new EventHandler (UserTasksChanged));
+ TaskService.UserTasks.TasksChanged += (TaskEventHandler) DispatchService.GuiDispatch (new TaskEventHandler (UserTasksChanged));
+ TaskService.UserTasks.TasksAdded += (TaskEventHandler) DispatchService.GuiDispatch (new TaskEventHandler (UserTasksChanged));
+ TaskService.UserTasks.TasksRemoved += (TaskEventHandler) DispatchService.GuiDispatch (new TaskEventHandler (UserTasksChanged));
+
IdeApp.Workspace.FirstWorkspaceItemOpened += CombineOpened;
IdeApp.Workspace.LastWorkspaceItemClosed += CombineClosed;
PropertyService.PropertyChanged += (EventHandler<PropertyChangedEventArgs>) DispatchService.GuiDispatch (new EventHandler<PropertyChangedEventArgs> (OnPropertyUpdated));
ValidateButtons ();
// Initialize with existing tags.
- UserTasksChanged (this, EventArgs.Empty);
+ UserTasksChanged (this, null);
}
void CombineOpened (object sender, EventArgs e)
@@ -150,10 +154,12 @@ namespace MonoDevelop.Ide.Tasks
ValidateButtons ();
}
- void UserTasksChanged (object sender, EventArgs e)
+ void UserTasksChanged (object sender, TaskEventArgs e)
{
+ if (updating)
+ return;
store.Clear ();
- foreach (UserTask task in IdeApp.Services.TaskService.UserTasks)
+ foreach (Task task in TaskService.UserTasks)
{
store.AppendValues (GettextCatalog.GetString (Enum.GetName (typeof (TaskPriority), task.Priority)), task.Completed, task.Description, task, GetColorByPriority (task.Priority), task.Completed ? (int)Pango.Weight.Light : (int)Pango.Weight.Bold);
}
@@ -185,7 +191,7 @@ namespace MonoDevelop.Ide.Tasks
{
do
{
- UserTask task = (UserTask) store.GetValue (iter, (int)Columns.UserTask);
+ Task task = (Task) store.GetValue (iter, (int)Columns.UserTask);
store.SetValue (iter, (int)Columns.Foreground, GetColorByPriority (task.Priority));
} while (store.IterNext (ref iter));
}
@@ -205,12 +211,17 @@ namespace MonoDevelop.Ide.Tasks
void NewUserTaskClicked (object obj, EventArgs e)
{
- UserTask task = new UserTask ();
- IdeApp.Services.TaskService.UserTasks.Add (task);
+ Task task = new Task ();
+ task.WorkspaceObject = IdeApp.ProjectOperations.CurrentSelectedWorkspaceItem;
+ updating = true;
+ TaskService.UserTasks.Add (task);
+ updating = false;
TreeIter iter = store.AppendValues (GettextCatalog.GetString (Enum.GetName (typeof (TaskPriority), task.Priority)), task.Completed, task.Description, task, GetColorByPriority (task.Priority), task.Completed ? (int)Pango.Weight.Light : (int)Pango.Weight.Bold);
view.Selection.SelectIter (iter);
TreePath path = store.GetPath (iter);
- view.ScrollToCell (path, view.Columns[(int)Columns.Description], false, 0, 0);
+ view.ScrollToCell (path, view.Columns[(int)Columns.Description], true, 0, 0);
+ view.SetCursorOnCell (path, view.Columns[(int)Columns.Description], cellRendDesc, true);
+ TaskService.SaveUserTasks (task.WorkspaceObject);
}
void DeleteUserTaskClicked (object obj, EventArgs e)
@@ -220,9 +231,12 @@ namespace MonoDevelop.Ide.Tasks
TreeIter iter;
if (store.GetIter (out iter, view.Selection.GetSelectedRows ()[0]))
{
- UserTask task = (UserTask) store.GetValue (iter, (int)Columns.UserTask);
- IdeApp.Services.TaskService.UserTasks.Remove (task);
+ Task task = (Task) store.GetValue (iter, (int)Columns.UserTask);
+ updating = true;
+ TaskService.UserTasks.Remove (task);
+ updating = false;
store.Remove (ref iter);
+ TaskService.SaveUserTasks (task.WorkspaceObject);
}
}
}
@@ -231,7 +245,7 @@ namespace MonoDevelop.Ide.Tasks
{
Gtk.TreeIter iter;
if (store.GetIterFromString (out iter, args.Path)) {
- UserTask task = (UserTask) store.GetValue (iter, (int)Columns.UserTask);
+ Task task = (Task) store.GetValue (iter, (int)Columns.UserTask);
if (args.Active == 0)
{
task.Priority = TaskPriority.High;
@@ -244,6 +258,7 @@ namespace MonoDevelop.Ide.Tasks
}
store.SetValue (iter, (int)Columns.Priority, priorities [args.Active]);
store.SetValue (iter, (int)Columns.Foreground, GetColorByPriority (task.Priority));
+ TaskService.SaveUserTasks (task.WorkspaceObject);
}
}
@@ -274,10 +289,11 @@ namespace MonoDevelop.Ide.Tasks
Gtk.TreeIter iter;
if (store.GetIterFromString (out iter, args.Path)) {
bool val = (bool)store.GetValue (iter, (int)Columns.Completed);
- UserTask task = (UserTask) store.GetValue (iter, (int)Columns.UserTask);
+ Task task = (Task) store.GetValue (iter, (int)Columns.UserTask);
task.Completed = !val;
store.SetValue (iter, (int)Columns.Completed, !val);
store.SetValue (iter, (int)Columns.Bold, task.Completed ? (int)Pango.Weight.Light : (int)Pango.Weight.Bold);
+ TaskService.SaveUserTasks (task.WorkspaceObject);
}
}
@@ -297,9 +313,10 @@ namespace MonoDevelop.Ide.Tasks
{
Gtk.TreeIter iter;
if (store.GetIterFromString (out iter, args.Path)) {
- UserTask task = (UserTask) store.GetValue (iter, (int)Columns.UserTask);
+ Task task = (Task) store.GetValue (iter, (int)Columns.UserTask);
task.Description = args.NewText;
store.SetValue (iter, (int)Columns.Description, args.NewText);
+ TaskService.SaveUserTasks (task.WorkspaceObject);
}
}
@@ -353,13 +370,13 @@ namespace MonoDevelop.Ide.Tasks
void OnUserTaskCopied (object o, EventArgs args)
{
- UserTask task;
+ Task task;
TreeModel model;
TreeIter iter;
if (view.Selection.GetSelected (out model, out iter))
{
- task = (UserTask) model.GetValue (iter, (int)Columns.UserTask);
+ task = (Task) model.GetValue (iter, (int)Columns.UserTask);
}
else return; // no one selected