org.eclipse.pde.internal.runtime.logview.LogView.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.pde.internal.runtime.logview.LogView.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2007 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
 *******************************************************************************/

package org.eclipse.pde.internal.runtime.logview;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Comparator;

import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.util.Policy;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;
import org.eclipse.pde.internal.runtime.PDERuntimeMessages;
import org.eclipse.pde.internal.runtime.PDERuntimePlugin;
import org.eclipse.pde.internal.runtime.PDERuntimePluginImages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISharedImages;
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.part.ViewPart;

public class LogView extends ViewPart implements ILogListener {
    public static final String P_LOG_WARNING = "warning"; //$NON-NLS-1$
    public static final String P_LOG_ERROR = "error"; //$NON-NLS-1$
    public static final String P_LOG_INFO = "info"; //$NON-NLS-1$
    public static final String P_LOG_LIMIT = "limit"; //$NON-NLS-1$
    public static final String P_USE_LIMIT = "useLimit"; //$NON-NLS-1$
    public static final String P_SHOW_ALL_SESSIONS = "allSessions"; //$NON-NLS-1$
    private static final String P_COLUMN_1 = "column2"; //$NON-NLS-1$
    private static final String P_COLUMN_2 = "column3"; //$NON-NLS-1$
    private static final String P_COLUMN_3 = "column4"; //$NON-NLS-1$
    public static final String P_ACTIVATE = "activate"; //$NON-NLS-1$
    public static final String P_ORDER_TYPE = "orderType"; //$NON-NLS-1$
    public static final String P_ORDER_VALUE = "orderValue"; //$NON-NLS-1$

    private int MESSAGE_ORDER;
    private int PLUGIN_ORDER;
    private int DATE_ORDER;

    public final static byte MESSAGE = 0x0;
    public final static byte PLUGIN = 0x1;
    public final static byte DATE = 0x2;
    public static int ASCENDING = 1;
    public static int DESCENDING = -1;

    private ArrayList fLogs;

    //   private Clipboard fClipboard;

    //   private IMemento fMemento;
    private File fInputFile;
    private String fDirectory;

    private Comparator fComparator;

    // hover text
    private boolean fCanOpenTextShell;
    private Text fTextLabel;
    private Shell fTextShell;

    private boolean fFirstEvent = true;

    private TreeColumn fColumn1;
    private TreeColumn fColumn2;
    private TreeColumn fColumn3;

    private Tree fTree;
    private TreeViewer fTreeViewer;
    private LogViewLabelProvider fLabelProvider;

    private Action fPropertiesAction;
    private Action fDeleteLogAction;
    private Action fReadLogAction;
    //   private Action fCopyAction;
    private Action fActivateViewAction;
    private Action fOpenLogAction;
    private Action fExportAction;

    public LogView() {
        fLogs = new ArrayList();
        fInputFile = Platform.getLogFileLocation().toFile();
    }

    public void createPartControl(Composite parent) {
        readLogFile();
        createViewer(parent);
        createActions();
        //      fClipboard = new Clipboard(fTree.getDisplay());
        fTree.setToolTipText(""); //$NON-NLS-1$
        getSite().setSelectionProvider(fTreeViewer);
        initializeViewerSorter();

        makeHoverShell();

        Platform.addLogListener(this);
        //      PlatformUI.getWorkbench().getHelpSystem().setHelp(fTree, IHelpContextIds.LOG_VIEW);
    }

    private void createActions() {
        IActionBars bars = getViewSite().getActionBars();

        //      fCopyAction = createCopyAction();
        //      bars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction);

        IToolBarManager toolBarManager = bars.getToolBarManager();

        fExportAction = createExportAction();
        toolBarManager.add(fExportAction);

        final Action importLogAction = createImportLogAction();
        toolBarManager.add(importLogAction);

        toolBarManager.add(new Separator());

        final Action clearAction = createClearAction();
        toolBarManager.add(clearAction);

        fDeleteLogAction = createDeleteLogAction();
        toolBarManager.add(fDeleteLogAction);

        fOpenLogAction = createOpenLogAction();
        toolBarManager.add(fOpenLogAction);

        fReadLogAction = createReadLogAction();
        toolBarManager.add(fReadLogAction);

        toolBarManager.add(new Separator());

        IMenuManager mgr = bars.getMenuManager();
        mgr.add(createFilterAction());
        mgr.add(new Separator());

        fActivateViewAction = createActivateViewAction();
        mgr.add(fActivateViewAction);

        createPropertiesAction();

        MenuManager popupMenuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        IMenuListener listener = new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                //            manager.add(fCopyAction);
                manager.add(new Separator());
                manager.add(clearAction);
                manager.add(fDeleteLogAction);
                manager.add(fOpenLogAction);
                manager.add(fReadLogAction);
                manager.add(new Separator());
                manager.add(fExportAction);
                manager.add(importLogAction);
                manager.add(new Separator());
                ((EventDetailsDialogAction) fPropertiesAction).setComparator(fComparator);
                manager.add(fPropertiesAction);
                manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
            }
        };
        popupMenuManager.addMenuListener(listener);
        popupMenuManager.setRemoveAllWhenShown(true);
        getSite().registerContextMenu(popupMenuManager, getSite().getSelectionProvider());
        Menu menu = popupMenuManager.createContextMenu(fTree);
        fTree.setMenu(menu);
    }

    private Action createActivateViewAction() {
        Action action = new Action(PDERuntimeMessages.get().LogView_activate) { //          
            public void run() {
                //            fMemento.putString(P_ACTIVATE, isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
            }
        };
        //      action.setChecked(fMemento.getString(P_ACTIVATE).equals("true")); //$NON-NLS-1$
        return action;
    }

    private Action createClearAction() {
        Action action = new Action(PDERuntimeMessages.get().LogView_clear) {
            public void run() {
                handleClear();
            }
        };
        action.setImageDescriptor(PDERuntimePluginImages.DESC_CLEAR);
        action.setDisabledImageDescriptor(PDERuntimePluginImages.DESC_CLEAR_DISABLED);
        action.setToolTipText(PDERuntimeMessages.get().LogView_clear_tooltip);
        action.setText(PDERuntimeMessages.get().LogView_clear);
        return action;
    }

    private Action createCopyAction() {
        Action action = new Action(PDERuntimeMessages.get().LogView_copy) {
            public void run() {
                copyToClipboard(fTreeViewer.getSelection());
            }
        };
        action.setImageDescriptor(
                PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
        return action;
    }

    private Action createDeleteLogAction() {
        Action action = new Action(PDERuntimeMessages.get().LogView_delete) {
            public void run() {
                doDeleteLog();
            }
        };
        action.setToolTipText(PDERuntimeMessages.get().LogView_delete_tooltip);
        action.setImageDescriptor(PDERuntimePluginImages.DESC_REMOVE_LOG);
        action.setDisabledImageDescriptor(PDERuntimePluginImages.DESC_REMOVE_LOG_DISABLED);
        action.setEnabled(fInputFile.exists() && fInputFile.equals(Platform.getLogFileLocation().toFile()));
        return action;
    }

    private Action createExportAction() {
        Action action = new Action(PDERuntimeMessages.get().LogView_export) {
            public void run() {
                handleExport();
            }
        };
        action.setToolTipText(PDERuntimeMessages.get().LogView_export_tooltip);
        action.setImageDescriptor(PDERuntimePluginImages.DESC_EXPORT);
        action.setDisabledImageDescriptor(PDERuntimePluginImages.DESC_EXPORT_DISABLED);
        action.setEnabled(fInputFile.exists());
        return action;
    }

    private Action createFilterAction() {
        Action action = new Action(PDERuntimeMessages.get().LogView_filter) {
            public void run() {
                handleFilter();
            }
        };
        action.setToolTipText(PDERuntimeMessages.get().LogView_filter);
        action.setImageDescriptor(PDERuntimePluginImages.DESC_FILTER);
        action.setDisabledImageDescriptor(PDERuntimePluginImages.DESC_FILTER_DISABLED);
        return action;
    }

    private Action createImportLogAction() {
        Action action = new Action(PDERuntimeMessages.get().LogView_import) {
            public void run() {
                handleImport();
            }
        };
        action.setToolTipText(PDERuntimeMessages.get().LogView_import_tooltip);
        action.setImageDescriptor(PDERuntimePluginImages.DESC_IMPORT);
        action.setDisabledImageDescriptor(PDERuntimePluginImages.DESC_IMPORT_DISABLED);
        return action;
    }

    private Action createOpenLogAction() {
        Action action = null;
        try {
            // check to see if org.eclipse.ui.ide is available
            Class.forName("org.eclipse.ui.ide.IDE"); //$NON-NLS-1$
            // check to see if org.eclipse.core.filesystem is available
            Class.forName("org.eclipse.core.filesystem.IFileStore"); //$NON-NLS-1$
            action = new OpenIDELogFileAction(this);
        } catch (ClassNotFoundException e) {
            action = new Action() {
                public void run() {
                    if (fInputFile.exists()) {
                        Job job = getOpenLogFileJob();
                        job.setUser(false);
                        job.setPriority(Job.SHORT);
                        job.schedule();
                    }
                }
            };
        }
        action.setText(PDERuntimeMessages.get().LogView_view_currentLog);
        action.setImageDescriptor(PDERuntimePluginImages.DESC_OPEN_LOG);
        action.setDisabledImageDescriptor(PDERuntimePluginImages.DESC_OPEN_LOG_DISABLED);
        action.setEnabled(fInputFile.exists());
        action.setToolTipText(PDERuntimeMessages.get().LogView_view_currentLog_tooltip);
        return action;
    }

    private void createPropertiesAction() {
        fPropertiesAction = new EventDetailsDialogAction(fTree.getShell(), fTreeViewer);
        fPropertiesAction.setImageDescriptor(PDERuntimePluginImages.DESC_PROPERTIES);
        fPropertiesAction.setDisabledImageDescriptor(PDERuntimePluginImages.DESC_PROPERTIES_DISABLED);
        fPropertiesAction.setToolTipText(PDERuntimeMessages.get().LogView_properties_tooltip);
        fPropertiesAction.setEnabled(false);
    }

    private Action createReadLogAction() {
        Action action = new Action(PDERuntimeMessages.get().LogView_readLog_restore) {
            public void run() {
                fInputFile = Platform.getLogFileLocation().toFile();
                reloadLog();
            }
        };
        action.setToolTipText(PDERuntimeMessages.get().LogView_readLog_restore_tooltip);
        action.setImageDescriptor(PDERuntimePluginImages.DESC_READ_LOG);
        action.setDisabledImageDescriptor(PDERuntimePluginImages.DESC_READ_LOG_DISABLED);
        return action;
    }

    private void createViewer(Composite parent) {
        fTreeViewer = new TreeViewer(parent, SWT.FULL_SELECTION);
        fTree = fTreeViewer.getTree();
        fTree.setLinesVisible(true);
        createColumns(fTree);
        fTreeViewer.setContentProvider(new LogViewContentProvider(this));
        fTreeViewer.setLabelProvider(fLabelProvider = new LogViewLabelProvider());
        fLabelProvider.connect(this);
        fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent e) {
                handleSelectionChanged(e.getSelection());
                if (fPropertiesAction.isEnabled())
                    ((EventDetailsDialogAction) fPropertiesAction).resetSelection();
            }
        });
        fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                ((EventDetailsDialogAction) fPropertiesAction).setComparator(fComparator);
                fPropertiesAction.run();
            }
        });
        fTreeViewer.setInput(this);
        addMouseListeners();
    }

    private void createColumns(Tree tree) {
        fColumn1 = new TreeColumn(tree, SWT.LEFT);
        fColumn1.setText(PDERuntimeMessages.get().LogView_column_message);
        //      fColumn1.setWidth(fMemento.getInteger(P_COLUMN_1).intValue());
        fColumn1.setWidth(300);
        fColumn1.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                MESSAGE_ORDER *= -1;
                ViewerComparator comparator = getViewerComparator(MESSAGE);
                fTreeViewer.setComparator(comparator);
                boolean isComparatorSet = ((EventDetailsDialogAction) fPropertiesAction).resetSelection(MESSAGE,
                        MESSAGE_ORDER);
                setComparator(MESSAGE);
                if (!isComparatorSet)
                    ((EventDetailsDialogAction) fPropertiesAction).setComparator(fComparator);
                //            fMemento.putInteger(P_ORDER_VALUE, MESSAGE_ORDER);
                //            fMemento.putInteger(P_ORDER_TYPE, MESSAGE);
                setColumnSorting(fColumn1, MESSAGE_ORDER);
            }
        });

        fColumn2 = new TreeColumn(tree, SWT.LEFT);
        fColumn2.setText(PDERuntimeMessages.get().LogView_column_plugin);
        //      fColumn2.setWidth(fMemento.getInteger(P_COLUMN_2).intValue());
        fColumn2.setWidth(150);
        fColumn2.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                PLUGIN_ORDER *= -1;
                ViewerComparator comparator = getViewerComparator(PLUGIN);
                fTreeViewer.setComparator(comparator);
                boolean isComparatorSet = ((EventDetailsDialogAction) fPropertiesAction).resetSelection(PLUGIN,
                        PLUGIN_ORDER);
                setComparator(PLUGIN);
                if (!isComparatorSet)
                    ((EventDetailsDialogAction) fPropertiesAction).setComparator(fComparator);
                //            fMemento.putInteger(P_ORDER_VALUE, PLUGIN_ORDER);
                //            fMemento.putInteger(P_ORDER_TYPE, PLUGIN);
                setColumnSorting(fColumn2, PLUGIN_ORDER);
            }
        });

        fColumn3 = new TreeColumn(tree, SWT.LEFT);
        fColumn3.setText(PDERuntimeMessages.get().LogView_column_date);
        //      fColumn3.setWidth(fMemento.getInteger(P_COLUMN_3).intValue());
        fColumn3.setWidth(150);
        fColumn3.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                DATE_ORDER *= -1;
                ViewerComparator comparator = getViewerComparator(DATE);
                fTreeViewer.setComparator(comparator);
                setComparator(DATE);
                ((EventDetailsDialogAction) fPropertiesAction).setComparator(fComparator);
                //            fMemento.putInteger(P_ORDER_VALUE, DATE_ORDER);
                //            fMemento.putInteger(P_ORDER_TYPE, DATE);
                setColumnSorting(fColumn3, DATE_ORDER);
            }
        });

        tree.setHeaderVisible(true);
    }

    private void initializeViewerSorter() {
        //      byte orderType = fMemento.getInteger(P_ORDER_TYPE).byteValue();
        byte orderType = DATE;
        ViewerComparator comparator = getViewerComparator(orderType);
        fTreeViewer.setComparator(comparator);
        //      if (orderType == MESSAGE )
        //         setColumnSorting(fColumn1, MESSAGE_ORDER);
        //      else if (orderType == PLUGIN)
        //         setColumnSorting(fColumn2, PLUGIN_ORDER);
        //      else if (orderType == DATE)
        setColumnSorting(fColumn3, DATE_ORDER);
    }

    private void setColumnSorting(TreeColumn column, int order) {
        fTree.setSortColumn(column);
        fTree.setSortDirection(order == ASCENDING ? SWT.UP : SWT.DOWN);
    }

    public void dispose() {
        writeSettings();
        Platform.removeLogListener(this);
        //      fClipboard.dispose();
        if (fTextShell != null)
            fTextShell.dispose();
        LogReader.reset();
        fLabelProvider.disconnect(this);
        super.dispose();
    }

    private void handleImport() {
        //      FileDialog dialog = new FileDialog(getViewSite().getShell());
        //      dialog.setFilterExtensions(new String[] { "*.log" }); //$NON-NLS-1$
        //      if (fDirectory != null)
        //         dialog.setFilterPath(fDirectory);
        //      handleImportPath(dialog.open());
    }

    public void handleImportPath(String path) {
        if (path != null && new Path(path).toFile().exists()) {
            fInputFile = new Path(path).toFile();
            fDirectory = fInputFile.getParent();
            IRunnableWithProgress op = new IRunnableWithProgress() {
                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                    monitor.beginTask(PDERuntimeMessages.get().LogView_operation_importing,
                            IProgressMonitor.UNKNOWN);
                    readLogFile();
                }
            };
            ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell());
            try {
                pmd.run(true, true, op);
            } catch (InvocationTargetException e) {
            } catch (InterruptedException e) {
            } finally {
                fReadLogAction.setText(PDERuntimeMessages.get().LogView_readLog_reload);
                fReadLogAction.setToolTipText(PDERuntimeMessages.get().LogView_readLog_reload);
                asyncRefresh(false);
                resetDialogButtons();
            }
        }
    }

    private void handleExport() {
        //      FileDialog dialog = new FileDialog(getViewSite().getShell(), SWT.SAVE);
        //      dialog.setFilterExtensions(new String[] { "*.log" }); //$NON-NLS-1$
        //      if (fDirectory != null)
        //         dialog.setFilterPath(fDirectory);
        //      String path = dialog.open();
        //      if (path != null) {
        //         if (path.indexOf('.') == -1 && !path.endsWith(".log")) //$NON-NLS-1$
        //            path += ".log"; //$NON-NLS-1$
        //         File outputFile = new Path(path).toFile();
        //         fDirectory = outputFile.getParent();
        //         if (outputFile.exists()) {
        //            String message = NLS.bind(PDERuntimeMessages.LogView_confirmOverwrite_message, outputFile.toString());
        //            if (!MessageDialog.openQuestion(getViewSite().getShell(), PDERuntimeMessages.LogView_exportLog, message)) 
        //               return;
        //         }
        //         copy(fInputFile, outputFile);
        //      }
    }

    private void copy(File inputFile, File outputFile) {
        BufferedReader reader = null;
        BufferedWriter writer = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), "UTF-8")); //$NON-NLS-1$
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")); //$NON-NLS-1$
            while (reader.ready()) {
                writer.write(reader.readLine());
                writer.write(System.getProperty("line.separator")); //$NON-NLS-1$
            }
        } catch (IOException e) {
        } finally {
            try {
                if (reader != null)
                    reader.close();
                if (writer != null)
                    writer.close();
            } catch (IOException e1) {
            }
        }
    }

    private void handleFilter() {
        FilterDialog dialog = new FilterDialog(PDERuntimePlugin.getActiveWorkbenchShell(), null);
        //      FilterDialog dialog = new FilterDialog(PDERuntimePlugin.getActiveWorkbenchShell(), fMemento);
        dialog.create();
        dialog.getShell().setText(PDERuntimeMessages.get().LogView_FilterDialog_title);
        if (dialog.open() == Window.OK)
            reloadLog();
    }

    private void doDeleteLog() {
        String title = PDERuntimeMessages.get().LogView_confirmDelete_title;
        String message = PDERuntimeMessages.get().LogView_confirmDelete_message;
        if (!MessageDialog.openConfirm(fTree.getShell(), title, message))
            return;
        if (fInputFile.delete() || fLogs.size() > 0) {
            fLogs.clear();
            asyncRefresh(false);
            resetDialogButtons();
        }
    }

    public void fillContextMenu(IMenuManager manager) {
    }

    public LogEntry[] getLogs() {
        return (LogEntry[]) fLogs.toArray(new LogEntry[fLogs.size()]);
    }

    protected void handleClear() {
        BusyIndicator.showWhile(fTree.getDisplay(), new Runnable() {
            public void run() {
                fLogs.clear();
                asyncRefresh(false);
                resetDialogButtons();
            }
        });
    }

    protected void reloadLog() {
        IRunnableWithProgress op = new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                monitor.beginTask(PDERuntimeMessages.get().LogView_operation_reloading, IProgressMonitor.UNKNOWN);
                readLogFile();
            }
        };
        ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell());
        try {
            pmd.run(true, true, op);
        } catch (InvocationTargetException e) {
        } catch (InterruptedException e) {
        } finally {
            fReadLogAction.setText(PDERuntimeMessages.get().LogView_readLog_restore);
            fReadLogAction.setToolTipText(PDERuntimeMessages.get().LogView_readLog_restore);
            asyncRefresh(false);
            resetDialogButtons();
        }
    }

    private void readLogFile() {
        fLogs.clear();
        if (!fInputFile.exists())
            return;
        LogReader.parseLogFile(fInputFile, fLogs, null);
        //      LogReader.parseLogFile(fInputFile, fLogs, fMemento);
    }

    public void logging(IStatus status, String plugin) {
        if (!fInputFile.equals(Platform.getLogFileLocation().toFile()))
            return;
        if (fFirstEvent) {
            readLogFile();
            asyncRefresh();
            fFirstEvent = false;
        } else {
            pushStatus(status);
        }
    }

    private void pushStatus(IStatus status) {
        LogEntry entry = new LogEntry(status);
        LogReader.addEntry(entry, fLogs, null, true);
        //      LogReader.addEntry(entry, fLogs, fMemento, true);
        asyncRefresh();
    }

    private void asyncRefresh() {
        asyncRefresh(true);
    }

    private void asyncRefresh(final boolean activate) {
        if (fTree.isDisposed())
            return;
        Display display = fTree.getDisplay();
        final ViewPart view = this;
        if (display != null) {
            display.asyncExec(new Runnable() {
                public void run() {
                    if (!fTree.isDisposed()) {
                        fTreeViewer.refresh();
                        fDeleteLogAction.setEnabled(
                                fInputFile.exists() && fInputFile.equals(Platform.getLogFileLocation().toFile()));
                        fOpenLogAction.setEnabled(fInputFile.exists());
                        fExportAction.setEnabled(fInputFile.exists());
                        if (activate && fActivateViewAction.isChecked()) {
                            IWorkbenchPage page = PDERuntimePlugin.getActivePage();
                            if (page != null)
                                page.bringToTop(view);
                        }
                    }
                }
            });
        }
    }

    public void setFocus() {
        if (fTree != null && !fTree.isDisposed())
            fTree.setFocus();
    }

    private void handleSelectionChanged(ISelection selection) {
        updateStatus(selection);
        //      fCopyAction.setEnabled(!selection.isEmpty());
        fPropertiesAction.setEnabled(!selection.isEmpty());
    }

    private void updateStatus(ISelection selection) {
        IStatusLineManager status = getViewSite().getActionBars().getStatusLineManager();
        if (selection.isEmpty())
            status.setMessage(null);
        else {
            LogEntry entry = (LogEntry) ((IStructuredSelection) selection).getFirstElement();
            status.setMessage(((LogViewLabelProvider) fTreeViewer.getLabelProvider()).getColumnText(entry, 0));
        }
    }

    private void copyToClipboard(ISelection selection) {
        StringWriter writer = new StringWriter();
        PrintWriter pwriter = new PrintWriter(writer);
        if (selection.isEmpty())
            return;
        LogEntry entry = (LogEntry) ((IStructuredSelection) selection).getFirstElement();
        entry.write(pwriter);
        pwriter.flush();
        String textVersion = writer.toString();
        try {
            pwriter.close();
            writer.close();
        } catch (IOException e) {
        }
        //      if (textVersion.trim().length() > 0) {
        //          //set the clipboard contents
        //         fClipboard.setContents(
        //               new Object[] { textVersion },
        //               new Transfer[] { TextTransfer.getInstance() });
        //      }
    }

    public void init(IViewSite site, IMemento memento) throws PartInitException {
        super.init(site, memento);
        //      if (memento == null)
        //         this.fMemento = XMLMemento.createWriteRoot("LOGVIEW"); //$NON-NLS-1$
        //      else
        //         this.fMemento = memento;
        //      readSettings();

        // initialize column ordering 
        //      final byte type = this.fMemento.getInteger(P_ORDER_TYPE).byteValue();
        //      switch (type){
        //      case DATE:
        //         DATE_ORDER = this.fMemento.getInteger(P_ORDER_VALUE).intValue();
        //         MESSAGE_ORDER = DESCENDING;
        //         PLUGIN_ORDER = DESCENDING;
        //         break;
        //      case MESSAGE:
        //         MESSAGE_ORDER = this.fMemento.getInteger(P_ORDER_VALUE).intValue();
        //         DATE_ORDER = DESCENDING;
        //         PLUGIN_ORDER = DESCENDING;
        //         break;
        //      case PLUGIN:
        //         PLUGIN_ORDER = this.fMemento.getInteger(P_ORDER_VALUE).intValue();
        //         MESSAGE_ORDER = DESCENDING;
        //         DATE_ORDER = DESCENDING;
        //         break;
        //      default:
        DATE_ORDER = DESCENDING;
        MESSAGE_ORDER = DESCENDING;
        PLUGIN_ORDER = DESCENDING;
        //      }
        //      setComparator(fMemento.getInteger(P_ORDER_TYPE).byteValue());
        setComparator(DATE);
    }

    private void initializeMemento() {
        //      if (fMemento.getString(P_USE_LIMIT) == null)
        //         fMemento.putString(P_USE_LIMIT, "true"); //$NON-NLS-1$
        //      if (fMemento.getInteger(P_LOG_LIMIT) == null)
        //         fMemento.putInteger(P_LOG_LIMIT, 50);
        //      if (fMemento.getString(P_LOG_INFO) == null)
        //         fMemento.putString(P_LOG_INFO, "true"); //$NON-NLS-1$
        //      if (fMemento.getString(P_LOG_WARNING) == null)
        //         fMemento.putString(P_LOG_WARNING, "true"); //$NON-NLS-1$
        //      if (fMemento.getString(P_LOG_ERROR) == null)
        //         fMemento.putString(P_LOG_ERROR, "true"); //$NON-NLS-1$
        //      if (fMemento.getString(P_SHOW_ALL_SESSIONS) == null)
        //         fMemento.putString(P_SHOW_ALL_SESSIONS, "true"); //$NON-NLS-1$
        //      Integer width = fMemento.getInteger(P_COLUMN_1);
        //      if (width == null || width.intValue() == 0)
        //         fMemento.putInteger(P_COLUMN_1, 300);
        //      width = fMemento.getInteger(P_COLUMN_2);
        //      if (width == null || width.intValue() == 0)
        //         fMemento.putInteger(P_COLUMN_2, 150);
        //      width = fMemento.getInteger(P_COLUMN_3);
        //      if (width == null || width.intValue() == 0)
        //         fMemento.putInteger(P_COLUMN_3, 150);
        //      if (fMemento.getString(P_ACTIVATE) == null)
        //         fMemento.putString(P_ACTIVATE, "true"); //$NON-NLS-1$
        //
        //      fMemento.putInteger(P_ORDER_VALUE, DESCENDING);
        //      fMemento.putInteger(P_ORDER_TYPE, DATE);
    }

    public void saveState(IMemento memento) {
        //      if (this.fMemento == null || memento == null)
        //         return;
        //      this.fMemento.putInteger(P_COLUMN_1, fColumn1.getWidth());
        //      this.fMemento.putInteger(P_COLUMN_2, fColumn2.getWidth());
        //      this.fMemento.putInteger(P_COLUMN_3, fColumn3.getWidth());
        //      this.fMemento.putString(P_ACTIVATE,
        //            fActivateViewAction.isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
        //      memento.putMemento(this.fMemento);
        //      writeSettings();
    }

    private void addMouseListeners() {
        //      Listener tableListener = new Listener() {
        //         public void handleEvent(Event e) {
        //            switch (e.type) {
        //            case SWT.MouseMove:
        //               onMouseMove(e);
        //               break;
        //            case SWT.MouseHover:
        //               onMouseHover(e);
        //               break;
        //            case SWT.MouseDown:
        //               onMouseDown(e);
        //               break;
        //            }
        //         }
        //      };
        //      int[] tableEvents = new int[] { SWT.MouseDown, SWT.MouseMove, SWT.MouseHover };
        //      for (int i = 0; i < tableEvents.length; i++) {
        //         fTree.addListener(tableEvents[i], tableListener);
        //      }
    }

    private void makeHoverShell() {
        fTextShell = new Shell(fTree.getShell(), SWT.NO_FOCUS | SWT.ON_TOP /*| SWT.TOOL*/);
        Display display = fTextShell.getDisplay();
        fTextShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
        GridLayout layout = new GridLayout(1, false);
        int border = ((fTree.getShell().getStyle() & SWT.NO_TRIM) == 0) ? 0 : 1;
        layout.marginHeight = border;
        layout.marginWidth = border;
        fTextShell.setLayout(layout);
        fTextShell.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        Composite shellComposite = new Composite(fTextShell, SWT.NONE);
        layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        shellComposite.setLayout(layout);
        shellComposite.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_BEGINNING));
        fTextLabel = new Text(shellComposite, SWT.WRAP | SWT.MULTI | SWT.READ_ONLY);
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.widthHint = 100;
        gd.grabExcessHorizontalSpace = true;
        fTextLabel.setLayoutData(gd);
        Color c = fTree.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND);
        fTextLabel.setBackground(c);
        c = fTree.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND);
        fTextLabel.setForeground(c);
        fTextLabel.setEditable(false);
        fTextShell.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                onTextShellDispose(e);
            }
        });
    }

    void onTextShellDispose(DisposeEvent e) {
        fCanOpenTextShell = true;
        setFocus();
    }

    void onMouseDown(Event e) {
        if (fTextShell != null && !fTextShell.isDisposed() && !fTextShell.isFocusControl()) {
            fTextShell.setVisible(false);
            fCanOpenTextShell = true;
        }
    }

    void onMouseHover(Event e) {
        if (!fCanOpenTextShell)
            return;
        fCanOpenTextShell = false;
        Point point = new Point(e.x, e.y);
        TreeItem item = fTree.getItem(point);
        if (item == null)
            return;
        String message = ((LogEntry) item.getData()).getStack();
        if (message == null)
            return;

        fTextLabel.setText(message);
        Rectangle bounds = fTree.getDisplay().getBounds();
        //      Point cursorPoint = fTree.getDisplay().getCursorLocation();
        int x = point.x;
        int y = point.y + 25;
        int width = fTree.getColumn(0).getWidth();
        int height = 125;
        //      if (cursorPoint.x + width > bounds.width)
        //         x -= width;
        //      if (cursorPoint.y + height + 25 > bounds.height)
        //         y -= height + 27;

        fTextShell.setLocation(fTree.toDisplay(x, y));
        fTextShell.setSize(width, height);
        fTextShell.setVisible(true);
    }

    void onMouseMove(Event e) {
        if (fTextShell != null && !fTextShell.isDisposed() && fTextShell.isVisible())
            fTextShell.setVisible(false);

        Point point = new Point(e.x, e.y);
        TreeItem item = fTree.getItem(point);
        if (item == null)
            return;
        Image image = item.getImage();
        LogEntry entry = (LogEntry) item.getData();
        int parentCount = getNumberOfParents(entry);
        int startRange = 20 + Math.max(image.getBounds().width + 2, 7 + 2) * parentCount;
        int endRange = startRange + 16;
        fCanOpenTextShell = e.x >= startRange && e.x <= endRange;
    }

    private int getNumberOfParents(LogEntry entry) {
        LogEntry parent = (LogEntry) entry.getParent(entry);
        if (parent == null)
            return 0;
        return 1 + getNumberOfParents(parent);
    }

    public Comparator getComparator() {
        return fComparator;
    }

    private void setComparator(byte sortType) {
        if (sortType == DATE) {
            fComparator = new Comparator() {
                public int compare(Object e1, Object e2) {
                    long date1 = ((LogEntry) e1).getDate().getTime();
                    long date2 = ((LogEntry) e2).getDate().getTime();
                    if (date1 == date2) {
                        int result = fLogs.indexOf(e2) - fLogs.indexOf(e1);
                        if (DATE_ORDER == DESCENDING)
                            result *= DESCENDING;
                        return result;
                    }
                    if (DATE_ORDER == DESCENDING)
                        return date1 > date2 ? DESCENDING : ASCENDING;
                    return date1 < date2 ? DESCENDING : ASCENDING;
                }
            };
        } else if (sortType == PLUGIN) {
            fComparator = new Comparator() {
                public int compare(Object e1, Object e2) {
                    LogEntry entry1 = (LogEntry) e1;
                    LogEntry entry2 = (LogEntry) e2;
                    return getDefaultComparator().compare(entry1.getPluginId(), entry2.getPluginId())
                            * PLUGIN_ORDER;
                }
            };
        } else {
            fComparator = new Comparator() {
                public int compare(Object e1, Object e2) {
                    LogEntry entry1 = (LogEntry) e1;
                    LogEntry entry2 = (LogEntry) e2;
                    return getDefaultComparator().compare(entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
                }
            };
        }
    }

    private Comparator getDefaultComparator() {
        return Policy.getComparator();
    }

    private ViewerComparator getViewerComparator(byte sortType) {
        if (sortType == PLUGIN) {
            return new ViewerComparator() {
                public int compare(Viewer viewer, Object e1, Object e2) {
                    LogEntry entry1 = (LogEntry) e1;
                    LogEntry entry2 = (LogEntry) e2;
                    return getComparator().compare(entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER;
                }
            };
        } else if (sortType == MESSAGE) {
            return new ViewerComparator() {
                public int compare(Viewer viewer, Object e1, Object e2) {
                    LogEntry entry1 = (LogEntry) e1;
                    LogEntry entry2 = (LogEntry) e2;
                    return getComparator().compare(entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
                }
            };
        } else {
            return new ViewerComparator() {
                public int compare(Viewer viewer, Object e1, Object e2) {
                    long date1 = ((LogEntry) e1).getDate().getTime();
                    long date2 = ((LogEntry) e2).getDate().getTime();
                    if (date1 == date2) {
                        int result = fLogs.indexOf(e2) - fLogs.indexOf(e1);
                        if (DATE_ORDER == DESCENDING)
                            result *= DESCENDING;
                        return result;
                    }
                    if (DATE_ORDER == DESCENDING)
                        return date1 > date2 ? DESCENDING : ASCENDING;
                    return date1 < date2 ? DESCENDING : ASCENDING;
                }
            };
        }
    }

    private void resetDialogButtons() {
        ((EventDetailsDialogAction) fPropertiesAction).resetDialogButtons();
    }

    /**
     * Returns the filter dialog settings object used to maintain
     * state between filter dialogs
     * @return the dialog settings to be used
     */
    private IDialogSettings getLogSettings() {
        IDialogSettings settings = PDERuntimePlugin.getDefault().getDialogSettings();
        return settings.getSection(getClass().getName());
    }

    /**
     * Returns the plugin preferences used to maintain
     * state of log view
     * @return the plugin preferences
     */
    private Preferences getLogPreferences() {
        return PDERuntimePlugin.getDefault().getPluginPreferences();
    }

    private void readSettings() {
        IDialogSettings s = getLogSettings();
        Preferences p = getLogPreferences();
        if (s == null || p == null) {
            initializeMemento();
            return;
        }
        try {
            //         fMemento.putString(P_USE_LIMIT, s.getBoolean(P_USE_LIMIT) ? "true":"false"); //$NON-NLS-1$ //$NON-NLS-2$
            //         fMemento.putString(P_LOG_INFO, s.getBoolean(P_LOG_INFO) ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
            //         fMemento.putString(P_LOG_WARNING, s.getBoolean(P_LOG_WARNING) ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
            //         fMemento.putString(P_LOG_ERROR, s.getBoolean(P_LOG_ERROR) ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
            //         fMemento.putString(P_SHOW_ALL_SESSIONS, s.getBoolean(P_SHOW_ALL_SESSIONS) ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
            //         fMemento.putInteger(P_LOG_LIMIT, s.getInt(P_LOG_LIMIT));
            //         fMemento.putInteger(P_COLUMN_1, p.getInt(P_COLUMN_1) > 0 ? p.getInt(P_COLUMN_1) : 300);
            //         fMemento.putInteger(P_COLUMN_2, p.getInt(P_COLUMN_2) > 0 ? p.getInt(P_COLUMN_2) : 150);
            //         fMemento.putInteger(P_COLUMN_3, p.getInt(P_COLUMN_3) > 0 ? p.getInt(P_COLUMN_3) : 150);
            //         fMemento.putString(P_ACTIVATE, p.getBoolean(P_ACTIVATE) ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
            //         int order = p.getInt(P_ORDER_VALUE);
            //         fMemento.putInteger(P_ORDER_VALUE, order == 0 ? DESCENDING : order);
            //         fMemento.putInteger(P_ORDER_TYPE, p.getInt(P_ORDER_TYPE));
        } catch (NumberFormatException e) {
            //         fMemento.putInteger(P_LOG_LIMIT, 50);
            //         fMemento.putInteger(P_COLUMN_1, 300);
            //         fMemento.putInteger(P_COLUMN_2, 150);
            //         fMemento.putInteger(P_COLUMN_3, 150);
            //         fMemento.putInteger(P_ORDER_TYPE, DATE);
            //         fMemento.putInteger(P_ORDER_VALUE, DESCENDING);
        }
    }

    private void writeSettings() {
        writeViewSettings();
        writeFilterSettings();
    }

    private void writeFilterSettings() {
        IDialogSettings settings = getLogSettings();
        if (settings == null)
            settings = PDERuntimePlugin.getDefault().getDialogSettings().addNewSection(getClass().getName());
        //      settings.put(P_USE_LIMIT, fMemento.getString(P_USE_LIMIT).equals("true")); //$NON-NLS-1$
        //      settings.put(P_LOG_LIMIT, fMemento.getInteger(P_LOG_LIMIT).intValue());
        //      settings.put(P_LOG_INFO, fMemento.getString(P_LOG_INFO).equals("true")); //$NON-NLS-1$
        //      settings.put(P_LOG_WARNING, fMemento.getString(P_LOG_WARNING).equals("true")); //$NON-NLS-1$
        //      settings.put(P_LOG_ERROR, fMemento.getString(P_LOG_ERROR).equals("true")); //$NON-NLS-1$
        //      settings.put(P_SHOW_ALL_SESSIONS, fMemento.getString(P_SHOW_ALL_SESSIONS).equals("true")); //$NON-NLS-1$
    }

    private void writeViewSettings() {
        Preferences preferences = getLogPreferences();
        //      preferences.setValue(P_COLUMN_1, fMemento.getInteger(P_COLUMN_1).intValue());
        //      preferences.setValue(P_COLUMN_2, fMemento.getInteger(P_COLUMN_2).intValue());
        //      preferences.setValue(P_COLUMN_3, fMemento.getInteger(P_COLUMN_3).intValue());
        //      preferences.setValue(P_ACTIVATE, fMemento.getString(P_ACTIVATE).equals("true")); //$NON-NLS-1$
        //      int order = fMemento.getInteger(P_ORDER_VALUE).intValue();
        //      preferences.setValue(P_ORDER_VALUE, order == 0 ? DESCENDING : order);
        //      preferences.setValue(P_ORDER_TYPE, fMemento.getInteger(P_ORDER_TYPE).intValue());
    }

    public void sortByDateDescending() {
        setColumnSorting(fColumn3, DESCENDING);
    }

    protected Job getOpenLogFileJob() {
        final Shell shell = getViewSite().getShell();
        return new Job(PDERuntimeMessages.get().OpenLogDialog_message) {
            protected IStatus run(IProgressMonitor monitor) {
                boolean failed = false;
                if (fInputFile.length() <= LogReader.MAX_FILE_LENGTH) {
                    //               failed = !Program.launch(fInputFile.getAbsolutePath());
                    //               if (failed) {
                    //                  Program p = Program.findProgram(".txt"); //$NON-NLS-1$
                    //                  if (p != null) {
                    //                     p.execute(fInputFile.getAbsolutePath());
                    //                     return Status.OK_STATUS;
                    //                  }
                    //               }
                }
                if (failed) {
                    final OpenLogDialog openDialog = new OpenLogDialog(shell, fInputFile);
                    Display.getDefault().asyncExec(new Runnable() {
                        public void run() {
                            openDialog.create();
                            openDialog.open();
                        }
                    });
                }
                return Status.OK_STATUS;
            }
        };
    }

    protected File getLogFile() {
        return fInputFile;
    }
}