/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     Cagatay Kavukcuoglu <cagatayk@acm.org> - Filter for markers in same project
 *     Sebastian Davids <sdavids@gmx.de> - Reordered menu items
 *******************************************************************************/

package org.eclipse.ui.views.tasklist;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
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.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.IBasicPropertyConstants;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.AccessibleControlAdapter;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceAdapter;
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.events.HelpEvent;
import org.eclipse.swt.events.HelpListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.internal.views.tasklist.TaskListMessages;
import org.eclipse.ui.part.CellEditorActionHandler;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.MarkerTransfer;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;

/**
 * Main class for the Task List view for displaying tasks and problem annotations
 * on resources, and for opening an editor on the resource when the user commands.
 * <p>
 * This standard view has id <code>"org.eclipse.ui.views.TaskList"</code>.
 * </p>
 * <p>
 * The workbench will automatically instantiate this class when a Task List
 * view is needed for a workbench window. This class is not intended
 * to be instantiated or subclassed by clients.
 * </p>
 */
public class TaskList extends ViewPart {

    private Table table;

    private TaskSorter sorter;

    private CellEditor descriptionEditor;

    private TableViewer viewer;

    private TasksFilter filter = new TasksFilter();

    private IMemento memento;

    private boolean markerLimitExceeded;

    private Composite parent;

    private StackLayout stackLayout = new StackLayout();

    private Composite compositeMarkerLimitExceeded;

    private CellEditorActionHandler editorActionHandler;

    private TaskAction newTaskAction;

    private TaskAction copyTaskAction;

    private TaskAction pasteTaskAction;

    private TaskAction removeTaskAction;

    private TaskAction purgeCompletedAction;

    private TaskAction gotoTaskAction;

    private TaskAction selectAllAction;

    private ResolveMarkerAction resolveMarkerAction;

    private TaskAction filtersAction;

    private MarkCompletedAction markCompletedAction;

    private TaskAction propertiesAction;

    //sort by action
    private Action sortByCategoryAction;

    private Action sortByCompletedAction;

    private Action sortByPriorityAction;

    private Action sortByDescriptionAction;

    private Action sortByResourceAction;

    private Action sortByContainerAction;

    private Action sortByLocationAction;

    private Action sortByCreationTimeAction;

    private Action sortAscendingAction;

    private Action sortDescendingAction;

    private Clipboard clipboard;

    private static String[] tableColumnProperties = {
            IBasicPropertyConstants.P_IMAGE, IMarker.DONE, IMarker.PRIORITY,
            IMarker.MESSAGE, IMarkerConstants.P_RESOURCE_NAME,
            IMarkerConstants.P_CONTAINER_NAME,
            IMarkerConstants.P_LINE_AND_LOCATION };

    // Persistance tags.
    private static final String TAG_COLUMN = "column"; //$NON-NLS-1$

    private static final String TAG_NUMBER = "number"; //$NON-NLS-1$

    private static final String TAG_WIDTH = "width"; //$NON-NLS-1$

    private static final String TAG_FILTER = "filter"; //$NON-NLS-1$

    private static final String TAG_SELECTION = "selection"; //$NON-NLS-1$

    private static final String TAG_ID = "id"; //$NON-NLS-1$

    private static final String TAG_MARKER = "marker"; //$NON-NLS-1$

    private static final String TAG_RESOURCE = "resource"; //$NON-NLS-1$

    private static final String TAG_TOP_INDEX = "topIndex"; //$NON-NLS-1$

    private static final String TAG_SORT_SECTION = "TaskListSortState"; //$NON-NLS-1$

    static class TaskListLabelProvider extends LabelProvider implements
            ITableLabelProvider {

        private static String[] keys = { IBasicPropertyConstants.P_IMAGE,
                IMarkerConstants.P_COMPLETE_IMAGE,
                IMarkerConstants.P_PRIORITY_IMAGE, IMarker.MESSAGE,
                IMarkerConstants.P_RESOURCE_NAME,
                IMarkerConstants.P_CONTAINER_NAME,
                IMarkerConstants.P_LINE_AND_LOCATION };

        public String getColumnText(Object element, int columnIndex) {
            if (columnIndex >= 3 && columnIndex <= 6)
                return (String) MarkerUtil.getProperty(element,
                        keys[columnIndex]);
            return ""; //$NON-NLS-1$
        }

        public Image getColumnImage(Object element, int columnIndex) {
            if (columnIndex >= 0 && columnIndex <= 2) {
                return (Image) MarkerUtil.getProperty(element,
                        keys[columnIndex]);
            }
            return null;
        }
    }

    class SortByAction extends Action {

        private int column;

        /**
         * @param column
         */
        public SortByAction(int column) {
            this.column = column;
        }

        public void run() {
            sorter.setTopPriority(column);
            updateSortingState();
            viewer.refresh();
            IDialogSettings workbenchSettings = getPlugin().getDialogSettings();
            IDialogSettings settings = workbenchSettings
                    .getSection(TAG_SORT_SECTION);
            if (settings == null)
                settings = workbenchSettings.addNewSection(TAG_SORT_SECTION);
            sorter.saveState(settings);
        }
    }

    class SortDirectionAction extends Action {

        private int direction;

        /**
         * @param direction
         */
        public SortDirectionAction(int direction) {
            this.direction = direction;
        }

        public void run() {
            sorter.setTopPriorityDirection(direction);
            updateSortingState();
            viewer.refresh();
            IDialogSettings workbenchSettings = getPlugin().getDialogSettings();
            IDialogSettings settings = workbenchSettings
                    .getSection(TAG_SORT_SECTION);
            if (settings == null)
                settings = workbenchSettings.addNewSection(TAG_SORT_SECTION);
            sorter.saveState(settings);
        }
    }

    private String columnHeaders[] = {
            TaskListMessages.TaskList_headerIcon,
            TaskListMessages.TaskList_headerCompleted, 
            TaskListMessages.TaskList_headerPriority, 
            TaskListMessages.TaskList_headerDescription, 
            TaskListMessages.TaskList_headerResource,
            TaskListMessages.TaskList_headerFolder, 
            TaskListMessages.TaskList_headerLocation
    };

    private ColumnLayoutData columnLayouts[] = {
            new ColumnPixelData(16, false, true), new ColumnPixelData(16, false, true),
            new ColumnPixelData(16, false, true), new ColumnWeightData(200),
            new ColumnWeightData(75), new ColumnWeightData(150),
            new ColumnWeightData(60) };

    private IPartListener partListener = new IPartListener() {
        public void partActivated(IWorkbenchPart part) {
            TaskList.this.partActivated(part);
        }

        public void partBroughtToTop(IWorkbenchPart part) {
        }

        public void partClosed(IWorkbenchPart part) {
            TaskList.this.partClosed(part);
        }

        public void partDeactivated(IWorkbenchPart part) {
        }

        public void partOpened(IWorkbenchPart part) {
        }
    };

    private ISelectionChangedListener focusSelectionChangedListener = new ISelectionChangedListener() {
        public void selectionChanged(SelectionChangedEvent event) {
            TaskList.this.focusSelectionChanged(event);
        }
    };

    private IResource[] focusResources;

    private IWorkbenchPart focusPart;

    private ISelectionProvider focusSelectionProvider;

    private ICellModifier cellModifier = new ICellModifier() {
        public Object getValue(Object element, String property) {
            return MarkerUtil.getProperty(element, property);
        }

        public boolean canModify(Object element, String property) {
            return MarkerUtil.isEditable((IMarker) element);
        }

        /**
         * Modifies a marker as a result of a successfully completed direct editing.
         */
        public void modify(Object element, String property, Object value) {
            Item item = (Item) element;
            IMarker marker = (IMarker) item.getData();
            setProperty(marker, property, value);
        }
    };

    /**
     * Creates a new task list view.
     */
    public TaskList() {
        super();
    }

    /**
     * @param control
     */
    void addDragSupport(Control control) {

        int operations = DND.DROP_COPY;
        Transfer[] transferTypes = new Transfer[] {
                MarkerTransfer.getInstance(), TextTransfer.getInstance() };
        DragSourceListener listener = new DragSourceAdapter() {
            public void dragSetData(DragSourceEvent event) {
                performDragSetData(event);
            }

            public void dragFinished(DragSourceEvent event) {
            }
        };
        viewer.addDragSupport(operations, transferTypes, listener);
    }

    void cancelEditing() {
        getTableViewer().cancelEditing();
    }

    void createColumns() {
        /**
         * This class handles selections of the column headers.
         * Selection of the column header will cause resorting
         * of the shown tasks using that column's sorter.
         * Repeated selection of the header will toggle
         * sorting order (ascending versus descending).
         */
        SelectionListener headerListener = new SelectionAdapter() {
            /**
             * Handles the case of user selecting the
             * header area.
             * <p>If the column has not been selected previously,
             * it will set the sorter of that column to be
             * the current tasklist sorter. Repeated
             * presses on the same column header will
             * toggle sorting order (ascending/descending).
             */
            public void widgetSelected(SelectionEvent e) {
                // column selected - need to sort
                int column = table.indexOf((TableColumn) e.widget);
                if (column == sorter.getTopPriority())
                    sorter.reverseTopPriority();
                else {
                    sorter.setTopPriority(column);
                }
                updateSortingState();
                viewer.refresh();
                IDialogSettings workbenchSettings = getPlugin()
                        .getDialogSettings();
                IDialogSettings settings = workbenchSettings
                        .getSection(TAG_SORT_SECTION);
                if (settings == null)
                    settings = workbenchSettings
                            .addNewSection(TAG_SORT_SECTION);
                sorter.saveState(settings);
            }
        };

        if (memento != null) {
            //restore columns width
            IMemento children[] = memento.getChildren(TAG_COLUMN);
            if (children != null) {
                for (int i = 0; i < children.length; i++) {
                    Integer val = children[i].getInteger(TAG_NUMBER);
                    if (val != null) {
                        int index = val.intValue();
                        val = children[i].getInteger(TAG_WIDTH);
                        if (val != null) {
                            columnLayouts[index] = new ColumnPixelData(val
                                    .intValue(), true);
                        }
                    }
                }
            }
        }

        boolean text = "carbon".equals(SWT.getPlatform()); //$NON-NLS-1$
        TableLayout layout = new TableLayout();
        table.setLayout(layout);
        table.setHeaderVisible(true);

        for (int i = 0; i < columnHeaders.length; i++) {
            TableColumn tc = new TableColumn(table, SWT.NONE, i);

            if (!text && i == 1)
                tc.setImage(MarkerUtil.getImage("header_complete")); //$NON-NLS-1$
            else if (!text && i == 2)
                tc.setImage(MarkerUtil.getImage("header_priority")); //$NON-NLS-1$
            else
                tc.setText(columnHeaders[i]);

            if (text && (i == 1 || i == 2)) {
                tc.pack();
                columnLayouts[i] = new ColumnPixelData(Math.max(16, tc
                        .getWidth()), false, true);
            }

            tc.setResizable(columnLayouts[i].resizable);
            layout.addColumnData(columnLayouts[i]);
            tc.addSelectionListener(headerListener);
        }
    }

    /**
     * Returns a string that summarizes the contents of the
     * given markers.
     */
    static String createMarkerReport(IMarker[] markers) {
        StringBuffer buf = new StringBuffer();
        // Create the header
        buf.append(TaskListMessages.TaskList_reportKind);
        buf.append("\t"); //$NON-NLS-1$
        buf.append(TaskListMessages.TaskList_reportStatus); 
        buf.append("\t"); //$NON-NLS-1$
        buf.append(TaskListMessages.TaskList_reportPriority); 
        buf.append("\t"); //$NON-NLS-1$
        buf.append(TaskListMessages.TaskList_headerDescription);
        buf.append("\t"); //$NON-NLS-1$
        buf.append(TaskListMessages.TaskList_headerResource); 
        buf.append("\t"); //$NON-NLS-1$
        buf.append(TaskListMessages.TaskList_headerFolder); 
        buf.append("\t"); //$NON-NLS-1$
        buf.append(TaskListMessages.TaskList_headerLocation); 
        buf.append(System.getProperty("line.separator")); //$NON-NLS-1$

        // Create the report for the markers
        for (int i = 0; i < markers.length; i++) {
            writeMarker(buf, markers[i]);
        }
        return buf.toString();
    }

    /**
     * Writes a string representation of the given marker to the buffer.
     */
    static void writeMarker(StringBuffer buf, IMarker marker) {
        buf.append(MarkerUtil.getKindText(marker));
        buf.append("\t"); //$NON-NLS-1$
        buf.append(MarkerUtil.getCompleteText(marker));
        buf.append("\t"); //$NON-NLS-1$
        buf.append(MarkerUtil.getPriorityText(marker));
        buf.append("\t"); //$NON-NLS-1$
        buf.append(MarkerUtil.getMessage(marker));
        buf.append("\t"); //$NON-NLS-1$
        buf.append(MarkerUtil.getResourceName(marker));
        buf.append("\t"); //$NON-NLS-1$
        buf.append(MarkerUtil.getContainerName(marker));
        buf.append("\t"); //$NON-NLS-1$
        buf.append(MarkerUtil.getLineAndLocation(marker));
        buf.append(System.getProperty("line.separator")); //$NON-NLS-1$
    }

    /* package */
    boolean isMarkerLimitExceeded() {
        return markerLimitExceeded;
    }

    /* package */
    void setMarkerLimitExceeded(boolean markerLimitExceeded) {
        this.markerLimitExceeded = markerLimitExceeded;

        if (markerLimitExceeded) {
            stackLayout.topControl = compositeMarkerLimitExceeded;
        } else {
            stackLayout.topControl = table;
        }

        parent.layout();
    }

    /* (non-Javadoc)
     * Method declared on IWorkbenchPart.
     */
    public void createPartControl(Composite parent) {
        //	long t = System.currentTimeMillis();
        createPartControl0(parent);
        //	t = System.currentTimeMillis() - t;
        //	System.out.println("TaskList.createPartControl: " + t + "ms");
    }

    private void createPartControl0(Composite parent) {
        this.parent = parent;
        clipboard = new Clipboard(parent.getDisplay());
        createTable(parent);
        viewer = new TableViewer(table);
        viewer.setUseHashlookup(true);
        createColumns();
        makeActions();
        fillActionBars();
        addDragSupport(table);

        compositeMarkerLimitExceeded = new Composite(parent, SWT.NONE);
        compositeMarkerLimitExceeded.setLayout(new GridLayout());
        Label labelMarkerLimitExceeded = new Label(
                compositeMarkerLimitExceeded, SWT.WRAP);
        labelMarkerLimitExceeded.setText(TaskListMessages.TaskList_markerLimitExceeded);
        parent.setLayout(stackLayout);
        setMarkerLimitExceeded(false);

        viewer.setContentProvider(new TaskListContentProvider(this));
        viewer.setLabelProvider(new TaskListLabelProvider());
        if (memento != null) {
            //restore filter
            IMemento filterMem = memento.getChild(TAG_FILTER);
            if (filterMem != null)
                getFilter().restoreState(filterMem);
        }

        sorter = new TaskSorter();
        IDialogSettings workbenchSettings = getPlugin().getDialogSettings();
        IDialogSettings settings = workbenchSettings
                .getSection(TAG_SORT_SECTION);
        sorter.restoreState(settings);
        viewer.setSorter(sorter);

        //update the menu to indicate how task are currently sorted
        updateSortingState();
        viewer.setInput(getWorkspace().getRoot());
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                TaskList.this.selectionChanged(event);
            }
        });
        viewer.addOpenListener(new IOpenListener() {
            public void open(OpenEvent event) {
                gotoTaskAction.run();
            }
        });
        viewer.getControl().addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                handleKeyPressed(e);
            }
        });

        //Add in some accessibility support to supplement the description that we already 
        //get from the SWT table.
        viewer.getControl().getAccessible().addAccessibleControlListener(
                new AccessibleControlAdapter() {

                    /* (non-Javadoc)
                     * @see org.eclipse.swt.accessibility.AccessibleControlListener#getValue(org.eclipse.swt.accessibility.AccessibleControlEvent)
                     */
                    public void getValue(AccessibleControlEvent e) {

                        int childIndex = e.childID;

                        if (childIndex == ACC.CHILDID_SELF) {
                            super.getValue(e);
                            return;
                        }
                        Object item = viewer.getElementAt(childIndex);
                        if (item instanceof IMarker) {
                            IMarker marker = (IMarker) item;

                            //If it is editable all we need is completeness
                            // the rest is found by the table accessibility
                            if (MarkerUtil.isEditable(marker))
                                e.result = MarkerUtil.getCompleteText(marker);
                            else
                                //Otherwise all it needs is severity
                                e.result = MarkerUtil.getKindText(marker);

                        } else {
                            super.getValue(e);
                            return;
                        }

                    }

                });

        CellEditor editors[] = new CellEditor[columnHeaders.length];
        editors[1] = new CheckboxCellEditor(table);
        String[] priorities = new String[] {
                TaskListMessages.TaskList_high, 
                TaskListMessages.TaskList_normal, 
                TaskListMessages.TaskList_low
        };
        editors[2] = new ComboBoxCellEditor(table, priorities, SWT.READ_ONLY);
        editors[3] = descriptionEditor = new TextCellEditor(table);
        viewer.setCellEditors(editors);
        viewer.setCellModifier(cellModifier);
        viewer.setColumnProperties(tableColumnProperties);

        // Configure the context menu to be lazily populated on each pop-up.
        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                TaskList.this.fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(table);
        table.setMenu(menu);
        // Be sure to register it so that other plug-ins can add actions.
        getSite().registerContextMenu(menuMgr, viewer);

        // Track selection in the page.
        getSite().getPage().addPartListener(partListener);

        // Add global action handlers.
        editorActionHandler = new CellEditorActionHandler(getViewSite()
                .getActionBars());
        editorActionHandler.addCellEditor(descriptionEditor);
        editorActionHandler.setCopyAction(copyTaskAction);
        editorActionHandler.setPasteAction(pasteTaskAction);
        editorActionHandler.setDeleteAction(removeTaskAction);
        editorActionHandler.setSelectAllAction(selectAllAction);

        getViewSite().getActionBars().setGlobalActionHandler(
                ActionFactory.PROPERTIES.getId(), propertiesAction);

        getSite().setSelectionProvider(viewer);

        if (memento != null)
            restoreState(memento);
        memento = null;

        // Set help on the view itself
        viewer.getControl().addHelpListener(new HelpListener() {
            /*
             * @see HelpListener#helpRequested(HelpEvent)
             */
            public void helpRequested(HelpEvent e) {
                String contextId = null;
                // See if there is a context registered for the current selection
                IMarker marker = (IMarker) ((IStructuredSelection) getSelection())
                        .getFirstElement();
                if (marker != null) {
                    contextId = IDE.getMarkerHelpRegistry().getHelp(marker);
                }

                if (contextId == null)
                    contextId = ITaskListHelpContextIds.TASK_LIST_VIEW;

                getSite().getWorkbenchWindow().getWorkbench().getHelpSystem()
						.displayHelp(contextId);
            }
        });

        // Prime the status line and title.
        updateStatusMessage();
        updateTitle();
    }

    /**
     * Creates the table control.
     */
    void createTable(Composite parent) {
        table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
                | SWT.FULL_SELECTION);
        table.setLinesVisible(true);
        //table.setLayout(new TableLayout());

        new TableEditor(table);
    }

    /* (non-Javadoc)
     * Method declared on IWorkbenchPart.
     */
    public void dispose() {
        super.dispose();
        getSite().getPage().removePartListener(partListener);
        if (focusSelectionProvider != null) {
            focusSelectionProvider
                    .removeSelectionChangedListener(focusSelectionChangedListener);
            focusSelectionProvider = null;
        }
        focusPart = null;
        if (editorActionHandler != null) {
            editorActionHandler.dispose();
            editorActionHandler = null;
        }
        if (clipboard != null)
            clipboard.dispose();
    }

    /**
     * Activates the editor on the given marker.
     * 
     * @param marker the marker to edit
     */
    public void edit(IMarker marker) {
        viewer.editElement(marker, 3);
    }

    /**
     * Fills the local tool bar and menu manager with actions.
     */
    void fillActionBars() {
        IActionBars actionBars = getViewSite().getActionBars();
        IMenuManager menu = actionBars.getMenuManager();
        IMenuManager submenu = new MenuManager(TaskListMessages.SortByMenu_text);

        menu.add(submenu);
        submenu.add(sortByCategoryAction);
        submenu.add(sortByCompletedAction);
        submenu.add(sortByPriorityAction);
        submenu.add(sortByDescriptionAction);
        submenu.add(sortByResourceAction);
        submenu.add(sortByContainerAction);
        submenu.add(sortByLocationAction);
        submenu.add(sortByCreationTimeAction);
        submenu.add(new Separator());
        submenu.add(sortAscendingAction);
        submenu.add(sortDescendingAction);

        menu.add(filtersAction);

        IToolBarManager toolBar = actionBars.getToolBarManager();
        toolBar.add(newTaskAction);
        toolBar.add(removeTaskAction);
        toolBar.add(filtersAction);
    }

    /**
     * Contributes actions to the pop-up menu.
     */
    void fillContextMenu(IMenuManager menu) {
        // update enabled state for actions that aren't updated in selectionChanged
        IStructuredSelection selection = (IStructuredSelection) getSelection();
        markCompletedAction.setEnabled(markCompletedAction
                .shouldEnable(selection));
        resolveMarkerAction.setEnabled(resolveMarkerAction
                .shouldEnable(selection));

        // add the actions to the menu
        menu.add(newTaskAction);
        menu.add(gotoTaskAction);
        menu.add(new Separator());
        menu.add(copyTaskAction);
        menu.add(pasteTaskAction);
        menu.add(removeTaskAction);
        menu.add(new Separator());
        menu.add(markCompletedAction);
        menu.add(purgeCompletedAction);
        menu.add(new Separator());
        menu.add(resolveMarkerAction);
        menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        menu
                .add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS
                        + "-end")); //$NON-NLS-1$
        menu.add(propertiesAction);
    }

    /**
     * The filter settings have changed.
     * Refreshes the viewer and title bar.
     */
    void filterChanged() {

        BusyIndicator.showWhile(viewer.getControl().getShell().getDisplay(),
                new Runnable() {
                    public void run() {
                        // Filter has already been updated by dialog; just refresh.
                        // Don't need to update labels for existing elements 
                        // since changes to filter settings don't affect them.
                        viewer.getControl().setRedraw(false);
                        viewer.refresh(false);
                        viewer.getControl().setRedraw(true);
                        // update after refresh since the content provider caches summary info
                        updateStatusMessage();
                        updateTitle();
                    }
                });

    }

    void focusSelectionChanged(SelectionChangedEvent event) {
        updateFocusResource(event.getSelection());
    }

    /* (non-Javadoc)
     * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class)
     */
    public Object getAdapter(Class adapter) {
        if (adapter == IShowInSource.class) {
            return new IShowInSource() {
                public ShowInContext getShowInContext() {
                    return new ShowInContext(null, getSelection());
                }
            };
        }
        if (adapter == IShowInTargetList.class) {
            return new IShowInTargetList() {
                public String[] getShowInTargetIds() {
                    return new String[] { IPageLayout.ID_RES_NAV };
                }

            };
        }
        return super.getAdapter(adapter);
    }

    /**
     * Returns a clipboard for cut/copy/paste actions.
     * <p>
     * May only be called after this part's viewer has been created.
     * The clipboard is disposed when this part is disposed.
     * </p>
     * @return a clipboard
     * @since 2.0
     */
    /*package*/
    Clipboard getClipboard() {
        return clipboard;
    }

    /**
     * Returns the filter for the viewer.
     */
    TasksFilter getFilter() {
        return filter;
    }

    /**
     * Returns the UI plugin for the task list.
     */
    static AbstractUIPlugin getPlugin() {
        return (AbstractUIPlugin) Platform.getPlugin(PlatformUI.PLUGIN_ID);
    }

    /**
     * Returns the resource for which the task list is showing tasks.
     *
     * @return the resource, possibly the workspace root
     */
    public IResource getResource() {
        if (showSelections()) {
            if (focusResources != null && focusResources.length >= 1
                    && focusResources[0] != null) {
                return focusResources[0];
            }
        }

        return getWorkspace().getRoot();
    }

    /**
     * Get the resources.
     * 
     * @return the resources
     */
    public IResource[] getResources() {
        if (showSelections()) {
            if (focusResources != null) {
                return focusResources;
            }
        }

        return new IResource[] { getWorkspace().getRoot() };
    }

    /**
     * Returns the resource depth which the task list is using to show tasks.
     *
     * @return an <code>IResource.DEPTH_*</code> constant
     */
    int getResourceDepth() {
        if (showSelections() && !showChildrenHierarchy())
            return IResource.DEPTH_ZERO;

        return IResource.DEPTH_INFINITE;
    }

    /**
     * API method which returns the current selection.
     *
     * @return the current selection (element type: <code>IMarker</code>)
     */
    public ISelection getSelection() {
        return viewer.getSelection();
    }

    /**
     * Returns the message to display in the status line.
     */
    String getStatusMessage(IStructuredSelection selection) {
        if (selection != null && selection.size() == 1) {
            IMarker marker = (IMarker) selection.getFirstElement();
            return MarkerUtil.getMessage(marker);
        }

        TaskListContentProvider provider = (TaskListContentProvider) viewer
                .getContentProvider();

        if (selection != null && selection.size() > 1) {
            return provider.getStatusSummarySelected(selection);
        }
        return provider.getStatusSummaryVisible();
    }

    /**
     * When created, new task instance is cached in
     * order to keep it at the top of the list until
     * first edited. This method returns it, or
     * null if there is no task instance pending
     * for first editing.
     */
    TableViewer getTableViewer() {
        return viewer;
    }

    /**
     * Returns the workspace.
     */
    IWorkspace getWorkspace() {
        return ResourcesPlugin.getWorkspace();
    }

    /**
     * Handles key events in viewer.
     */
    void handleKeyPressed(KeyEvent event) {
        if (event.character == SWT.DEL && event.stateMask == 0
                && removeTaskAction.isEnabled())
            removeTaskAction.run();
    }

    /* (non-Javadoc)
     * Method declared on IViewPart.
     */
    public void init(IViewSite site, IMemento memento) throws PartInitException {
        super.init(site, memento);
        this.memento = memento;
    }

    /**
     * Returns whether we are interested in markers on the given resource.
     */
    boolean checkResource(IResource resource) {
        if (!showSelections()) {
            return true;
        }

        IResource[] resources = getResources();
        IResource resource2;

        if (showOwnerProject()) {
            IProject project;

            for (int i = 0, l = resources.length; i < l; i++) {
                resource2 = resources[i];

                if (resource2 == null) {
                    return true;
                }
                project = resource2.getProject();

                if (project == null
                        || project.equals(resource.getProject()))
                    return true;
            }
        }

        if (showChildrenHierarchy()) {
            for (int i = 0, l = resources.length; i < l; i++) {
                resource2 = resources[i];

                if (resource2 != null
                        && resource2.getFullPath().isPrefixOf(
                                resource.getFullPath()))
                    return true;
            }
        } else
            for (int i = 0, l = resources.length; i < l; i++) {
                resource2 = resources[i];

                if (resource.equals(resource2))
                    return true;
            }

        return false;
    }

    /**
     * Returns whether the given marker should be shown,
     * given the current filter settings.
     */
    boolean shouldShow(IMarker marker) {
        return checkResource(marker.getResource())
                && getFilter().select(marker);
    }

    /**
     * Makes actions used in the local tool bar and
     * popup menu.
     */
    void makeActions() {
        ISharedImages sharedImages = PlatformUI.getWorkbench()
                .getSharedImages();

        // goto
        gotoTaskAction = new GotoTaskAction(this, "gotoFile"); //$NON-NLS-1$
        gotoTaskAction.setText(TaskListMessages.GotoTask_text); 
        gotoTaskAction.setToolTipText(TaskListMessages.GotoTask_tooltip); 
        gotoTaskAction.setImageDescriptor(MarkerUtil
                .getImageDescriptor("gotoobj")); //$NON-NLS-1$
        gotoTaskAction.setEnabled(false);

        // new task
        newTaskAction = new NewTaskAction(this, "newTask"); //$NON-NLS-1$
        newTaskAction.setText(TaskListMessages.NewTask_text); 
        newTaskAction.setToolTipText(TaskListMessages.NewTask_tooltip);
        newTaskAction.setImageDescriptor(MarkerUtil
                .getImageDescriptor("addtsk")); //$NON-NLS-1$
        newTaskAction.setDisabledImageDescriptor(MarkerUtil
                .getImageDescriptor("addtsk_disabled")); //$NON-NLS-1$

        // copy task
        copyTaskAction = new CopyTaskAction(this, "copy"); //$NON-NLS-1$
        copyTaskAction.setText(TaskListMessages.CopyTask_text); 
        copyTaskAction.setToolTipText(TaskListMessages.CopyTask_tooltip);
        copyTaskAction.setEnabled(false);

        // paste task
        pasteTaskAction = new PasteTaskAction(this, "paste"); //$NON-NLS-1$
        pasteTaskAction.setText(TaskListMessages.PasteTask_text); 
        pasteTaskAction.setToolTipText(TaskListMessages.PasteTask_tooltip);
        pasteTaskAction.setEnabled(false);

        // remove task
        removeTaskAction = new RemoveTaskAction(this, "delete"); //$NON-NLS-1$
        removeTaskAction.setText(TaskListMessages.RemoveTask_text);
        removeTaskAction.setToolTipText(TaskListMessages.RemoveTask_tooltip); 
        removeTaskAction.setImageDescriptor(sharedImages
                .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
        removeTaskAction.setDisabledImageDescriptor(sharedImages
                .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE_DISABLED));
        removeTaskAction.setEnabled(false);

        //mark completed task
        markCompletedAction = new MarkCompletedAction(this, "markCompleted"); //$NON-NLS-1$
        markCompletedAction.setText(TaskListMessages.MarkCompleted_text);
        markCompletedAction.setToolTipText(TaskListMessages.MarkCompleted_tooltip);
        markCompletedAction.setEnabled(false);

        //delete completed task
        purgeCompletedAction = new PurgeCompletedAction(this, "deleteCompleted"); //$NON-NLS-1$
        purgeCompletedAction.setText(TaskListMessages.PurgeCompleted_text);
        purgeCompletedAction.setToolTipText(TaskListMessages.PurgeCompleted_tooltip); 
        purgeCompletedAction.setImageDescriptor(sharedImages
                .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
        purgeCompletedAction.setEnabled(true);

        // select all
        selectAllAction = new SelectAllTasksAction(this, "selectAll"); //$NON-NLS-1$
        selectAllAction.setText(TaskListMessages.SelectAll_text); 
        selectAllAction.setToolTipText(TaskListMessages.SelectAll_tooltip);

        // resolutions
        resolveMarkerAction = new ResolveMarkerAction(this, "resolve"); //$NON-NLS-1$
        resolveMarkerAction.setText(TaskListMessages.Resolve_text); 
        resolveMarkerAction.setToolTipText(TaskListMessages.Resolve_tooltip);
        resolveMarkerAction.setEnabled(false);

        // Sort by ->	
        sortByCategoryAction = new SortByAction(TaskSorter.TYPE);
        sortByCategoryAction.setText(TaskListMessages.SortByCategory_text);
        sortByCategoryAction.setToolTipText(TaskListMessages.SortByCategory_tooltip);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(sortByCategoryAction,
				ITaskListHelpContextIds.TASK_SORT_TYPE_ACTION);

        sortByCompletedAction = new SortByAction(TaskSorter.COMPLETION);
        sortByCompletedAction.setText(TaskListMessages.SortByCompleted_text);
        sortByCompletedAction.setToolTipText(TaskListMessages.SortByCompleted_tooltip); 
        PlatformUI.getWorkbench().getHelpSystem().setHelp(
				sortByCompletedAction,
				ITaskListHelpContextIds.TASK_SORT_COMPLETED_ACTION);

        sortByPriorityAction = new SortByAction(TaskSorter.PRIORITY);
        sortByPriorityAction.setText(TaskListMessages.SortByPriority_text); 
        sortByPriorityAction.setToolTipText(TaskListMessages.SortByPriority_tooltip); 
        PlatformUI.getWorkbench().getHelpSystem().setHelp(sortByPriorityAction,
				ITaskListHelpContextIds.TASK_SORT_PRIORITY_ACTION);

        sortByDescriptionAction = new SortByAction(TaskSorter.DESCRIPTION);
        sortByDescriptionAction.setText(TaskListMessages.SortByDescription_text); 
        sortByDescriptionAction.setToolTipText(TaskListMessages.SortByDescription_tooltip);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(
				sortByDescriptionAction,
				ITaskListHelpContextIds.TASK_SORT_DESCRIPTION_ACTION);

        sortByResourceAction = new SortByAction(TaskSorter.RESOURCE);
        sortByResourceAction.setText(TaskListMessages.SortByResource_text);
        sortByResourceAction.setToolTipText(TaskListMessages.SortByResource_tooltip); 
        PlatformUI.getWorkbench().getHelpSystem().setHelp(sortByResourceAction,
				ITaskListHelpContextIds.TASK_SORT_RESOURCE_ACTION);

        sortByContainerAction = new SortByAction(TaskSorter.FOLDER);
        sortByContainerAction.setText(TaskListMessages.SortByContainer_text); 
        sortByContainerAction.setToolTipText(TaskListMessages.SortByContainer_tooltip);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(
				sortByContainerAction,
				ITaskListHelpContextIds.TASK_SORT_FOLDER_ACTION);

        sortByLocationAction = new SortByAction(TaskSorter.LOCATION);
        sortByLocationAction.setText(TaskListMessages.SortByLocation_text); 
        sortByLocationAction.setToolTipText(TaskListMessages.SortByLocation_tooltip); 
        PlatformUI.getWorkbench().getHelpSystem().setHelp(sortByLocationAction,
				ITaskListHelpContextIds.TASK_SORT_LOCATION_ACTION);

        sortByCreationTimeAction = new SortByAction(TaskSorter.CREATION_TIME);
        sortByCreationTimeAction.setText(TaskListMessages.SortByCreationTime_text);
        sortByCreationTimeAction.setToolTipText(TaskListMessages.SortByCreationTime_tooltip); 
        PlatformUI.getWorkbench().getHelpSystem().setHelp(
				sortByCreationTimeAction,
				ITaskListHelpContextIds.TASK_SORT_CREATION_TIME_ACTION);

        sortAscendingAction = new SortDirectionAction(TaskSorter.ASCENDING);
        sortAscendingAction.setText(TaskListMessages.SortAscending_text);
        sortAscendingAction.setToolTipText(TaskListMessages.SortAscending_tooltip);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(sortAscendingAction,
				ITaskListHelpContextIds.TASK_SORT_ASCENDING_ACTION);

        sortDescendingAction = new SortDirectionAction(TaskSorter.DESCENDING);
        sortDescendingAction.setText(TaskListMessages.SortDescending_text);
        sortDescendingAction.setToolTipText(TaskListMessages.SortDescending_tooltip);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(sortDescendingAction,
				ITaskListHelpContextIds.TASK_SORT_DESCENDING_ACTION);

        // filters...
        filtersAction = new FiltersAction(this, "filter"); //$NON-NLS-1$
        filtersAction.setText(TaskListMessages.Filters_text); 
        filtersAction.setToolTipText(TaskListMessages.Filters_tooltip);
        filtersAction.setImageDescriptor(MarkerUtil
                .getImageDescriptor("filter")); //$NON-NLS-1$

        // properties
        propertiesAction = new TaskPropertiesAction(this, "properties"); //$NON-NLS-1$
        propertiesAction.setText(TaskListMessages.Properties_text); 
        propertiesAction.setToolTipText(TaskListMessages.Properties_tooltip);
        propertiesAction.setEnabled(false);
    }

    /**
     * The markers have changed.  Update the status line and title bar.
     */
    void markersChanged() {
        updateStatusMessage();
        updateTitle();
    }

    void partActivated(IWorkbenchPart part) {
        if (part == focusPart)
            return;

        if (focusSelectionProvider != null) {
            focusSelectionProvider
                    .removeSelectionChangedListener(focusSelectionChangedListener);
            focusSelectionProvider = null;
        }

        focusPart = part;
        if (focusPart != null) {
            focusSelectionProvider = focusPart.getSite().getSelectionProvider();
            if (focusSelectionProvider != null) {
                focusSelectionProvider
                        .addSelectionChangedListener(focusSelectionChangedListener);
                updateFocusResource(focusSelectionProvider.getSelection());
            } else {
                updateFocusResource(null);
            }
        }

    }

    void partClosed(IWorkbenchPart part) {
        if (part != focusPart)
            return;
        if (focusSelectionProvider != null) {
            focusSelectionProvider
                    .removeSelectionChangedListener(focusSelectionChangedListener);
            focusSelectionProvider = null;
        }
        focusPart = null;
    }

    /**
     * The user is attempting to drag marker data.  Add the appropriate
     * data to the event depending on the transfer type.
     */
    void performDragSetData(DragSourceEvent event) {
        if (MarkerTransfer.getInstance().isSupportedType(event.dataType)) {
            event.data = ((IStructuredSelection) viewer.getSelection())
                    .toArray();
            return;
        }
        if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
            Object[] data = ((IStructuredSelection) viewer.getSelection())
                    .toArray();
            if (data != null) {
                IMarker[] markers = new IMarker[data.length];
                for (int i = 0; i < markers.length; i++) {
                    markers[i] = (IMarker) data[i];
                }
                event.data = createMarkerReport(markers);
            }
            return;
        }
    }

    void restoreState(IMemento memento) {
        //restore selection
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IMemento selectionMem = memento.getChild(TAG_SELECTION);
        if (selectionMem != null) {
            ArrayList selectionList = new ArrayList();
            IMemento markerMems[] = selectionMem.getChildren(TAG_MARKER);
            for (int i = 0; i < markerMems.length; i++) {
                try {
                    long id = Long.parseLong(markerMems[i].getString(TAG_ID));
                    IResource resource = root.findMember(markerMems[i]
                            .getString(TAG_RESOURCE));
                    if (resource != null) {
                        IMarker marker = resource.findMarker(id);
                        if (marker != null) {
                            selectionList.add(marker);
                        }
                    }
                } catch (NumberFormatException e) {
                } catch (CoreException e) {
                }

            }
            viewer.setSelection(new StructuredSelection(selectionList));
        }

        Table table = viewer.getTable();
        //restore vertical position
        try {
            String topIndexStr = memento.getString(TAG_TOP_INDEX);
            table.setTopIndex(Integer.parseInt(topIndexStr));
        } catch (NumberFormatException e) {
        }
    }

    /* (non-Javadoc)
     * Method declared on IViewPart.
     */
    public void saveState(IMemento memento) {
        if (viewer == null) {
            if (this.memento != null) //Keep the old state;
                memento.putMemento(this.memento);
            return;
        }

        //save filter
        getFilter().saveState(memento.createChild(TAG_FILTER));

        //save columns width
        Table table = viewer.getTable();
        TableColumn columns[] = table.getColumns();
        //check whether it has ever been layed out
        //workaround for 1GDTU19: ITPUI:WIN2000 - Task list columns "collapsed" left
        boolean shouldSave = false;
        for (int i = 0; i < columns.length; i++) {
            if (columnLayouts[i].resizable && columns[i].getWidth() != 0) {
                shouldSave = true;
                break;
            }
        }
        if (shouldSave) {
            for (int i = 0; i < columns.length; i++) {
                if (columnLayouts[i].resizable) {
                    IMemento child = memento.createChild(TAG_COLUMN);
                    child.putInteger(TAG_NUMBER, i);
                    child.putInteger(TAG_WIDTH, columns[i].getWidth());
                }
            }
        }

        //save selection
        Object markers[] = ((IStructuredSelection) viewer.getSelection())
                .toArray();
        if (markers.length > 0) {
            IMemento selectionMem = memento.createChild(TAG_SELECTION);
            for (int i = 0; i < markers.length; i++) {
                IMemento elementMem = selectionMem.createChild(TAG_MARKER);
                IMarker marker = (IMarker) markers[i];
                elementMem.putString(TAG_RESOURCE, marker.getResource()
                        .getFullPath().toString());
                elementMem.putString(TAG_ID, String.valueOf(marker.getId()));
            }
        }

        //save vertical position
        int topIndex = table.getTopIndex();
        memento.putString(TAG_TOP_INDEX, String.valueOf(topIndex));
    }

    /**
     * Handles marker selection change in the task list by updating availability of
     * the actions in the local tool bar.
     */
    void selectionChanged(SelectionChangedEvent event) {
        IStructuredSelection selection = (IStructuredSelection) event
                .getSelection();
        updateStatusMessage(selection);
        updateTitle();

        updatePasteEnablement();

        // If selection is empty, then disable copy, remove and goto.	
        if (selection.isEmpty()) {
            copyTaskAction.setEnabled(false);
            removeTaskAction.setEnabled(false);
            gotoTaskAction.setEnabled(false);
            propertiesAction.setEnabled(false);
            return;
        }
        

        // Can only open properties for a single task at a time
        propertiesAction.setEnabled(selection.size() == 1);

        // Can always copy
        copyTaskAction.setEnabled(true);

        // Determine if goto should be enabled
        IMarker selectedMarker = (IMarker) selection.getFirstElement();
        boolean canJump = selection.size() == 1
                && selectedMarker.getResource().getType() == IResource.FILE;
        gotoTaskAction.setEnabled(canJump);

        // Determine if remove should be enabled
        boolean canRemove = true;
        for (Iterator markers = selection.iterator(); markers.hasNext();) {
            IMarker m = (IMarker) markers.next();
            if (!MarkerUtil.isEditable(m)) {
                canRemove = false;
                break;
            }
        }
        removeTaskAction.setEnabled(canRemove);

        // if there is an active editor on the selection's input, tell
        // the editor to goto the marker
        if (canJump) {
            IEditorPart editor = getSite().getPage().getActiveEditor();
            if (editor != null) {
                IFile file = ResourceUtil.getFile(editor.getEditorInput());
                if (file != null) {
                    if (selectedMarker.getResource().equals(file)) {
                        IDE.gotoMarker(editor, selectedMarker);
                    }
                }
            }
        }
    }

    /* (non-Javadoc)
     * Method declared on IWorkbenchPart.
     */
    public void setFocus() {
        viewer.getControl().setFocus();
    }

    /**
     * Sets the property on a marker to the given value.
     */
    void setProperty(IMarker marker, String property, Object value) {
        if (MarkerUtil.getProperty(marker, property).equals(value)) {
            return;
        }
        try {
            if (property == tableColumnProperties[1]) { // Completed
                marker.setAttribute(IMarker.DONE, value);
            } else if (property == tableColumnProperties[2]) { // Priority
                // this property is used only by cell editor, where order is High, Normal, Low
                marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH
                        - ((Integer) value).intValue());
            } else if (property == tableColumnProperties[3]) { // Description
                marker.setAttribute(IMarker.MESSAGE, value);
                // Let's not refilter too lightly - see if it is needed
                //			TaskSorter sorter = (TaskSorter) viewer.getSorter();
                //			if (sorter != null && sorter.getColumnNumber() == 3) {
                //				viewer.refresh();
                //			}
            }
        } catch (CoreException e) {
            String msg = TaskListMessages.TaskList_errorModifyingTask; 
            ErrorDialog.openError(getSite().getShell(), msg, null, e
                    .getStatus());
        }
    }

    /**
     * API method which sets the current selection of this viewer.
     *
     * @param selection a structured selection of <code>IMarker</code> objects
     * @param reveal <code>true</code> to reveal the selection, <false> otherwise
     */
    public void setSelection(ISelection selection, boolean reveal) {
        Assert.isTrue(selection instanceof IStructuredSelection);
        IStructuredSelection ssel = (IStructuredSelection) selection;

        for (Iterator i = ssel.iterator(); i.hasNext();)
            Assert.isTrue(i.next() instanceof IMarker);

        if (viewer != null)
            viewer.setSelection(selection, reveal);
    }

    boolean showChildrenHierarchy() {
        switch (getFilter().onResource) {
        case TasksFilter.ON_ANY_RESOURCE:
        case TasksFilter.ON_SELECTED_RESOURCE_AND_CHILDREN:
        case TasksFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT:
        // added by cagatayk@acm.org
        case TasksFilter.ON_WORKING_SET:
        default:
            return true;
        case TasksFilter.ON_SELECTED_RESOURCE_ONLY:
            return false;
        }
    }

    boolean showSelections() {
        switch (getFilter().onResource) {
        case TasksFilter.ON_SELECTED_RESOURCE_ONLY:
        case TasksFilter.ON_SELECTED_RESOURCE_AND_CHILDREN:
        case TasksFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT:
            // added by cagatayk@acm.org
            return true;
        case TasksFilter.ON_ANY_RESOURCE:
        case TasksFilter.ON_WORKING_SET:
        default:
            return false;
        }
    }

    // showOwnerProject() added by cagatayk@acm.org 
    boolean showOwnerProject() {
        return getFilter().onResource == TasksFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT;
    }

    /**
     * Processes state change of the 'showSelections' switch.
     * If true, it will resync with the saved input element.
     * Otherwise, it will reconfigure to show all the
     * problems/tasks in the workbench.
     * 
     * @param value the value
     */
    void toggleInputSelection(boolean value) {
        /*
         if (value) {
         handleInput(inputSelection, false);
         } else {
         // detach from input and link to the workbench object
         handleInput(WorkbenchPlugin.getPluginWorkbench(), true);
         }
         updateTitle();
         */
    }

    /**
     * If true, current input will be
     * remembered and further selections will be
     * ignored.
     * 
     * @param value the value
     */
    void toggleLockInput(boolean value) {
        /*
         if (!value) {
         handleInput(inputSelection, false);
         lockedInput = null;
         } else {
         lockedInput = (IElement) getInput();
         }
         String lockedInputPath = "";
         if (lockedInput != null && lockedInput instanceof IResource) {
         IResource resource = (IResource) lockedInput;
         lockedInputPath = resource.getFullPath().toString();
         }
         IDialogStore store = WorkbenchPlugin.getDefault().getDialogStore();
         store.put(STORE_LOCKED_INPUT, lockedInputPath);
         updateTitle();
         */
    }

    /**
     * Updates the focus resource, and refreshes if we're showing only tasks for the focus resource.
     */
    void updateFocusResource(ISelection selection) {
        ArrayList list = new ArrayList();

        if (selection instanceof IStructuredSelection) {
            Iterator iterator = ((IStructuredSelection) selection).iterator();
            while (iterator.hasNext()) {
                Object object = iterator.next();

                if (object instanceof IAdaptable) {
                    ITaskListResourceAdapter taskListResourceAdapter;
                    Object adapter = ((IAdaptable) object)
                            .getAdapter(ITaskListResourceAdapter.class);
                    if (adapter != null
                            && adapter instanceof ITaskListResourceAdapter) {
                        taskListResourceAdapter = (ITaskListResourceAdapter) adapter;
                    } else {
                        taskListResourceAdapter = DefaultTaskListResourceAdapter
                                .getDefault();
                    }

                    IResource resource = taskListResourceAdapter
                            .getAffectedResource((IAdaptable) object);
                    if (resource != null) {
                        list.add(resource);
                    }
                }
            }
        }

        if (list.size() == 0 && focusPart instanceof IEditorPart) {
            IEditorInput input = ((IEditorPart) focusPart).getEditorInput();
            if (input != null) {
                IResource resource = ResourceUtil.getResource(input);
                if (resource != null) {
                    list.add(resource);
                }
            }
        }

        int l = list.size();
        if (l < 1) {
            return; // required to achieve lazy update behavior.
        }

        IResource[] resources = (IResource[]) list.toArray(new IResource[l]);
        for (int i = 0; i < l; i++) {
            Assert.isNotNull(resources[i]);
        }

        if (!Arrays.equals(resources, focusResources)) {
            boolean updateNeeded = false;

            if (showOwnerProject()) {
                int m = focusResources == null ? 0 : focusResources.length;
                if (l != m) {
                    updateNeeded = true;
                } else {
                    for (int i = 0; i < l; i++) {
                        IProject oldProject = m < 1 ? null : focusResources[0]
                                .getProject();
                        IProject newProject = resources[0].getProject();
                        boolean projectsEqual = (oldProject == null ? newProject == null
                                : oldProject.equals(newProject));
                        if (!projectsEqual) {
                            updateNeeded = true;
                            break;
                        }
                    }
                }
            } else if (showSelections()) {
                updateNeeded = true;
            }

            // remember the focus resources even if update is not needed,
            // so that we know them if the filter settings change
            focusResources = resources;

            if (updateNeeded) {
                viewer.getControl().setRedraw(false);
                viewer.refresh();
                viewer.getControl().setRedraw(true);
                updateStatusMessage();
                updateTitle();
            }
        }
    }

    /**
     * Updates the enablement of the paste action
     */
    void updatePasteEnablement() {
        // Paste if clipboard contains tasks
        MarkerTransfer transfer = MarkerTransfer.getInstance();
        IMarker[] markerData = (IMarker[]) getClipboard().getContents(transfer);
        boolean canPaste = false;
        if (markerData != null) {
            for (int i = 0; i < markerData.length; i++) {
                if (MarkerUtil.isMarkerType(markerData[i], IMarker.TASK)) {
                    canPaste = true;
                    break;
                }
            }
        }
        pasteTaskAction.setEnabled(canPaste);
    }

    /**
     * Updates that message displayed in the status line.
     */
    void updateStatusMessage() {
        ISelection selection = viewer.getSelection();

        if (selection instanceof IStructuredSelection)
            updateStatusMessage((IStructuredSelection) selection);
        else
            updateStatusMessage(null);
    }

    /**
     * Updates that message displayed in the status line.
     */
    void updateStatusMessage(IStructuredSelection selection) {
        String message = getStatusMessage(selection);
        getViewSite().getActionBars().getStatusLineManager()
                .setMessage(message);
    }

    /**
     * Updates the title of the view.  Should be called when filters change.
     */
    void updateTitle() {
        TaskListContentProvider provider = (TaskListContentProvider) getTableViewer()
                .getContentProvider();
        String summary = provider.getTitleSummary();
        setContentDescription(summary);
    }

    /**
     * Method updateSortingState.
     */
    void updateSortingState() {
        int curColumn = sorter.getTopPriority();
        sortByCategoryAction.setChecked(curColumn == TaskSorter.TYPE);
        sortByCompletedAction.setChecked(curColumn == TaskSorter.COMPLETION);
        sortByPriorityAction.setChecked(curColumn == TaskSorter.PRIORITY);
        sortByDescriptionAction.setChecked(curColumn == TaskSorter.DESCRIPTION);
        sortByResourceAction.setChecked(curColumn == TaskSorter.RESOURCE);
        sortByContainerAction.setChecked(curColumn == TaskSorter.FOLDER);
        sortByLocationAction.setChecked(curColumn == TaskSorter.LOCATION);
        sortByCreationTimeAction
                .setChecked(curColumn == TaskSorter.CREATION_TIME);

        int curDirection = sorter.getTopPriorityDirection();
        sortAscendingAction.setChecked(curDirection == TaskSorter.ASCENDING);
        sortDescendingAction.setChecked(curDirection == TaskSorter.DESCENDING);
    }

}
