+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.message.ui;
+
+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.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Path;
+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.IAction;
+import org.eclipse.jface.action.IContributionItem;
+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.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+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.TreeSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.browser.LocationListener;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+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.program.Program;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Listener;
+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.IPerspectiveDescriptor;
+import org.eclipse.ui.IPerspectiveListener2;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.dialogs.FilteredTree;
+import org.eclipse.ui.dialogs.PatternFilter;
+import org.eclipse.ui.part.ViewPart;
+import org.simantics.message.DetailStatus;
+import org.simantics.message.ILogListener;
+import org.simantics.message.IMessageDataSchemeExtension;
+import org.simantics.message.IMessageSchemeManager;
+import org.simantics.message.MessageSchemeException;
+import org.simantics.message.MessageService;
+import org.simantics.message.ReferenceSerializationException;
+import org.simantics.message.util.HtmlUtil;
+import org.simantics.utils.ui.ErrorLogger;
+
+import com.ibm.icu.text.DateFormat;
+import com.ibm.icu.text.SimpleDateFormat;
+
+/**
+ * A direct rip of Eclipse's own <code>LogView</code> for our own purposes.
+ *
+ * <p>
+ * The only thing that has changed is the the dependence on
+ * <code>Activator.getLogFile()</code> instead of
+ * <code>Platform.getLogFileLocation()</code>.
+ *
+ * @author Tuukka Lehtonen
+ * @see org.eclipse.ui.internal.views.LogView
+ */
+@SuppressWarnings("deprecation")\r
+public class LogView extends ViewPart implements ILogListener {
+
+ public static final int DEFAULT_EXPAND_LEVEL = 1;
+
+ 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_DEBUG = "debug"; //$NON-NLS-1$
+ public static final String P_LOG_LIMIT = "limit"; //$NON-NLS-1$
+ public static final String P_EXPAND_LEVEL = "expandLevel"; //$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_SHOW_FILTER_TEXT = "show_filter_text"; //$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$
+ public static final String P_IMPORT_LOG = "importLog"; //$NON-NLS-1$
+ public static final String P_GROUP_BY = "groupBy"; //$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;
+
+ public static final int GROUP_BY_NONE = 0;
+ public static final int GROUP_BY_SESSION = 1;
+ public static final int GROUP_BY_PLUGIN = 2;
+
+ private List<Object> elements;
+ private Map<Object, Object> groups;
+ private LogSession currentSession;
+
+ private List<Object> batchedEntries;
+ private boolean batchEntries;
+
+ private Clipboard fClipboard;
+
+ private IMemento fMemento;
+ private File fInputFile;
+ private String fDirectory;
+
+ private Comparator<Object> fComparator;
+
+ // hover text
+ private boolean fCanOpenTextShell;
+ private Text fTextLabel;
+ private Shell fTextShell;
+
+ private boolean fFirstEvent = true;
+
+ private TreeColumn fColumn1;
+ @SuppressWarnings("unused")\r
+ private TreeColumn fColumn2;
+ private TreeColumn fColumn3;
+
+ private Tree fTree;
+ private FilteredTree fFilteredTree;
+ private LogViewLabelProvider fLabelProvider;
+ //private ScrolledComposite fMessageDescriptorComposite;
+ //private FormText fMessageDescription;
+ private Browser fMessageDescription;
+
+ private Action fPropertiesAction;
+ private Action fDeleteLogAction;
+ private Action fReadLogAction;
+ private Action fCopyAction;
+ private Action fActivateViewAction;
+ private Action fOpenLogAction;
+ private Action fExportAction;
+
+ private LocalResourceManager resourceManager;
+
+ /**
+ * Action called when user selects "Group by -> ..." from menu.
+ */
+ class GroupByAction extends Action {
+ private int groupBy;
+
+ public GroupByAction(String text, int groupBy) {
+ super(text, IAction.AS_RADIO_BUTTON);
+
+ this.groupBy = groupBy;
+
+ if (fMemento.getInteger(LogView.P_GROUP_BY).intValue() == groupBy) {
+ setChecked(true);
+ }
+ }
+
+ public void run() {
+ if (fMemento.getInteger(LogView.P_GROUP_BY).intValue() != groupBy) {
+ fMemento.putInteger(LogView.P_GROUP_BY, groupBy);
+ reloadLog();
+ }
+ }
+ }
+
+ /**
+ * Constructor
+ */
+ public LogView() {
+ elements = new ArrayList<Object>();
+ groups = new HashMap<Object, Object>();
+ batchedEntries = new ArrayList<Object>();
+ fInputFile = getPlatformLogFile();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createPartControl(Composite parent) {
+ resourceManager = new LocalResourceManager(JFaceResources.getResources());
+
+ SashForm sashForm = new SashForm(parent, SWT.VERTICAL | SWT.SMOOTH);
+
+ final Composite composite = new Composite(sashForm, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.marginBottom = 0;
+ layout.marginTop = 0;
+ layout.marginLeft = 0;
+ layout.marginRight = 0;
+ composite.setLayout(layout);
+
+ readLogFile();
+ createViewer(composite);
+ getSite().setSelectionProvider(fFilteredTree.getViewer());
+ createActions();
+ fClipboard = new Clipboard(fTree.getDisplay());
+ fTree.setToolTipText(""); //$NON-NLS-1$
+ initializeViewerSorter();
+
+ makeHoverShell();
+
+ /*
+ fMessageDescriptorComposite = new ScrolledComposite(sashForm, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(fMessageDescriptorComposite);
+ TableWrapLayout layout2 = new TableWrapLayout();
+ layout2.bottomMargin = 0;
+ layout2.topMargin = 0;
+ layout2.leftMargin = 0;
+ layout2.rightMargin = 0;
+ fMessageDescriptorComposite.setLayout(layout2);
+
+ fMessageDescription = new FormText(fMessageDescriptorComposite, SWT.NONE);
+ fMessageDescription.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ TableWrapData data = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB);
+ fMessageDescription.setLayoutData(data);
+ TextColors.bindTo(resourceManager, fMessageDescription);
+ fMessageDescription.addHyperlinkListener(new IHyperlinkListener() {
+ @Override
+ public void linkActivated(HyperlinkEvent event) {
+ String s = (String) event.data;
+ //System.out.println("link activated: " + s);
+ try {
+ URI uri = new URI(s);
+ String scheme = uri.getScheme();
+ String schemeSpecificPart = uri.getSchemeSpecificPart();
+
+ IMessageSchemeManager msm = org.simantics.message.internal.Activator.getDefault().getMessageSchemeManager();
+ IMessageDataSchemeExtension[] exts = msm.getByScheme(scheme);
+
+ for (IMessageDataSchemeExtension ext : exts) {
+ Object data = ext.getSerializer().deserialize(schemeSpecificPart);
+ ext.getHandler().perform(data);
+ return;
+ }
+ } catch (URISyntaxException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (ReferenceSerializationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ @Override
+ public void linkEntered(HyperlinkEvent e) {
+ //System.out.println("link entered: " + e.data);
+ }
+ @Override
+ public void linkExited(HyperlinkEvent e) {
+ //System.out.println("link exited: " + e.data);
+ }
+ });
+ fMessageDescription.setText("Select a message to show its description here.", false, false);
+
+ fMessageDescriptorComposite.setContent(fMessageDescription);
+ fMessageDescriptorComposite.setExpandVertical(true);
+ fMessageDescriptorComposite.setExpandHorizontal(true);
+ fMessageDescriptorComposite.addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ Rectangle r = fMessageDescriptorComposite.getClientArea();
+ //System.out.println("scrolled composite resized: " + e + ", client area: " + r);
+ Point contentSize = fMessageDescription.computeSize(r.width, SWT.DEFAULT);
+ //System.out.println("computed content size: " + contentSize);
+ fMessageDescriptorComposite.setMinSize(contentSize);
+ }
+ });
+ */
+ fMessageDescription = new Browser(sashForm, SWT.NONE);
+ fMessageDescription.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+ fMessageDescription.setText("<html><head></head><body><p>Select a message to show its description here.</p></body></html>");
+ fMessageDescription.addLocationListener(new LocationListener() {
+ @Override
+ public void changed(LocationEvent event) {
+ //System.out.println("changed: " + event);
+ }
+ @Override
+ public void changing(LocationEvent event) {
+ //System.out.println("changing: " + event);
+ String location = event.location;
+ if ("about:blank".equals(location)) {
+ event.doit = true;
+ } else {
+ event.doit = false;
+ //System.out.println("link activated: " + location);
+ try {
+ URI uri = new URI(location);
+ String scheme = uri.getScheme();
+ //String schemeSpecificPart = uri.getSchemeSpecificPart();
+
+ IMessageSchemeManager msm = org.simantics.message.internal.Activator.getDefault().getMessageSchemeManager();
+ IMessageDataSchemeExtension[] exts = msm.getByScheme(scheme);
+
+ for (IMessageDataSchemeExtension ext : exts) {
+ Object data = ext.getSerializer().deserialize(uri);
+ try {
+ ext.getHandler().perform(data);
+ return;
+ } catch (MessageSchemeException e) {
+ ErrorLogger.defaultLogError(e);
+ }
+ }
+ return;
+ } catch (URISyntaxException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (ReferenceSerializationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ });
+
+ sashForm.setWeights(new int[] { 5, 2 });
+
+ fFilteredTree.getViewer().addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection s = (IStructuredSelection) event.getSelection();
+ if (s.isEmpty()) {
+ //fMessageDescription.setText("Select a message to show its description here.", false, false);
+ fMessageDescription.setText("<html><head></head><body><pre>Select a message to show its description here.</pre></body></html>");
+ } else {
+ AbstractEntry entry = (AbstractEntry) s.getFirstElement();
+ if (entry instanceof LogEntry) {
+ LogEntry logEntry = (LogEntry) entry;
+ String msg = logEntry.getDetailedDescription();
+ if (msg == null || msg.trim().isEmpty())
+ msg = logEntry.getMessage();
+
+ // FormText only supports texts of Short.MAX_VALUE length
+ // since TextSegment.TextFragment uses shorts. This message
+ // truncation enables us to show even lengthy messages.
+ if (msg.length() > Short.MAX_VALUE) {
+ StringBuilder truncated = new StringBuilder();
+ truncated.append("... [truncated ");
+ truncated.append(msg.length() - (Short.MAX_VALUE - 100));
+ truncated.append(" out of ");
+ truncated.append(msg.length());
+ truncated.append(" characters]");
+ msg = msg.substring(0, Short.MAX_VALUE - 100) + truncated;
+ }
+ try {
+ //fMessageDescription.setText(FormTextUtil.form(msg), true, false);
+ //fMessageDescription.setText(HtmlUtil.html(msg));
+ fMessageDescription.setText(msg);
+ } catch (SWTException e) {
+ // Failed to parse markup, fall back to not parsing the input.
+ //fMessageDescription.setText(FormTextUtil.form(msg), false, false);
+ fMessageDescription.setText(msg);
+ }
+ } else if (entry instanceof Group) {
+ if (entry instanceof LogSession) {
+ LogSession logSession = (LogSession) entry;
+ //fMessageDescription.setText(logSession.getSessionData(), false, false);
+ fMessageDescription.setText(logSession.getSessionData());
+ } else {
+ Group grp = (Group) entry;
+ //fMessageDescription.setText(grp.toString(), false, false);
+ fMessageDescription.setText(grp.toString());
+ }
+ }
+ }
+ //fMessageDescription.refresh();
+ //composite.layout(true);
+ }
+ });
+
+ MessageService.getDefault().addLogListener(this);
+// PlatformUI.getWorkbench().getHelpSystem().setHelp(fTree, IHelpContextIds.LOG_VIEW);
+ getSite().getWorkbenchWindow().addPerspectiveListener(new IPerspectiveListener2() {
+
+ public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId) {
+ if (!(partRef instanceof IViewReference))
+ return;
+
+ IWorkbenchPart part = partRef.getPart(false);
+ if (part == null) {
+ return;
+ }
+
+ if (part.equals(LogView.this)) {
+ if (changeId.equals(IWorkbenchPage.CHANGE_VIEW_SHOW)) {
+ if (!batchedEntries.isEmpty()) {
+ pushBatchedEntries();
+ }
+
+ batchEntries = false;
+ } else if (changeId.equals(IWorkbenchPage.CHANGE_VIEW_HIDE)) {
+ batchEntries = true;
+ }
+ }
+ }
+
+ public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
+ // empty
+ }
+
+ public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) {
+ // empty
+ }
+
+ });
+ }
+
+ /**
+ * Creates the actions for the viewsite action bars
+ */
+ 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());
+ toolBarManager.add(createShowTextFilter());
+
+ // FOR TESTING
+// toolBarManager.add(new Separator());
+// final Action testAction = createTestAction();
+// toolBarManager.add(testAction);
+ // FOR TESTING ENDS
+
+ IMenuManager mgr = bars.getMenuManager();
+
+ mgr.add(createGroupByAction());
+
+ mgr.add(new Separator());
+
+ mgr.add(createFilterAction());
+
+ mgr.add(new Separator());
+
+ fActivateViewAction = createActivateViewAction();
+ mgr.add(fActivateViewAction);
+
+// mgr.add(createShowTextFilter());
+
+ 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(createImportLogAction());
+ manager.add(new Separator());
+
+ ((EventDetailsDialogAction) fPropertiesAction).setComparator(fComparator);
+ TreeItem[] selection = fTree.getSelection();
+ if ((selection.length > 0) && (selection[0].getData() instanceof LogEntry)) {
+ 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(Messages.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;
+ }
+
+ @SuppressWarnings("unused")\r
+ private Action createTestAction() {
+ Action action = new Action("Test") {
+ public void run() {
+ IStatus s1 = new Status(IStatus.INFO, Activator.PLUGIN_ID, "Test message 1", null);
+ IStatus s2 = new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Test message 2", null);
+ IStatus s3 = new DetailStatus(IStatus.ERROR, Activator.PLUGIN_ID, "This is the short message.", HtmlUtil.p("A multi-lined message...\n<br/>continuing...<br/><br/>still...<br/>Error occurred, report at " + HtmlUtil.a("http://www.simantics.org", "simantics.org")), null);
+ MessageService.defaultLog(s1);
+ MessageService.defaultLog(s2);
+ MessageService.defaultLog(s3);
+// Activator.getDefault().getLog().log(s1);
+// Activator.getDefault().getLog().log(s2);
+// Activator.getDefault().getLog().log(s3);
+
+ MultiStatus s4 = new MultiStatus(Activator.PLUGIN_ID, 0, "Test message 4", new Exception());
+ s4.merge(new Status(IStatus.INFO, Activator.PLUGIN_ID, "MultiStatus Test 1", null));
+ s4.merge(new Status(IStatus.WARNING, Activator.PLUGIN_ID, "MultiStatus Test 2", null));
+ s4.merge(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "MultiStatus Test 3", null));
+ MessageService.defaultLog(s4);
+// Activator.getDefault().getLog().log(s4);
+ }
+ };
+ action.setImageDescriptor(ImageDescriptor.getMissingImageDescriptor());
+ action.setToolTipText("Produce test log entries");
+ return action;
+ }
+
+ private Action createClearAction() {
+ Action action = new Action(Messages.LogView_clear) {
+ public void run() {
+ handleClear();
+ }
+ };
+ action.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_CLEAR));
+ action.setDisabledImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_CLEAR_DISABLED));
+ action.setToolTipText(Messages.LogView_clear_tooltip);
+ action.setText(Messages.LogView_clear);
+ return action;
+ }
+
+ private Action createCopyAction() {
+ Action action = new Action(Messages.LogView_copy) {
+ public void run() {
+ copyToClipboard(fFilteredTree.getViewer().getSelection());
+ }
+ };
+ action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
+ return action;
+ }
+
+ private Action createDeleteLogAction() {
+ Action action = new Action(Messages.LogView_delete) {
+ public void run() {
+ doDeleteLog();
+ }
+ };
+ action.setToolTipText(Messages.LogView_delete_tooltip);
+ action.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_REMOVE_LOG));
+ action.setDisabledImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_REMOVE_LOG_DISABLED));
+ action.setEnabled(fInputFile.exists() && isPlatformLog(fInputFile));
+ return action;
+ }
+
+ private Action createExportAction() {
+ Action action = new Action(Messages.LogView_export) {
+ public void run() {
+ handleExport();
+ }
+ };
+ action.setToolTipText(Messages.LogView_export_tooltip);
+ action.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_EXPORT));
+ action.setDisabledImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_EXPORT_DISABLED));
+ action.setEnabled(fInputFile.exists());
+ return action;
+ }
+
+ private Action createFilterAction() {
+ Action action = new Action(Messages.LogView_filter) {
+ public void run() {
+ handleFilter();
+ }
+ };
+ action.setToolTipText(Messages.LogView_filter);
+ action.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_FILTER));
+ action.setDisabledImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_FILTER_DISABLED));
+ return action;
+ }
+
+ private Action createImportLogAction() {
+ Action action = new ImportLogAction(this, Messages.LogView_import, fMemento);
+ action.setToolTipText(Messages.LogView_import_tooltip);
+ action.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_IMPORT));
+ action.setDisabledImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_IMPORT_DISABLED));
+ return action;
+ }
+
+ private Action createOpenLogAction() {
+ Action action = null;
+ /*
+ try {
+ // TODO this isn't the best way to check... we should be smarter and use package admin
+ // 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(Messages.LogView_view_currentLog);
+ action.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_OPEN_LOG));
+ action.setDisabledImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_OPEN_LOG_DISABLED));
+ action.setEnabled(fInputFile.exists());
+ action.setToolTipText(Messages.LogView_view_currentLog_tooltip);
+ return action;
+ }
+
+ private void createPropertiesAction() {
+ fPropertiesAction = new EventDetailsDialogAction(fTree.getShell(), fFilteredTree.getViewer(), fMemento);
+ fPropertiesAction.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_PROPERTIES));
+ fPropertiesAction.setDisabledImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_PROPERTIES_DISABLED));
+ fPropertiesAction.setToolTipText(Messages.LogView_properties_tooltip);
+ fPropertiesAction.setEnabled(false);
+ }
+
+ private Action createReadLogAction() {
+ Action action = new Action(Messages.LogView_readLog_restore) {
+ public void run() {
+ fInputFile = getPlatformLogFile();
+ reloadLog();
+ }
+ };
+ action.setToolTipText(Messages.LogView_readLog_restore_tooltip);
+ action.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_READ_LOG));
+ action.setDisabledImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_READ_LOG_DISABLED));
+ return action;
+ }
+
+ /**
+ * Creates the Show Text Filter view menu action
+ * @return the new action for the Show Text Filter
+ */
+ private Action createShowTextFilter() {
+ Action action = new Action(Messages.LogView_show_filter_text, Action.AS_CHECK_BOX) {
+ public void run() {
+ showFilterText(isChecked());
+ }
+ };
+ action.setToolTipText(Messages.LogView_show_filter_tooltip);
+ action.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.DESC_SHOW_TEXT_FILTER));
+ boolean visible = fMemento.getBoolean(P_SHOW_FILTER_TEXT).booleanValue();
+ action.setChecked(visible);
+ showFilterText(visible);
+ return action;
+ }
+
+ /**
+ * Shows/hides the filter text control from the filtered tree. This method also sets the
+ * P_SHOW_FILTER_TEXT preference to the visible state
+ *
+ * @param visible if the filter text control should be shown or not
+ */
+ private void showFilterText(boolean visible) {
+ fMemento.putBoolean(P_SHOW_FILTER_TEXT, visible);
+ Composite ctrl = fFilteredTree.getFilterControl().getParent();
+ GridData gd = (GridData) ctrl.getLayoutData();
+ gd.exclude = !visible;
+ ctrl.setVisible(visible);
+ gd.verticalIndent = 8;
+ gd.horizontalIndent = 4;
+ if (!visible) // reset control if we aren't visible
+ fFilteredTree.getFilterControl().setText(Messages.LogView_show_filter_initialText);
+ fFilteredTree.layout(false);
+ }
+
+ private IContributionItem createGroupByAction() {
+ IMenuManager manager = new MenuManager(Messages.LogView_GroupBy);
+ manager.add(new GroupByAction(Messages.LogView_GroupBySession, LogView.GROUP_BY_SESSION));
+ manager.add(new GroupByAction(Messages.LogView_GroupByPlugin, LogView.GROUP_BY_PLUGIN));
+ manager.add(new GroupByAction(Messages.LogView_GroupByNone, LogView.GROUP_BY_NONE));
+ return manager;
+ }
+
+ private void createViewer(Composite parent) {
+
+ fFilteredTree = new FilteredTree(parent, SWT.FULL_SELECTION, new PatternFilter() {
+ protected boolean isLeafMatch(Viewer viewer, Object element) {
+ if (element instanceof LogEntry) {
+ LogEntry logEntry = (LogEntry) element;
+ String message = logEntry.getMessage();
+ String plugin = logEntry.getPluginId();
+ String date = logEntry.getFormattedDate();
+ return wordMatches(message) || wordMatches(plugin) || wordMatches(date);
+ }
+ return false;
+ }
+ });
+ fFilteredTree.setInitialText(Messages.LogView_show_filter_initialText);
+ fTree = fFilteredTree.getViewer().getTree();
+ fTree.setLinesVisible(true);
+ createColumns(fTree);
+ fFilteredTree.getViewer().setAutoExpandLevel(fMemento.getInteger(P_EXPAND_LEVEL).intValue());
+ fFilteredTree.getViewer().setContentProvider(new LogViewContentProvider(this));
+ fFilteredTree.getViewer().setLabelProvider(fLabelProvider = new LogViewLabelProvider(this));
+ fLabelProvider.connect(this);
+ fFilteredTree.getViewer().addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent e) {
+ handleSelectionChanged(e.getSelection());
+ if (fPropertiesAction.isEnabled())
+ ((EventDetailsDialogAction) fPropertiesAction).resetSelection();
+ }
+ });
+ fFilteredTree.getViewer().addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ ((EventDetailsDialogAction) fPropertiesAction).setComparator(fComparator);
+ fPropertiesAction.run();
+ }
+ });
+ fFilteredTree.getViewer().setInput(this);
+ addMouseListeners();
+ addDragSource();
+ }
+
+ private void createColumns(final Tree tree) {
+ fColumn1 = new TreeColumn(tree, SWT.LEFT);
+ fColumn1.setText(Messages.LogView_column_message);
+ fColumn1.setWidth(fMemento.getInteger(P_COLUMN_1).intValue());
+ fColumn1.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ MESSAGE_ORDER *= -1;
+ ViewerComparator comparator = getViewerComparator(MESSAGE);
+ fFilteredTree.getViewer().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);
+ }
+ });
+ tree.addControlListener(new ControlAdapter() {
+
+ @Override
+ public void controlResized(ControlEvent e) {
+ fColumn1.setWidth(tree.getSize().x - 20);
+ }
+
+ });
+
+// fColumn2 = new TreeColumn(tree, SWT.LEFT);
+// fColumn2.setText(Messages.LogView_column_plugin);
+// fColumn2.setWidth(fMemento.getInteger(P_COLUMN_2).intValue());
+// fColumn2.addSelectionListener(new SelectionAdapter() {
+// public void widgetSelected(SelectionEvent e) {
+// PLUGIN_ORDER *= -1;
+// ViewerComparator comparator = getViewerComparator(PLUGIN);
+// fFilteredTree.getViewer().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(Messages.LogView_column_date);
+// fColumn3.setWidth(fMemento.getInteger(P_COLUMN_3).intValue());
+// fColumn3.addSelectionListener(new SelectionAdapter() {
+// public void widgetSelected(SelectionEvent e) {
+// DATE_ORDER *= -1;
+// ViewerComparator comparator = getViewerComparator(DATE);
+// fFilteredTree.getViewer().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();
+ ViewerComparator comparator = getViewerComparator(orderType);
+ fFilteredTree.getViewer().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();
+ MessageService.getDefault().removeLogListener(this);
+ fClipboard.dispose();
+ if (fTextShell != null)
+ fTextShell.dispose();
+ fLabelProvider.disconnect(this);
+ fFilteredTree.dispose();
+ resourceManager.dispose();
+ super.dispose();
+ }
+
+ void handleImport() {
+ FileDialog dialog = new FileDialog(getViewSite().getShell());
+ dialog.setFilterExtensions(new String[] {"*.log"}); //$NON-NLS-1$
+ if (fDirectory != null)
+ dialog.setFilterPath(fDirectory);
+ String path = dialog.open();
+ if (path == null) { // cancel
+ return;
+ }
+
+ File file = new Path(path).toFile();
+ if (file.exists()) {
+ handleImportPath(path);
+ } else {
+ String msg = NLS.bind(Messages.LogView_FileCouldNotBeFound, file.getName());
+ MessageDialog.openError(getViewSite().getShell(), Messages.LogView_OpenFile, msg);
+ }
+ }
+
+ 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) {
+ monitor.beginTask(Messages.LogView_operation_importing, IProgressMonitor.UNKNOWN);
+ readLogFile();
+ }
+ };
+ ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell());
+ try {
+ pmd.run(true, true, op);
+ } catch (InvocationTargetException e) { // do nothing
+ } catch (InterruptedException e) { // do nothing
+ } finally {
+ fReadLogAction.setText(Messages.LogView_readLog_reload);
+ fReadLogAction.setToolTipText(Messages.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(Messages.LogView_confirmOverwrite_message, outputFile.toString());
+ if (!MessageDialog.openQuestion(getViewSite().getShell(), Messages.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) { // do nothing
+ } finally {
+ try {
+ if (reader != null)
+ reader.close();
+ if (writer != null)
+ writer.close();
+ } catch (IOException e1) { // do nothing
+ }
+ }
+ }
+
+ private void handleFilter() {
+ FilterDialog dialog = new FilterDialog(Activator.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), fMemento);
+ dialog.create();
+ dialog.getShell().setText(Messages.LogView_FilterDialog_title);
+ if (dialog.open() == Window.OK)
+ reloadLog();
+ }
+
+ private void doDeleteLog() {
+ String title = Messages.LogView_confirmDelete_title;
+ String message = Messages.LogView_confirmDelete_message;
+ if (!MessageDialog.openConfirm(fTree.getShell(), title, message))
+ return;
+ if (fInputFile.delete() || elements.size() > 0) {
+ elements.clear();
+ groups.clear();
+ currentSession.removeAllChildren();
+ asyncRefresh(false);
+ resetDialogButtons();
+ }
+ }
+
+ public void fillContextMenu(IMenuManager manager) { // nothing
+ }
+
+ public AbstractEntry[] getElements() {
+ return (AbstractEntry[]) elements.toArray(new AbstractEntry[elements.size()]);
+ }
+
+ protected void handleClear() {
+ BusyIndicator.showWhile(fTree.getDisplay(), new Runnable() {
+ public void run() {
+ elements.clear();
+ groups.clear();
+ currentSession.removeAllChildren();
+ asyncRefresh(false);
+ resetDialogButtons();
+ }
+ });
+ }
+
+ protected void reloadLog() {
+ IRunnableWithProgress op = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ monitor.beginTask(Messages.LogView_operation_reloading, IProgressMonitor.UNKNOWN);
+ readLogFile();
+ }
+ };
+ ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell());
+ try {
+ pmd.run(true, true, op);
+ } catch (InvocationTargetException e) { // do nothing
+ } catch (InterruptedException e) { // do nothing
+ } finally {
+ fReadLogAction.setText(Messages.LogView_readLog_restore);
+ fReadLogAction.setToolTipText(Messages.LogView_readLog_restore);
+ asyncRefresh(false);
+ resetDialogButtons();
+ }
+ }
+
+ private void readLogFile() {
+ if (!fInputFile.exists())
+ return;
+
+ elements.clear();
+ groups.clear();
+
+ List<Object> result = new ArrayList<Object>();
+ currentSession = LogReader.parseLogFile(fInputFile, result, fMemento);
+ group(result);
+ limitEntriesCount();
+
+ getSite().getShell().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ setContentDescription(getTitleSummary());
+ }
+ });
+
+ }
+
+ private String getTitleSummary() {
+ String path = ""; //$NON-NLS-1$
+ try {
+ path = fInputFile.getCanonicalPath();
+ } catch (IOException e) { // log nothing
+ }
+
+ if (isPlatformLogOpen()) {
+ // Remove the content description in this case
+ // to save vertical space from the view.
+ //return Messages.LogView_WorkspaceLogFile;
+ return "";
+ }
+
+ Map<String, File> sources = LogFilesManager.getLogSources();
+ if (sources.containsValue(path)) {
+ for (Iterator<String> i = sources.keySet().iterator(); i.hasNext();) {
+ String key = i.next();
+ if (sources.get(key).equals(path)) {
+ return NLS.bind(Messages.LogView_LogFileTitle, new String[] {key, path});
+ }
+ }
+ }
+
+ return path;
+ }
+
+ /**
+ * Add new entries to correct groups in the view.
+ * @param entries new entries to show up in groups in the view.
+ */
+ private void group(List<?> entries) {
+ if (fMemento.getInteger(P_GROUP_BY).intValue() == GROUP_BY_NONE) {
+ elements.addAll(entries);
+ } else {
+ for (Iterator<?> i = entries.iterator(); i.hasNext();) {
+ LogEntry entry = (LogEntry) i.next();
+ Group group = getGroup(entry);
+ group.addChild(entry);
+ }
+ }
+ }
+
+ /**
+ * Limits the number of entries according to the max entries limit set in
+ * memento.
+ */
+ private void limitEntriesCount() {
+ int limit = Integer.MAX_VALUE;
+ if (fMemento.getString(LogView.P_USE_LIMIT).equals("true")) {//$NON-NLS-1$
+ limit = fMemento.getInteger(LogView.P_LOG_LIMIT).intValue();
+ }
+
+ int entriesCount = getEntriesCount();
+
+ if (entriesCount <= limit) {
+ return;
+ }
+ Comparator<Object> dateComparator = new Comparator<Object>() {
+ public int compare(Object o1, Object o2) {
+ Date l1 = ((LogEntry) o1).getDate();
+ Date l2 = ((LogEntry) o2).getDate();
+ if ((l1 != null) && (l2 != null)) {
+ return l1.before(l2) ? -1 : 1;
+ } else if ((l1 == null) && (l2 == null)) {
+ return 0;
+ } else
+ return (l1 == null) ? -1 : 1;
+ }
+ };
+
+ if (fMemento.getInteger(P_GROUP_BY).intValue() == GROUP_BY_NONE) {
+ elements.subList(0, elements.size() - limit).clear();
+ } else {
+ List<Object> copy = new ArrayList<Object>(entriesCount);
+ for (Iterator<?> i = elements.iterator(); i.hasNext();) {
+ AbstractEntry group = (AbstractEntry) i.next();
+ copy.addAll(Arrays.asList(group.getChildren(group)));
+ }
+
+ Collections.sort(copy, dateComparator);
+ List<?> toRemove = copy.subList(0, copy.size() - limit);
+
+ for (Iterator<?> i = elements.iterator(); i.hasNext();) {
+ AbstractEntry group = (AbstractEntry) i.next();
+ group.removeChildren(toRemove);
+ }
+ }
+
+ }
+
+ private int getEntriesCount() {
+ if (fMemento.getInteger(P_GROUP_BY).intValue() == GROUP_BY_NONE) {
+ return elements.size();
+ }
+ int size = 0;
+ for (Iterator<?> i = elements.iterator(); i.hasNext();) {
+ AbstractEntry group = (AbstractEntry) i.next();
+ size += group.size();
+ }
+ return size;
+ }
+
+ /**
+ * Returns group appropriate for the entry. Group depends on P_GROUP_BY
+ * preference, or is null if grouping is disabled (GROUP_BY_NONE), or group
+ * could not be determined. May create group if it haven't existed before.
+ *
+ * @param entry entry to be grouped
+ * @return group or null if grouping is disabled
+ */
+ protected Group getGroup(LogEntry entry) {
+ int groupBy = fMemento.getInteger(P_GROUP_BY).intValue();
+ Object elementGroupId = null;
+ String groupName = null;
+
+ switch (groupBy) {
+ case GROUP_BY_PLUGIN :
+ groupName = entry.getPluginId();
+ elementGroupId = groupName;
+ break;
+
+ case GROUP_BY_SESSION :
+ elementGroupId = entry.getSession();
+ break;
+
+ default : // grouping is disabled
+ return null;
+ }
+
+ if (elementGroupId == null) { // could not determine group
+ return null;
+ }
+
+ Group group = (Group) groups.get(elementGroupId);
+ if (group == null) {
+ if (groupBy == GROUP_BY_SESSION) {
+ group = entry.getSession();
+ } else {
+ group = new Group(groupName);
+ }
+ groups.put(elementGroupId, group);
+ elements.add(group);
+ }
+
+ return group;
+ }
+
+ public void logging(IStatus status, String plugin) {
+ if (!isPlatformLog(fInputFile))
+ return;
+
+ if (batchEntries) {
+ // create LogEntry immediately to don't loose IStatus creation date.
+ LogEntry entry = createLogEntry(status);
+ batchedEntries.add(entry);
+ return;
+ }
+
+ if (fFirstEvent) {
+ readLogFile();
+ asyncRefresh(true);
+ fFirstEvent = false;
+ } else {
+ LogEntry entry = createLogEntry(status);
+
+ if (!batchedEntries.isEmpty()) {
+ // batch new entry as well, to have only one asyncRefresh()
+ batchedEntries.add(entry);
+ pushBatchedEntries();
+ } else {
+ pushEntry(entry);
+ asyncRefresh(true);
+ }
+ }
+ }
+
+ /**
+ * Push batched entries to log view.
+ */
+ private void pushBatchedEntries() {
+ Job job = new Job(Messages.LogView_AddingBatchedEvents) {
+ protected IStatus run(IProgressMonitor monitor) {
+ for (int i = 0; i < batchedEntries.size(); i++) {
+ if (!monitor.isCanceled()) {
+ LogEntry entry = (LogEntry) batchedEntries.get(i);
+ pushEntry(entry);
+ batchedEntries.remove(i);
+ }
+ }
+ asyncRefresh(true);
+ return Status.OK_STATUS;
+ }
+ };
+ job.schedule();
+ }
+
+ private LogEntry createLogEntry(IStatus status) {
+ LogEntry entry = new LogEntry(status);
+ entry.setSession(currentSession);
+ return entry;
+ }
+
+ private synchronized void pushEntry(LogEntry entry) {
+ if (LogReader.isLogged(entry, fMemento)) {
+ group(Collections.singletonList(entry));
+ limitEntriesCount();
+ }
+ 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()) {
+ fFilteredTree.getViewer().refresh();
+ fFilteredTree.getViewer().expandToLevel(fMemento.getInteger(P_EXPAND_LEVEL).intValue());
+ fDeleteLogAction.setEnabled(fInputFile.exists() && isPlatformLog(fInputFile));
+ fOpenLogAction.setEnabled(fInputFile.exists());
+ fExportAction.setEnabled(fInputFile.exists());
+ if (activate && fActivateViewAction.isChecked()) {
+ IWorkbenchPage page = Activator.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ if (page != null)
+ page.bringToTop(view);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ public void setFocus() {
+ if (fFilteredTree != null && !fFilteredTree.isDisposed())
+ fFilteredTree.setFocus();
+ }
+
+ private void handleSelectionChanged(ISelection selection) {
+ updateStatus(selection);
+ fCopyAction.setEnabled((!selection.isEmpty()) && ((IStructuredSelection) selection).getFirstElement() instanceof LogEntry);
+ fPropertiesAction.setEnabled(!selection.isEmpty());
+ }
+
+ private void updateStatus(ISelection selection) {
+ IStatusLineManager status = getViewSite().getActionBars().getStatusLineManager();
+ if (selection.isEmpty())
+ status.setMessage(null);
+ else {
+ Object element = ((IStructuredSelection) selection).getFirstElement();
+ status.setMessage(((LogViewLabelProvider) fFilteredTree.getViewer().getLabelProvider()).getColumnText(element, 0));
+ }
+ }
+
+ /**
+ * Converts selected log view element to string.
+ * @return textual log entry representation or null if selection doesn't contain log entry
+ */
+ private static String selectionToString(ISelection selection) {
+ StringWriter writer = new StringWriter();
+ PrintWriter pwriter = new PrintWriter(writer);
+ if (selection.isEmpty())
+ return null;
+ LogEntry entry = (LogEntry) ((IStructuredSelection) selection).getFirstElement();
+ entry.write(pwriter);
+ pwriter.flush();
+ String textVersion = writer.toString();
+ try {
+ pwriter.close();
+ writer.close();
+ } catch (IOException e) {
+ // empty
+ }
+
+ return textVersion;
+ }
+
+ /**
+ * Copies selected element to clipboard.
+ */
+ private void copyToClipboard(ISelection selection) {
+ String textVersion = selectionToString(selection);
+ if ((textVersion != null) && (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());
+ }
+
+ private void initializeMemento() {
+ if (fMemento.getInteger(P_EXPAND_LEVEL) == null) {
+ fMemento.putInteger(P_EXPAND_LEVEL, DEFAULT_EXPAND_LEVEL);
+ }
+ 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_LOG_DEBUG) == null) {
+ fMemento.putString(P_LOG_DEBUG, "true"); //$NON-NLS-1$
+ }
+ if (fMemento.getString(P_SHOW_ALL_SESSIONS) == null) {
+ fMemento.putString(P_SHOW_ALL_SESSIONS, "false"); //$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, "false"); //$NON-NLS-1$
+ }
+ if (fMemento.getBoolean(P_SHOW_FILTER_TEXT) == null) {
+ fMemento.putBoolean(P_SHOW_FILTER_TEXT, false);
+ }
+ fMemento.putInteger(P_ORDER_VALUE, DESCENDING);
+ fMemento.putInteger(P_ORDER_TYPE, DATE);
+ if (fMemento.getInteger(P_GROUP_BY) == null) {
+ fMemento.putInteger(P_GROUP_BY, GROUP_BY_NONE);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ /**
+ * Adds drag source support to error log tree.
+ */
+ private void addDragSource() {
+ DragSource source = new DragSource(fTree, DND.DROP_COPY);
+ Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
+ source.setTransfer(types);
+
+ source.addDragListener(new DragSourceAdapter() {
+
+ public void dragStart(DragSourceEvent event) {
+ ISelection selection = fFilteredTree.getViewer().getSelection();
+ if (selection.isEmpty()) {
+ event.doit = false;
+ return;
+ }
+
+ AbstractEntry entry = (AbstractEntry) ((TreeSelection) selection).getFirstElement();
+ if (!(entry instanceof LogEntry)) {
+ event.doit = false;
+ return;
+ }
+ }
+
+ public void dragSetData(DragSourceEvent event) {
+ if (!TextTransfer.getInstance().isSupportedType(event.dataType)) {
+ return;
+ }
+
+ ISelection selection = fFilteredTree.getViewer().getSelection();
+ String textVersion = selectionToString(selection);
+ event.data = textVersion;
+ }
+ });
+ }
+
+ 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 || fTextShell == null || fTextShell.isDisposed())
+ return;
+ fCanOpenTextShell = false;
+ Point point = new Point(e.x, e.y);
+ TreeItem item = fTree.getItem(point);
+ if (item == null)
+ return;
+
+ String message = null;
+ if (item.getData() instanceof LogEntry) {
+ message = ((LogEntry) item.getData()).getStack();
+ } else if (item.getData() instanceof LogSession) {
+ LogSession session = ((LogSession) item.getData());
+ message = Messages.LogView_SessionStarted;
+ if (session.getDate() != null) {
+ DateFormat formatter = new SimpleDateFormat(LogEntry.F_DATE_FORMAT);
+ message += formatter.format(session.getDate());
+ }
+ }
+
+ 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();
+ Object data = item.getData();
+ if (data instanceof LogEntry) {
+ LogEntry entry = (LogEntry) data;
+ 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(AbstractEntry entry) {
+ AbstractEntry parent = (AbstractEntry) entry.getParent(entry);
+ if (parent == null)
+ return 0;
+ return 1 + getNumberOfParents(parent);
+ }
+
+ public Comparator<Object> getComparator() {
+ return fComparator;
+ }
+
+ private void setComparator(byte sortType) {
+ if (sortType == DATE) {
+ fComparator = new Comparator<Object>() {
+ public int compare(Object e1, Object e2) {
+ long date1 = 0;
+ long date2 = 0;
+ if ((e1 instanceof LogEntry) && (e2 instanceof LogEntry)) {
+ date1 = ((LogEntry) e1).getDate().getTime();
+ date2 = ((LogEntry) e2).getDate().getTime();
+ } else if ((e1 instanceof LogSession) && (e2 instanceof LogSession)) {
+ date1 = ((LogSession) e1).getDate() == null ? 0 : ((LogSession) e1).getDate().getTime();
+ date2 = ((LogSession) e2).getDate() == null ? 0 : ((LogSession) e2).getDate().getTime();
+ }
+ if (date1 == date2) {
+ int result = elements.indexOf(e2) - elements.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<Object>() {
+ public int compare(Object e1, Object e2) {
+ if ((e1 instanceof LogEntry) && (e2 instanceof LogEntry)) {
+ LogEntry entry1 = (LogEntry) e1;
+ LogEntry entry2 = (LogEntry) e2;
+ return getDefaultComparator().compare(entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER;
+ }
+ return 0;
+ }
+ };
+ } else {
+ fComparator = new Comparator<Object>() {
+ public int compare(Object e1, Object e2) {
+ if ((e1 instanceof LogEntry) && (e2 instanceof LogEntry)) {
+ LogEntry entry1 = (LogEntry) e1;
+ LogEntry entry2 = (LogEntry) e2;
+ return getDefaultComparator().compare(entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
+ }
+ return 0;
+ }
+ };
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Comparator<Object> getDefaultComparator() {
+ return Policy.getComparator();
+ }
+
+ private ViewerComparator getViewerComparator(byte sortType) {
+ if (sortType == PLUGIN) {
+ return new ViewerComparator() {
+ @SuppressWarnings("unchecked")
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ if ((e1 instanceof LogEntry) && (e2 instanceof LogEntry)) {
+ LogEntry entry1 = (LogEntry) e1;
+ LogEntry entry2 = (LogEntry) e2;
+ return getComparator().compare(entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER;
+ }
+ return 0;
+ }
+ };
+ } else if (sortType == MESSAGE) {
+ return new ViewerComparator() {
+ @SuppressWarnings("unchecked")
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ if ((e1 instanceof LogEntry) && (e2 instanceof LogEntry)) {
+ LogEntry entry1 = (LogEntry) e1;
+ LogEntry entry2 = (LogEntry) e2;
+ return getComparator().compare(entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
+ }
+ return 0;
+ }
+ };
+ } else {
+ return new ViewerComparator() {
+ private int indexOf(Object[] array, Object o) {
+ if (o == null)
+ return -1;
+ for (int i = 0; i < array.length; ++i)
+ if (o.equals(array[i]))
+ return i;
+ return -1;
+ }
+
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ long date1 = 0;
+ long date2 = 0;
+ if ((e1 instanceof LogEntry) && (e2 instanceof LogEntry)) {
+ date1 = ((LogEntry) e1).getDate().getTime();
+ date2 = ((LogEntry) e2).getDate().getTime();
+ } else if ((e1 instanceof LogSession) && (e2 instanceof LogSession)) {
+ date1 = ((LogSession) e1).getDate() == null ? 0 : ((LogSession) e1).getDate().getTime();
+ date2 = ((LogSession) e2).getDate() == null ? 0 : ((LogSession) e2).getDate().getTime();
+ }
+
+ if (date1 == date2) {
+ // Everything that appears in logview should be an AbstractEntry.
+ AbstractEntry parent = (AbstractEntry) ((AbstractEntry) e1).getParent(null);
+ Object[] children = null;
+ if (parent != null)
+ children = parent.getChildren(parent);
+
+ int result = 0;
+ if (children != null) {
+ // The elements in children seem to be in reverse order,
+ // i.e. latest log message first, therefore index(e2)-index(e1)
+ result = indexOf(children, e2) - indexOf(children, e1);
+ } else {
+ result = elements.indexOf(e1) - elements.indexOf(e2);
+ }
+ 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 = Activator.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 Activator.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_LOG_DEBUG, s.getBoolean(P_LOG_DEBUG) ? "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));
+ fMemento.putBoolean(P_SHOW_FILTER_TEXT, p.getBoolean(P_SHOW_FILTER_TEXT));
+ fMemento.putInteger(P_GROUP_BY, p.getInt(P_GROUP_BY));
+ fMemento.putInteger(P_EXPAND_LEVEL, s.getInt(P_EXPAND_LEVEL));
+ } catch (NumberFormatException e) {
+ fMemento.putInteger(P_EXPAND_LEVEL, DEFAULT_EXPAND_LEVEL);
+ 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);
+ fMemento.putInteger(P_GROUP_BY, GROUP_BY_NONE);
+ }
+ }
+
+ private void writeSettings() {
+ writeViewSettings();
+ writeFilterSettings();
+ }
+
+ private void writeFilterSettings() {
+ IDialogSettings settings = getLogSettings();
+ if (settings == null)
+ settings = Activator.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_LOG_DEBUG, fMemento.getString(P_LOG_DEBUG).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());
+ preferences.setValue(P_SHOW_FILTER_TEXT, fMemento.getBoolean(P_SHOW_FILTER_TEXT).booleanValue());
+ preferences.setValue(P_GROUP_BY, fMemento.getInteger(P_GROUP_BY).intValue());
+ preferences.setValue(P_EXPAND_LEVEL, fMemento.getInteger(P_EXPAND_LEVEL).intValue());
+ }
+
+ public void sortByDateDescending() {
+ setColumnSorting(fColumn3, DESCENDING);
+ }
+
+ protected Job getOpenLogFileJob() {
+ final Shell shell = getViewSite().getShell();
+ return new Job(Messages.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;
+ }
+
+ /**
+ * Returns whether given session equals to currently displayed in LogView.
+ * @param session LogSession
+ * @return true if given session equals to currently displayed in LogView
+ */
+ public boolean isCurrentLogSession(LogSession session) {
+ return isPlatformLogOpen() && (currentSession != null) && (currentSession.equals(session));
+ }
+
+ /**
+ * Returns whether currently open log is platform log or imported file.
+ * @return true if currently open log is platform log, false otherwise
+ */
+ public boolean isPlatformLogOpen() {
+ return isPlatformLog(fInputFile);
+ }
+
+ /**
+ * Returns whether currently open log is platform log or imported file.
+ * @return true if currently open log is platform log, false otherwise
+ */
+ public boolean isPlatformLog(File file) {
+ return (file.equals(getPlatformLogFile()));
+ }
+
+ public File getPlatformLogFile() {
+ return org.simantics.message.internal.Activator.getLogFile();
+ }
+}