From ceac9d1f90d4a435247a402ce7e551b90a2ab9f7 Mon Sep 17 00:00:00 2001 From: cperkonig Date: Tue, 4 Oct 2005 11:01:58 +0000 Subject: [PATCH] Initial implementation of the new Debug Plugin --- .../phpeclipse/xdebug/ui/EnvironmentVariable.java | 76 ++ .../phpeclipse/xdebug/ui/MultipleInputDialog.java | 362 +++++++ .../xdebug/ui/XDebugUIMessages.properties | 50 + .../phpeclipse/xdebug/ui/XDebugUIPlugin.java | 150 +++ .../phpeclipse/xdebug/ui/XDebugUIPluginImages.java | 162 ++++ .../ui/actions/BreakpointRulerActionDelegate.java | 20 + .../ui/actions/ToggleBreakpointRulerAction.java | 123 +++ .../php/launching/PHPDebugModelPresentation.java | 121 +++ .../xdebug/ui/php/launching/PHPEnvironmentTab.java | 841 +++++++++++++++++ .../xdebug/ui/php/launching/PHPMainTab.java | 323 +++++++ .../xdebug/ui/php/launching/PHPTabGroup.java | 20 + .../ui/php/model/PHPBreakpointAdapterFactory.java | 19 + .../ui/php/model/PHPLineBreakpointAdapter.java | 73 ++ .../xdebug/ui/preference/XDebugPreferencePage.java | 52 + .../ui/views/logview/EventDetailsDialog.java | 630 +++++++++++++ .../ui/views/logview/EventDetailsDialogAction.java | 94 ++ .../xdebug/ui/views/logview/FilterDialog.java | 164 ++++ .../xdebug/ui/views/logview/LogEntry.java | 237 +++++ .../xdebug/ui/views/logview/LogReader.java | 308 ++++++ .../xdebug/ui/views/logview/LogSession.java | 60 ++ .../xdebug/ui/views/logview/LogView.java | 993 ++++++++++++++++++++ .../ui/views/logview/LogViewContentProvider.java | 43 + .../ui/views/logview/LogViewLabelProvider.java | 68 ++ .../xdebug/ui/views/logview/OpenLogDialog.java | 269 ++++++ 24 files changed, 5258 insertions(+), 0 deletions(-) create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/EnvironmentVariable.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/MultipleInputDialog.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIMessages.properties create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIPlugin.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIPluginImages.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/actions/BreakpointRulerActionDelegate.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/actions/ToggleBreakpointRulerAction.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPDebugModelPresentation.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPEnvironmentTab.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPMainTab.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPTabGroup.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/model/PHPBreakpointAdapterFactory.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/model/PHPLineBreakpointAdapter.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/preference/XDebugPreferencePage.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialog.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialogAction.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/FilterDialog.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogEntry.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogReader.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogSession.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogView.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewContentProvider.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewLabelProvider.java create mode 100644 net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/OpenLogDialog.java diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/EnvironmentVariable.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/EnvironmentVariable.java new file mode 100644 index 0000000..f615429 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/EnvironmentVariable.java @@ -0,0 +1,76 @@ +package net.sourceforge.phpeclipse.xdebug.ui; + +/** + * A key/value set whose data is passed into Runtime.exec(...) + */ +public class EnvironmentVariable +{ + // The name of the environment variable + private String name; + + // The value of the environment variable + private String value; + + public EnvironmentVariable(String name, String value) + { + this.name = name; + this.value = value; + } + + /** + * Returns this variable's name, which serves as the key in the key/value + * pair this variable represents + * + * @return this variable's name + */ + public String getName() + { + return name; + } + + /** + * Returns this variables value. + * + * @return this variable's value + */ + public String getValue() + { + return value; + } + + /** + * Sets this variable's value + * @param value + */ + public void setValue(String value) + { + this.value = value; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return getName(); + } + + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + boolean equal = false; + if (obj instanceof EnvironmentVariable) { + EnvironmentVariable var = (EnvironmentVariable)obj; + equal = var.getName().equals(name); + } + return equal; + } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return name.hashCode(); + } +} + diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/MultipleInputDialog.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/MultipleInputDialog.java new file mode 100644 index 0000000..3af109a --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/MultipleInputDialog.java @@ -0,0 +1,362 @@ +package net.sourceforge.phpeclipse.xdebug.ui; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.StringVariableSelectionDialog; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class MultipleInputDialog extends Dialog { + protected static final String FIELD_NAME = "FIELD_NAME"; //$NON-NLS-1$ + protected static final int TEXT = 100; + protected static final int BROWSE = 101; + protected static final int VARIABLE = 102; + + protected Composite panel; + + protected List fieldList = new ArrayList(); + protected List controlList = new ArrayList(); + protected List validators = new ArrayList(); + protected Map valueMap = new HashMap(); + + private String title; + + + + public MultipleInputDialog(Shell shell, String title) { + super(shell); + this.title = title; + setShellStyle(getShellStyle() | SWT.RESIZE); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) + */ + protected void configureShell(Shell shell) { + super.configureShell(shell); + if (title != null) { + shell.setText(title); + } + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createButtonBar(org.eclipse.swt.widgets.Composite) + */ + protected Control createButtonBar(Composite parent) { + Control bar = super.createButtonBar(parent); + validateFields(); + return bar; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Control createDialogArea(Composite parent) { + Composite container = (Composite)super.createDialogArea(parent); + container.setLayout(new GridLayout(2, false)); + container.setLayoutData(new GridData(GridData.FILL_BOTH)); + + panel = new Composite(container, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + panel.setLayout(layout); + panel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + for (Iterator i = fieldList.iterator(); i.hasNext();) { + FieldSummary field = (FieldSummary)i.next(); + switch(field.type) { + case TEXT: + createTextField(field.name, field.initialValue, field.allowsEmpty); + break; + case BROWSE: + createBrowseField(field.name, field.initialValue, field.allowsEmpty); + break; + case VARIABLE: + createVariablesField(field.name, field.initialValue, field.allowsEmpty); + break; + } + } + + fieldList = null; // allow it to be gc'd + Dialog.applyDialogFont(container); + return container; + } + + public void addBrowseField(String labelText, String initialValue, boolean allowsEmpty) { + fieldList.add(new FieldSummary(BROWSE, labelText, initialValue, allowsEmpty)); + } + public void addTextField(String labelText, String initialValue, boolean allowsEmpty) { + fieldList.add(new FieldSummary(TEXT, labelText, initialValue, allowsEmpty)); + } + public void addVariablesField(String labelText, String initialValue, boolean allowsEmpty) { + fieldList.add(new FieldSummary(VARIABLE, labelText, initialValue, allowsEmpty)); + } + + protected void createTextField(String labelText, String initialValue, boolean allowEmpty) { + Label label = new Label(panel, SWT.NONE); + label.setText(labelText); + label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); + + final Text text = new Text(panel, SWT.SINGLE | SWT.BORDER); + text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + text.setData(FIELD_NAME, labelText); + + // make sure rows are the same height on both panels. + label.setSize(label.getSize().x, text.getSize().y); + + if (initialValue != null) { + text.setText(initialValue); + } + + if (!allowEmpty) { + validators.add(new Validator() { + public boolean validate() { + return !text.getText().equals(""); //$NON-NLS-1$ + } + }); + text.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validateFields(); + } + }); + } + + controlList.add(text); + } + + protected void createBrowseField(String labelText, String initialValue, boolean allowEmpty) { + Label label = new Label(panel, SWT.NONE); + label.setText(labelText); + label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); + + Composite comp = new Composite(panel, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight=0; + layout.marginWidth=0; + comp.setLayout(layout); + comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + final Text text = new Text(comp, SWT.SINGLE | SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = 200; + text.setLayoutData(data); + text.setData(FIELD_NAME, labelText); + + // make sure rows are the same height on both panels. + label.setSize(label.getSize().x, text.getSize().y); + + if (initialValue != null) { + text.setText(initialValue); + } + + if (!allowEmpty) { + validators.add(new Validator() { + public boolean validate() { + return !text.getText().equals(""); //$NON-NLS-1$ + } + }); + + text.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validateFields(); + } + }); + } + + Button button = createButton(comp, IDialogConstants.IGNORE_ID, "&Browse...", false); + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + DirectoryDialog dialog = new DirectoryDialog(getShell()); + dialog.setMessage("Select a file:"); + String currentWorkingDir = text.getText(); + if (!currentWorkingDir.trim().equals("")) { //$NON-NLS-1$ + File path = new File(currentWorkingDir); + if (path.exists()) { + dialog.setFilterPath(currentWorkingDir); + } + } + + String selectedDirectory = dialog.open(); + if (selectedDirectory != null) { + text.setText(selectedDirectory); + } + } + }); + + controlList.add(text); + + } + + + public void createVariablesField(String labelText, String initialValue, boolean allowEmpty) { + Label label = new Label(panel, SWT.NONE); + label.setText(labelText); + label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); + + Composite comp = new Composite(panel, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight=0; + layout.marginWidth=0; + comp.setLayout(layout); + comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + final Text text = new Text(comp, SWT.SINGLE | SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = 200; + text.setLayoutData(data); + text.setData(FIELD_NAME, labelText); + + // make sure rows are the same height on both panels. + label.setSize(label.getSize().x, text.getSize().y); + + if (initialValue != null) { + text.setText(initialValue); + } + + if (!allowEmpty) { + validators.add(new Validator() { + public boolean validate() { + return !text.getText().equals(""); //$NON-NLS-1$ + } + }); + + text.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validateFields(); + } + }); + } + + Button button = createButton(comp, IDialogConstants.IGNORE_ID, "Varia&bles...", false); + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell()); + int code = dialog.open(); + if (code == IDialogConstants.OK_ID) { + String variable = dialog.getVariableExpression(); + if (variable != null) { + text.insert(variable); + } + } + } + }); + + controlList.add(text); + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#okPressed() + */ + protected void okPressed() { + for (Iterator i = controlList.iterator(); i.hasNext(); ) { + Control control = (Control)i.next(); + if (control instanceof Text) { + valueMap.put(control.getData(FIELD_NAME), ((Text)control).getText()); + } + } + controlList = null; + super.okPressed(); + } + + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#open() + */ + public int open() { + applyDialogFont(panel); + return super.open(); + } + + public Object getValue(String key) { + return valueMap.get(key); + } + + public String getStringValue(String key) { + return (String) getValue(key); + } + + public void validateFields() { + for(Iterator i = validators.iterator(); i.hasNext(); ) { + Validator validator = (Validator) i.next(); + if (!validator.validate()) { + getButton(IDialogConstants.OK_ID).setEnabled(false); + return; + } + } + getButton(IDialogConstants.OK_ID).setEnabled(true); + } + +// /* (non-Javadoc) +// * @see org.eclipse.jface.window.Window#getInitialLocation(org.eclipse.swt.graphics.Point) +// */ +// protected Point getInitialLocation(Point initialSize) { +// Point initialLocation= DialogSettingsHelper.getInitialLocation(getDialogSettingsSectionName()); +// if (initialLocation != null) { +// return initialLocation; +// } +// return super.getInitialLocation(initialSize); +// } + + + protected String getDialogSettingsSectionName() { + return IDebugUIConstants.PLUGIN_ID + ".MULTIPLE_INPUT_DIALOG_2"; //$NON-NLS-1$ + } + +// /* (non-Javadoc) +// * @see org.eclipse.jface.window.Window#getInitialSize() +// */ +// protected Point getInitialSize() { +// Point size = super.getInitialSize(); +// return DialogSettingsHelper.getInitialSize(getDialogSettingsSectionName(), size); +// } + +// /* (non-Javadoc) +// * @see org.eclipse.jface.window.Window#close() +// */ +// public boolean close() { +// DialogSettingsHelper.persistShellGeometry(getShell(), getDialogSettingsSectionName()); +// return super.close(); +// } + + protected class FieldSummary { + int type; + String name; + String initialValue; + boolean allowsEmpty; + + public FieldSummary(int type, String name, String initialValue, boolean allowsEmpty) { + this.type = type; + this.name = name; + this.initialValue = initialValue; + this.allowsEmpty = allowsEmpty; + } + } + + protected class Validator { + boolean validate() { + return true; + } + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIMessages.properties b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIMessages.properties new file mode 100644 index 0000000..711cbbd --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIMessages.properties @@ -0,0 +1,50 @@ +LogView.column.severity = ! +LogView.column.message = Message +LogView.column.plugin = Plug-in +LogView.column.date = Date +LogView.clear = C&lear log viewer +LogView.clear.tooltip = Clear log viewer +LogView.copy = &Copy +LogView.delete = &Delete log +LogView.delete.tooltip = Delete log +LogView.export = &Export log... +LogView.export.tooltip = Export log +LogView.import = &Import log... +LogView.import.tooltip = Import log +LogView.filter = &Filters... +LogView.readLog.reload = Re&load this workspace's log +LogView.readLog.restore = &Restore log +LogView.readLog.restore.tooltip = Restore log +LogView.severity.error = Error +LogView.severity.warning = Warning +LogView.severity.info = Info +LogView.confirmDelete.title = Confirm Delete +LogView.confirmDelete.message = Are you sure you want to permanently delete all logged events? +LogView.confirmOverwrite.message = File " {0}" exists. Would you like to overwrite it? +LogView.operation.importing = Importing log... +LogView.operation.reloading = Reloading... +LogView.activate = &Activate on new events +LogView.view.currentLog = &Open log +LogView.view.currentLog.tooltip = Open log + +LogView.FilterDialog.title = Log Filters +LogView.FilterDialog.eventTypes = Event Types +LogView.FilterDialog.information = &Information +LogView.FilterDialog.warning = &Warning +LogView.FilterDialog.error = &Error +LogView.FilterDialog.limitTo = &Limit visible events to: +LogView.FilterDialog.eventsLogged = Show events logged during: +LogView.FilterDialog.allSessions = &All sessions +LogView.FilterDialog.recentSession = &Most recent session + +EventDetailsDialog.title= Event Details +EventDetailsDialog.date=Date: +EventDetailsDialog.severity=Severity: +EventDetailsDialog.message=Message: +EventDetailsDialog.exception=Exception Stack Trace: +EventDetailsDialog.session=Session Data: +EventDetailsDialog.noStack = An exception stack trace could not be found. +EventDetailsDialog.previous=View details of previous event +EventDetailsDialog.next=View details of next event +EventDetailsDialog.copy=Copy event details to clipboard + diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIPlugin.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIPlugin.java new file mode 100644 index 0000000..03dc4a5 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIPlugin.java @@ -0,0 +1,150 @@ +package net.sourceforge.phpeclipse.xdebug.ui; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.plugin.*; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class XDebugUIPlugin extends AbstractUIPlugin { + + private static final String BUNDLE_NAME = "net.sourceforge.phpeclipse.xdebug.ui.XDebugUIMessages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private static final String PLUGIN_ID ="net.sourceforge.phpeclipse.xdebug.ui"; + + + //The shared instance. + private static XDebugUIPlugin plugin; + + /** + * The constructor. + */ + public XDebugUIPlugin() { + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + */ + public static XDebugUIPlugin getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path. + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin("net.sourceforge.phpeclipse.xdebug.ui", path); + } + + /** + * Convenience method which returns the unique identifier of this plugin. + */ + public static String getUniqueIdentifier() { + return PLUGIN_ID; + } + + /** + * Utility method with conventions + */ + public static void errorDialog(Shell shell, String title, String message, IStatus s) { + // if the 'message' resource string and the IStatus' message are the same, + // don't show both in the dialog + if (s != null && message.equals(s.getMessage())) { + message= null; + } + ErrorDialog.openError(shell, title, message, s); + } + + + /** + * Utility method with conventions + */ + public static void errorDialog(Shell shell, String title, String message, Throwable t) { + IStatus status; + if (t instanceof CoreException) { + status= ((CoreException)t).getStatus(); + // if the 'message' resource string and the IStatus' message are the same, + // don't show both in the dialog + if (status != null && message.equals(status.getMessage())) { + message= null; + } + } else { + status= new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, "Error within Debug UI: ", t); //$NON-NLS-1$ + log(status); + } + ErrorDialog.openError(shell, title, message, status); + } + + /** + * Logs the specified status with this plug-in's log. + * + * @param status status to log + */ + public static void log(IStatus status) { + getDefault().getLog().log(status); + } + + /** + * Logs an internal error with the specified throwable + * + * @param e the exception to be logged + */ + public static void log(Throwable e) { + log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, "Internal Error", e)); + } + + /** + * Returns the standard display to be used. The method first checks, if + * the thread calling this method has an associated display. If so, this + * display is returned. Otherwise the method returns the default display. + */ + public static Display getStandardDisplay() { + Display display; + display= Display.getCurrent(); + if (display == null) + display= Display.getDefault(); + return display; + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIPluginImages.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIPluginImages.java new file mode 100644 index 0000000..69e49cc --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/XDebugUIPluginImages.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.ui; + + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; + +public class XDebugUIPluginImages { + + + /* Declare Common paths */ + private static URL ICON_BASE_URL= null; + + static { + String pathSuffix = "icons/"; //$NON-NLS-1$ + ICON_BASE_URL= XDebugUIPlugin.getDefault().getBundle().getEntry(pathSuffix); + } + + // The plugin registry + private static ImageRegistry fgImageRegistry = null; + + /* + * Set of predefined Image Descriptors. + */ + private static final String T_OBJ= "obj16/"; //$NON-NLS-1$ +// private static final String T_OVR= "ovr16/"; //$NON-NLS-1$ + private static final String T_EVIEW= "eview16/"; //$NON-NLS-1$ + private static final String T_LCL="elcl16/"; + + public static final String IMG_EVIEW_ARGUMENTS_TAB = "IMG_EVIEW_ARGUMENTS_TAB"; + public static final String IMG_EVIEW_ENVIROMENT_TAB = "IMG_EVIEW_ENVIROMENT_TAB"; + + + public static final String IMG_PREV_EVENT="IMG_PREV_EVENT"; + public static final String DESC_NEXT_EVENT="DESC_NEXT_EVENT"; + public static final String IMG_ERROR_ST_OBJ="IMG_ERROR_ST_OBJ"; + public static final String IMG_WARNING_ST_OBJ="IMG_WARNING_ST_OBJ"; + public static final String IMG_INFO_ST_OBJ="IMG_INFO_ST_OBJ"; + public static final String IMG_ERROR_STACK_OBJ="IMG_ERROR_STACK_OBJ"; + + + public static final String IMG_PROPERTIES = "IMG_PROPERTIES"; +// public static final String IMG_PROPERTIES_DISABLED = "IMG_PROPERTIES_DISABLED"; + public static final String IMG_CLEAR = "IMG_CLEAR"; +// public static final String IMG_CLEAR_DISABLED = "IMG_CLEAR_DISABLED"; + public static final String IMG_READ_LOG = "IMG_READ_LOG"; +// public static final String IMG_READ_LOG_DISABLED = "IMG_READ_LOG_DISABLED"; + public static final String IMG_REMOVE_LOG = "IMG_REMOVE_LOG"; +// public static final String IMG_REMOVE_LOG_DISABLED = "IMG_REMOVE_LOG_DISABLED"; + public static final String IMG_FILTER = "IMG_FILTER"; +// public static final String IMG_FILTER_DISABLED = "IMG_FILTER_DISABLED"; + public static final String IMG_EXPORT = "IMG_EXPORT"; +// public static final String IMG_EXPORT_DISABLED = "IMG_EXPORT_DISABLED"; + public static final String IMG_IMPORT = "IMG_IMPORT"; +// public static final String IMG_IMPORT_DISABLED = "IMG_IMPORT_DISABLED"; + public static final String IMG_OPEN_LOG = "IMG_OPEN_LOG"; + + + + + + /** + * Returns the image managed under the given key in this registry. + * + * @param key the image's key + * @return the image managed under the given key + */ + public static Image get(String key) { + return getImageRegistry().get(key); + } + + /** + * Returns the ImageDescriptor identified by the given key, + * or null if it does not exist. + */ + public static ImageDescriptor getImageDescriptor(String key) { + return getImageRegistry().getDescriptor(key); + } + + /* + * Helper method to access the image registry from the XDebugUIPlugin class. + */ + public static ImageRegistry getImageRegistry() { + if (fgImageRegistry == null) { + initializeImageRegistry(); + } + return fgImageRegistry; + } + + public static void initializeImageRegistry() { + fgImageRegistry= new ImageRegistry(XDebugUIPlugin.getStandardDisplay()); + declareImages(); + } + + private static void declareImages() { + declareRegistryImage(IMG_EVIEW_ARGUMENTS_TAB, T_EVIEW + "arguments_tab.gif"); //$NON-NLS-1$ + declareRegistryImage(IMG_EVIEW_ENVIROMENT_TAB, T_EVIEW + "environment_tab.gif"); //$NON-NLS-1$ + + declareRegistryImage(IMG_ERROR_ST_OBJ,T_OBJ+"error_st_obj.gif"); + declareRegistryImage(IMG_WARNING_ST_OBJ,T_OBJ + "warning_st_obj.gif"); + declareRegistryImage(IMG_INFO_ST_OBJ,T_OBJ +"info_st_obj.gif"); + declareRegistryImage(IMG_ERROR_STACK_OBJ,T_OBJ +"error_stack.gif"); + + declareRegistryImage(IMG_PROPERTIES,T_LCL + "properties.gif"); +// declareRegistryImage(IMG_PROPERTIES_DISABLED + declareRegistryImage(IMG_CLEAR,T_LCL + "clear_log.gif"); +// declareRegistryImage(IMG_CLEAR_DISABLED + declareRegistryImage(IMG_READ_LOG ,T_LCL + "restore_log.gif"); +// declareRegistryImage(IMG_READ_LOG_DISABLED + declareRegistryImage(IMG_REMOVE_LOG,T_LCL + "remove_log.gif"); +// declareRegistryImage(IMG_REMOVE_LOG_DISABLED + declareRegistryImage(IMG_FILTER,T_LCL + "filter_log.gif"); +// declareRegistryImage(IMG_FILTER_DISABLED + declareRegistryImage(IMG_EXPORT,T_LCL + "export_log.gif"); +// declareRegistryImage(IMG_EXPORT_DISABLED + declareRegistryImage(IMG_IMPORT,T_LCL + "import_log.gif"); +// declareRegistryImage(IMG_IMPORT_DISABLED + declareRegistryImage(IMG_OPEN_LOG,T_LCL + "open_log.gif"); + + } + + /** + * Declare an Image in the registry table. + * @param key The key to use when registering the image + * @param path The path where the image can be found. This path is relative to where + * this plugin class is found (i.e. typically the packages directory) + */ + private final static void declareRegistryImage(String key, String path) { + ImageDescriptor desc= ImageDescriptor.getMissingImageDescriptor(); + try { + desc= ImageDescriptor.createFromURL(makeIconFileURL(path)); + } catch (MalformedURLException me) { + XDebugUIPlugin.log(me); + } + fgImageRegistry.put(key, desc); + } + + private static URL makeIconFileURL(String iconPath) throws MalformedURLException { + if (ICON_BASE_URL == null) { + throw new MalformedURLException(); + } + + return new URL(ICON_BASE_URL, iconPath); + } + + + + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/actions/BreakpointRulerActionDelegate.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/actions/BreakpointRulerActionDelegate.java new file mode 100644 index 0000000..5f906be --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/actions/BreakpointRulerActionDelegate.java @@ -0,0 +1,20 @@ +package net.sourceforge.phpeclipse.xdebug.ui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.ui.texteditor.AbstractRulerActionDelegate; +import org.eclipse.ui.texteditor.ITextEditor; + + + +public class BreakpointRulerActionDelegate extends AbstractRulerActionDelegate { + + private ToggleBreakpointRulerAction fTargetAction; + + protected IAction createAction(ITextEditor editor, + IVerticalRulerInfo rulerInfo) { + fTargetAction = new ToggleBreakpointRulerAction( editor, rulerInfo ); + return fTargetAction; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/actions/ToggleBreakpointRulerAction.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/actions/ToggleBreakpointRulerAction.java new file mode 100644 index 0000000..d6a03d2 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/actions/ToggleBreakpointRulerAction.java @@ -0,0 +1,123 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpeclipse.xdebug.ui.actions; + +import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin; +import net.sourceforge.phpeclipse.xdebug.ui.php.model.PHPLineBreakpointAdapter; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + +public class ToggleBreakpointRulerAction extends Action { + + static class EmptySelection implements ISelection { + + public boolean isEmpty() { + return true; + } + } + + private IVerticalRulerInfo fRuler; + private IWorkbenchPart fTargetPart; + private PHPLineBreakpointAdapter fBreakpointAdapter; + private static final ISelection EMPTY_SELECTION = new EmptySelection(); + + public ToggleBreakpointRulerAction( IWorkbenchPart part, IVerticalRulerInfo ruler ) { + super( "Toggle Breakpoint" ); //$NON-NLS-1$ + + fRuler= ruler; + fRuler = ruler; + setTargetPart( part ); + fBreakpointAdapter = new PHPLineBreakpointAdapter(); +// part.getSite().getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp( this, ICDebugHelpContextIds.TOGGLE_BREAKPOINT_ACTION ); +// setId( IInternalCDebugUIConstants.ACTION_TOGGLE_BREAKPOINT ); + } + + + /** + * @see Action#run() + */ + public void run() { + try { + fBreakpointAdapter.toggleLineBreakpoints( getTargetPart(), getTargetSelection() ); + } + catch( CoreException e ) { + XDebugUIPlugin.errorDialog( getTargetPart().getSite().getShell(),"Error", "Operation failed" , e.getStatus() ); + } + } + + /** + * Returns this action's vertical ruler info. + * + * @return this action's vertical ruler + */ + protected IVerticalRulerInfo getVerticalRulerInfo() { + return fRuler; + } + + private IWorkbenchPart getTargetPart() { + return this.fTargetPart; + } + + private void setTargetPart( IWorkbenchPart targetPart ) { + this.fTargetPart = targetPart; + } + + /** + * Returns the current selection in the active part, possibly + * and empty selection, but never null. + * + * @return the selection in the active part, possibly empty + */ + private ISelection getTargetSelection() { + IDocument doc = getDocument(); + if ( doc != null ) { + int line = getVerticalRulerInfo().getLineOfLastMouseButtonActivity(); + try { + IRegion region = doc.getLineInformation( line ); + return new TextSelection( doc, region.getOffset(), region.getLength() ); + } + catch( BadLocationException e ) { + DebugPlugin.log( e ); + } + } + return EMPTY_SELECTION; + } + + private IDocument getDocument() { + IWorkbenchPart targetPart = getTargetPart(); + if ( targetPart instanceof ITextEditor ) { + ITextEditor textEditor = (ITextEditor)targetPart; + IDocumentProvider provider = textEditor.getDocumentProvider(); + if ( provider != null ) + return provider.getDocument( textEditor.getEditorInput() ); + } +// else if ( targetPart instanceof DisassemblyView ) { +// DisassemblyView dv = (DisassemblyView)targetPart; +// IDocumentProvider provider = dv.getDocumentProvider(); +// if ( provider != null ) +// return provider.getDocument( dv.getInput() ); +// } + return null; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPDebugModelPresentation.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPDebugModelPresentation.java new file mode 100644 index 0000000..858937f --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPDebugModelPresentation.java @@ -0,0 +1,121 @@ +package net.sourceforge.phpeclipse.xdebug.ui.php.launching; + + + +import net.sourceforge.phpeclipse.xdebug.php.model.XDebugLineBreakpoint; +import net.sourceforge.phpeclipse.xdebug.php.model.XDebugStackFrame; +import net.sourceforge.phpeclipse.xdebug.php.model.XDebugTarget; +import net.sourceforge.phpeclipse.xdebug.php.model.XDebugThread; +import net.sourceforge.phpeclipse.xdebug.php.model.XDebugValue; +import net.sourceforge.phpeclipse.xdebug.php.model.XDebugVariable; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.debug.core.model.ILineBreakpoint; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugModelPresentation; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.IValueDetailListener; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorRegistry; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; + +public class PHPDebugModelPresentation implements IDebugModelPresentation { + + public void setAttribute(String attribute, Object value) { + // TODO Auto-generated method stub + + } + + /** + * @see IDebugModelPresentation#getImage(Object) + */ + public Image getImage(Object element) { + if (element instanceof XDebugLineBreakpoint) { + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_BREAKPOINT); + } else if (element instanceof IMarker) { + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_BREAKPOINT); + } else if (element instanceof XDebugStackFrame || element instanceof XDebugThread || element instanceof XDebugTarget) { + return null; + } else if (element instanceof XDebugVariable) { + return getVariableImage((XDebugVariable)element); + } else if (element instanceof XDebugValue) { + return getValueImage((XDebugValue)element); + } + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_BREAKPOINT); + } + private Image getVariableImage(XDebugVariable phpVar) { + /* if (phpVar != null) { + if (phpVar.isLocal()) + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_VARIABLE); + if (phpVar.isHashValue()) + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_VARIABLE); + } + */ + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_VARIABLE); + } + + private Image getValueImage(XDebugValue phpVar) { + if (phpVar != null) { + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_VARIABLE); + } + return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_VARIABLE); + } + + + public String getText(Object element) { + // TODO Auto-generated method stub + return null; + } + + public void computeDetail(IValue value, IValueDetailListener listener) { + // TODO Auto-generated method stub + + } + + public void addListener(ILabelProviderListener listener) { + // TODO Auto-generated method stub + + } + + public void dispose() { + // TODO Auto-generated method stub + + } + + public boolean isLabelProperty(Object element, String property) { + // TODO Auto-generated method stub + return false; + } + + public void removeListener(ILabelProviderListener listener) { + // TODO Auto-generated method stub + + } + + public IEditorInput getEditorInput(Object element) { + + if (element instanceof IFile) { + return new FileEditorInput((IFile)element); + } + if (element instanceof ILineBreakpoint) { + return new FileEditorInput((IFile)((ILineBreakpoint)element).getMarker().getResource()); + } + return null; + } + + public String getEditorId(IEditorInput input, Object element) { + IEditorRegistry registry= PlatformUI.getWorkbench().getEditorRegistry(); + IEditorDescriptor descriptor= registry.getDefaultEditor(input.getName()); + if (descriptor != null) + return descriptor.getId(); + + return null; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPEnvironmentTab.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPEnvironmentTab.java new file mode 100644 index 0000000..9133de0 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPEnvironmentTab.java @@ -0,0 +1,841 @@ +/* + * Created on 14.07.2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package net.sourceforge.phpeclipse.xdebug.ui.php.launching; + +import java.text.MessageFormat; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; +import net.sourceforge.phpeclipse.xdebug.ui.EnvironmentVariable; +import net.sourceforge.phpeclipse.xdebug.ui.MultipleInputDialog; +import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPluginImages; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ColumnLayoutData; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableLayout; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.dialogs.ListSelectionDialog; + +/** + * @author Christian + * + * TODO To change the template for this generated type comment go to Window - + * Preferences - Java - Code Style - Code Templates + */ +public class PHPEnvironmentTab extends AbstractLaunchConfigurationTab { + + protected TableViewer environmentTable; + + protected String[] envTableColumnHeaders = { "Variable", "Value" }; + + protected ColumnLayoutData[] envTableColumnLayouts = { + new ColumnWeightData(50), new ColumnWeightData(50) }; + + private static final String NAME_LABEL = "Name"; + + private static final String VALUE_LABEL = "Value"; + + protected static final String P_VARIABLE = "variable"; //$NON-NLS-1$ + + protected static final String P_VALUE = "value"; //$NON-NLS-1$ + + protected static String[] envTableColumnProperties = { P_VARIABLE, P_VALUE }; + + protected Button envAddButton; + + protected Button envAddCGIButton; + + protected Button envEditButton; + + protected Button envRemoveButton; + + protected Button appendEnvironment; + + protected Button replaceEnvironment; + + protected Button envSelectButton; + + /** + * Content provider for the environment table + */ + protected class EnvironmentVariableContentProvider implements + IStructuredContentProvider { + public Object[] getElements(Object inputElement) { + EnvironmentVariable[] elements = new EnvironmentVariable[0]; + ILaunchConfiguration config = (ILaunchConfiguration) inputElement; + Map m; + try { + m = config.getAttribute( + ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map) null); + } catch (CoreException e) { + XDebugCorePlugin.log(new Status(IStatus.ERROR, + XDebugCorePlugin.PLUGIN_ID, IStatus.ERROR, + "Error reading configuration", e)); //$NON-NLS-1$ + return elements; + } + if (m != null && !m.isEmpty()) { + elements = new EnvironmentVariable[m.size()]; + String[] varNames = new String[m.size()]; + m.keySet().toArray(varNames); + for (int i = 0; i < m.size(); i++) { + elements[i] = new EnvironmentVariable(varNames[i], + (String) m.get(varNames[i])); + } + } + return elements; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput == null) { + return; + } + if (viewer instanceof TableViewer) { + TableViewer tableViewer = (TableViewer) viewer; + if (tableViewer.getTable().isDisposed()) { + return; + } + tableViewer.setSorter(new ViewerSorter() { + public int compare(Viewer iviewer, Object e1, Object e2) { + if (e1 == null) { + return -1; + } else if (e2 == null) { + return 1; + } else { + return ((EnvironmentVariable) e1).getName() + .compareToIgnoreCase( + ((EnvironmentVariable) e2) + .getName()); + } + } + }); + } + } + } + + /** + * Label provider for the environment table + */ + public class EnvironmentVariableLabelProvider extends LabelProvider + implements ITableLabelProvider { + public String getColumnText(Object element, int columnIndex) { + String result = null; + if (element != null) { + EnvironmentVariable var = (EnvironmentVariable) element; + switch (columnIndex) { + case 0: // variable + result = var.getName(); + break; + case 1: // value + result = var.getValue(); + break; + } + } + return result; + } + + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + // Create main composite + Composite mainComposite = new Composite(parent, SWT.NONE); + setControl(mainComposite); + // WorkbenchHelp.setHelp(getControl(), + // IDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_ENVIRONMENT_TAB); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + mainComposite.setLayout(layout); + mainComposite.setLayoutData(gridData); + mainComposite.setFont(parent.getFont()); + + createEnvironmentTable(mainComposite); + createTableButtons(mainComposite); + createAppendReplace(mainComposite); + + Dialog.applyDialogFont(mainComposite); + } + + /** + * Creates and configures the widgets which allow the user to choose whether + * the specified environment should be appended to the native environment or + * if it should completely replace it. + * + * @param parent + * the composite in which the widgets should be created + */ + protected void createAppendReplace(Composite parent) { + Composite appendReplaceComposite = new Composite(parent, SWT.NONE); + GridData gridData = new GridData(); + gridData.horizontalSpan = 2; + GridLayout layout = new GridLayout(); + appendReplaceComposite.setLayoutData(gridData); + appendReplaceComposite.setLayout(layout); + appendReplaceComposite.setFont(parent.getFont()); + + appendEnvironment = createRadioButton(appendReplaceComposite, + "&Append environment to native environment"); + appendEnvironment.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateLaunchConfigurationDialog(); + } + }); + replaceEnvironment = createRadioButton(appendReplaceComposite, + "Re&place native environment with specified environment"); + } + + /** + * Updates the enablement of the append/replace widgets. The widgets should + * disable when there are no environment variables specified. + */ + protected void updateAppendReplace() { + boolean enable = environmentTable.getTable().getItemCount() > 0; + appendEnvironment.setEnabled(enable); + replaceEnvironment.setEnabled(enable); + } + + /** + * Creates and configures the table that displayed the key/value pairs that + * comprise the environment. + * + * @param parent + * the composite in which the table should be created + */ + protected void createEnvironmentTable(Composite parent) { + Font font = parent.getFont(); + // Create table composite + Composite tableComposite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.numColumns = 1; + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.heightHint = 150; + tableComposite.setLayout(layout); + tableComposite.setLayoutData(gridData); + tableComposite.setFont(font); + // Create label + Label label = new Label(tableComposite, SWT.NONE); + label.setFont(font); + label.setText("Environment variables to &set"); + // Create table + environmentTable = new TableViewer(tableComposite, SWT.BORDER + | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); + Table table = environmentTable.getTable(); + TableLayout tableLayout = new TableLayout(); + table.setLayout(tableLayout); + table.setHeaderVisible(true); + table.setFont(font); + gridData = new GridData(GridData.FILL_BOTH); + environmentTable.getControl().setLayoutData(gridData); + environmentTable + .setContentProvider(new EnvironmentVariableContentProvider()); + environmentTable + .setLabelProvider(new EnvironmentVariableLabelProvider()); + environmentTable.setColumnProperties(envTableColumnProperties); + environmentTable + .addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + handleTableSelectionChanged(event); + } + }); + environmentTable.addDoubleClickListener(new IDoubleClickListener() { + public void doubleClick(DoubleClickEvent event) { + if (!environmentTable.getSelection().isEmpty()) { + handleEnvEditButtonSelected(); + } + } + }); + // Create columns + for (int i = 0; i < envTableColumnHeaders.length; i++) { + tableLayout.addColumnData(envTableColumnLayouts[i]); + TableColumn tc = new TableColumn(table, SWT.NONE, i); + tc.setResizable(envTableColumnLayouts[i].resizable); + tc.setText(envTableColumnHeaders[i]); + } + } + + /** + * Responds to a selection changed event in the environment table + * + * @param event + * the selection change event + */ + protected void handleTableSelectionChanged(SelectionChangedEvent event) { + int size = ((IStructuredSelection) event.getSelection()).size(); + envEditButton.setEnabled(size == 1); + envRemoveButton.setEnabled(size > 0); + } + + /** + * Creates the add/edit/remove buttons for the environment table + * + * @param parent + * the composite in which the buttons should be created + */ + protected void createTableButtons(Composite parent) { + // Create button composite + Composite buttonComposite = new Composite(parent, SWT.NONE); + GridLayout glayout = new GridLayout(); + glayout.marginHeight = 0; + glayout.marginWidth = 0; + glayout.numColumns = 1; + GridData gdata = new GridData(GridData.VERTICAL_ALIGN_BEGINNING + | GridData.HORIZONTAL_ALIGN_END); + buttonComposite.setLayout(glayout); + buttonComposite.setLayoutData(gdata); + buttonComposite.setFont(parent.getFont()); + + createVerticalSpacer(buttonComposite, 1); + // Create buttons + envAddButton = createPushButton(buttonComposite, "New", null); + envAddButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + handleEnvAddButtonSelected(); + } + }); + envAddCGIButton = createPushButton(buttonComposite, "CGIButton", null); + envAddCGIButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + handleEnvAddCGIButtonSelected(); + } + }); + + envSelectButton = createPushButton(buttonComposite, "Se&lect...", null); + envSelectButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + handleEnvSelectButtonSelected(); + } + }); + envEditButton = createPushButton(buttonComposite, "Edit", null); + envEditButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + handleEnvEditButtonSelected(); + } + }); + envEditButton.setEnabled(false); + envRemoveButton = createPushButton(buttonComposite, "Remove", null); + envRemoveButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + handleEnvRemoveButtonSelected(); + } + }); + envRemoveButton.setEnabled(false); + } + + /** + * Adds a new environment variable to the table. + */ + protected void handleEnvAddButtonSelected() { + MultipleInputDialog dialog = new MultipleInputDialog(getShell(), + "New Environment Variable"); + dialog.addTextField(NAME_LABEL, null, false); + dialog.addVariablesField(VALUE_LABEL, null, true); + + if (dialog.open() != Window.OK) { + return; + } + + String name = dialog.getStringValue(NAME_LABEL); + String value = dialog.getStringValue(VALUE_LABEL); + + if (name != null && value != null && name.length() > 0 + && value.length() > 0) { + addVariable(new EnvironmentVariable(name.trim(), value.trim())); + updateAppendReplace(); + } + } + + /** + * Attempts to add the given variable. Returns whether the variable was + * added or not (as when the user answers not to overwrite an existing + * variable). + * + * @param variable + * the variable to add + * @return whether the variable was added + */ + protected boolean addVariable(EnvironmentVariable variable) { + String name = variable.getName(); + TableItem[] items = environmentTable.getTable().getItems(); + for (int i = 0; i < items.length; i++) { + EnvironmentVariable existingVariable = (EnvironmentVariable) items[i] + .getData(); + if (existingVariable.getName().equals(name)) { + boolean overWrite = MessageDialog.openQuestion(getShell(),"Overwrite variable?", + MessageFormat.format("A variable named {0} already exists. Overwrite?",new String[] { name })); + if (!overWrite) { + return false; + } + environmentTable.remove(existingVariable); + break; + } + } + environmentTable.add(variable); + updateLaunchConfigurationDialog(); + return true; + } + + /** + * Displays a dialog that allows user to select native environment variables + * to add to the table. + */ + private void handleEnvSelectButtonSelected() { + // get Environment Variables from the OS + Map envVariables = getNativeEnvironment(); + + // get Environment Variables from the table + TableItem[] items = environmentTable.getTable().getItems(); + for (int i = 0; i < items.length; i++) { + EnvironmentVariable var = (EnvironmentVariable) items[i].getData(); + envVariables.remove(var.getName()); + } + + ListSelectionDialog dialog = new NativeEnvironmentDialog(getShell(), + envVariables, createSelectionDialogContentProvider(), + createSelectionDialogLabelProvider(), + "Select &environment variables to add:"); + dialog.setTitle("Select Environment Variables"); + + int button = dialog.open(); + if (button == Window.OK) { + Object[] selected = dialog.getResult(); + for (int i = 0; i < selected.length; i++) { + environmentTable.add(selected[i]); + } + } + + updateAppendReplace(); + updateLaunchConfigurationDialog(); + } + + /** + * Displays a dialog that allows user to select native environment variables + * to add to the table. + */ + private void handleEnvAddCGIButtonSelected() { + + Map envVariables = new HashMap(); + + envVariables.put("HTTP_COOKIE", new EnvironmentVariable("HTTP_COOKIE", + "TestCookie=1")); + envVariables.put("REDIRECT_QUERY_STRING", new EnvironmentVariable( + "REDIRECT_QUERY_STRING", "")); + envVariables.put("REDIRECT_STATUS", new EnvironmentVariable( + "REDIRECT_STATUS", "200")); + envVariables.put("REDIRECT_URL", new EnvironmentVariable( + "REDIRECT_URL", "")); + envVariables.put("SERVER_SOFTWARE", new EnvironmentVariable( + "SERVER_SOFTWARE", "DBG / 2.1")); + envVariables.put("SERVER_NAME", new EnvironmentVariable("SERVER_NAME", + "localhost")); + envVariables.put("SERVER_ADDR", new EnvironmentVariable("SERVER_ADDR", + "127.0.0.1")); + envVariables.put("SERVER_PORT", new EnvironmentVariable("SERVER_PORT", + "80")); + envVariables.put("REMOTE_ADDR", new EnvironmentVariable("REMOTE_ADDR", + "127.0.0.1")); + envVariables.put("GATEWAY_INTERFACE", new EnvironmentVariable( + "GATEWAY_INTERFACE", "CGI / 1.1")); + envVariables.put("SERVER_PROTOCOL", new EnvironmentVariable( + "SERVER_PROTOCOL", "HTTP / 1.1")); + envVariables.put("REQUEST_METHOD", new EnvironmentVariable( + "REQUEST_METHOD", "GET")); + envVariables.put("QUERY_STRING", new EnvironmentVariable( + "QUERY_STRING", "")); + envVariables.put("REDIRECT_QUERY_STRING", new EnvironmentVariable( + "REDIRECT_QUERY_STRING", "")); + // envVariables.put("REQUEST_URI" + OSFilePath; + // envVariables.put("PATH_INFO=" + OSFilePath; + // envVariables.put("PATH_TRANSLATED=" + OSFilePath; + + // get Environment Variables from the table + TableItem[] items = environmentTable.getTable().getItems(); + for (int i = 0; i < items.length; i++) { + EnvironmentVariable var = (EnvironmentVariable) items[i].getData(); + envVariables.remove(var.getName()); + } + + ListSelectionDialog dialog = new NativeEnvironmentDialog(getShell(), + envVariables, createSelectionDialogContentProvider(), + createSelectionDialogLabelProvider(), + "Select &environment variables to add:"); + dialog.setTitle("Select Environment Variables"); + + int button = dialog.open(); + if (button == Window.OK) { + Object[] selected = dialog.getResult(); + for (int i = 0; i < selected.length; i++) { + environmentTable.add(selected[i]); + } + } + + updateAppendReplace(); + updateLaunchConfigurationDialog(); + } + + /** + * Creates a label provider for the native native environment variable + * selection dialog. + * + * @return A label provider for the native native environment variable + * selection dialog. + */ + private ILabelProvider createSelectionDialogLabelProvider() { + return new ILabelProvider() { + public Image getImage(Object element) { + return null; + } + + public String getText(Object element) { + EnvironmentVariable var = (EnvironmentVariable) element; + return var.getName() + " [" + var.getValue() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public void addListener(ILabelProviderListener listener) { + } + + public void dispose() { + } + + public boolean isLabelProperty(Object element, String property) { + return false; + } + + public void removeListener(ILabelProviderListener listener) { + } + }; + } + + /** + * Creates a content provider for the native native environment variable + * selection dialog. + * + * @return A content provider for the native native environment variable + * selection dialog. + */ + private IStructuredContentProvider createSelectionDialogContentProvider() { + return new IStructuredContentProvider() { + public Object[] getElements(Object inputElement) { + EnvironmentVariable[] elements = null; + if (inputElement instanceof HashMap) { + Comparator comparator = new Comparator() { + public int compare(Object o1, Object o2) { + String s1 = (String) o1; + String s2 = (String) o2; + return s1.compareTo(s2); + } + + }; + TreeMap envVars = new TreeMap(comparator); + envVars.putAll((Map) inputElement); + elements = new EnvironmentVariable[envVars.size()]; + int index = 0; + for (Iterator iterator = envVars.keySet().iterator(); iterator + .hasNext(); index++) { + Object key = iterator.next(); + elements[index] = (EnvironmentVariable) envVars + .get(key); + } + } + return elements; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + }; + } + + /** + * Gets native environment variable from the LaunchManager. Creates + * EnvironmentVariable objects. + * + * @return Map of name - EnvironmentVariable pairs based on native + * environment. + */ + private Map getNativeEnvironment() { + Map stringVars = DebugPlugin.getDefault().getLaunchManager() + .getNativeEnvironment(); + HashMap vars = new HashMap(); + for (Iterator i = stringVars.keySet().iterator(); i.hasNext();) { + String key = (String) i.next(); + String value = (String) stringVars.get(key); + vars.put(key, new EnvironmentVariable(key, value)); + } + return vars; + } + + /** + * Creates an editor for the value of the selected environment variable. + */ + private void handleEnvEditButtonSelected() { + IStructuredSelection sel = (IStructuredSelection) environmentTable + .getSelection(); + EnvironmentVariable var = (EnvironmentVariable) sel.getFirstElement(); + if (var == null) { + return; + } + String originalName = var.getName(); + String value = var.getValue(); + MultipleInputDialog dialog = new MultipleInputDialog(getShell(), + "Edit Environment Variable"); + dialog.addTextField(NAME_LABEL, originalName, false); + dialog.addVariablesField(VALUE_LABEL, value, true); + + if (dialog.open() != Window.OK) { + return; + } + String name = dialog.getStringValue(NAME_LABEL); + value = dialog.getStringValue(VALUE_LABEL); + if (!originalName.equals(name)) { + if (addVariable(new EnvironmentVariable(name, value))) { + environmentTable.remove(var); + } + } else { + var.setValue(value); + environmentTable.update(var, null); + updateLaunchConfigurationDialog(); + } + } + + /** + * Removes the selected environment variable from the table. + */ + private void handleEnvRemoveButtonSelected() { + IStructuredSelection sel = (IStructuredSelection) environmentTable + .getSelection(); + environmentTable.getControl().setRedraw(false); + for (Iterator i = sel.iterator(); i.hasNext();) { + EnvironmentVariable var = (EnvironmentVariable) i.next(); + environmentTable.remove(var); + } + environmentTable.getControl().setRedraw(true); + updateAppendReplace(); + updateLaunchConfigurationDialog(); + } + + /** + * Updates the environment table for the given launch configuration + * + * @param configuration + */ + protected void updateEnvironment(ILaunchConfiguration configuration) { + environmentTable.setInput(configuration); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) + */ + public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) + */ + public void initializeFrom(ILaunchConfiguration configuration) { + boolean append = true; + try { + append = configuration.getAttribute( + ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true); + } catch (CoreException e) { + XDebugCorePlugin.log(e.getStatus()); + } + if (append) { + appendEnvironment.setSelection(true); + replaceEnvironment.setSelection(false); + } else { + replaceEnvironment.setSelection(true); + appendEnvironment.setSelection(false); + } + updateEnvironment(configuration); + updateAppendReplace(); + } + + /** + * Stores the environment in the given configuration + * + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) + */ + public void performApply(ILaunchConfigurationWorkingCopy configuration) { + // Convert the table's items into a Map so that this can be saved in the + // configuration's attributes. + TableItem[] items = environmentTable.getTable().getItems(); + Map map = new HashMap(items.length); + for (int i = 0; i < items.length; i++) { + EnvironmentVariable var = (EnvironmentVariable) items[i].getData(); + map.put(var.getName(), var.getValue()); + } + if (map.size() == 0) { + configuration.setAttribute( + ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map) null); + } else { + configuration.setAttribute( + ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, map); + } + configuration.setAttribute( + ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, + appendEnvironment.getSelection()); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName() + */ + public String getName() { + return "Environment"; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage() + */ + public Image getImage() { + return XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_EVIEW_ENVIROMENT_TAB); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) + */ + public void activated(ILaunchConfigurationWorkingCopy workingCopy) { + // do nothing when activated + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#deactivated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) + */ + public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) { + // do nothing when deactivated + } + + private class NativeEnvironmentDialog extends ListSelectionDialog { + public NativeEnvironmentDialog(Shell parentShell, Object input, + IStructuredContentProvider contentProvider, + ILabelProvider labelProvider, String message) { + super(parentShell, input, contentProvider, labelProvider, message); + setShellStyle(getShellStyle() | SWT.RESIZE); + } + + protected IDialogSettings getDialogSettings() { + IDialogSettings settings = XDebugCorePlugin.getDefault() + .getDialogSettings(); + IDialogSettings section = settings + .getSection(getDialogSettingsSectionName()); + if (section == null) { + section = settings + .addNewSection(getDialogSettingsSectionName()); + } + return section; + } + + /** + * Returns the name of the section that this dialog stores its settings + * in + * + * @return String + */ + protected String getDialogSettingsSectionName() { + return IDebugUIConstants.PLUGIN_ID + + ".ENVIRONMENT_TAB.NATIVE_ENVIROMENT_DIALOG"; //$NON-NLS-1$ + } + + // /* (non-Javadoc) + // * @see + // org.eclipse.jface.window.Window#getInitialLocation(org.eclipse.swt.graphics.Point) + // */ + // protected Point getInitialLocation(Point initialSize) { + // Point initialLocation= + // DialogSettingsHelper.getInitialLocation(getDialogSettingsSectionName()); + // if (initialLocation != null) { + // return initialLocation; + // } + // return super.getInitialLocation(initialSize); + // } + + // /* (non-Javadoc) + // * @see org.eclipse.jface.window.Window#getInitialSize() + // */ + // protected Point getInitialSize() { + // Point size = super.getInitialSize(); + // return DialogSettingsHelper.getInitialSize(getDialogSettingsSectionName(), size); + // } + + // /* (non-Javadoc) + // * @see org.eclipse.jface.window.Window#close() + // */ + // public boolean close() { + // DialogSettingsHelper.persistShellGeometry(getShell(), getDialogSettingsSectionName()); + // return super.close(); + // } + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPMainTab.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPMainTab.java new file mode 100644 index 0000000..03e5e3e --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPMainTab.java @@ -0,0 +1,323 @@ +package net.sourceforge.phpeclipse.xdebug.ui.php.launching; + +import net.sourceforge.phpdt.internal.ui.PHPUiImages; +import net.sourceforge.phpdt.internal.ui.util.PHPFileSelector; +import net.sourceforge.phpdt.internal.ui.util.PHPProjectSelector; +import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; +import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; + +public class PHPMainTab extends AbstractLaunchConfigurationTab { + + // Project UI widgets + protected Text fProjText; + protected Button fProjButton; + + // Main class UI widgets + protected Text fMainText; + protected Button fSearchButton; + protected PHPProjectSelector projectSelector; + protected PHPFileSelector fileSelector; + private Button fUseDefaultInterpreterButton; + private Button fInterpreterButton; + private Text fInterpreterText; + private Label fInterpreterLabel; + + public PHPMainTab() { + super(); + } + + public void createControl(Composite parent) { + Font font = parent.getFont(); + + Composite comp = new Composite(parent, SWT.NONE); + setControl(comp); +// PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_MAIN_TAB); + GridLayout topLayout = new GridLayout(); + topLayout.verticalSpacing = 0; + comp.setLayout(topLayout); + comp.setFont(font); + + createProjectEditor(comp); + createVerticalSpacer(comp, 1); + createMainTypeEditor(comp); + createVerticalSpacer(comp, 1); + createInterpreterEditor(comp); + } + + /** + * Creates the widgets for specifying a main type. + * + * @param parent the parent composite + */ + private void createProjectEditor(Composite parent) { + Font font= parent.getFont(); + Group group= new Group(parent, SWT.NONE); + group.setText("Project:"); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + group.setLayoutData(gd); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + group.setLayout(layout); + group.setFont(font); + + projectSelector = new PHPProjectSelector(group); + projectSelector.setBrowseDialogMessage("Choose the project containing the application entry point:"); + projectSelector.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + projectSelector.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent evt) { + updateLaunchConfigurationDialog(); + } + }); + } + + + /** + * Creates the widgets for specifying a php file. + * + * @param parent the parent composite + */ + private void createMainTypeEditor(Composite parent) { + Font font= parent.getFont(); + Group mainGroup= new Group(parent, SWT.NONE); + mainGroup.setText("File: "); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + mainGroup.setLayoutData(gd); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + mainGroup.setLayout(layout); + mainGroup.setFont(font); + + fileSelector = new PHPFileSelector(mainGroup, projectSelector); + fileSelector.setBrowseDialogMessage("Choose the PHP file that represents the application entry point:"); + fileSelector.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fileSelector.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent evt) { + updateLaunchConfigurationDialog(); + } + }); + } + + /** + * Creates the widgets for specifying debug settings. + * + * @param parent the parent composite + */ + private void createInterpreterEditor(Composite parent) { + Font font= parent.getFont(); + Group interpreterGroup= new Group(parent, SWT.NONE); + interpreterGroup.setText("Interpreter: "); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + interpreterGroup.setLayoutData(gd); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + interpreterGroup.setLayout(layout); + interpreterGroup.setFont(font); + +// fInterpreterLabel= new Label(interpreterGroup, SWT.NONE); +// fInterpreterLabel.setText("Interpreter: "); +// gd= new GridData(); +// gd.horizontalSpan = 2; +// fInterpreterLabel.setLayoutData(gd); +// fInterpreterLabel.setFont(font); + + fInterpreterText= new Text(interpreterGroup, SWT.SINGLE | SWT.BORDER); + gd= new GridData(GridData.FILL_HORIZONTAL); + fInterpreterText.setLayoutData(gd); + fInterpreterText.setFont(font); + fInterpreterText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent evt) { + updateLaunchConfigurationDialog(); + } + }); + + + fInterpreterButton= createPushButton(interpreterGroup,"Browse..", null); + fInterpreterButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + handleBrowseSellected(event); + } + }); + + fUseDefaultInterpreterButton = new Button(interpreterGroup,SWT.CHECK); + fUseDefaultInterpreterButton.setText("Use default interpreter"); + gd = new GridData(GridData.FILL_HORIZONTAL); + fUseDefaultInterpreterButton.setLayoutData(gd); + fUseDefaultInterpreterButton.setFont(font); + fUseDefaultInterpreterButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + handleDefaultSellected(event); + } + }); + + } + + /** + * Set the appropriate enabled state for the appletviewqer text widget. + */ + protected void setInterpreterTextEnabledState() { + if (isDefaultInterpreter()) { + fInterpreterText.setEnabled(false); + fInterpreterButton.setEnabled(false); + } else { + fInterpreterText.setEnabled(true); + fInterpreterButton.setEnabled(true); + } + } + + /** + * Returns whether the default appletviewer is to be used + */ + protected boolean isDefaultInterpreter() { + return fUseDefaultInterpreterButton.getSelection(); + } + + + + protected void handleDefaultSellected(SelectionEvent event) { + setInterpreterTextEnabledState(); + updateLaunchConfigurationDialog(); +// if (isDefaultInterpreter()) { +// fInterpreterText.setText("default Interpreter"); +// } + + } + + protected void handleBrowseSellected(SelectionEvent event) { + FileDialog dlg=new FileDialog(getShell(),SWT.OPEN); + String fileName=dlg.open(); + if (fileName!=null) { + fInterpreterText.setText(fileName); + updateLaunchConfigurationDialog(); + } + } + + protected IProject getContext() { + IWorkbenchPage page= XDebugCorePlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage(); + if (page != null) { + ISelection selection = page.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + if (!ss.isEmpty()) { + Object obj = ss.getFirstElement(); + if (obj instanceof IResource) + return ((IResource) obj).getProject(); + } + } + IEditorPart part = page.getActiveEditor(); + if (part != null) { + IEditorInput input = part.getEditorInput(); + IResource file = (IResource) input.getAdapter(IResource.class); + if (file != null) { + return file.getProject(); + } + } + } + return null; + } + + public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { + IProject project = getContext(); + if (project != null) + configuration.setAttribute(IXDebugConstants.ATTR_PHP_PROJECT, project.getName()); + } + + + public void initializeFrom(ILaunchConfiguration configuration) { + try { + String project = configuration.getAttribute(IXDebugConstants.ATTR_PHP_PROJECT, (String)null); + if (project != null) { + projectSelector.setSelectionText(project); + } + String file = configuration.getAttribute(IXDebugConstants.ATTR_PHP_FILE, (String)null); + if (file != null) { + fileSelector.setSelectionText(file); + } + + String interpreterFile=configuration.getAttribute(IXDebugConstants.ATTR_PHP_INTERPRETER, (String) null); + if(interpreterFile!=null) + fInterpreterText.setText(interpreterFile); + boolean selection=configuration.getAttribute(IXDebugConstants.ATTR_PHP_DEFAULT_INTERPRETER, true); + fUseDefaultInterpreterButton.setSelection(selection); + setInterpreterTextEnabledState(); + + } catch (CoreException e) { + setErrorMessage(e.getMessage()); + } + } + + public void performApply(ILaunchConfigurationWorkingCopy configuration) { + String project = projectSelector.getSelectionText().trim(); + if (project.length() == 0) { + project = null; + } + configuration.setAttribute(IXDebugConstants.ATTR_PHP_PROJECT, project); + + IFile file = fileSelector.getSelection(); + configuration.setAttribute(IXDebugConstants.ATTR_PHP_FILE, file == null ? "" : file.getProjectRelativePath() + .toString()); + configuration.setAttribute(IXDebugConstants.ATTR_PHP_DEFAULT_INTERPRETER, this.fUseDefaultInterpreterButton.getSelection()); + configuration.setAttribute(IXDebugConstants.ATTR_PHP_INTERPRETER, this.fInterpreterText.getText()); + + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration) + */ + public boolean isValid(ILaunchConfiguration launchConfig) { + try { + + String projectName = launchConfig.getAttribute(IXDebugConstants.ATTR_PHP_PROJECT, ""); + if (projectName.length() == 0) { + setErrorMessage("Iinvalid Project"); + return false; + } + + String fileName = launchConfig.getAttribute(IXDebugConstants.ATTR_PHP_FILE, ""); + if (fileName.length() == 0) { + setErrorMessage("Invalid File"); + return false; + } + } catch (CoreException e) { +// XDebugCorePlugin.log(e); + } + + setErrorMessage(null); + return super.isValid(launchConfig); + } + public Image getImage() { + return PHPUiImages.get(PHPUiImages.IMG_CTOOLS_PHP_PAGE); + } + + public String getName() { + return "Main"; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPTabGroup.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPTabGroup.java new file mode 100644 index 0000000..772df58 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/launching/PHPTabGroup.java @@ -0,0 +1,20 @@ +package net.sourceforge.phpeclipse.xdebug.ui.php.launching; + +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +public class PHPTabGroup extends AbstractLaunchConfigurationTabGroup { + + + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + setTabs(new ILaunchConfigurationTab[] { + new PHPMainTab(), + new SourceLookupTab(), + new PHPEnvironmentTab(), + new CommonTab() + }); + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/model/PHPBreakpointAdapterFactory.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/model/PHPBreakpointAdapterFactory.java new file mode 100644 index 0000000..1124273 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/model/PHPBreakpointAdapterFactory.java @@ -0,0 +1,19 @@ +package net.sourceforge.phpeclipse.xdebug.ui.php.model; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; + +public class PHPBreakpointAdapterFactory implements IAdapterFactory { + + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (adapterType == IToggleBreakpointsTarget.class) { + return new PHPLineBreakpointAdapter(); + } + return null; + } + + public Class[] getAdapterList() { + return new Class[]{IToggleBreakpointsTarget.class}; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/model/PHPLineBreakpointAdapter.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/model/PHPLineBreakpointAdapter.java new file mode 100644 index 0000000..e2a5415 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/php/model/PHPLineBreakpointAdapter.java @@ -0,0 +1,73 @@ +package net.sourceforge.phpeclipse.xdebug.ui.php.model; + +import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants; +import net.sourceforge.phpeclipse.xdebug.php.model.XDebugLineBreakpoint; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.ILineBreakpoint; +import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; + +public class PHPLineBreakpointAdapter implements IToggleBreakpointsTarget { + + public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) + throws CoreException { + IEditorPart editorPart = (IEditorPart)part; + + IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class); + ITextSelection textSelection = (ITextSelection) selection; + int lineNumber = textSelection.getStartLine()+1; + IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(IXDebugConstants.ID_PHP_DEBUG_MODEL); + for (int i = 0; i < breakpoints.length; i++) { + IBreakpoint breakpoint = breakpoints[i]; + if (resource.equals(breakpoint.getMarker().getResource())) { + if (((ILineBreakpoint)breakpoint).getLineNumber() == (lineNumber )) { + // remove + breakpoint.delete(); + return; + } + } + } + // create line breakpoint (doc line numbers start at 0) + XDebugLineBreakpoint lineBreakpoint = new XDebugLineBreakpoint(resource, lineNumber); +// DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(lineBreakpoint); + + } + + public boolean canToggleLineBreakpoints(IWorkbenchPart part, + ISelection selection) { + // TODO Auto-generated method stub + return true; + } + + public void toggleMethodBreakpoints(IWorkbenchPart part, + ISelection selection) throws CoreException { + // TODO Auto-generated method stub + + } + + public boolean canToggleMethodBreakpoints(IWorkbenchPart part, + ISelection selection) { + // TODO Auto-generated method stub + return false; + } + + public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) + throws CoreException { + // TODO Auto-generated method stub + + } + + public boolean canToggleWatchpoints(IWorkbenchPart part, + ISelection selection) { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/preference/XDebugPreferencePage.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/preference/XDebugPreferencePage.java new file mode 100644 index 0000000..58580b8 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/preference/XDebugPreferencePage.java @@ -0,0 +1,52 @@ +package net.sourceforge.phpeclipse.xdebug.ui.preference; + +import net.sourceforge.phpeclipse.externaltools.ExternalToolsPlugin; +import net.sourceforge.phpeclipse.xdebug.core.IXDebugPreferenceConstants; +import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; + +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.FileFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.IntegerFieldEditor; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + + +public class XDebugPreferencePage extends FieldEditorPreferencePage implements + IWorkbenchPreferencePage { + + /* Preference page for the default XDebug-Settings */ + + public XDebugPreferencePage() { + super(FieldEditorPreferencePage.GRID); + + // Set the preference store for the preference page. + IPreferenceStore store = + XDebugCorePlugin.getDefault().getPreferenceStore(); + store.setDefault(IXDebugPreferenceConstants.DEBUGPORT_PREFERENCE,IXDebugPreferenceConstants.DEFAULT_DEBUGPORT); + // get the default form the externalToolsPlugin + String interpreter=ExternalToolsPlugin.getDefault().getPreferenceStore().getString(ExternalToolsPlugin.PHP_RUN_PREF); + store.setDefault(IXDebugPreferenceConstants.PHP_INTERPRETER_PREFERENCE,interpreter); + setPreferenceStore(store); + } + + public void init(IWorkbench workbench) { + setDescription("Default Entries for XDebug:"); + } + + protected void createFieldEditors() { + IntegerFieldEditor debugPort = new IntegerFieldEditor(IXDebugPreferenceConstants.DEBUGPORT_PREFERENCE, "&Debugport:", getFieldEditorParent(),5); + debugPort.setValidRange(1025,65535); + debugPort.setErrorMessage("Debugport must be between 1024 and 65536"); + addField(debugPort); + + FileFieldEditor phpInterpreter = new FileFieldEditor(IXDebugPreferenceConstants.PHP_INTERPRETER_PREFERENCE, "PHP &Interpreter:",true,getFieldEditorParent()); + phpInterpreter.setErrorMessage("File not found"); + addField(phpInterpreter); + + } + + + + +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialog.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialog.java new file mode 100644 index 0000000..afd7581 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialog.java @@ -0,0 +1,630 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.ui.views.logview; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.Collator; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; + +import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; +import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin; +import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPluginImages; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableTreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +public class EventDetailsDialog extends Dialog { + private LogEntry entry, parentEntry; + private LogViewLabelProvider labelProvider; + private static int COPY_ID = 22; + private TableTreeViewer provider; + private int elementNum, totalElementCount; + private LogEntry[] entryChildren; + private int childIndex = 0; + private boolean isOpen; + + private Label dateLabel; + private Label severityImageLabel; + private Label severityLabel; + private Text msgText; + private Text stackTraceText; + private Text sessionDataText; + private Clipboard clipboard; + private Button copyButton; + private Button backButton; + private Button nextButton; + private Image imgNextEnabled; + private Image imgPrevEnabled; + private Image imgCopyEnabled; + private SashForm sashForm; + + // sorting + private static int ASCENDING = 1; + private Comparator comparator = null; + private Collator collator; + + // location configuration + private IDialogSettings dialogSettings; + private Point dialogLocation; + private Point dialogSize; + private int[] sashWeights; + + // externalize strings + private String EVENT_NO_STACK = "EventDetailsDialog.noStack"; //$NON-NLS-1$ + private String EVENT_PREVIOUS = "EventDetailsDialog.previous"; //$NON-NLS-1$ + private String EVENT_NEXT = "EventDetailsDialog.next"; //$NON-NLS-1$ + private String EVENT_COPY = "EventDetailsDialog.copy"; //$NON-NLS-1$ + + /** + * @param parentShell + * shell in which dialog is displayed + */ + protected EventDetailsDialog(Shell parentShell, IAdaptable selection, ISelectionProvider provider) { + super(parentShell); + labelProvider = new LogViewLabelProvider(); + this.provider = (TableTreeViewer) provider; + this.entry = (LogEntry)selection; + setShellStyle(SWT.MODELESS | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.CLOSE | SWT.BORDER | SWT.TITLE); + clipboard = new Clipboard(parentShell.getDisplay()); + initialize(); + createImages(); + collator = Collator.getInstance(); + readConfiguration(); + } + + private void initialize() { + elementNum = getParentElementNum(); + totalElementCount = provider.getTableTree().getTable().getItemCount() - getVisibleChildrenCount(); + parentEntry = (LogEntry) entry.getParent(entry); + if (isChild(entry)){ + setEntryChildren(parentEntry); + resetChildIndex(); + } + } + + private void resetChildIndex(){ + for (int i = 0; i 0) + width -= 100; + else + width = width/2; + sashWeights = new int[]{width, getSashForm().getClientArea().width-width}; + } + getSashForm().setWeights(sashWeights); + return super.open(); + } + + public boolean close() { + storeSettings(); + isOpen = false; + imgCopyEnabled.dispose(); + imgNextEnabled.dispose(); + imgPrevEnabled.dispose(); + return super.close(); + } + + public void create() { + super.create(); + + // dialog location + if (dialogLocation != null) + getShell().setLocation(dialogLocation); + + // dialog size + if (dialogSize != null) + getShell().setSize(dialogSize); + else + getShell().setSize(500,550); + + + applyDialogFont(buttonBar); + getButton(IDialogConstants.OK_ID).setFocus(); + } + + protected void buttonPressed(int buttonId) { + if (IDialogConstants.OK_ID == buttonId) + okPressed(); + else if (IDialogConstants.CANCEL_ID == buttonId) + cancelPressed(); + else if (IDialogConstants.BACK_ID == buttonId) + backPressed(); + else if (IDialogConstants.NEXT_ID == buttonId) + nextPressed(); + else if (COPY_ID == buttonId) + copyPressed(); + } + + protected void backPressed() { + if (isChild(entry)) { + if (childIndex > 0) { + childIndex--; + entry = entryChildren[childIndex]; + } else + entry = parentEntry; + } else { + if (elementNum - 1 >= 0) + elementNum -= 1; + entry = (LogEntry) provider.getElementAt(elementNum); + } + setEntrySelectionInTable(); + } + + protected void nextPressed() { + if (isChild(entry) && childIndex < entryChildren.length-1) { + childIndex++; + entry = entryChildren[childIndex]; + } else if (elementNum + 1 < totalElementCount){ + elementNum += 1; + entry = (LogEntry) provider.getElementAt(elementNum); + } else { // at end of list but can branch into child elements - bug 58083 + setEntryChildren(entry); + entry = entryChildren[0]; + } + setEntrySelectionInTable(); + } + + protected void copyPressed() { + StringWriter writer = new StringWriter(); + PrintWriter pwriter = new PrintWriter(writer); + + entry.write(pwriter); + pwriter.flush(); + String textVersion = writer.toString(); + try { + pwriter.close(); + writer.close(); + } catch (IOException e) { + } + // set the clipboard contents + clipboard.setContents(new Object[] { textVersion }, new Transfer[] { TextTransfer.getInstance()}); + } + + public void setComparator(Comparator comparator){ + this.comparator = comparator; + updateProperties(); + } + private void setComparator(byte sortType, final int sortOrder){ + if (sortType == LogView.DATE){ + comparator = new Comparator(){ + public int compare(Object e1, Object e2) { + try { + SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$ + Date date1 = formatter.parse(((LogEntry)e1).getDate()); + Date date2 = formatter.parse(((LogEntry)e2).getDate()); + if (sortOrder == ASCENDING) + return date1.before(date2) ? -1 : 1; + return date1.after(date2) ? -1 : 1; + } catch (ParseException e) { + } + return 0; + } + }; + } else if (sortType == LogView.PLUGIN){ + comparator = new Comparator(){ + public int compare(Object e1, Object e2) { + LogEntry entry1 = (LogEntry)e1; + LogEntry entry2 = (LogEntry)e2; + return collator.compare(entry1.getPluginId(), entry2.getPluginId()) * sortOrder; + } + }; + } else { + comparator = new Comparator(){ + public int compare(Object e1, Object e2) { + LogEntry entry1 = (LogEntry)e1; + LogEntry entry2 = (LogEntry)e2; + return collator.compare(entry1.getMessage(), entry2.getMessage()) * sortOrder; + } + }; + } + } + + public void resetSelection(IAdaptable selectedEntry, byte sortType, int sortOrder){ + setComparator(sortType, sortOrder); + resetSelection(selectedEntry); + } + + public void resetSelection(IAdaptable selectedEntry){ + if (entry.equals(selectedEntry) && + elementNum == getParentElementNum()){ + updateProperties(); + return; + } + entry = (LogEntry)selectedEntry; + initialize(); + updateProperties(); + } + + public void resetButtons(){ + backButton.setEnabled(false); + nextButton.setEnabled(false); + } + + private void setEntrySelectionInTable(){ + ISelection selection = new StructuredSelection(entry); + provider.setSelection(selection); + } + + public void updateProperties() { + if (isChild(entry)){ + parentEntry = (LogEntry) entry.getParent(entry); + setEntryChildren(parentEntry); + resetChildIndex(); + } + + + totalElementCount = provider.getTableTree().getTable().getItemCount() - getVisibleChildrenCount(); + dateLabel.setText(entry.getDate()); + severityImageLabel.setImage(labelProvider.getColumnImage(entry, 1)); + severityLabel.setText(entry.getSeverityText()); + msgText.setText(entry.getMessage()); + String stack = entry.getStack(); + if (stack != null) { + stackTraceText.setText(stack); + } else { + stackTraceText.setText(XDebugUIPlugin.getString(EVENT_NO_STACK)); + } + LogSession session = entry.getSession(); + if (session != null && session.getSessionData() != null) + sessionDataText.setText(session.getSessionData()); + + updateButtons(); + } + + private void updateButtons(){ + boolean isAtEnd = elementNum == totalElementCount - 1; + if (isChild(entry)){ + backButton.setEnabled(true); + boolean isLastChild = childIndex == entryChildren.length-1; + nextButton.setEnabled(!isLastChild || !isAtEnd || entry.hasChildren()); + } else { + backButton.setEnabled(elementNum != 0); + nextButton.setEnabled(!isAtEnd || entry.hasChildren()); + } + } + + private void setEntryChildren(LogEntry parent){ + Object[] children = parent.getChildren(parent); + if (comparator != null) + Arrays.sort(children, comparator); + entryChildren = new LogEntry[children.length]; + + System.arraycopy(children,0,entryChildren,0,children.length); + } + + private int getParentElementNum(){ + LogEntry itemEntry = (LogEntry)((IStructuredSelection)provider.getSelection()).getFirstElement(); + itemEntry = getRootEntry(itemEntry); + + for (int i = 0; i 0; + } + public String toString() { + return getSeverityText(); + } + /** + * @see IWorkbenchAdapter#getChildren(Object) + */ + public Object[] getChildren(Object parent) { + if (children == null) + return new Object[0]; + return children.toArray(); + } + + /** + * @see IWorkbenchAdapter#getImageDescriptor(Object) + */ + public ImageDescriptor getImageDescriptor(Object arg0) { + return null; + } + + /** + * @see IWorkbenchAdapter#getLabel(Object) + */ + public String getLabel(Object obj) { + return getSeverityText(); + } + + /** + * @see IWorkbenchAdapter#getParent(Object) + */ + public Object getParent(Object obj) { + return parent; + } + + void setParent(LogEntry parent) { + this.parent = parent; + } + + private String getSeverityText(int severity) { + switch (severity) { + case IStatus.ERROR : + return XDebugUIPlugin.getString(KEY_ERROR); + case IStatus.WARNING : + return XDebugUIPlugin.getString(KEY_WARNING); + case IStatus.INFO : + return XDebugUIPlugin.getString(KEY_INFO); + } + return "?"; //$NON-NLS-1$ + } + + int processLogLine(String line, boolean root) { + //!ENTRY + //!SUBENTRY + StringTokenizer stok = new StringTokenizer(line, " ", true); //$NON-NLS-1$ + StringBuffer dateBuffer = new StringBuffer(); + + int dateCount = 5; + int depth = 0; + for (int i = 0; stok.hasMoreTokens();) { + String token = stok.nextToken(); + if (i >= dateCount) { + dateBuffer.append(token); + continue; + } else if (token.equals(" ")) //$NON-NLS-1$ + continue; + switch (i) { + case 0 : // entry or subentry + if (root) + i += 2; + else + i++; + break; + case 1 : // depth + depth = parseInteger(token); + i++; + break; + case 2 : + pluginId = token; + i++; + break; + case 3 : // severity + severity = parseInteger(token); + i++; + break; + case 4 : // code + code = parseInteger(token); + i++; + break; + } + } + date = dateBuffer.toString().trim(); + return depth; + } + + private int parseInteger(String token) { + try { + return Integer.parseInt(token); + } catch (NumberFormatException e) { + return 0; + } + } + + void setStack(String stack) { + this.stack = stack; + } + void setMessage(String message) { + this.message = message; + } + + private void processStatus(IStatus status) { + pluginId = status.getPlugin(); + severity = status.getSeverity(); + code = status.getCode(); + DateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$ + date = formatter.format(new Date()); + message = status.getMessage(); + Throwable throwable = status.getException(); + if (throwable != null) { + StringWriter swriter = new StringWriter(); + PrintWriter pwriter = new PrintWriter(swriter); + throwable.printStackTrace(pwriter); + pwriter.flush(); + pwriter.close(); + stack = swriter.toString(); + } + IStatus[] schildren = status.getChildren(); + if (schildren.length > 0) { + children = new ArrayList(); + for (int i = 0; i < schildren.length; i++) { + LogEntry child = new LogEntry(schildren[i]); + addChild(child); + } + } + } + void addChild(LogEntry child) { + if (children == null) + children = new ArrayList(); + children.add(child); + child.setParent(this); + } + public void write(PrintWriter writer) { + writer.print(getSeverityText()); + if (date != null) { + writer.print(" "); //$NON-NLS-1$ + writer.print(getDate()); + } + if (message != null) { + writer.print(" "); //$NON-NLS-1$ + writer.print(getMessage()); + } + writer.println(); + if (stack != null) + writer.println(stack); + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogReader.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogReader.java new file mode 100644 index 0000000..7a33d18 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogReader.java @@ -0,0 +1,308 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.ui.views.logview; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.RandomAccessFile; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Date; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.ui.IMemento; + +class LogReader { + private static final int SESSION_STATE = 10; + public static final long MAX_FILE_LENGTH = 1024*1024; + private static final int ENTRY_STATE = 20; + private static final int SUBENTRY_STATE = 30; + private static final int MESSAGE_STATE = 40; + private static final int STACK_STATE = 50; + private static final int TEXT_STATE = 60; + private static final int UNKNOWN_STATE = 70; + + private static LogSession currentSession; + + public static void parseLargeFile(File file, ArrayList entries, IMemento memento) { + ArrayList parents = new ArrayList(); + LogEntry current = null; + LogSession session = null; + int writerState = UNKNOWN_STATE; + StringWriter swriter = null; + PrintWriter writer = null; + int state = UNKNOWN_STATE; + currentSession = null; + RandomAccessFile random = null; + try { + random = new RandomAccessFile(file, "r"); //$NON-NLS-1$ + random.seek(file.length() - MAX_FILE_LENGTH); + for (;;) { + String line = random.readLine(); + if (line == null) + break; + + line = line.trim(); + if (line.length() == 0) + continue; + + if (line.startsWith("!SESSION")) { //$NON-NLS-1$ + state = SESSION_STATE; + } else if (line.startsWith("!ENTRY")) { //$NON-NLS-1$ + state = ENTRY_STATE; + } else if (line.startsWith("!SUBENTRY")) { //$NON-NLS-1$ + state = SUBENTRY_STATE; + } else if (line.startsWith("!MESSAGE")) { //$NON-NLS-1$ + state = MESSAGE_STATE; + } else if (line.startsWith("!STACK")) { //$NON-NLS-1$ + state = STACK_STATE; + } else + state = TEXT_STATE; + + if (state == TEXT_STATE) { + if (writer != null) + writer.println(line); + continue; + } + + if (writer != null) { + if (writerState == STACK_STATE && current != null) { + current.setStack(swriter.toString()); + } else if (writerState == SESSION_STATE && session != null) { + session.setSessionData(swriter.toString()); + } else if (writerState == MESSAGE_STATE && current != null){ + String message = current.getMessage() + swriter.toString(); + message = message.trim(); + current.setMessage(message); + } + writerState = UNKNOWN_STATE; + swriter = null; + writer.close(); + writer = null; + } + + if (state == STACK_STATE) { + swriter = new StringWriter(); + writer = new PrintWriter(swriter, true); + writerState = STACK_STATE; + } else if (state == SESSION_STATE) { + session = new LogSession(); + session.processLogLine(line); + swriter = new StringWriter(); + writer = new PrintWriter(swriter, true); + writerState = SESSION_STATE; + updateCurrentSession(session); + if (currentSession.equals(session) && !memento.getString(LogView.P_SHOW_ALL_SESSIONS).equals("true")) //$NON-NLS-1$ + entries.clear(); + } else if (state == ENTRY_STATE) { + LogEntry entry = new LogEntry(); + entry.setSession(session); + entry.processLogLine(line, true); + setNewParent(parents, entry, 0); + current = entry; + addEntry(current, entries, memento, false); + } else if (state == SUBENTRY_STATE) { + LogEntry entry = new LogEntry(); + entry.setSession(session); + int depth = entry.processLogLine(line, false); + setNewParent(parents, entry, depth); + current = entry; + LogEntry parent = (LogEntry) parents.get(depth - 1); + parent.addChild(entry); + } else if (state == MESSAGE_STATE) { + swriter = new StringWriter(); + writer = new PrintWriter(swriter, true); + String message = ""; //$NON-NLS-1$ + if (line.length() > 8) + message = line.substring(9).trim(); + message = message.trim(); + if (current != null) + current.setMessage(message); + writerState = MESSAGE_STATE; + } + } + } catch (FileNotFoundException e) { + } catch (IOException e) { + } finally { + try { + if (random != null) + random.close(); + } catch (IOException e1) { + } + } + } + + public static void parseLogFile(File file, ArrayList entries, IMemento memento) { + ArrayList parents = new ArrayList(); + LogEntry current = null; + LogSession session = null; + int writerState = UNKNOWN_STATE; + StringWriter swriter = null; + PrintWriter writer = null; + int state = UNKNOWN_STATE; + currentSession = null; + BufferedReader reader = null; + try { + + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); //$NON-NLS-1$ + while(reader.ready()) { + String line = reader.readLine(); + if (line == null) + continue; + line = line.trim(); + if (line.length() == 0) + continue; + + if (line.startsWith("!SESSION")) { //$NON-NLS-1$ + state = SESSION_STATE; + } else if (line.startsWith("!ENTRY")) { //$NON-NLS-1$ + state = ENTRY_STATE; + } else if (line.startsWith("!SUBENTRY")) { //$NON-NLS-1$ + state = SUBENTRY_STATE; + } else if (line.startsWith("!MESSAGE")) { //$NON-NLS-1$ + state = MESSAGE_STATE; + } else if (line.startsWith("!STACK")) { //$NON-NLS-1$ + state = STACK_STATE; + } else + state = TEXT_STATE; + + if (state == TEXT_STATE) { + if (writer != null) + writer.println(line); + continue; + } + + if (writer != null) { + if (writerState == STACK_STATE && current != null) { + current.setStack(swriter.toString()); + } else if (writerState == SESSION_STATE && session != null) { + session.setSessionData(swriter.toString()); + } else if (writerState == MESSAGE_STATE && current != null){ + String message = current.getMessage() + swriter.toString(); + message = message.trim(); + current.setMessage(message); + } + writerState = UNKNOWN_STATE; + swriter = null; + writer.close(); + writer = null; + } + + if (state == STACK_STATE) { + swriter = new StringWriter(); + writer = new PrintWriter(swriter, true); + writerState = STACK_STATE; + } else if (state == SESSION_STATE) { + session = new LogSession(); + session.processLogLine(line); + swriter = new StringWriter(); + writer = new PrintWriter(swriter, true); + writerState = SESSION_STATE; + updateCurrentSession(session); + if (currentSession.equals(session) && !memento.getString(LogView.P_SHOW_ALL_SESSIONS).equals("true")) //$NON-NLS-1$ + entries.clear(); + } else if (state == ENTRY_STATE) { + LogEntry entry = new LogEntry(); + entry.setSession(session); + entry.processLogLine(line, true); + setNewParent(parents, entry, 0); + current = entry; + addEntry(current, entries, memento, false); + } else if (state == SUBENTRY_STATE) { + LogEntry entry = new LogEntry(); + entry.setSession(session); + int depth = entry.processLogLine(line, false); + setNewParent(parents, entry, depth); + current = entry; + LogEntry parent = (LogEntry) parents.get(depth - 1); + parent.addChild(entry); + } else if (state == MESSAGE_STATE) { + swriter = new StringWriter(); + writer = new PrintWriter(swriter, true); + String message = ""; //$NON-NLS-1$ + if (line.length() > 8) + message = line.substring(9).trim(); + message = message.trim(); + if (current != null) + current.setMessage(message); + writerState = MESSAGE_STATE; + } + } + } catch (FileNotFoundException e) { + } catch (IOException e) { + } finally { + try { + if (reader != null) + reader.close(); + } catch (IOException e1) { + } + } + } + + private static void updateCurrentSession(LogSession session) { + if (currentSession == null) { + currentSession = session; + return; + } + Date currentDate = currentSession.getDate(); + Date sessionDate = session.getDate(); + if (currentDate == null && sessionDate != null) + currentSession = session; + else if (currentDate != null && sessionDate == null) + currentSession = session; + else if (currentDate != null && sessionDate != null && sessionDate.after(currentDate)) + currentSession = session; + } + + public static void addEntry(LogEntry current, ArrayList entries, IMemento memento, boolean useCurrentSession) { + int severity = current.getSeverity(); + boolean doAdd = true; + switch(severity) { + case IStatus.INFO: + doAdd = memento.getString(LogView.P_LOG_INFO).equals("true"); //$NON-NLS-1$ + break; + case IStatus.WARNING: + doAdd = memento.getString(LogView.P_LOG_WARNING).equals("true"); //$NON-NLS-1$ + break; + case IStatus.ERROR: + doAdd = memento.getString(LogView.P_LOG_ERROR).equals("true"); //$NON-NLS-1$ + break; + } + if (doAdd) { + if (useCurrentSession) + current.setSession(currentSession); + entries.add(0, current); + + if (memento.getString(LogView.P_USE_LIMIT).equals("true") //$NON-NLS-1$ + && entries.size() > memento.getInteger(LogView.P_LOG_LIMIT).intValue()) + entries.remove(entries.size() - 1); + } + } + + private static void setNewParent( + ArrayList parents, + LogEntry entry, + int depth) { + if (depth + 1 > parents.size()) + parents.add(entry); + else + parents.set(depth, entry); + } + + public static void reset() { + currentSession = null; + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogSession.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogSession.java new file mode 100644 index 0000000..f4adc8c --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogSession.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.ui.views.logview; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.StringTokenizer; + +public class LogSession { + private String sessionData; + private Date date; + + /** + * Constructor for LogSession. + */ + public LogSession() { + } + + public Date getDate() { + return date; + } + + public void setDate(String dateString) { + SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$ + try { + date = formatter.parse(dateString); + } catch (ParseException e) { + } + } + + public String getSessionData() { + return sessionData; + } + + void setSessionData(String data) { + this.sessionData = data; + } + + public void processLogLine(String line) { + StringTokenizer tokenizer = new StringTokenizer(line); + if (tokenizer.countTokens() == 6) { + tokenizer.nextToken(); + StringBuffer dateBuffer = new StringBuffer(); + for (int i = 0; i < 4; i++) { + dateBuffer.append(tokenizer.nextToken()); + dateBuffer.append(" "); //$NON-NLS-1$ + } + setDate(dateBuffer.toString().trim()); + } + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogView.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogView.java new file mode 100644 index 0000000..d698b1c --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogView.java @@ -0,0 +1,993 @@ +/*********************************************************************************************************************************** + * Copyright (c) 2000, 2004 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made + * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + **********************************************************************************************************************************/ + +package net.sourceforge.phpeclipse.xdebug.ui.views.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.text.Collator; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; + +import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; +import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin; +import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPluginImages; + +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.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.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.ColumnPixelData; +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.ITreeViewerListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableLayout; +import org.eclipse.jface.viewers.TableTreeViewer; +import org.eclipse.jface.viewers.TreeExpansionEvent; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.custom.TableTree; +import org.eclipse.swt.custom.TableTreeItem; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +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.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Point; +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.Control; +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.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPage; +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.part.ViewPart; + +public class LogView extends ViewPart implements ILogListener { + public final static String ID_LOGVIEW = "net.sourceforge.phpdt.internal.debug.core.logview.LogView"; //$NON-NLS-1$ + + private TableTreeViewer tableTreeViewer; + + private ArrayList logs = new ArrayList(); + + 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 = "column1"; //$NON-NLS-1$ + + private static final String P_COLUMN_2 = "column2"; //$NON-NLS-1$ + + private static final String P_COLUMN_3 = "column3"; //$NON-NLS-1$ + + private static final String P_COLUMN_4 = "column4"; //$NON-NLS-1$ + + public static final String P_ACTIVATE = "activate"; //$NON-NLS-1$ + + private int MESSAGE_ORDER = -1; + + private int PLUGIN_ORDER = -1; + + private int DATE_ORDER = -1; + + public static byte MESSAGE = 0x0; + + public static byte PLUGIN = 0x1; + + public static byte DATE = 0x2; + + private static int ASCENDING = 1; + + private static int DESCENDING = -1; + + private Action clearAction; + + private Action copyAction; + + private Action readLogAction; + + private Action deleteLogAction; + + private Action exportAction; + + private Action importAction; + + private Action activateViewAction; + + private Action propertiesAction; + + private Action viewLogAction; + + private Action filterAction; + + private Clipboard clipboard; + + private IMemento memento; + + private File inputFile; + + private String directory; + + private TableColumn column0; + + private TableColumn column1; + + private TableColumn column2; + + private TableColumn column3; + + private TableColumn column4; + + private static Font boldFont; + + private Comparator comparator; + + private Collator collator; + + // hover text + private boolean canOpenTextShell; + + private Text textLabel; + + private Shell textShell; + + private boolean firstEvent = true; + + public LogView() { + logs = new ArrayList(); + inputFile = Platform.getLogFileLocation().toFile(); + } + + public void createPartControl(Composite parent) { + readLogFile(); + TableTree tableTree = new TableTree(parent, SWT.FULL_SELECTION); + tableTree.setLayoutData(new GridData(GridData.FILL_BOTH)); + createColumns(tableTree.getTable()); + createViewer(tableTree); + createPopupMenuManager(tableTree); + makeActions(tableTree.getTable()); + fillToolBar(); + Platform.addLogListener(this); + getSite().setSelectionProvider(tableTreeViewer); + clipboard = new Clipboard(tableTree.getDisplay()); + // WorkbenchHelp.setHelp(tableTree, IHelpContextIds.LOG_VIEW); + tableTreeViewer.getTableTree().getTable().setToolTipText(""); //$NON-NLS-1$ + initializeFonts(); + applyFonts(); + } + + private void initializeFonts() { + Font tableFont = tableTreeViewer.getTableTree().getFont(); + FontData[] fontDataList = tableFont.getFontData(); + FontData fontData; + if (fontDataList.length > 0) + fontData = fontDataList[0]; + else + fontData = new FontData(); + fontData.setStyle(SWT.BOLD); + boldFont = new Font(tableTreeViewer.getTableTree().getDisplay(), fontData); + } + + /* + * Set all rows where the tableTreeItem has children to have a bold font. + */ + private void applyFonts() { + if (tableTreeViewer == null || tableTreeViewer.getTableTree().isDisposed()) + return; + int max = tableTreeViewer.getTableTree().getItemCount(); + int index = 0, tableIndex = 0; + while (index < max) { + LogEntry entry = (LogEntry) tableTreeViewer.getElementAt(index); + if (entry == null) + return; + if (entry.hasChildren()) { + tableTreeViewer.getTableTree().getItems()[index].setFont(boldFont); + tableIndex = applyChildFonts(entry, tableIndex); + } else { + tableTreeViewer.getTableTree().getItems()[index].setFont(tableTreeViewer.getTableTree().getFont()); + } + index++; + tableIndex++; + } + } + + private int applyChildFonts(LogEntry parent, int index) { + if (!tableTreeViewer.getExpandedState(parent) || !parent.hasChildren()) + return index; + LogEntry[] children = getEntryChildren(parent); + for (int i = 0; i < children.length; i++) { + index++; + if (children[i].hasChildren()) { + TableItem tableItem = getTableItem(index); + if (tableItem != null) { + tableItem.setFont(boldFont); + } + index = applyChildFonts(children[i], index); + } else { + TableItem tableItem = getTableItem(index); + if (tableItem != null) { + tableItem.setFont(tableTreeViewer.getTableTree().getFont()); + } + } + } + return index; + } + + private LogEntry[] getEntryChildren(LogEntry parent) { + Object[] entryChildren = parent.getChildren(parent); + if (comparator != null) + Arrays.sort(entryChildren, comparator); + LogEntry[] children = new LogEntry[entryChildren.length]; + System.arraycopy(entryChildren, 0, children, 0, entryChildren.length); + return children; + } + + private TableItem getTableItem(int index) { + TableItem[] tableItems = tableTreeViewer.getTableTree().getTable().getItems(); + if (index > tableItems.length - 1) + return null; + return tableItems[index]; + } + + private void fillToolBar() { + IActionBars bars = getViewSite().getActionBars(); + bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction); + IToolBarManager toolBarManager = bars.getToolBarManager(); + toolBarManager.add(exportAction); + toolBarManager.add(importAction); + toolBarManager.add(new Separator()); + toolBarManager.add(clearAction); + toolBarManager.add(deleteLogAction); + toolBarManager.add(viewLogAction); + toolBarManager.add(readLogAction); + toolBarManager.add(new Separator()); + IMenuManager mgr = bars.getMenuManager(); + mgr.add(filterAction); + mgr.add(new Separator()); + mgr.add(activateViewAction); + } + + private void createViewer(TableTree tableTree) { + tableTreeViewer = new TableTreeViewer(tableTree); + tableTreeViewer.setContentProvider(new LogViewContentProvider(this)); + tableTreeViewer.setLabelProvider(new LogViewLabelProvider()); + tableTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent e) { + handleSelectionChanged(e.getSelection()); + if (propertiesAction.isEnabled()) + ((EventDetailsDialogAction) propertiesAction).resetSelection(); + } + }); + tableTreeViewer.addDoubleClickListener(new IDoubleClickListener() { + public void doubleClick(DoubleClickEvent event) { + ((EventDetailsDialogAction) propertiesAction).setComparator(comparator); + propertiesAction.run(); + } + }); + tableTreeViewer.addTreeListener(new ITreeViewerListener() { + public void treeCollapsed(TreeExpansionEvent event) { + applyFonts(); + } + + public void treeExpanded(TreeExpansionEvent event) { + applyFonts(); + } + }); + addMouseListeners(); + tableTreeViewer.setInput(Platform.class); + } + + private void createPopupMenuManager(TableTree tableTree) { + MenuManager popupMenuManager = new MenuManager(); + IMenuListener listener = new IMenuListener() { + public void menuAboutToShow(IMenuManager mng) { + fillContextMenu(mng); + } + }; + popupMenuManager.addMenuListener(listener); + popupMenuManager.setRemoveAllWhenShown(true); + Menu menu = popupMenuManager.createContextMenu(tableTree); + tableTree.setMenu(menu); + } + + private void createColumns(Table table) { + column0 = new TableColumn(table, SWT.NULL); + column0.setText(""); //$NON-NLS-1$ + column1 = new TableColumn(table, SWT.NULL); + column1.setText(XDebugUIPlugin.getString("LogView.column.severity")); //$NON-NLS-1$ + column2 = new TableColumn(table, SWT.NULL); + column2.setText(XDebugUIPlugin.getString("LogView.column.message")); //$NON-NLS-1$ + column2.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + MESSAGE_ORDER *= -1; + ViewerSorter sorter = getViewerSorter(MESSAGE); + tableTreeViewer.setSorter(sorter); + collator = sorter.getCollator(); + boolean isComparatorSet = ((EventDetailsDialogAction) propertiesAction).resetSelection(MESSAGE, MESSAGE_ORDER); + setComparator(MESSAGE); + if (!isComparatorSet) + ((EventDetailsDialogAction) propertiesAction).setComparator(comparator); + applyFonts(); + } + }); + column3 = new TableColumn(table, SWT.NULL); + column3.setText(XDebugUIPlugin.getString("LogView.column.plugin")); //$NON-NLS-1$ + column3.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + PLUGIN_ORDER *= -1; + ViewerSorter sorter = getViewerSorter(PLUGIN); + tableTreeViewer.setSorter(sorter); + collator = sorter.getCollator(); + boolean isComparatorSet = ((EventDetailsDialogAction) propertiesAction).resetSelection(PLUGIN, PLUGIN_ORDER); + setComparator(PLUGIN); + if (!isComparatorSet) + ((EventDetailsDialogAction) propertiesAction).setComparator(comparator); + applyFonts(); + } + }); + column4 = new TableColumn(table, SWT.NULL); + column4.setText(XDebugUIPlugin.getString("LogView.column.date")); //$NON-NLS-1$ + column4.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if (DATE_ORDER == ASCENDING) { + DATE_ORDER = DESCENDING; + } else { + DATE_ORDER = ASCENDING; + } + ViewerSorter sorter = getViewerSorter(DATE); + tableTreeViewer.setSorter(sorter); + collator = sorter.getCollator(); + boolean isComparatorSet = ((EventDetailsDialogAction) propertiesAction).resetSelection(DATE, DATE_ORDER); + setComparator(DATE); + if (!isComparatorSet) + ((EventDetailsDialogAction) propertiesAction).setComparator(comparator); + applyFonts(); + } + }); + TableLayout tlayout = new TableLayout(); + tlayout.addColumnData(new ColumnPixelData(21)); + tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_1).intValue())); + tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_2).intValue())); + tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_3).intValue())); + tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_4).intValue())); + table.setLayout(tlayout); + table.setHeaderVisible(true); + } + + private void makeActions(Table table) { + propertiesAction = new EventDetailsDialogAction(table.getShell(), tableTreeViewer); + propertiesAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_PROPERTIES)); + propertiesAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_PROPERTIES)); + propertiesAction.setToolTipText(XDebugUIPlugin.getString("LogView.properties.tooltip")); //$NON-NLS-1$ + propertiesAction.setEnabled(false); + clearAction = new Action(XDebugUIPlugin.getString("LogView.clear")) { //$NON-NLS-1$ + public void run() { + handleClear(); + } + }; + clearAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_CLEAR)); + clearAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_CLEAR)); + clearAction.setToolTipText(XDebugUIPlugin.getString("LogView.clear.tooltip")); //$NON-NLS-1$ + clearAction.setText(XDebugUIPlugin.getString("LogView.clear")); //$NON-NLS-1$ + readLogAction = new Action(XDebugUIPlugin.getString("LogView.readLog.restore")) { //$NON-NLS-1$ + public void run() { + inputFile = Platform.getLogFileLocation().toFile(); + reloadLog(); + } + }; + readLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.readLog.restore.tooltip")); //$NON-NLS-1$ + readLogAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_READ_LOG)); + readLogAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_READ_LOG)); + deleteLogAction = new Action(XDebugUIPlugin.getString("LogView.delete")) { //$NON-NLS-1$ + public void run() { + doDeleteLog(); + } + }; + deleteLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.delete.tooltip")); //$NON-NLS-1$ + deleteLogAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_REMOVE_LOG)); + deleteLogAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_REMOVE_LOG)); + deleteLogAction.setEnabled(inputFile.exists() && inputFile.equals(Platform.getLogFileLocation().toFile())); + copyAction = new Action(XDebugUIPlugin.getString("LogView.copy")) { //$NON-NLS-1$ + public void run() { + copyToClipboard(tableTreeViewer.getSelection()); + } + }; + copyAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); + filterAction = new Action(XDebugUIPlugin.getString("LogView.filter")) { //$NON-NLS-1$ + public void run() { + handleFilter(); + } + }; + filterAction.setToolTipText(XDebugUIPlugin.getString("LogView.filter")); //$NON-NLS-1$ + filterAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_FILTER)); + filterAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_FILTER)); + exportAction = new Action(XDebugUIPlugin.getString("LogView.export")) { //$NON-NLS-1$ + public void run() { + handleExport(); + } + }; + exportAction.setToolTipText(XDebugUIPlugin.getString("LogView.export.tooltip")); //$NON-NLS-1$ + exportAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_EXPORT)); + exportAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_EXPORT)); + importAction = new Action(XDebugUIPlugin.getString("LogView.import")) { //$NON-NLS-1$ + public void run() { + handleImport(); + } + }; + importAction.setToolTipText(XDebugUIPlugin.getString("LogView.import.tooltip")); //$NON-NLS-1$ + importAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_IMPORT)); + importAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_IMPORT)); + activateViewAction = new Action(XDebugUIPlugin.getString("LogView.activate")) { //$NON-NLS-1$ + public void run() { + } + }; + activateViewAction.setChecked(memento.getString(P_ACTIVATE).equals("true")); //$NON-NLS-1$ + viewLogAction = new Action(XDebugUIPlugin.getString("LogView.view.currentLog")) { //$NON-NLS-1$ + public void run() { + if (inputFile.exists()) { + if (inputFile.length() > LogReader.MAX_FILE_LENGTH) { + OpenLogDialog openDialog = new OpenLogDialog(getViewSite().getShell(), inputFile); + openDialog.create(); + openDialog.open(); + } else { + boolean canLaunch = Program.launch(inputFile.getAbsolutePath()); + if (!canLaunch) { + Program p = Program.findProgram(".txt"); //$NON-NLS-1$ + if (p != null) + p.execute(inputFile.getAbsolutePath()); + else { + OpenLogDialog openDialog = new OpenLogDialog(getViewSite().getShell(), inputFile); + openDialog.create(); + openDialog.open(); + } + } + } + } + } + }; + viewLogAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_OPEN_LOG)); + viewLogAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_OPEN_LOG)); + viewLogAction.setEnabled(inputFile.exists()); + viewLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.view.currentLog.tooltip")); //$NON-NLS-1$ + } + + public void dispose() { + Platform.removeLogListener(this); + clipboard.dispose(); + LogReader.reset(); + boldFont.dispose(); + super.dispose(); + } + + private void handleImport() { + FileDialog dialog = new FileDialog(getViewSite().getShell()); + dialog.setFilterExtensions(new String[] { "*.log" }); //$NON-NLS-1$ + if (directory != null) + dialog.setFilterPath(directory); + String path = dialog.open(); + if (path != null && new Path(path).toFile().exists()) { + inputFile = new Path(path).toFile(); + directory = inputFile.getParent(); + IRunnableWithProgress op = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + monitor.beginTask(XDebugUIPlugin.getString("LogView.operation.importing"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$ + readLogFile(); + } + }; + ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell()); + try { + pmd.run(true, true, op); + } catch (InvocationTargetException e) { + } catch (InterruptedException e) { + } finally { + readLogAction.setText(XDebugUIPlugin.getString("LogView.readLog.reload")); //$NON-NLS-1$ + readLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.readLog.reload")); //$NON-NLS-1$ + asyncRefresh(false); + resetDialogButtons(); + } + } + } + + private void handleExport() { + FileDialog dialog = new FileDialog(getViewSite().getShell(), SWT.SAVE); + dialog.setFilterExtensions(new String[] { "*.log" }); //$NON-NLS-1$ + if (directory != null) + dialog.setFilterPath(directory); + String path = dialog.open(); + if (path != null) { + if (!path.endsWith(".log")) //$NON-NLS-1$ + path += ".log"; //$NON-NLS-1$ + File outputFile = new Path(path).toFile(); + directory = outputFile.getParent(); + if (outputFile.exists()) { + String message = "LogView.confirmOverwrite.message"; +// String message = PHPDebugUIPlugin.getFormattedMessage("LogView.confirmOverwrite.message", //$NON-NLS-1$ +// outputFile.toString()); + if (!MessageDialog.openQuestion(getViewSite().getShell(), exportAction.getText(), message)) + return; + } + copy(inputFile, 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(XDebugCorePlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), memento); + dialog.create(); + dialog.getShell().setText(XDebugUIPlugin.getString("LogView.FilterDialog.title")); //$NON-NLS-1$ + if (dialog.open() == FilterDialog.OK) + reloadLog(); + } + + private void doDeleteLog() { + String title = XDebugUIPlugin.getString("LogView.confirmDelete.title"); //$NON-NLS-1$ + String message = XDebugUIPlugin.getString("LogView.confirmDelete.message"); //$NON-NLS-1$ + if (!MessageDialog.openConfirm(tableTreeViewer.getControl().getShell(), title, message)) + return; + if (inputFile.delete()) { + logs.clear(); + asyncRefresh(false); + resetDialogButtons(); + } + } + + public void fillContextMenu(IMenuManager manager) { + manager.add(copyAction); + manager.add(new Separator()); + manager.add(clearAction); + manager.add(deleteLogAction); + manager.add(viewLogAction); + manager.add(readLogAction); + manager.add(new Separator()); + manager.add(exportAction); + manager.add(importAction); + manager.add(new Separator()); + ((EventDetailsDialogAction) propertiesAction).setComparator(comparator); + manager.add(propertiesAction); + } + + public LogEntry[] getLogs() { + return (LogEntry[]) logs.toArray(new LogEntry[logs.size()]); + } + + protected void handleClear() { + BusyIndicator.showWhile(tableTreeViewer.getControl().getDisplay(), new Runnable() { + public void run() { + logs.clear(); + asyncRefresh(false); + resetDialogButtons(); + } + }); + } + + protected void reloadLog() { + IRunnableWithProgress op = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + monitor.beginTask(XDebugUIPlugin.getString("LogView.operation.reloading"), //$NON-NLS-1$ + IProgressMonitor.UNKNOWN); + readLogFile(); + } + }; + ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell()); + try { + pmd.run(true, true, op); + } catch (InvocationTargetException e) { + } catch (InterruptedException e) { + } finally { + readLogAction.setText(XDebugUIPlugin.getString("LogView.readLog.restore")); //$NON-NLS-1$ + readLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.readLog.restore")); //$NON-NLS-1$ + asyncRefresh(false); + resetDialogButtons(); + } + } + + private void readLogFile() { + logs.clear(); + if (!inputFile.exists()) + return; + if (inputFile.length() > LogReader.MAX_FILE_LENGTH) + LogReader.parseLargeFile(inputFile, logs, memento); + else + LogReader.parseLogFile(inputFile, logs, memento); + } + + public void logging(IStatus status, String plugin) { + if (!inputFile.equals(Platform.getLogFileLocation().toFile())) + return; + if (firstEvent) { + readLogFile(); + asyncRefresh(); + firstEvent = false; + } else { + pushStatus(status); + } + } + + private void pushStatus(IStatus status) { + LogEntry entry = new LogEntry(status); + LogReader.addEntry(entry, logs, memento, true); + asyncRefresh(); + } + + private void asyncRefresh() { + asyncRefresh(true); + } + + private void asyncRefresh(final boolean activate) { + final Control control = tableTreeViewer.getControl(); + if (control.isDisposed()) + return; + Display display = control.getDisplay(); + final ViewPart view = this; + if (display != null) { + display.asyncExec(new Runnable() { + public void run() { + if (!control.isDisposed()) { + tableTreeViewer.refresh(); + deleteLogAction.setEnabled(inputFile.exists() && inputFile.equals(Platform.getLogFileLocation().toFile())); + viewLogAction.setEnabled(inputFile.exists()); + if (activate && activateViewAction.isChecked()) { + IWorkbenchPage page = XDebugCorePlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage(); + if (page != null) + page.bringToTop(view); + } + } + applyFonts(); + } + }); + } + } + + public void setFocus() { + if (tableTreeViewer != null && !tableTreeViewer.getTableTree().isDisposed()) + tableTreeViewer.getTableTree().getTable().setFocus(); + } + + private void handleSelectionChanged(ISelection selection) { + updateStatus(selection); + copyAction.setEnabled(!selection.isEmpty()); + propertiesAction.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) tableTreeViewer.getLabelProvider()).getColumnText(entry, 2)); + } + } + + 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 + clipboard.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.memento = XMLMemento.createWriteRoot("LOGVIEW"); //$NON-NLS-1$ + else + this.memento = memento; + initializeMemento(); + } + + private void initializeMemento() { + if (memento.getString(P_USE_LIMIT) == null) + memento.putString(P_USE_LIMIT, "true"); //$NON-NLS-1$ + if (memento.getInteger(P_LOG_LIMIT) == null) + memento.putInteger(P_LOG_LIMIT, 50); + if (memento.getString(P_LOG_INFO) == null) + memento.putString(P_LOG_INFO, "true"); //$NON-NLS-1$ + if (memento.getString(P_LOG_WARNING) == null) + memento.putString(P_LOG_WARNING, "true"); //$NON-NLS-1$ + if (memento.getString(P_LOG_ERROR) == null) + memento.putString(P_LOG_ERROR, "true"); //$NON-NLS-1$ + if (memento.getString(P_SHOW_ALL_SESSIONS) == null) + memento.putString(P_SHOW_ALL_SESSIONS, "true"); //$NON-NLS-1$ + Integer width = memento.getInteger(P_COLUMN_1); + if (width == null || width.intValue() == 0) + memento.putInteger(P_COLUMN_1, 20); + width = memento.getInteger(P_COLUMN_2); + if (width == null || width.intValue() == 0) + memento.putInteger(P_COLUMN_2, 300); + width = memento.getInteger(P_COLUMN_3); + if (width == null || width.intValue() == 0) + memento.putInteger(P_COLUMN_3, 150); + width = memento.getInteger(P_COLUMN_4); + if (width == null || width.intValue() == 0) + memento.putInteger(P_COLUMN_4, 150); + if (memento.getString(P_ACTIVATE) == null) + memento.putString(P_ACTIVATE, "true"); //$NON-NLS-1$ + } + + public void saveState(IMemento memento) { + if (this.memento == null || memento == null) + return; + this.memento.putInteger(P_COLUMN_1, column1.getWidth()); + this.memento.putInteger(P_COLUMN_2, column2.getWidth()); + this.memento.putInteger(P_COLUMN_3, column3.getWidth()); + this.memento.putInteger(P_COLUMN_4, column4.getWidth()); + this.memento.putString(P_ACTIVATE, activateViewAction.isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ + memento.putMemento(this.memento); + } + + 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++) { + tableTreeViewer.getTableTree().getTable().addListener(tableEvents[i], tableListener); + } + } + + private void makeHoverShell() { + Control control = tableTreeViewer.getControl(); + textShell = new Shell(control.getShell(), SWT.NO_FOCUS | SWT.ON_TOP); + Display display = textShell.getDisplay(); + textShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + GridLayout layout = new GridLayout(1, false); + int border = ((control.getShell().getStyle() & SWT.NO_TRIM) == 0) ? 0 : 1; + layout.marginHeight = border; + layout.marginWidth = border; + textShell.setLayout(layout); + textShell.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + Composite shellComposite = new Composite(textShell, 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)); + textLabel = new Text(shellComposite, SWT.WRAP | SWT.MULTI); + GridData gd = new GridData(GridData.FILL_BOTH); + gd.widthHint = 100; + gd.grabExcessHorizontalSpace = true; + textLabel.setLayoutData(gd); + Color c = control.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND); + textLabel.setBackground(c); + c = control.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND); + textLabel.setForeground(c); + textLabel.setEditable(false); + textShell.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + onTextShellDispose(e); + } + }); + } + + void onTextShellDispose(DisposeEvent e) { + canOpenTextShell = true; + setFocus(); + } + + void onMouseDown(Event e) { + if (textShell != null && !textShell.isDisposed() && !textShell.isFocusControl()) { + textShell.close(); + canOpenTextShell = true; + } + } + + void onMouseHover(Event e) { + if (!canOpenTextShell) + return; + canOpenTextShell = false; + Point point = new Point(e.x, e.y); + TableTree table = tableTreeViewer.getTableTree(); + TableTreeItem item = table.getItem(point); + if (item == null) + return; + String message = ((LogEntry) item.getData()).getStack(); + if (message == null) + return; + makeHoverShell(); + textLabel.setText(message); + int x = point.x + 5; + int y = point.y - (table.getItemHeight() * 2) - 20; + textShell.setLocation(table.toDisplay(x, y)); + textShell.setSize(tableTreeViewer.getTableTree().getSize().x - x, 125); + textShell.open(); + setFocus(); + } + + void onMouseMove(Event e) { + if (textShell != null && !textShell.isDisposed()) { + textShell.close(); + canOpenTextShell = textShell.isDisposed() && e.x > column0.getWidth() && e.x < (column0.getWidth() + column1.getWidth()); + } else { + canOpenTextShell = e.x > column0.getWidth() && e.x < (column0.getWidth() + column1.getWidth()); + } + } + + public Comparator getComparator() { + return comparator; + } + + private void setComparator(byte sortType) { + if (sortType == DATE) { + comparator = new Comparator() { + public int compare(Object e1, Object e2) { + try { + SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$ + Date date1 = formatter.parse(((LogEntry) e1).getDate()); + Date date2 = formatter.parse(((LogEntry) e2).getDate()); + if (DATE_ORDER == ASCENDING) + return date1.before(date2) ? -1 : 1; + return date1.after(date2) ? -1 : 1; + } catch (ParseException e) { + } + return 0; + } + }; + } else if (sortType == PLUGIN) { + comparator = new Comparator() { + public int compare(Object e1, Object e2) { + LogEntry entry1 = (LogEntry) e1; + LogEntry entry2 = (LogEntry) e2; + return collator.compare(entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER; + } + }; + } else { + comparator = new Comparator() { + public int compare(Object e1, Object e2) { + LogEntry entry1 = (LogEntry) e1; + LogEntry entry2 = (LogEntry) e2; + return collator.compare(entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER; + } + }; + } + } + + private ViewerSorter getViewerSorter(byte sortType) { + if (sortType == PLUGIN) { + return new ViewerSorter() { + public int compare(Viewer viewer, Object e1, Object e2) { + LogEntry entry1 = (LogEntry) e1; + LogEntry entry2 = (LogEntry) e2; + return super.compare(viewer, entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER; + } + }; + } else if (sortType == MESSAGE) { + return new ViewerSorter() { + public int compare(Viewer viewer, Object e1, Object e2) { + LogEntry entry1 = (LogEntry) e1; + LogEntry entry2 = (LogEntry) e2; + return super.compare(viewer, entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER; + } + }; + } else { + return new ViewerSorter() { + public int compare(Viewer viewer, Object e1, Object e2) { + try { + SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$ + Date date1 = formatter.parse(((LogEntry) e1).getDate()); + Date date2 = formatter.parse(((LogEntry) e2).getDate()); + if (DATE_ORDER == ASCENDING) + return date1.before(date2) ? -1 : 1; + return date1.after(date2) ? -1 : 1; + } catch (ParseException e) { + } + return 0; + } + }; + } + } + + private void resetDialogButtons() { + ((EventDetailsDialogAction) propertiesAction).resetDialogButtons(); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewContentProvider.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewContentProvider.java new file mode 100644 index 0000000..3a12f46 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewContentProvider.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.ui.views.logview; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class LogViewContentProvider + implements ITreeContentProvider, IStructuredContentProvider { + private LogView logView; + + public LogViewContentProvider(LogView logView) { + this.logView = logView; + } + public void dispose() { + } + public Object[] getChildren(Object element) { + return ((LogEntry) element).getChildren(element); + } + public Object[] getElements(Object element) { + return logView.getLogs(); + } + public Object getParent(Object element) { + return ((LogEntry) element).getParent(element); + } + public boolean hasChildren(Object element) { + return ((LogEntry) element).hasChildren(); + } + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + public boolean isDeleted(Object element) { + return false; + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewLabelProvider.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewLabelProvider.java new file mode 100644 index 0000000..2cc65c3 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewLabelProvider.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpeclipse.xdebug.ui.views.logview; + +import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPluginImages; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +public class LogViewLabelProvider + extends LabelProvider + implements ITableLabelProvider { + private Image infoImage; + private Image errorImage; + private Image warningImage; + private Image errorWithStackImage; + + public LogViewLabelProvider() { + errorImage = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_ERROR_ST_OBJ); + warningImage = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_WARNING_ST_OBJ); + infoImage = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_INFO_ST_OBJ); + errorWithStackImage = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_ERROR_STACK_OBJ); + } + public void dispose() { + errorImage.dispose(); + infoImage.dispose(); + warningImage.dispose(); + errorWithStackImage.dispose(); + super.dispose(); + } + public Image getColumnImage(Object element, int columnIndex) { + LogEntry entry = (LogEntry) element; + if (columnIndex == 1) { + switch (entry.getSeverity()) { + case IStatus.INFO : + return infoImage; + case IStatus.WARNING : + return warningImage; + case IStatus.ERROR : + return (entry.getStack() == null ? errorImage : errorWithStackImage); + } + } + return null; + } + + public String getColumnText(Object element, int columnIndex) { + LogEntry entry = (LogEntry) element; + switch (columnIndex) { + case 2 : + return entry.getMessage(); + case 3 : + return entry.getPluginId(); + case 4 : + return entry.getDate(); + } + return ""; //$NON-NLS-1$ + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/OpenLogDialog.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/OpenLogDialog.java new file mode 100644 index 0000000..c1b0bb1 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/OpenLogDialog.java @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright (c) 2003, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package net.sourceforge.phpeclipse.xdebug.ui.views.logview; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.RandomAccessFile; +import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; + +import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; +import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * Displays the error log in non-Win32 platforms - see bug 55314. + */ +public final class OpenLogDialog extends Dialog { + // input log file + private File logFile; + // location/size configuration + private IDialogSettings dialogSettings; + private Point dialogLocation; + private Point dialogSize; + private int DEFAULT_WIDTH = 750; + private int DEFAULT_HEIGHT = 800; + + public OpenLogDialog(Shell parentShell, File logFile) { + super(parentShell); + this.logFile = logFile; + setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.MIN | SWT.MODELESS); + + } + + /* + * (non-Javadoc) Method declared on Window. + */ + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(XDebugUIPlugin.getString("OpenLogDialog.title")); //$NON-NLS-1$ + readConfiguration(); + } + + /* + * (non-Javadoc) Method declared on Dialog. + */ + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, + true); + } + + public void create() { + super.create(); + // dialog location + if (dialogLocation != null) + getShell().setLocation(dialogLocation); + // dialog size + if (dialogSize != null) + getShell().setSize(dialogSize); + else + getShell().setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); + getButton(IDialogConstants.CLOSE_ID).setFocus(); + } + + /* + * (non-Javadoc) Method declared on Dialog. + */ + protected Control createDialogArea(Composite parent) { + Composite outer = (Composite) super.createDialogArea(parent); + Text text = new Text(outer, SWT.MULTI | SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL + | SWT.NO_FOCUS | SWT.H_SCROLL); + text.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL + | GridData.VERTICAL_ALIGN_FILL); + gridData.grabExcessVerticalSpace = true; + gridData.grabExcessHorizontalSpace = true; + text.setLayoutData(gridData); + text.setText(getLogSummary()); + return outer; + } + + private String getLogSummary() { + StringWriter out = new StringWriter(); + PrintWriter writer = new PrintWriter(out); + if (logFile.length() > LogReader.MAX_FILE_LENGTH) { + readLargeFileWithMonitor(writer); + } else { + readFileWithMonitor(writer); + } + writer.close(); + return out.toString(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int) + */ + protected void buttonPressed(int buttonId) { + if (buttonId == IDialogConstants.CLOSE_ID) { + storeSettings(); + close(); + } + super.buttonPressed(buttonId); + } + + //--------------- configuration handling -------------- + /** + * Stores the current state in the dialog settings. + * + * @since 2.0 + */ + private void storeSettings() { + writeConfiguration(); + } + + /** + * Returns the dialog settings object used to share state between several + * event detail dialogs. + * + * @return the dialog settings to be used + */ + private IDialogSettings getDialogSettings() { + IDialogSettings settings = XDebugCorePlugin.getDefault().getDialogSettings(); + dialogSettings = settings.getSection(getClass().getName()); + if (dialogSettings == null) + dialogSettings = settings.addNewSection(getClass().getName()); + return dialogSettings; + } + + /** + * Initializes itself from the dialog settings with the same state as at the + * previous invocation. + */ + private void readConfiguration() { + IDialogSettings s = getDialogSettings(); + try { + int x = s.getInt("x"); //$NON-NLS-1$ + int y = s.getInt("y"); //$NON-NLS-1$ + dialogLocation = new Point(x, y); + x = s.getInt("width"); //$NON-NLS-1$ + y = s.getInt("height"); //$NON-NLS-1$ + dialogSize = new Point(x, y); + } catch (NumberFormatException e) { + dialogLocation = null; + dialogSize = null; + } + } + + private void writeConfiguration() { + IDialogSettings s = getDialogSettings(); + Point location = getShell().getLocation(); + s.put("x", location.x); //$NON-NLS-1$ + s.put("y", location.y); //$NON-NLS-1$ + Point size = getShell().getSize(); + s.put("width", size.x); //$NON-NLS-1$ + s.put("height", size.y); //$NON-NLS-1$ + } + + // reading file within MAX_FILE_LENGTH size + private void readFile(PrintWriter writer) throws FileNotFoundException, IOException { + BufferedReader bReader = new BufferedReader(new FileReader(logFile)); + while (bReader.ready()) + writer.println(bReader.readLine()); + } + + // reading large files + private void readLargeFile(PrintWriter writer) throws FileNotFoundException, + IOException { + RandomAccessFile random = null; + boolean hasStarted = false; + try { + random = new RandomAccessFile(logFile, "r"); //$NON-NLS-1$ + random.seek(logFile.length() - LogReader.MAX_FILE_LENGTH); + for (;;) { + String line = random.readLine(); + if (line == null) + break; + line = line.trim(); + if (line.length() == 0) + continue; + if (!hasStarted + && (line.startsWith("!ENTRY") || line.startsWith("!SESSION"))) //$NON-NLS-1$ //$NON-NLS-2$ + hasStarted = true; + if (hasStarted) + writer.println(line); + continue; + } + } finally { + try { + if (random != null) + random.close(); + } catch (IOException e1) { + } + } + } + + private void readLargeFileWithMonitor(final PrintWriter writer) { + IRunnableWithProgress runnable = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, + InterruptedException { + monitor + .beginTask( + XDebugUIPlugin.getString("OpenLogDialog.message"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$ + try { + readLargeFile(writer); + } catch (IOException e) { + writer.println(XDebugUIPlugin.getString("OpenLogDialog.cannotDisplay")); //$NON-NLS-1$ + } + } + }; + ProgressMonitorDialog dialog = new ProgressMonitorDialog(getParentShell()); + try { + dialog.run(true, true, runnable); + } catch (InvocationTargetException e) { + } catch (InterruptedException e) { + } + } + + private void readFileWithMonitor(final PrintWriter writer) { + IRunnableWithProgress runnable = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, + InterruptedException { + monitor + .beginTask( + XDebugUIPlugin + .getString("OpenLogDialog.message"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$ + try { + readFile(writer); + } catch (IOException e) { + writer.println(XDebugUIPlugin + .getString("OpenLogDialog.cannotDisplay")); //$NON-NLS-1$ + } + } + }; + ProgressMonitorDialog dialog = new ProgressMonitorDialog(getParentShell()); + try { + dialog.run(true, true, runnable); + } catch (InvocationTargetException e) { + } catch (InterruptedException e) { + } + } +} -- 1.7.1