Skip to main content
summaryrefslogblamecommitdiffstats
blob: 742e80c5af23a22d26ca2eeeaddbc36d90890ab8 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                                                 
                                                   
                           
                        
                         

                          
                     


                                                

                                                 
                                       

                                                       




                                                
                                        
















                                                            
                                              

                                              

                                                          

                                                           

                                                 
                                        


                                                     
                                            
                                     
                                                

                                                
                                            
                                                               
                                                                
                                                          
                                                  

                                          













                                                                      
                                       
                                       











                                                

                                                       


                                            
                                                











                                              


                                                
                                                                          
                                                         
                                  


                                                              

                                                                                       
                                                                                       
 


                                                          
                                                               
                                                    
                                   
                                                                 








                                                                                                               
                                                                            
    










                                                                                     
                                                           















                                                                                                   




















                                                                                           


                                                                       

                                                          
                                                                
                                                                                 


                                   
                                                          
                                                                                         

                                                                 
                                                                       
                                                                      









                                                                                                
                                                          



                                                                                     











                                                                                                                 









                                                                                                                                                          






                                                                 

                                                      



                                                                
                                                          
                                                                                                            







                                                                                                                                             



                                         
        



















                                                                                                            




                                                                     
                                                                

                         

                                                          


                                                                                                            






                                                                      








                                                                   
                                                              

                         

                                                          



                                                                                                            






                                                                      









                                                         
                
                         

                                                          




















                                                                                                                                                            


                                                                                 









                                                                                                                                                                                                



                                                                                                                   





                                     











                                                                              
                                                          





















                                                                                                                           

                                                                     

                                                       



                                                                  
                                                          












                                                                          
                                                                                  


                                                                                     





                                                                                                        


                                                                                                                        

                                                                        








                                                                                                 


                                                                 



                                                
                                                          












                                                                                                                               

















                                                                                                                              
                                 








































                                                                                                                            

                                            


                                                         

                           
                                                          




                                                                                                    


                                                                  







                                                                                                         



                                                                                  



                             

                                                                     

                                           




                                                         
                                                          

                                                            
                                                       


                                                                                 
         
    




























                                                                       



                                                                                       
                                

                                                                          
                                                                        
                                                                






























                                                                                                        
                                                                                                                   








                                                                                           
                                                                                                             






                                                                                                        
                                                                                                                   








                                                                                           
                                                                                                             






                                                                                                        
                                                                                                                   








                                                                                           
                                                                                                             






                                                                                                        
                                                                                                                   








                                                                                           
                                                                                                             






                                                                                                        
                                                                                                                   








                                                                                           
                                                                                                             



                                                                        

                                                     






                                                                                            
                                                                       
                                 
                                            







                                                                                            
                                                                      
                                

                                            







                                                                    

                                                                                   

















                                                                                            

                                                                          
                                                                                        




                                                                                                
                                
                                            
                                                



                 








                                                                                               
                                                                                                                          



                                               


                                                          
                        
                                                            

                 



                                                     

                                                                              

                                                                      

                                                                                    

                                     

                                                     


                                                                                 


                                                                             



                                                                          





                            





                                                                           








                                                               
                                                             







                                      
                                                       





                                       




                                                                           














                                                                                                

                                                                                  







                                                                  
                                                                        


                                                  


                                                                        

                                                      




                                                                                       


                                                  
                                                                                               

                                                                           
                                                                        
                                       
                                                                                                
                                 
                         






                                                                                           

                                                                                      
                                                                                                  

                                                              
                                                                      
                                                                                             
                                                        
                                                                                           
                                                 

















                                                                                                           

                                                                                                                








                                                                                        
                                                                                            



                                                                          
                                         





























                                                                                                                                            
                                 
                                                 
                                               
                                                                   


















                                                                                        

                                                             



                                          

                                                             
                                          

                                                        
                                                         
                                                         


















                                                                                                
                                                                                  

                                                             





                                                                              
                                                                                              








                                                                              
















































                                                                                 
                                         

                                                                                                      




































                                                                                                                              



                                                                                
         
         
























                                                                                              

                                







































                                                                                                                          







                                                                                                                  


                                                                             






                                                                        











                                                                                          
                                                      
                                                                                                                      



                                     






                                                                                




                                                                                                       





















                                                                   
                                                       









                                                
                                        
                              

                                                  
                                    
                                     
                                                                           
                                                                                                      

                                                                                                                 
























                                                                                                                                              




































                                                                                           


                                                            
                                    

                                     
                                        


                                                 

                                        
                                            
                                      
        

     



                                                                  
                                

                                                               


                                                                              


                                                                
                                              



                                                                      
                                                                                           
                                                                     












                                                                                  





                                                                                               

                                                                                                          




                                                              


                             

                                                                                                            
                                                   


                                                                                
                 



                                                            
                                







                                                                        

























































                                                                           

                                                                          
                                 
         



                                             
















                                               
















































































                                                                                                       






































































































                                                                                                                                                                                                                                                
/*******************************************************************************
 * Copyright (c) 2004 - 2005 University Of British Columbia and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University Of British Columbia - initial API and implementation
 *******************************************************************************/
package org.eclipse.mylar.tasks.ui.views;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.security.auth.login.LoginException;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.Window;
import org.eclipse.mylar.bugzilla.core.BugReport;
import org.eclipse.mylar.bugzilla.core.BugzillaRepository;
import org.eclipse.mylar.bugzilla.ui.BugzillaOpenStructure;
import org.eclipse.mylar.bugzilla.ui.ViewBugzillaAction;
import org.eclipse.mylar.core.ITaskscapeListener;
import org.eclipse.mylar.core.MylarPlugin;
import org.eclipse.mylar.dt.MylarWebRef;
import org.eclipse.mylar.tasks.AbstractCategory;
import org.eclipse.mylar.tasks.BugzillaHit;
import org.eclipse.mylar.tasks.BugzillaQueryCategory;
import org.eclipse.mylar.tasks.BugzillaTask;
import org.eclipse.mylar.tasks.ITask;
import org.eclipse.mylar.tasks.ITaskListElement;
import org.eclipse.mylar.tasks.MylarTasksPlugin;
import org.eclipse.mylar.tasks.Task;
import org.eclipse.mylar.tasks.TaskCategory;
import org.eclipse.mylar.tasks.MylarTasksPlugin.Priority_Level;
import org.eclipse.mylar.tasks.bugzilla.BugzillaStructureBridge;
import org.eclipse.mylar.tasks.ui.BugzillaTaskEditorInput;
import org.eclipse.mylar.tasks.ui.TaskEditorInput;
import org.eclipse.mylar.ui.MylarImages;
import org.eclipse.mylar.ui.MylarUiPlugin;
import org.eclipse.mylar.ui.internal.views.Highlighter;
import org.eclipse.mylar.ui.internal.views.HighlighterImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.internal.Workbench;
import org.eclipse.ui.part.DrillDownAdapter;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.IProgressService;

/**
 * @author Mik Kersten
 */
public class TaskListView extends ViewPart {

	private static TaskListView INSTANCE;
	
	//private CheckboxTreeViewer viewer;
	private TreeViewer viewer;
    private DrillDownAdapter drillDownAdapter;
    
    private RefreshAction refresh;
    private CreateTaskAction createTask;
    private CreateCategoryAction createCategory;
    private CreateBugzillaQueryCategoryAction createBugzillaQueryCategory;
    private CreateBugzillaTaskAction createBugzillaTask; 
//    private RenameAction rename;
    private DeleteAction delete;
    private OpenTaskEditorAction doubleClickAction;
    private ClearTaskscapeAction clearSelectedTaskscapeAction;

    //private Action toggleIntersectionModeAction = new ToggleIntersectionModeAction();
//    private Action toggleFilteringAction = new ToggleGlobalInterestFilteringAction();

    private MarkTaskCompleteAction completeTask;
    private MarkTaskIncompleteAction incompleteTask;
    private FilterCompletedTasksAction filterCompleteTask;
//    private FilterIncompleteTasksAction filterInCompleteTask;
    private PriorityDropDownAction filterOnPriority;
    private Action moveTaskToRoot; 
    private PriorityFilter priorityFilter = new PriorityFilter();
    
    protected String[] columnNames = new String[] { "", ".", "!", "Description", "handle" };
    protected int[] columnWidths = new int[] { 70, 20, 20, 120, 70 };
    private TreeColumn[] columns;
    private IMemento taskListMemento;
    public static final String columnWidthIdentifier = "org.eclipse.mylar.tasks.ui.views.tasklist.columnwidth";
    public static final String tableSortIdentifier = "org.eclipse.mylar.tasks.ui.views.tasklist.sortIndex";
    private int sortIndex = 2;
    
    private String[] PRIORITY_LEVELS = { "P1", "P2", "P3", "P4", "P5" };    
    
    private final class MoveTaskToRootAction extends Action {
		public MoveTaskToRootAction() {
			setText("Move Task to Root");
	        setToolTipText("Move Task to Root");
		}
		@Override
		public void run() {
			ISelection selection = viewer.getSelection();
		    Object obj = ((IStructuredSelection)selection).getFirstElement();
		    if (obj instanceof ITask) {
		    	ITask t = (ITask) obj;
		    	TaskCategory cat = t.getCategory();
		    	if (cat != null) {
		    		cat.removeTask(t);
		    		t.setCategory(null);
		    		t.setParent(null);
		    		MylarTasksPlugin.getTaskListManager().getTaskList().addRootTask(t);
		    		viewer.refresh();
		    	} else if (t.getParent() != null) {
		    		t.getParent().removeSubTask(t);
		    		t.setParent(null);
		    		MylarTasksPlugin.getTaskListManager().getTaskList().addRootTask(t);
		    		viewer.refresh();
		    	}
		    }		    
		}
	}
    
//    private final class FilterIncompleteTasksAction extends Action {
//    	public FilterIncompleteTasksAction() {
//    		setText("Filter Incomplete Tasks");
//            setToolTipText("Filter Incomplete Tasks");
////            setImageDescriptor(MylarImages.FILTER_COMPLETE);
//            setChecked(MylarTasksPlugin.getDefault().isFilterInCompleteMode());
//    	}
//    	
//		@Override
//		public void run() {
//			MylarTasksPlugin.getDefault().setFilterInCompleteMode(isChecked());
//			if (isChecked()) {
//				viewer.addFilter(inCompleteFilter);
//				filterCompleteTask.setChecked(false);
//				viewer.removeFilter(completeFilter);
//			} else {
//				viewer.removeFilter(inCompleteFilter);
//			}
//		    viewer.refresh();
//		}
//	}

	private final class FilterCompletedTasksAction extends Action {
		public FilterCompletedTasksAction() {
			setText("Filter Completed Tasks");
	        setToolTipText("Filter Completed Tasks");
	        setImageDescriptor(MylarImages.FILTER_COMPLETE);
	        setChecked(MylarTasksPlugin.getDefault().isFilterCompleteMode());
		}
		@Override
		public void run() {
            MylarPlugin.getDefault().actionObserved(this);
			MylarTasksPlugin.getDefault().setFilterCompleteMode(isChecked());
			if (isChecked()) {
				viewer.addFilter(completeFilter);
//				filterInCompleteTask.setChecked(false);
//				viewer.removeFilter(inCompleteFilter);
			} else {
				viewer.removeFilter(completeFilter);        			
			}
		    viewer.refresh();
		}
	}

	private final class OpenTaskEditorAction extends Action {
		@Override
		public void run() {
            MylarPlugin.getDefault().actionObserved(this);
		    ISelection selection = viewer.getSelection();
		    Object obj = ((IStructuredSelection)selection).getFirstElement();
		    if (obj instanceof ITask) {
		    	((ITask)obj).openTaskInEditor();
		    } else if (obj instanceof BugzillaQueryCategory){
		    	
		    	BugzillaQueryDialog sqd = new BugzillaQueryDialog(Display.getCurrent().getActiveShell());
	        	if(sqd.open() == Dialog.OK){
		        	BugzillaQueryCategory queryCategory = (BugzillaQueryCategory)obj;
		        	queryCategory.setDescription(sqd.getName());
		        	queryCategory.setUrl(sqd.getUrl());
		        	
		            queryCategory.refreshBugs();
		            viewer.refresh();
	        	}
		    } else if(obj instanceof BugzillaHit){
		    	BugzillaHit hit = (BugzillaHit)obj;
		    	if(hit.isTask()){
		    		hit.getAssociatedTask().openTaskInEditor();
		    	} else {
			    	BugzillaOpenStructure open = new BugzillaOpenStructure(((BugzillaHit)obj).getServerName(), ((BugzillaHit)obj).getID(),-1);
			    	List<BugzillaOpenStructure> selectedBugs = new ArrayList<BugzillaOpenStructure>();
			    	selectedBugs.add(open);
			    	ViewBugzillaAction viewBugs = new ViewBugzillaAction("Display bugs in editor", selectedBugs);
					viewBugs.schedule();
		    	}
		    }
		    viewer.refresh(obj);
		}
	}

	private final class ClearTaskscapeAction extends Action {
		public ClearTaskscapeAction() {
			setText("Clear Task Context");
	        setToolTipText("Clear Task Context");
	        setImageDescriptor(MylarImages.ERASE_TASKSCAPE);
		}
		@Override
		public void run() {
            MylarPlugin.getDefault().actionObserved(this);
		    Object selectedObject = ((IStructuredSelection)viewer.getSelection()).getFirstElement();
		    if (selectedObject != null && selectedObject instanceof ITask) {
		    	MylarPlugin.getTaskscapeManager().taskDeleted(((ITask)selectedObject).getHandle(), ((Task)selectedObject).getPath());
		    	viewer.refresh();
		    } else if (selectedObject != null && selectedObject instanceof BugzillaHit) {
		    	BugzillaTask task = ((BugzillaHit)selectedObject).getAssociatedTask();
		    	if(task != null){
		    		MylarPlugin.getTaskscapeManager().taskDeleted(task.getHandle(), task.getPath());
		    	}
		    	viewer.refresh();
		    }
		}
	}
	
//	private final class RenameAction extends Action {
//		public RenameAction() {
//			setText("Rename");
//	        setToolTipText("Rename");
//		}
//		@Override
//		public void run() {
//		    String label = "category";
//		    Object selectedObject = ((IStructuredSelection)viewer.getSelection()).getFirstElement();
//		    if (selectedObject instanceof Task)  label = "task";
//		    
//		    String newName = getLabelNameFromUser(label);
//		    if (selectedObject instanceof Task) {
//		        ((Task)selectedObject).setLabel(newName);
//		    } else if (selectedObject instanceof Category) {
//		        ((Category)selectedObject).setName(newName);
//		    }
//		    viewer.refresh(selectedObject);
//		}
//	}

	private final class MarkTaskIncompleteAction extends Action {
		public MarkTaskIncompleteAction() {
			setText("Mark Incomplete");
	        setToolTipText("Mark Incomplete");
	        setImageDescriptor(MylarImages.TASK_INCOMPLETE);
		}
		@Override
		public void run() {         
            MylarPlugin.getDefault().actionObserved(this);
		    Object selectedObject = ((IStructuredSelection)viewer.getSelection()).getFirstElement();
		    if (selectedObject instanceof Task){ 
		    	((Task)selectedObject).setCompleted(false);                	
		    } else if (selectedObject instanceof BugzillaHit){
		    	BugzillaHit hit = (BugzillaHit)selectedObject;
	        	BugzillaTask task = hit.getAssociatedTask(); 
	        	if(task != null){
			    	task.setCompleted(false);
			    	viewer.refresh();
	        	}
		    }
		    viewer.refresh();
		}
	}

	private final class MarkTaskCompleteAction extends Action {
		public MarkTaskCompleteAction() {
			setText("Mark Complete");
	        setToolTipText("Mark Complete");
	        setImageDescriptor(MylarImages.TASK_COMPLETE);
		}
		@Override
		public void run() {   
            MylarPlugin.getDefault().actionObserved(this);
		    Object selectedObject = ((IStructuredSelection)viewer.getSelection()).getFirstElement();
		    if (selectedObject instanceof Task){ 
		    	((Task)selectedObject).setCompleted(true);
		    	viewer.refresh(selectedObject);
		    } else if (selectedObject instanceof BugzillaHit){
		    	BugzillaHit hit = (BugzillaHit)selectedObject;
	        	BugzillaTask task = hit.getAssociatedTask(); 
	        	if(task != null){
			    	task.setCompleted(true);
			    	viewer.refresh();
	        	}
		    }
		}
	}

	private final class DeleteAction extends Action {
		public DeleteAction() {
			setText("Delete");
	        setToolTipText("Delete");
	        setImageDescriptor(MylarImages.REMOVE);
		}
		
		@Override
		public void run() {     
            MylarPlugin.getDefault().actionObserved(this);
		    boolean deleteConfirmed = MessageDialog.openQuestion(
		            Workbench.getInstance().getActiveWorkbenchWindow().getShell(),
		            "Confirm delete", 
		            "Delete selected item?");
		    if (!deleteConfirmed) { 
		        return;
		    } else {
		        Object selectedObject = ((IStructuredSelection)viewer.getSelection()).getFirstElement();
		        if (selectedObject instanceof Task) {
					MylarTasksPlugin.getTaskListManager().deleteTask((Task)selectedObject);
					MylarPlugin.getTaskscapeManager().taskDeleted(((Task)selectedObject).getHandle(), ((Task)selectedObject).getPath());
					IWorkbenchPage page = MylarTasksPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
					
					// if we couldn't get the page, get out of here
					if (page == null)
						return;
					try{
		                closeTaskEditors((ITask)selectedObject, page);
		            }catch(Exception e){
		            	MylarPlugin.log(e, " deletion failed");
		            }
		        } else if (selectedObject instanceof TaskCategory) {
		        	TaskCategory cat = (TaskCategory) selectedObject;
		        	for (ITask task : cat.getChildren()) {
		        		MylarPlugin.getTaskscapeManager().taskDeleted(task.getHandle(), task.getPath());
		        		IWorkbenchPage page = MylarTasksPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();    					
						if (page == null)
							return;
						try{
		                    closeTaskEditors(task, page);
		                }catch(Exception e){
		                	MylarPlugin.log(e, " deletion failed");
		                }
		        	}
		        	MylarTasksPlugin.getTaskListManager().deleteCategory((TaskCategory)selectedObject);
		        }  else if (selectedObject instanceof BugzillaQueryCategory) {
		        	BugzillaQueryCategory cat = (BugzillaQueryCategory) selectedObject;
		        	MylarTasksPlugin.getTaskListManager().deleteCategory(cat);
		        }
		    }
		    viewer.refresh();
		}
	}

	private final class CreateBugzillaQueryCategoryAction extends Action {
        
        public CreateBugzillaQueryCategoryAction() {
        	setText("Add Bugzilla Query");
            setToolTipText("Add Bugzilla Query");
            setImageDescriptor(MylarImages.CATEGORY_QUERY_NEW);
        }
        
        @Override
        public void run() {

        	// ask the user for the query string and a name
            MylarPlugin.getDefault().actionObserved(this);
        	BugzillaQueryDialog sqd = new BugzillaQueryDialog(Display.getCurrent().getActiveShell());
        	if(sqd.open() == Dialog.OK){
	        	final BugzillaQueryCategory queryCategory = new BugzillaQueryCategory(sqd.getName(), sqd.getUrl());
	        	
	            MylarTasksPlugin.getTaskListManager().getTaskList().addCategory(queryCategory);
	            WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
	            	protected void execute(IProgressMonitor monitor) throws CoreException {
		            	queryCategory.refreshBugs();
	            	}
	            };
	            
	            IProgressService service = PlatformUI.getWorkbench().getProgressService();
	            try {
	            	service.run(true, true, op);
	            } catch (Exception e) {
	            	MylarPlugin.log(e, "There was a problem executing the query refresh");
	            }  
				viewer.refresh();
        	}
        }
    }
	
	private final class CreateBugzillaTaskAction extends Action {
		public CreateBugzillaTaskAction() {
			setText("Add Bugzilla Report");
	        setToolTipText("Add Bugzilla Report");
	        setImageDescriptor(MylarImages.TASK_BUGZILLA_NEW);
		}
		@Override
		public void run() {
            MylarPlugin.getDefault().actionObserved(this);
		    String bugIdString = getBugIdFromUser();
		    int bugId = -1;
		    try {
		    	if (bugIdString != null) {
		    		bugId = Integer.parseInt(bugIdString);
		    	} else {
		    		return;
		    	}
		    } catch (NumberFormatException nfe) {
		        showMessage("Please enter a valid report number");
		        return;
		    }
			
		    // XXX we don't care about duplicates since we use a registrey
			// Check the existing tasks to see if the id is used already.
			// This is to prevent the creation of mutliple Bugzilla tasks
			//   for the same Bugzilla report.
//			boolean doesIdExistAlready = false;
//			doesIdExistAlready = lookForId("Bugzilla-" + bugId);				
//			if (doesIdExistAlready) {
//		        showMessage("A Bugzilla task with ID Bugzilla-" + bugId + " already exists.");
//		        return;
//			}
		
		    ITask newTask = new BugzillaTask("Bugzilla-"+bugId, "<bugzilla info>");				
		    Object selectedObject = ((IStructuredSelection)viewer.getSelection()).getFirstElement();
		    if (selectedObject instanceof TaskCategory){
		        ((TaskCategory)selectedObject).addTask(newTask);
		    } else { 
		        MylarTasksPlugin.getTaskListManager().getTaskList().addRootTask(newTask);
		    }
		    viewer.refresh();
		}
	}

	private final class RefreshAction extends Action {
		public RefreshAction() {
			setText("Refresh Bugzilla reports");
	    	setToolTipText("Refresh Bugzilla reports"); 
	    	setImageDescriptor(MylarImages.TASK_BUG_REFRESH);
		}
		
		@Override			
		public void run() {
            MylarPlugin.getDefault().actionObserved(this);
			// TODO background?
			// perform the update in an operation so that we get a progress monitor 
		    // update the structure bridge cache with the reference provider cached bugs
		    WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
		    	protected void execute(IProgressMonitor monitor) throws CoreException {
									
					List<ITask> tasks = MylarTasksPlugin.getTaskListManager().getTaskList().getRootTasks();
					
		            for (ITask task : tasks) {
						if (task instanceof BugzillaTask) {
							((BugzillaTask)task).refresh();
						}							
					}
		            for (AbstractCategory cat : MylarTasksPlugin.getTaskListManager().getTaskList().getCategories()) {
		            	if (cat instanceof TaskCategory) {
		            		for (ITask task : ((TaskCategory)cat).getChildren()) {
			            		if (task instanceof BugzillaTask) {
									((BugzillaTask)task).refresh();
								}	
			            	}
			            	refreshChildren(((TaskCategory)cat).getChildren());
		            	}
		            	else if (cat instanceof BugzillaQueryCategory) {
		            		final BugzillaQueryCategory bqc = (BugzillaQueryCategory) cat;
		            		PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {

								public void run() {
									bqc.refreshBugs();
									viewer.refresh();
								}
		            		});
		            	}
					}		                
					
		            // clear the caches
		    		Set<String> cachedHandles = new HashSet<String>();
		    		cachedHandles.addAll(MylarTasksPlugin.getDefault().getStructureBridge().getCachedHandles());
		            cachedHandles.addAll(MylarTasksPlugin.getReferenceProvider().getCachedHandles());
		            MylarTasksPlugin.getDefault().getStructureBridge().clearCache();
		        	MylarTasksPlugin.getReferenceProvider().clearCachedReports();
		
		        	BugzillaStructureBridge bridge = MylarTasksPlugin.getDefault().getStructureBridge();
		    		monitor.beginTask("Downloading Bugs" , cachedHandles.size());
		        	for(String key: cachedHandles){
		                try {
		                	String [] parts = key.split(";");
		                    final int id = Integer.parseInt(parts[1]);
		                	BugReport bug = BugzillaRepository.getInstance().getCurrentBug(id);
		                	if(bug != null)
		                		bridge.cache(key, bug);
		                }catch(Exception e){}
		                
		                monitor.worked(1);
		        	}
		        	monitor.done();
		        	viewer.refresh();
		    	}
		    };
		    	
		 	// Use the progess service to execute the runnable
			IProgressService service = PlatformUI.getWorkbench().getProgressService();
			try {
				service.run(true, false, op);
			} catch (InvocationTargetException e) {
				// Operation was canceled
			} catch (InterruptedException e) {
				// Handle the wrapped exception
			}
		}
	}

	private final class CreateTaskAction extends Action {
		public CreateTaskAction() {
			setText("Add Task");
	        setToolTipText("Add Task");
	        setImageDescriptor(MylarImages.TASK_NEW);
		}
		
        @Override
        public void run() {
            MylarPlugin.getDefault().actionObserved(this);
            String label = getLabelNameFromUser("task");
            if(label == null) return;
            Task newTask = new Task(MylarTasksPlugin.getTaskListManager().genUniqueTaskId(), label);
            
            Object selectedObject = ((IStructuredSelection)viewer.getSelection()).getFirstElement();
            if (selectedObject instanceof TaskCategory){
            	newTask.setCategory((TaskCategory)selectedObject);
                ((TaskCategory)selectedObject).addTask(newTask);
            } 
//            else if (selectedObject instanceof Task) {
//            	ITask t = (ITask) selectedObject;
//            	newTask.setParent(t);
//            	t.addSubTask(newTask);
//            }
            else {            	
                MylarTasksPlugin.getTaskListManager().getTaskList().addRootTask(newTask);                
            }  
            MylarUiPlugin.getDefault().setHighlighterMapping(
                    newTask.getHandle(), 
                    MylarUiPlugin.getDefault().getDefaultHighlighter().getName());
            viewer.refresh();
        }
    }
    
    private final class CreateCategoryAction extends Action {        
        public CreateCategoryAction() {
        	setText("Add Category");
            setToolTipText("Add Category");
            setImageDescriptor(MylarImages.CATEGORY_NEW);
        }
        
        @Override
        public void run() {
            MylarPlugin.getDefault().actionObserved(this);
            String label = getLabelNameFromUser("Category");
            if(label == null) return;
            TaskCategory cat = new TaskCategory(label);
            MylarTasksPlugin.getTaskListManager().getTaskList().addCategory(cat);
            viewer.refresh();
        }
    }    
    
    private final class TaskActivateAction extends Action {
    	
    	private ITask task;
    	
    	public TaskActivateAction(ITask task) {
    		this.task = task;
    	}
    	
		public void run() {
            MylarPlugin.getDefault().actionObserved(this);
            MylarTasksPlugin.getTaskListManager().activateTask(task);
		}
    }
    
    private final class TaskDeactivateAction extends Action {
    	
    	private ITask task;
    	
    	public TaskDeactivateAction(ITask task) {
    		this.task = task;
    	}
    	
		public void run() {
            MylarPlugin.getDefault().actionObserved(this);
            MylarTasksPlugin.getTaskListManager().deactivateTask(task);
		}
    }
    
    
    private final class PriorityDropDownAction extends Action implements IMenuCreator {
    	private Menu dropDownMenu = null;
    	
		public PriorityDropDownAction() {
			super();
			setText("Display Priorities");
			setToolTipText("Show Tasks with Priority Levels");
			setImageDescriptor(MylarImages.FILTER_PRIORITY);
			setMenuCreator(this);			
		}
    	
		public void dispose() {			
			if (dropDownMenu != null) {
				dropDownMenu.dispose();
				dropDownMenu = null;
			}
		}

		public Menu getMenu(Control parent) {			
			if (dropDownMenu != null) {
				dropDownMenu.dispose();
			}
			dropDownMenu = new Menu(parent);
			addActionsToMenu();
			return dropDownMenu;
		}

		public Menu getMenu(Menu parent) {
			if (dropDownMenu != null) {
				dropDownMenu.dispose();
			}
			dropDownMenu = new Menu(parent);
			addActionsToMenu();
			return dropDownMenu;
		}     
		
		public void addActionsToMenu() {
			Action P1 = new Action(PRIORITY_LEVELS[0], AS_CHECK_BOX) {	    		
	    		@Override
				public void run() {
	    			MylarTasksPlugin.setPriorityLevel(MylarTasksPlugin.Priority_Level.P1, isChecked());
	    			if (isChecked()) {
	    				priorityFilter.displayPriority(PRIORITY_LEVELS[0]);
	    			} else {
	    				priorityFilter.hidePriority(PRIORITY_LEVELS[0]);
	    			}
	    			viewer.refresh();
				}
			};  
			P1.setEnabled(true);
			P1.setChecked(MylarTasksPlugin.getPriorityLevel(MylarTasksPlugin.Priority_Level.P1));
			P1.setToolTipText(PRIORITY_LEVELS[0]);
			ActionContributionItem item= new ActionContributionItem(P1);
			item.fill(dropDownMenu, -1);
			
			Action P2 = new Action(PRIORITY_LEVELS[1], AS_CHECK_BOX) {	    		
	    		@Override
				public void run() {
	    			MylarTasksPlugin.setPriorityLevel(MylarTasksPlugin.Priority_Level.P2, isChecked());
	    			if (isChecked()) {
	    				priorityFilter.displayPriority(PRIORITY_LEVELS[1]);
	    			} else {
	    				priorityFilter.hidePriority(PRIORITY_LEVELS[1]);
	    			}
	    			viewer.refresh();
				}
			};  
			P2.setEnabled(true);
			P2.setChecked(MylarTasksPlugin.getPriorityLevel(MylarTasksPlugin.Priority_Level.P2));
			P2.setToolTipText(PRIORITY_LEVELS[1]);
			item= new ActionContributionItem(P2);
			item.fill(dropDownMenu, -1);
			
			Action P3 = new Action(PRIORITY_LEVELS[2], AS_CHECK_BOX) {	    		
	    		@Override
				public void run() { 
	    			MylarTasksPlugin.setPriorityLevel(MylarTasksPlugin.Priority_Level.P3, isChecked());
	    			if (isChecked()) {
	    				priorityFilter.displayPriority(PRIORITY_LEVELS[2]);
	    			} else {
	    				priorityFilter.hidePriority(PRIORITY_LEVELS[2]);
	    			}
	    			viewer.refresh();
				}
			};
			P3.setEnabled(true);
			P3.setChecked(MylarTasksPlugin.getPriorityLevel(MylarTasksPlugin.Priority_Level.P3));
			P3.setToolTipText(PRIORITY_LEVELS[2]);
			item= new ActionContributionItem(P3);
			item.fill(dropDownMenu, -1);
			
			Action P4 = new Action(PRIORITY_LEVELS[3], AS_CHECK_BOX) {	    		
	    		@Override
				public void run() {
	    			MylarTasksPlugin.setPriorityLevel(MylarTasksPlugin.Priority_Level.P4, isChecked());
	    			if (isChecked()) {
	    				priorityFilter.displayPriority(PRIORITY_LEVELS[3]);
	    			} else {
	    				priorityFilter.hidePriority(PRIORITY_LEVELS[3]);
	    			}
	    			viewer.refresh();
				}
			};
			P4.setEnabled(true);
			P4.setChecked(MylarTasksPlugin.getPriorityLevel(MylarTasksPlugin.Priority_Level.P4));
			P4.setToolTipText(PRIORITY_LEVELS[3]);
			item= new ActionContributionItem(P4);
			item.fill(dropDownMenu, -1);
						
			Action P5 = new Action(PRIORITY_LEVELS[4], AS_CHECK_BOX) {	    		
	    		@Override
				public void run() { 
	    			MylarTasksPlugin.setPriorityLevel(MylarTasksPlugin.Priority_Level.P5, isChecked());
	    			if (isChecked()) {
	    				priorityFilter.displayPriority(PRIORITY_LEVELS[4]);
	    			} else {
	    				priorityFilter.hidePriority(PRIORITY_LEVELS[4]);
	    			}	
	    			viewer.refresh();
	    		}
			};  
			P5.setEnabled(true);
			P5.setChecked(MylarTasksPlugin.getPriorityLevel(MylarTasksPlugin.Priority_Level.P5));
			P5.setToolTipText(PRIORITY_LEVELS[4]);
			item= new ActionContributionItem(P5);
			item.fill(dropDownMenu, -1);			
		}
		public void run() {	
			this.setChecked(isChecked());
		}
    }
    
    private ViewerFilter completeFilter = new ViewerFilter(){
		@Override
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			if (element instanceof ITask) {
				return !((ITask)element).isCompleted();
			} else { 
				return true;
			}
		}    	
    };
    
    private ViewerFilter inCompleteFilter = new ViewerFilter(){
		@Override
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			if (element instanceof ITask) {
				return ((ITask)element).isCompleted();
			} else {
				return true;
			} 
		}    			
    };
    
    public class PriorityFilter extends ViewerFilter {
    	// list of priorities that will be shown in the tasklistview
    	private List<String> priorities = new ArrayList<String>();
    	
    	public PriorityFilter() {
    		for (Priority_Level level : MylarTasksPlugin.getPriorityLevels()) {
    			displayPriority(level.toString());
    		}
    	}
    	
    	public void displayPriority(String p) {
    		if (!priorities.contains(p)) {
    			priorities.add(p);
    		}    		
    	}
    	
    	public void hidePriority(String p) {
    		priorities.remove(p);
    	}
		@Override
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			if (element instanceof ITask) {
				ITask task = (ITask) element;
				if (priorities.size() == PRIORITY_LEVELS.length) {
					return true;
				} else {
					for (String filter : priorities) {
						if (task.getPriority().equals(filter)) {
							return true;
						}
					}
					return false;
				}								
			} else {
				return true;
			}			
		}
    	
    };
    
    class TaskListContentProvider implements IStructuredContentProvider, ITreeContentProvider {
        public void inputChanged(Viewer v, Object oldInput, Object newInput) {
        	// don't care if the input changes
        }
        public void dispose() {
        	// don't care if we are disposed
        }
        public Object[] getElements(Object parent) {
            if (parent.equals(getViewSite())) {
            	return MylarTasksPlugin.getTaskListManager().getTaskList().getRoots().toArray();            	          
            }
            return getChildren(parent);
        }
        public Object getParent(Object child) {
            if (child instanceof ITask) {
            	if (((ITask)child).getParent() != null) {
            		return ((ITask)child).getParent();
            	} else {
            		return ((ITask)child).getCategory();
            	}
                
            }
            return null;
        }
        public Object [] getChildren(Object parent) {
        	if (parent instanceof TaskCategory) {
        		return ((TaskCategory)parent).getChildren().toArray();
        	} else if (parent instanceof Task) {
        		return ((Task)parent).getChildren().toArray();
        	} else if (parent instanceof BugzillaQueryCategory) {
        		return ((BugzillaQueryCategory) parent).getHits().toArray();
        	}
        	return new Object[0];
        }
        public boolean hasChildren(Object parent) {  
            if (parent instanceof TaskCategory) {
            	TaskCategory cat = (TaskCategory)parent;
                return cat.getChildren() != null && cat.getChildren().size() > 0;
            }  else if (parent instanceof Task) {
            	Task t = (Task) parent;
            	return t.getChildren() != null && t.getChildren().size() > 0;
            } else if (parent instanceof BugzillaQueryCategory) {
            	BugzillaQueryCategory cat = (BugzillaQueryCategory)parent;
                return cat.getHits() != null && cat.getHits().size() > 0;
            } 
            return false;
        }
    }

    public TaskListView() { 
    	INSTANCE = this;
    }

    class TaskListCellModifier implements ICellModifier {

        public boolean canModify(Object element, String property) {
            int columnIndex = Arrays.asList(columnNames).indexOf(property);
            if (element instanceof ITask) {
            	ITask task = (ITask) element;
                switch (columnIndex) {
                case 0: return true;
                case 1: return false;
                case 2: return !(task instanceof BugzillaTask);
                case 3: return !(task instanceof BugzillaTask);
                case 4: return false;
                }
            } else if (element instanceof AbstractCategory) {
                switch (columnIndex) {
                case 0:
                case 1: 
                case 2:
                	return false;
                case 3: return true;
                case 4: return false;
                } 
            } else if (element instanceof BugzillaHit){
            	if (columnIndex == 0) {
            		return true;
            	}else {
            		return false;
            	}            	
            }
            return false;
        }

        public Object getValue(Object element, String property) {
            int columnIndex = Arrays.asList(columnNames).indexOf(property);
            if (element instanceof ITask) {
				ITask task = (ITask) element;
				switch (columnIndex) {
				case 0:
					return new Boolean(task.isCompleted());
				case 1:
					return "";
				case 2:
					String priorityString = task.getPriority().substring(1);
					return new Integer(priorityString);
				case 3:
					return task.getLabel();
				case 4:
					return task.getHandle();
				}
			} else if (element instanceof AbstractCategory) {
				AbstractCategory cat = (AbstractCategory) element;
				switch (columnIndex) {
				case 0:
					return new Boolean(false);
				case 1:
					return "";
				case 2:
					return "";
				case 3:
					return cat.getDescription(true);
				case 4:
					return "";
				}
			} else if (element instanceof BugzillaHit) {
				BugzillaHit hit = (BugzillaHit) element;
				ITask task = hit.getAssociatedTask();
				switch (columnIndex) {
				case 0:
					if(task == null){
						return new Boolean(true);
					} else {
						return new Boolean(task.isCompleted());
					}
				case 1:
					return "";
				case 2:
					String priorityString = hit.getPriority().substring(1);
					return new Integer(priorityString);
				case 3:
					return hit.getDescription(true);
				case 4:
					return hit.getHandle();					
				}
			}
            return "";
        }

		public void modify(Object element, String property, Object value) {
			int columnIndex = -1;
			try {
				columnIndex = Arrays.asList(columnNames).indexOf(property);
				if (((TreeItem) element).getData() instanceof ITask) {

					final ITask task = (ITask) ((TreeItem) element).getData();
					switch (columnIndex) {
					case 0:
						if (task.isActive()) {
							new TaskDeactivateAction(task).run();
						} else {
							new TaskActivateAction(task).run();
						}
						viewer.setSelection(null);
						break;
					case 1:
						break;
					case 2:
						Integer intVal = (Integer) value;
						task.setPriority("P" + (intVal + 1));
						viewer.setSelection(null);
						break;
					case 3:
						task.setLabel(((String) value).trim());
						MylarTasksPlugin.getTaskListManager()
								.taskPropertyChanged(task, columnNames[3]);
						viewer.setSelection(null);
						break;
					case 4:
						break;
					}
				} else if (((TreeItem) element).getData() instanceof AbstractCategory) {
					AbstractCategory cat = (AbstractCategory)((TreeItem) element).getData();
					switch (columnIndex) {
					case 0:						
						viewer.setSelection(null);
						break;
					case 1:
						break;
					case 2:
						break;
					case 3:
						cat.setDescription(((String) value).trim());
						viewer.setSelection(null);
						break;
					case 4:
						break;
					}
				} else if (((TreeItem) element).getData() instanceof BugzillaHit) {
					BugzillaHit hit = (BugzillaHit)((TreeItem) element).getData();
					switch (columnIndex) {
					case 0:
						BugzillaTask task = hit.getAssociatedTask();
						if(task == null){
							task = new BugzillaTask(hit);
							hit.setAssociatedTask(task);
							MylarTasksPlugin.getTaskListManager().getTaskList().addToBugzillaTaskRegistry(task);
							// TODO move the task to a special folder
						} 
						if (task.isActive()) {
							MylarTasksPlugin.getTaskListManager()
									.deactivateTask(task);
						} else {
							MylarTasksPlugin.getTaskListManager().activateTask(
									task);
						}
						viewer.setSelection(null);
						break;
					case 1:
						break;
					case 2:
						break;
					case 3:						
						viewer.setSelection(null);
						break;
					case 4:
						break;
					}
				}
				viewer.refresh();
			} catch (Exception e) {
				MylarPlugin.log(e, e.getMessage());
			}
		}                
    }
    
    private class TaskListTableSorter extends ViewerSorter {

        private String column;

        public TaskListTableSorter(String column) {
            super();
            this.column = column;
        }

        /**
		 * compare - invoked when column is selected calls the actual comparison
		 * method for particular criteria
		 */
        @Override
        public int compare(Viewer compareViewer, Object o1, Object o2) {
        	if (o1 instanceof AbstractCategory) {
        		if (o2 instanceof AbstractCategory) {
        			return 0;
        		} else {
        			return -1;
        		}
        	} else if(o1 instanceof ITask){
        		if (o2 instanceof AbstractCategory) {
        			return -1;
        		} else if(o2 instanceof ITask) {
        			
        			ITask task1 = (ITask) o1;
        			ITask task2 = (ITask) o2;
                    
                    if (task1.isCompleted()) return 1;
                    if (task2.isCompleted()) return -1;
                    if (column == columnNames[1]) {
                        if (task1 instanceof BugzillaTask && !(task2 instanceof BugzillaTask)) {
                            return 1;
                        } else {
                            return -1;
                        }
                    } else if (column == columnNames[2]) {
                        return task1.getPriority().compareTo(task2.getPriority());
                    } else if (column == columnNames[3]) {
                        return task1.getLabel().compareTo(task2.getLabel());
                    } else if (column == columnNames[4]){
                    	return task1.getPath().compareTo(task2.getPath());
                    } else {
                    	return 0;
                    }
        		}
        	} else if(o1 instanceof BugzillaHit && o2 instanceof BugzillaHit){
        		BugzillaHit task1 = (BugzillaHit) o1;
        		BugzillaHit task2 = (BugzillaHit) o2;
                
                if (column == columnNames[1]) {
                    return 0;
                } else if (column == columnNames[2]) {
                    return task1.getPriority().compareTo(task2.getPriority());
                } else if (column == columnNames[3]) {
                    return task1.getDescription(false).compareTo(task2.getDescription(false));
                } else if (column == columnNames[4]){
                	return task1.getHandle().compareTo(task2.getHandle());
                } else {
                	return 0;
                }
        	} else{
        		return 0;
        	}
        	return 0;
        }
    }
    
    @Override
    public void init(IViewSite site,IMemento memento) throws PartInitException {
    	init(site);
    	this.taskListMemento = memento;
    }
    
    @Override
    public void saveState(IMemento memento) {
		IMemento colMemento = memento.createChild(columnWidthIdentifier);

		for (int i = 0; i < columnWidths.length; i++) {
			IMemento m = colMemento.createChild("col"+i);
			m.putInteger("width", columnWidths[i]);
		}
		
		IMemento sorter = memento.createChild(tableSortIdentifier);
		IMemento m = sorter.createChild("sorter");
		m.putInteger("sortIndex", sortIndex);
	}
    
    private void restoreState() {
        if (taskListMemento == null)
                return;
        IMemento taskListWidth = taskListMemento.getChild(columnWidthIdentifier);
        if (taskListWidth != null) {
        	for (int i = 0; i < columnWidths.length; i++) {
        		IMemento m = taskListWidth.getChild("col"+i);
        		if (m != null) {
        			int width = m.getInteger("width");
        			columnWidths[i] = width;
        			columns[i].setWidth(width);
        		}
        	}        	
        }
        IMemento sorterMemento = taskListMemento.getChild(tableSortIdentifier);
        if (sorterMemento != null) {
        	IMemento m = sorterMemento.getChild("sorter");
        	if (m != null) {
        		sortIndex = m.getInteger("sortIndex");
        	} else {
        		sortIndex = 2;
        	}
        } else {
        	sortIndex = 2; // default priority
        }
        viewer.setSorter(new TaskListTableSorter(columnNames[sortIndex]));
        viewer.addFilter(priorityFilter);
        if(MylarTasksPlugin.getDefault().isFilterInCompleteMode()) viewer.addFilter(inCompleteFilter);
        if(MylarTasksPlugin.getDefault().isFilterCompleteMode()) viewer.addFilter(completeFilter);
        viewer.refresh();
    }
        
    /** 
     * This is a callback that will allow us
     * to create the viewer and initialize it.
     */
    @Override
    public void createPartControl(Composite parent) {    	    	
        viewer = new TreeViewer(parent, SWT.VERTICAL | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.HIDE_SELECTION);
        viewer.getTree().setHeaderVisible(true);
        viewer.getTree().setLinesVisible(true);
        viewer.setColumnProperties(columnNames);
        viewer.setUseHashlookup(true);    
                
        columns = new TreeColumn[columnNames.length];
        for (int i = 0; i < columnNames.length; i++) {
            columns[i] = new TreeColumn(viewer.getTree(), 0); // SWT.LEFT
            columns[i].setText(columnNames[i]);
            columns[i].setWidth(columnWidths[i]);
            final int index = i;
            columns[i].addSelectionListener(new SelectionAdapter() {
            	
            	@Override
                public void widgetSelected(SelectionEvent e) {
            		sortIndex = index;
                    viewer.setSorter(new TaskListTableSorter(columnNames[sortIndex]));
                }
            });
            columns[i].addControlListener(new ControlListener () {
            	public void controlResized(ControlEvent e) {
            		for (int j = 0; j < columnWidths.length; j++) {
            			if (columns[j].equals(e.getSource())) {
            				columnWidths[j] = columns[j].getWidth();
            			}
            		}
            	}
				public void controlMoved(ControlEvent e) {	
					// don't care if the control is moved
				}
            });
        }
         
        CellEditor[] editors = new CellEditor[columnNames.length];
        TextCellEditor textEditor = new TextCellEditor(viewer.getTree());
        ((Text) textEditor.getControl()).setOrientation(SWT.LEFT_TO_RIGHT);
        editors[0] = new CheckboxCellEditor();
        editors[1] = textEditor;
        editors[2] = new ComboBoxCellEditor(viewer.getTree(), PRIORITY_LEVELS, SWT.READ_ONLY);
        editors[3] = textEditor;
        viewer.setCellEditors(editors);   
        viewer.setCellModifier(new TaskListCellModifier());
        viewer.setSorter(new TaskListTableSorter(columnNames[sortIndex]));
        
        drillDownAdapter = new DrillDownAdapter(viewer);
        viewer.setContentProvider(new TaskListContentProvider());
        TaskListLabelProvider lp = new TaskListLabelProvider();
        lp.setBackgroundColor(parent.getBackground());
        viewer.setLabelProvider(lp);
        viewer.setInput(getViewSite());
        
        makeActions();
        hookContextMenu();
        hookDoubleClickAction();
        contributeToActionBars();       
        ToolTipHandler toolTipHandler = new ToolTipHandler(viewer.getControl().getShell());
        toolTipHandler.activateHoverHelp(viewer.getControl());
        
        initDragAndDrop(parent);
        expandToActiveTasks();
        restoreState();
   }

    @MylarWebRef(name="Drag and drop article", url="http://www.eclipse.org/articles/Article-Workbench-DND/drag_drop.html")
    private void initDragAndDrop(Composite parent) {
        Transfer[] types = new Transfer[] { TextTransfer.getInstance() };

        viewer.addDragSupport(DND.DROP_MOVE, types, new DragSourceListener() {

            public void dragStart(DragSourceEvent event) {
                if (((StructuredSelection) viewer.getSelection()).isEmpty()) {
                    event.doit = false;
                }
            }

            public void dragSetData(DragSourceEvent event) {
                StructuredSelection selection = (StructuredSelection) viewer.getSelection();
                if (!selection.isEmpty()) {
                    event.data = "" + ((ITask) selection.getFirstElement()).getHandle();
                } else {
                    event.data = "null";
                }
            }

            public void dragFinished(DragSourceEvent event) {
            	// don't care if the drag is done
            }
        });

        viewer.addDropSupport(DND.DROP_MOVE, types, new ViewerDropAdapter(viewer) {
            {
                setFeedbackEnabled(false);
            }

            @Override
            public boolean performDrop(Object data) {
                Object selectedObject = ((IStructuredSelection) ((TreeViewer) getViewer())
                        .getSelection()).getFirstElement();
                if (selectedObject instanceof ITask) {
                    ITask source = (ITask) selectedObject;
                    if (source.getCategory() != null) {
                		source.getCategory().removeTask(source);
                	} else if (source.getParent() != null) {
                		source.getParent().removeSubTask(source);
                	} else {
                		MylarTasksPlugin.getTaskListManager().getTaskList().getRootTasks().remove(source);
                	}
                    
                    if (getCurrentTarget() instanceof TaskCategory) {
                    	((TaskCategory) getCurrentTarget()).addTask(source);
                    	source.setCategory((TaskCategory)getCurrentTarget());
                    } else if (getCurrentTarget() instanceof ITask) {
                    	ITask target = (ITask) getCurrentTarget();
                    	source.setCategory(null);
                    	target.addSubTask(source);                    	
                    	source.setParent(target);
                    }           
                    viewer.setSelection(null);
                    viewer.refresh();
                    return true;
                }
                return false;
            }

            @Override
            public boolean validateDrop(Object targetObject, int operation,
                    TransferData transferType) {
                Object selectedObject = ((IStructuredSelection) ((TreeViewer) getViewer())
                        .getSelection()).getFirstElement();
                if (selectedObject instanceof ITask) {
                    if (getCurrentTarget() != null && 
                    		(getCurrentTarget() instanceof ITask || getCurrentTarget() instanceof TaskCategory)) {
                    	return true;
                    } else {
                    	return false;
                    }
                }
                return TextTransfer.getInstance().isSupportedType(transferType);
            }

        });
    }
    
    private void expandToActiveTasks() {
    	List<ITask> activeTasks = MylarTasksPlugin.getTaskListManager().getTaskList().getActiveTasks();
    	for (ITask t : activeTasks) {
    		viewer.expandToLevel(t, 0);
    	}
    }

    private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu");
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                TaskListView.this.fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(menuMgr, viewer);
    }

    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();
        fillLocalPullDown(bars.getMenuManager());
        fillLocalToolBar(bars.getToolBarManager());
    }

    private void fillLocalPullDown(IMenuManager manager) {
    	drillDownAdapter.addNavigationActions(manager);
//        manager.add(createCategory);
//        manager.add(new Separator());
//        manager.add(createTask);
    }

    void fillContextMenu(IMenuManager manager) {
        manager.add(completeTask);
        manager.add(incompleteTask);
//        manager.add(new Separator());
        manager.add(createTask);
        manager.add(createBugzillaTask);
//        manager.add(rename);
        manager.add(delete);
        manager.add(clearSelectedTaskscapeAction);
        manager.add(moveTaskToRoot);
        manager.add(new Separator());
        MenuManager subMenuManager = new MenuManager("Choose Highlighter");
        final Object selectedObject = ((IStructuredSelection)viewer.getSelection()).getFirstElement();
        for (Iterator<Highlighter> it = MylarUiPlugin.getDefault().getHighlighters().iterator(); it.hasNext();) {
            final Highlighter highlighter = it.next();
            if (selectedObject instanceof Task){
                Action action = new Action() {
                	
                	@Override
                    public void run() { 
                        Task task = (Task)selectedObject;
                        MylarUiPlugin.getDefault().setHighlighterMapping(task.getHandle(), highlighter.getName());
                        TaskListView.this.viewer.refresh();
                        MylarPlugin.getTaskscapeManager().notifyPostPresentationSettingsChange(ITaskscapeListener.UpdateKind.HIGHLIGHTER);
//                        taskscapeComponent.getTableViewer().refresh();
                    }
                };
                if (highlighter.isGradient()) {
                    action.setImageDescriptor(new HighlighterImageDescriptor(highlighter.getBase(), highlighter.getLandmarkColor()));
                } else {
                    action.setImageDescriptor(new HighlighterImageDescriptor(highlighter.getLandmarkColor(), highlighter.getLandmarkColor()));
                }
                action.setText(highlighter.toString());
                subMenuManager.add(action);
            } else {
//                showMessage("Select task before choosing highlighter");
            }
        }
        manager.add(subMenuManager);
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        updateActionEnablement(selectedObject);
    }
    
    private void updateActionEnablement(Object sel){
    	if(sel != null && sel instanceof ITaskListElement){
	    	if(sel instanceof BugzillaHit){
				BugzillaTask task = ((BugzillaHit)sel).getAssociatedTask();
				if(task == null){
					clearSelectedTaskscapeAction.setEnabled(false);
				} else {
					clearSelectedTaskscapeAction.setEnabled(true);
				}
				completeTask.setEnabled(false);
				incompleteTask.setEnabled(false);
				moveTaskToRoot.setEnabled(false);
				delete.setEnabled(false);
			} else if(sel instanceof BugzillaTask){
				completeTask.setEnabled(false);
				incompleteTask.setEnabled(false);
			} else if(sel instanceof AbstractCategory){
				clearSelectedTaskscapeAction.setEnabled(false);
				moveTaskToRoot.setEnabled(false);
				completeTask.setEnabled(false);
				incompleteTask.setEnabled(false);
			} else {
				delete.setEnabled(true);
				moveTaskToRoot.setEnabled(true);
				completeTask.setEnabled(true);
				incompleteTask.setEnabled(true);
				clearSelectedTaskscapeAction.setEnabled(true);
			}
			
		}else {
			delete.setEnabled(true);
			moveTaskToRoot.setEnabled(true);
			clearSelectedTaskscapeAction.setEnabled(false);
		}
    }
    
    private void fillLocalToolBar(IToolBarManager manager) {
            manager.add(createTask);
        manager.add(createCategory);
        manager.add(new Separator());
        manager.add(createBugzillaTask);
        
    	manager.add(createBugzillaQueryCategory);
    	manager.add(refresh);
        manager.add(new Separator());
        manager.add(filterCompleteTask);
//        manager.add(filterInCompleteTask);
        manager.add(filterOnPriority);
        
    }

    /**
     * @see org.eclipse.pde.internal.ui.view.HistoryDropDownAction
     *
     */
    private void makeActions() {
    	refresh = new RefreshAction();      	               
        createTask = new CreateTaskAction();        
        createCategory = new CreateCategoryAction();
        createBugzillaQueryCategory = new CreateBugzillaQueryCategoryAction();
        createBugzillaTask = new CreateBugzillaTaskAction();                
        delete = new DeleteAction();
        completeTask = new MarkTaskCompleteAction();
        incompleteTask = new MarkTaskIncompleteAction();        
//        rename = new RenameAction();        
        clearSelectedTaskscapeAction = new ClearTaskscapeAction();
        moveTaskToRoot = new MoveTaskToRootAction();
        doubleClickAction = new OpenTaskEditorAction();            
        filterCompleteTask = new FilterCompletedTasksAction();        
//        filterInCompleteTask = new FilterIncompleteTasksAction();                        
        filterOnPriority = new PriorityDropDownAction();             
    }

    /**
	 * Recursive function that checks for the occurrence of a certain task id.
	 * All children of the supplied node will be checked.
	 * 
	 * @param task
	 *            The <code>ITask</code> object that is to be searched.
	 * @param taskId
	 *            The id that is being searched for.
	 * @return <code>true</code> if the id was found in the node or any of its
	 *         children
	 */
    protected boolean lookForId(String taskId) {
    	for (ITask task : MylarTasksPlugin.getTaskListManager().getTaskList().getRootTasks()) {
    		if (task.getHandle().equals(taskId)) {
    			return true;
    		}
    	}
    	for (TaskCategory cat : MylarTasksPlugin.getTaskListManager().getTaskList().getTaskCategories()) {
    		for (ITask task : cat.getChildren()) {
        		if (task.getHandle().equals(taskId)) {
        			return true;
        		}
        	}
    	}
		return false;
	}
	
	protected void closeTaskEditors(ITask task, IWorkbenchPage page) throws LoginException, IOException{
		IEditorInput input = null;		
		if (task instanceof BugzillaTask) {
			input = new BugzillaTaskEditorInput((BugzillaTask)task);
		} else if (task instanceof Task) {
			input = new TaskEditorInput((Task) task);
		}
		IEditorPart editor = page.findEditor(input);

		if (editor != null) {
			page.closeEditor(editor, false);
		}		
	}
	
	protected void refreshChildren(List<ITask> children) {
		if (children != null) {
            for (ITask child : children) {
				if (child instanceof BugzillaTask) {
					((BugzillaTask)child).refresh();
				}
			}
		}
	}

	private void hookDoubleClickAction() {
        viewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                doubleClickAction.run();
            }
        });
    }
    private void showMessage(String message) {
        MessageDialog.openInformation(
            viewer.getControl().getShell(),
            "Tasklist Message",
            message);
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    @Override
    public void setFocus() {
        viewer.getControl().setFocus();
        //TODO: foo
    }

    private String getBugIdFromUser() {
        InputDialog dialog = new InputDialog(
            Workbench.getInstance().getActiveWorkbenchWindow().getShell(), 
            "Enter Bugzilla ID", 
            "Enter the Bugzilla ID: ", 
            "", 
            null);
        int dialogResult = dialog.open();
        if (dialogResult == Window.OK) { 
            return dialog.getValue();
        } else {
            return null;
        }
    }
    
    private String getLabelNameFromUser(String kind) {
        
        InputDialog dialog = new InputDialog(
            Workbench.getInstance().getActiveWorkbenchWindow().getShell(), 
            "Enter name", 
            "Enter a name for the " + kind + ": ", 
            "", 
            null);
        int dialogResult = dialog.open();
        if (dialogResult == Window.OK) { 
            return dialog.getValue();
        } else {
            return null;
        }
    }
    
    public void notifyTaskDataChanged(ITask task) {
        if (viewer.getTree() != null && !viewer.getTree().isDisposed()) { 
        	viewer.refresh();
        }
    }
    
    public static TaskListView getDefault() {
    	return INSTANCE;
    }
    
    public TreeViewer getViewer() {
    	return viewer;
    }
    
    public ViewerFilter getCompleteFilter() {
    	return completeFilter;
    }
    
    public ViewerFilter getInCompleteFilter() {
    	return inCompleteFilter;
    }
    
    public PriorityFilter getPriorityFilter() {
    	return priorityFilter;
    }
}

//TextTransfer textTransfer = TextTransfer.getInstance();
//DropTarget target = new DropTarget(viewer.getTree(), DND.DROP_MOVE);
//target.setTransfer(new Transfer[] { textTransfer });
//target.addDropListener(new TaskListDropTargetListener(parent, null, textTransfer, true));
//
//DragSource source = new DragSource(viewer.getTree(), DND.DROP_MOVE);
//source.setTransfer(types); 

//source.addDragListener(new DragSourceListener() {
//public void dragStart(DragSourceEvent event) {
//  if (((StructuredSelection)viewer.getSelection()).isEmpty()) { 
//      event.doit = false; 
//  }
//}
//public void dragSetData(DragSourceEvent event) {
//  StructuredSelection selection = (StructuredSelection) viewer.getSelection();
//  if (!selection.isEmpty()) { 
//      event.data = "" + ((ITask)selection.getFirstElement()).getId();
//  } else {
//      event.data = "null";
//  }
//}
//
//public void dragFinished(DragSourceEvent event) { }
//});


//	public boolean getServerStatus() {
//		return serverStatus;
//	}
//	
//	/**
//	 * Sets whether or not we could connect to the Bugzilla server. If
//	 * necessary, the corresponding label in the view is updated.
//	 * 
//	 * @param canRead
//	 *            <code>true</code> if the Bugzilla server could be connected
//	 *            to
//	 */
//	public void setServerStatus(boolean canRead) {
//		if (serverStatus != canRead) {
//			serverStatus = canRead;
//			updateServerStatusLabel();
//		}
//	}
//	
//	private void updateServerStatusLabel() {
//		if (serverStatusLabel.isDisposed()) {
//			return;
//		}
//		if (serverStatus) {
//			serverStatusLabel.setText(CAN_READ_LABEL);
//		}
//		else {
//			serverStatusLabel.setText(CANNOT_READ_LABEL);
//		}
//	}
//	
//	private class ServerPingJob extends Job {
//		private boolean shouldCheckAgain = true;
//		private int counter = 0;
//		
//		public ServerPingJob(String name) {
//			super(name);
//		}
//		
//		public void stopPinging() {
//			shouldCheckAgain = false;
//		}
//
//		protected IStatus run(IProgressMonitor monitor) {
//			while (shouldCheckAgain) {
//				try {
//					final boolean canReadFromServer = TaskListView.checkServer();
//					Workbench.getInstance().getDisplay().asyncExec(new Runnable() {
//						public void run() {
//							setServerStatus(canReadFromServer);
//						}
//					});
//					Thread.sleep(10000/*MylarPreferencePage.getServerPing()*5000*/);
//				} catch (InterruptedException e) {
//					break;
//				}
//			}
//			return new Status(IStatus.OK, MylarPlugin.IDENTIFIER, IStatus.OK, "", null);
//		}
//	}
//	
//	/**
//	 * @return <code>true</code> if we could connect to the Bugzilla server
//	 */
//	public static boolean checkServer() {
//		boolean canRead = true;
//		BufferedReader in = null;
//		
//		// Call this function to intialize the Bugzilla url that the repository
//		// is using.
//		BugzillaRepository.getInstance();
//
//		try {
//			// connect to the bugzilla server
//			SSLContext ctx = SSLContext.getInstance("TLS");
//			javax.net.ssl.TrustManager[] tm = new javax.net.ssl.TrustManager[]{new TrustAll()};
//			ctx.init(null, tm, null);
//			HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
//			String urlText = "";
//			
//			// use the usename and password to get into bugzilla if we have it
//			if(BugzillaPreferences.getUserName() != null && !BugzillaPreferences.getUserName().equals("") && BugzillaPreferences.getPassword() != null && !BugzillaPreferences.getPassword().equals(""))
//			{
//				/*
//				 * The UnsupportedEncodingException exception for
//				 * URLEncoder.encode() should not be thrown, since every
//				 * implementation of the Java platform is required to support
//				 * the standard charset "UTF-8"
//				 */
//				try {
//					urlText += "?GoAheadAndLogIn=1&Bugzilla_login=" + URLEncoder.encode(BugzillaPreferences.getUserName(), "UTF-8") + "&Bugzilla_password=" + URLEncoder.encode(BugzillaPreferences.getPassword(), "UTF-8");
//				} catch (UnsupportedEncodingException e) { }
//			}
//			
//			URL url = new URL(BugzillaRepository.getURL() + "/enter_bug.cgi" + urlText);
//			
//			// create a new input stream for getting the bug
//			in = new BufferedReader(new InputStreamReader(url.openStream()));
//		}
//		catch (Exception e) {
//			// If there was an IOException, then there was a problem connecting.
//			// If there was some other exception, then it was a problem not
//			// related to the server.
//			if (e instanceof IOException) {
//				canRead = false;
//			}
//		}
//
//		// Close the BufferedReader if we opened one.
//		try {
//			if (in != null)
//				in.close();
//		} catch(IOException e) {}
//		
//		return canRead;
//	}
//
//	public void dispose() {
//		if (serverPingJob != null) {
//			serverPingJob.stopPinging();
//		}
//		super.dispose();
//	}

//      source.addDragListener(new DragSourceListener() {
//
//            public void dragStart(DragSourceEvent event) {
//                if (((StructuredSelection) viewer.getSelection()).getFirstElement() == null) {
//                    event.doit = false;
//                }
//            }
//
//            public void dragSetData(DragSourceEvent event) {
//                StructuredSelection selection = (StructuredSelection)viewer.getSelection();
//                ITask task = (ITask) selection.getFirstElement();
//                if (task != null) {
//                    event.data = "" + task.getId();
//                } else {
//                    event.data = " ";
//                }
//            }
//
//            public void dragFinished(DragSourceEvent event) {
//                StructuredSelection selection = (StructuredSelection)viewer.getSelection();
//                if (selection.isEmpty()) {
//                    return;
//                } else {
//                    ITask task = (ITask) selection.getFirstElement();
//                    
//                    System.err.println(">>> got task: " + task + ">> " + );
//
//                }
//            }
//
//        });

Back to the top