1 /***********************************************************************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made
3 * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
4 * http://www.eclipse.org/legal/cpl-v10.html
6 * Contributors: IBM Corporation - initial API and implementation
7 **********************************************************************************************************************************/
9 package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
11 import java.io.BufferedReader;
12 import java.io.BufferedWriter;
14 import java.io.FileInputStream;
15 import java.io.FileOutputStream;
16 import java.io.IOException;
17 import java.io.InputStreamReader;
18 import java.io.OutputStreamWriter;
19 import java.io.PrintWriter;
20 import java.io.StringWriter;
21 import java.lang.reflect.InvocationTargetException;
22 import java.text.Collator;
23 import java.text.ParseException;
24 import java.text.SimpleDateFormat;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Comparator;
28 import java.util.Date;
30 import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
31 import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin;
32 import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPluginImages;
34 import org.eclipse.core.runtime.ILogListener;
35 import org.eclipse.core.runtime.IProgressMonitor;
36 import org.eclipse.core.runtime.IStatus;
37 import org.eclipse.core.runtime.Path;
38 import org.eclipse.core.runtime.Platform;
39 import org.eclipse.jface.action.Action;
40 import org.eclipse.jface.action.IMenuListener;
41 import org.eclipse.jface.action.IMenuManager;
42 import org.eclipse.jface.action.IStatusLineManager;
43 import org.eclipse.jface.action.IToolBarManager;
44 import org.eclipse.jface.action.MenuManager;
45 import org.eclipse.jface.action.Separator;
46 import org.eclipse.jface.dialogs.MessageDialog;
47 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
48 import org.eclipse.jface.operation.IRunnableWithProgress;
49 import org.eclipse.jface.viewers.ColumnPixelData;
50 import org.eclipse.jface.viewers.DoubleClickEvent;
51 import org.eclipse.jface.viewers.IDoubleClickListener;
52 import org.eclipse.jface.viewers.ISelection;
53 import org.eclipse.jface.viewers.ISelectionChangedListener;
54 import org.eclipse.jface.viewers.IStructuredSelection;
55 import org.eclipse.jface.viewers.ITreeViewerListener;
56 import org.eclipse.jface.viewers.SelectionChangedEvent;
57 import org.eclipse.jface.viewers.TableLayout;
58 import org.eclipse.jface.viewers.TableTreeViewer;
59 import org.eclipse.jface.viewers.TreeExpansionEvent;
60 import org.eclipse.jface.viewers.Viewer;
61 import org.eclipse.jface.viewers.ViewerSorter;
62 import org.eclipse.swt.SWT;
63 import org.eclipse.swt.custom.BusyIndicator;
64 import org.eclipse.swt.custom.TableTree;
65 import org.eclipse.swt.custom.TableTreeItem;
66 import org.eclipse.swt.dnd.Clipboard;
67 import org.eclipse.swt.dnd.TextTransfer;
68 import org.eclipse.swt.dnd.Transfer;
69 import org.eclipse.swt.events.DisposeEvent;
70 import org.eclipse.swt.events.DisposeListener;
71 import org.eclipse.swt.events.SelectionAdapter;
72 import org.eclipse.swt.events.SelectionEvent;
73 import org.eclipse.swt.graphics.Color;
74 import org.eclipse.swt.graphics.Font;
75 import org.eclipse.swt.graphics.FontData;
76 import org.eclipse.swt.graphics.Point;
77 import org.eclipse.swt.layout.GridData;
78 import org.eclipse.swt.layout.GridLayout;
79 import org.eclipse.swt.program.Program;
80 import org.eclipse.swt.widgets.Composite;
81 import org.eclipse.swt.widgets.Control;
82 import org.eclipse.swt.widgets.Display;
83 import org.eclipse.swt.widgets.Event;
84 import org.eclipse.swt.widgets.FileDialog;
85 import org.eclipse.swt.widgets.Listener;
86 import org.eclipse.swt.widgets.Menu;
87 import org.eclipse.swt.widgets.Shell;
88 import org.eclipse.swt.widgets.Table;
89 import org.eclipse.swt.widgets.TableColumn;
90 import org.eclipse.swt.widgets.TableItem;
91 import org.eclipse.swt.widgets.Text;
92 import org.eclipse.ui.IActionBars;
93 import org.eclipse.ui.IMemento;
94 import org.eclipse.ui.ISharedImages;
95 import org.eclipse.ui.IViewSite;
96 import org.eclipse.ui.IWorkbenchPage;
97 import org.eclipse.ui.PartInitException;
98 import org.eclipse.ui.PlatformUI;
99 import org.eclipse.ui.XMLMemento;
100 import org.eclipse.ui.actions.ActionFactory;
101 import org.eclipse.ui.part.ViewPart;
103 public class LogView extends ViewPart implements ILogListener {
104 public final static String ID_LOGVIEW = "net.sourceforge.phpdt.internal.debug.core.logview.LogView"; //$NON-NLS-1$
106 private TableTreeViewer tableTreeViewer;
108 private ArrayList logs = new ArrayList();
110 public static final String P_LOG_WARNING = "warning"; //$NON-NLS-1$
112 public static final String P_LOG_ERROR = "error"; //$NON-NLS-1$
114 public static final String P_LOG_INFO = "info"; //$NON-NLS-1$
116 public static final String P_LOG_LIMIT = "limit"; //$NON-NLS-1$
118 public static final String P_USE_LIMIT = "useLimit"; //$NON-NLS-1$
120 public static final String P_SHOW_ALL_SESSIONS = "allSessions"; //$NON-NLS-1$
122 private static final String P_COLUMN_1 = "column1"; //$NON-NLS-1$
124 private static final String P_COLUMN_2 = "column2"; //$NON-NLS-1$
126 private static final String P_COLUMN_3 = "column3"; //$NON-NLS-1$
128 private static final String P_COLUMN_4 = "column4"; //$NON-NLS-1$
130 public static final String P_ACTIVATE = "activate"; //$NON-NLS-1$
132 private int MESSAGE_ORDER = -1;
134 private int PLUGIN_ORDER = -1;
136 private int DATE_ORDER = -1;
138 public static byte MESSAGE = 0x0;
140 public static byte PLUGIN = 0x1;
142 public static byte DATE = 0x2;
144 private static int ASCENDING = 1;
146 private static int DESCENDING = -1;
148 private Action clearAction;
150 private Action copyAction;
152 private Action readLogAction;
154 private Action deleteLogAction;
156 private Action exportAction;
158 private Action importAction;
160 private Action activateViewAction;
162 private Action propertiesAction;
164 private Action viewLogAction;
166 private Action filterAction;
168 private Clipboard clipboard;
170 private IMemento memento;
172 private File inputFile;
174 private String directory;
176 private TableColumn column0;
178 private TableColumn column1;
180 private TableColumn column2;
182 private TableColumn column3;
184 private TableColumn column4;
186 private static Font boldFont;
188 private Comparator comparator;
190 private Collator collator;
193 private boolean canOpenTextShell;
195 private Text textLabel;
197 private Shell textShell;
199 private boolean firstEvent = true;
202 logs = new ArrayList();
203 inputFile = Platform.getLogFileLocation().toFile();
206 public void createPartControl(Composite parent) {
208 TableTree tableTree = new TableTree(parent, SWT.FULL_SELECTION);
209 tableTree.setLayoutData(new GridData(GridData.FILL_BOTH));
210 createColumns(tableTree.getTable());
211 createViewer(tableTree);
212 createPopupMenuManager(tableTree);
213 makeActions(tableTree.getTable());
215 Platform.addLogListener(this);
216 getSite().setSelectionProvider(tableTreeViewer);
217 clipboard = new Clipboard(tableTree.getDisplay());
218 // WorkbenchHelp.setHelp(tableTree, IHelpContextIds.LOG_VIEW);
219 tableTreeViewer.getTableTree().getTable().setToolTipText(""); //$NON-NLS-1$
224 private void initializeFonts() {
225 Font tableFont = tableTreeViewer.getTableTree().getFont();
226 FontData[] fontDataList = tableFont.getFontData();
228 if (fontDataList.length > 0)
229 fontData = fontDataList[0];
231 fontData = new FontData();
232 fontData.setStyle(SWT.BOLD);
233 boldFont = new Font(tableTreeViewer.getTableTree().getDisplay(), fontData);
237 * Set all rows where the tableTreeItem has children to have a <b>bold </b> font.
239 private void applyFonts() {
240 if (tableTreeViewer == null || tableTreeViewer.getTableTree().isDisposed())
242 int max = tableTreeViewer.getTableTree().getItemCount();
243 int index = 0, tableIndex = 0;
244 while (index < max) {
245 LogEntry entry = (LogEntry) tableTreeViewer.getElementAt(index);
248 if (entry.hasChildren()) {
249 tableTreeViewer.getTableTree().getItems()[index].setFont(boldFont);
250 tableIndex = applyChildFonts(entry, tableIndex);
252 tableTreeViewer.getTableTree().getItems()[index].setFont(tableTreeViewer.getTableTree().getFont());
259 private int applyChildFonts(LogEntry parent, int index) {
260 if (!tableTreeViewer.getExpandedState(parent) || !parent.hasChildren())
262 LogEntry[] children = getEntryChildren(parent);
263 for (int i = 0; i < children.length; i++) {
265 if (children[i].hasChildren()) {
266 TableItem tableItem = getTableItem(index);
267 if (tableItem != null) {
268 tableItem.setFont(boldFont);
270 index = applyChildFonts(children[i], index);
272 TableItem tableItem = getTableItem(index);
273 if (tableItem != null) {
274 tableItem.setFont(tableTreeViewer.getTableTree().getFont());
281 private LogEntry[] getEntryChildren(LogEntry parent) {
282 Object[] entryChildren = parent.getChildren(parent);
283 if (comparator != null)
284 Arrays.sort(entryChildren, comparator);
285 LogEntry[] children = new LogEntry[entryChildren.length];
286 System.arraycopy(entryChildren, 0, children, 0, entryChildren.length);
290 private TableItem getTableItem(int index) {
291 TableItem[] tableItems = tableTreeViewer.getTableTree().getTable().getItems();
292 if (index > tableItems.length - 1)
294 return tableItems[index];
297 private void fillToolBar() {
298 IActionBars bars = getViewSite().getActionBars();
299 bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
300 IToolBarManager toolBarManager = bars.getToolBarManager();
301 toolBarManager.add(exportAction);
302 toolBarManager.add(importAction);
303 toolBarManager.add(new Separator());
304 toolBarManager.add(clearAction);
305 toolBarManager.add(deleteLogAction);
306 toolBarManager.add(viewLogAction);
307 toolBarManager.add(readLogAction);
308 toolBarManager.add(new Separator());
309 IMenuManager mgr = bars.getMenuManager();
310 mgr.add(filterAction);
311 mgr.add(new Separator());
312 mgr.add(activateViewAction);
315 private void createViewer(TableTree tableTree) {
316 tableTreeViewer = new TableTreeViewer(tableTree);
317 tableTreeViewer.setContentProvider(new LogViewContentProvider(this));
318 tableTreeViewer.setLabelProvider(new LogViewLabelProvider());
319 tableTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
320 public void selectionChanged(SelectionChangedEvent e) {
321 handleSelectionChanged(e.getSelection());
322 if (propertiesAction.isEnabled())
323 ((EventDetailsDialogAction) propertiesAction).resetSelection();
326 tableTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
327 public void doubleClick(DoubleClickEvent event) {
328 ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
329 propertiesAction.run();
332 tableTreeViewer.addTreeListener(new ITreeViewerListener() {
333 public void treeCollapsed(TreeExpansionEvent event) {
337 public void treeExpanded(TreeExpansionEvent event) {
342 tableTreeViewer.setInput(Platform.class);
345 private void createPopupMenuManager(TableTree tableTree) {
346 MenuManager popupMenuManager = new MenuManager();
347 IMenuListener listener = new IMenuListener() {
348 public void menuAboutToShow(IMenuManager mng) {
349 fillContextMenu(mng);
352 popupMenuManager.addMenuListener(listener);
353 popupMenuManager.setRemoveAllWhenShown(true);
354 Menu menu = popupMenuManager.createContextMenu(tableTree);
355 tableTree.setMenu(menu);
358 private void createColumns(Table table) {
359 column0 = new TableColumn(table, SWT.NULL);
360 column0.setText(""); //$NON-NLS-1$
361 column1 = new TableColumn(table, SWT.NULL);
362 column1.setText(XDebugUIPlugin.getString("LogView.column.severity")); //$NON-NLS-1$
363 column2 = new TableColumn(table, SWT.NULL);
364 column2.setText(XDebugUIPlugin.getString("LogView.column.message")); //$NON-NLS-1$
365 column2.addSelectionListener(new SelectionAdapter() {
366 public void widgetSelected(SelectionEvent e) {
368 ViewerSorter sorter = getViewerSorter(MESSAGE);
369 tableTreeViewer.setSorter(sorter);
370 collator = sorter.getCollator();
371 boolean isComparatorSet = ((EventDetailsDialogAction) propertiesAction).resetSelection(MESSAGE, MESSAGE_ORDER);
372 setComparator(MESSAGE);
373 if (!isComparatorSet)
374 ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
378 column3 = new TableColumn(table, SWT.NULL);
379 column3.setText(XDebugUIPlugin.getString("LogView.column.plugin")); //$NON-NLS-1$
380 column3.addSelectionListener(new SelectionAdapter() {
381 public void widgetSelected(SelectionEvent e) {
383 ViewerSorter sorter = getViewerSorter(PLUGIN);
384 tableTreeViewer.setSorter(sorter);
385 collator = sorter.getCollator();
386 boolean isComparatorSet = ((EventDetailsDialogAction) propertiesAction).resetSelection(PLUGIN, PLUGIN_ORDER);
387 setComparator(PLUGIN);
388 if (!isComparatorSet)
389 ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
393 column4 = new TableColumn(table, SWT.NULL);
394 column4.setText(XDebugUIPlugin.getString("LogView.column.date")); //$NON-NLS-1$
395 column4.addSelectionListener(new SelectionAdapter() {
396 public void widgetSelected(SelectionEvent e) {
397 if (DATE_ORDER == ASCENDING) {
398 DATE_ORDER = DESCENDING;
400 DATE_ORDER = ASCENDING;
402 ViewerSorter sorter = getViewerSorter(DATE);
403 tableTreeViewer.setSorter(sorter);
404 collator = sorter.getCollator();
405 boolean isComparatorSet = ((EventDetailsDialogAction) propertiesAction).resetSelection(DATE, DATE_ORDER);
407 if (!isComparatorSet)
408 ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
412 TableLayout tlayout = new TableLayout();
413 tlayout.addColumnData(new ColumnPixelData(21));
414 tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_1).intValue()));
415 tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_2).intValue()));
416 tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_3).intValue()));
417 tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_4).intValue()));
418 table.setLayout(tlayout);
419 table.setHeaderVisible(true);
422 private void makeActions(Table table) {
423 propertiesAction = new EventDetailsDialogAction(table.getShell(), tableTreeViewer);
424 propertiesAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_PROPERTIES));
425 propertiesAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_PROPERTIES));
426 propertiesAction.setToolTipText(XDebugUIPlugin.getString("LogView.properties.tooltip")); //$NON-NLS-1$
427 propertiesAction.setEnabled(false);
428 clearAction = new Action(XDebugUIPlugin.getString("LogView.clear")) { //$NON-NLS-1$
433 clearAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_CLEAR));
434 clearAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_CLEAR));
435 clearAction.setToolTipText(XDebugUIPlugin.getString("LogView.clear.tooltip")); //$NON-NLS-1$
436 clearAction.setText(XDebugUIPlugin.getString("LogView.clear")); //$NON-NLS-1$
437 readLogAction = new Action(XDebugUIPlugin.getString("LogView.readLog.restore")) { //$NON-NLS-1$
439 inputFile = Platform.getLogFileLocation().toFile();
443 readLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.readLog.restore.tooltip")); //$NON-NLS-1$
444 readLogAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_READ_LOG));
445 readLogAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_READ_LOG));
446 deleteLogAction = new Action(XDebugUIPlugin.getString("LogView.delete")) { //$NON-NLS-1$
451 deleteLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.delete.tooltip")); //$NON-NLS-1$
452 deleteLogAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_REMOVE_LOG));
453 deleteLogAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_REMOVE_LOG));
454 deleteLogAction.setEnabled(inputFile.exists() && inputFile.equals(Platform.getLogFileLocation().toFile()));
455 copyAction = new Action(XDebugUIPlugin.getString("LogView.copy")) { //$NON-NLS-1$
457 copyToClipboard(tableTreeViewer.getSelection());
460 copyAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
461 filterAction = new Action(XDebugUIPlugin.getString("LogView.filter")) { //$NON-NLS-1$
466 filterAction.setToolTipText(XDebugUIPlugin.getString("LogView.filter")); //$NON-NLS-1$
467 filterAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_FILTER));
468 filterAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_FILTER));
469 exportAction = new Action(XDebugUIPlugin.getString("LogView.export")) { //$NON-NLS-1$
474 exportAction.setToolTipText(XDebugUIPlugin.getString("LogView.export.tooltip")); //$NON-NLS-1$
475 exportAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_EXPORT));
476 exportAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_EXPORT));
477 importAction = new Action(XDebugUIPlugin.getString("LogView.import")) { //$NON-NLS-1$
482 importAction.setToolTipText(XDebugUIPlugin.getString("LogView.import.tooltip")); //$NON-NLS-1$
483 importAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_IMPORT));
484 importAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_IMPORT));
485 activateViewAction = new Action(XDebugUIPlugin.getString("LogView.activate")) { //$NON-NLS-1$
489 activateViewAction.setChecked(memento.getString(P_ACTIVATE).equals("true")); //$NON-NLS-1$
490 viewLogAction = new Action(XDebugUIPlugin.getString("LogView.view.currentLog")) { //$NON-NLS-1$
492 if (inputFile.exists()) {
493 if (inputFile.length() > LogReader.MAX_FILE_LENGTH) {
494 OpenLogDialog openDialog = new OpenLogDialog(getViewSite().getShell(), inputFile);
498 boolean canLaunch = Program.launch(inputFile.getAbsolutePath());
500 Program p = Program.findProgram(".txt"); //$NON-NLS-1$
502 p.execute(inputFile.getAbsolutePath());
504 OpenLogDialog openDialog = new OpenLogDialog(getViewSite().getShell(), inputFile);
513 viewLogAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_OPEN_LOG));
514 viewLogAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_OPEN_LOG));
515 viewLogAction.setEnabled(inputFile.exists());
516 viewLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.view.currentLog.tooltip")); //$NON-NLS-1$
519 public void dispose() {
520 Platform.removeLogListener(this);
527 private void handleImport() {
528 FileDialog dialog = new FileDialog(getViewSite().getShell());
529 dialog.setFilterExtensions(new String[] { "*.log" }); //$NON-NLS-1$
530 if (directory != null)
531 dialog.setFilterPath(directory);
532 String path = dialog.open();
533 if (path != null && new Path(path).toFile().exists()) {
534 inputFile = new Path(path).toFile();
535 directory = inputFile.getParent();
536 IRunnableWithProgress op = new IRunnableWithProgress() {
537 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
538 monitor.beginTask(XDebugUIPlugin.getString("LogView.operation.importing"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
542 ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell());
544 pmd.run(true, true, op);
545 } catch (InvocationTargetException e) {
546 } catch (InterruptedException e) {
548 readLogAction.setText(XDebugUIPlugin.getString("LogView.readLog.reload")); //$NON-NLS-1$
549 readLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.readLog.reload")); //$NON-NLS-1$
551 resetDialogButtons();
556 private void handleExport() {
557 FileDialog dialog = new FileDialog(getViewSite().getShell(), SWT.SAVE);
558 dialog.setFilterExtensions(new String[] { "*.log" }); //$NON-NLS-1$
559 if (directory != null)
560 dialog.setFilterPath(directory);
561 String path = dialog.open();
563 if (!path.endsWith(".log")) //$NON-NLS-1$
564 path += ".log"; //$NON-NLS-1$
565 File outputFile = new Path(path).toFile();
566 directory = outputFile.getParent();
567 if (outputFile.exists()) {
568 String message = "LogView.confirmOverwrite.message";
569 // String message = PHPDebugUIPlugin.getFormattedMessage("LogView.confirmOverwrite.message", //$NON-NLS-1$
570 // outputFile.toString());
571 if (!MessageDialog.openQuestion(getViewSite().getShell(), exportAction.getText(), message))
574 copy(inputFile, outputFile);
578 private void copy(File inputFile, File outputFile) {
579 BufferedReader reader = null;
580 BufferedWriter writer = null;
582 reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), "UTF-8")); //$NON-NLS-1$
583 writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")); //$NON-NLS-1$
584 while (reader.ready()) {
585 writer.write(reader.readLine());
586 writer.write(System.getProperty("line.separator")); //$NON-NLS-1$
588 } catch (IOException e) {
595 } catch (IOException e1) {
600 private void handleFilter() {
601 FilterDialog dialog = new FilterDialog(XDebugCorePlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), memento);
603 dialog.getShell().setText(XDebugUIPlugin.getString("LogView.FilterDialog.title")); //$NON-NLS-1$
604 if (dialog.open() == FilterDialog.OK)
608 private void doDeleteLog() {
609 String title = XDebugUIPlugin.getString("LogView.confirmDelete.title"); //$NON-NLS-1$
610 String message = XDebugUIPlugin.getString("LogView.confirmDelete.message"); //$NON-NLS-1$
611 if (!MessageDialog.openConfirm(tableTreeViewer.getControl().getShell(), title, message))
613 if (inputFile.delete()) {
616 resetDialogButtons();
620 public void fillContextMenu(IMenuManager manager) {
621 manager.add(copyAction);
622 manager.add(new Separator());
623 manager.add(clearAction);
624 manager.add(deleteLogAction);
625 manager.add(viewLogAction);
626 manager.add(readLogAction);
627 manager.add(new Separator());
628 manager.add(exportAction);
629 manager.add(importAction);
630 manager.add(new Separator());
631 ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
632 manager.add(propertiesAction);
635 public LogEntry[] getLogs() {
636 return (LogEntry[]) logs.toArray(new LogEntry[logs.size()]);
639 protected void handleClear() {
640 BusyIndicator.showWhile(tableTreeViewer.getControl().getDisplay(), new Runnable() {
644 resetDialogButtons();
649 protected void reloadLog() {
650 IRunnableWithProgress op = new IRunnableWithProgress() {
651 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
652 monitor.beginTask(XDebugUIPlugin.getString("LogView.operation.reloading"), //$NON-NLS-1$
653 IProgressMonitor.UNKNOWN);
657 ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell());
659 pmd.run(true, true, op);
660 } catch (InvocationTargetException e) {
661 } catch (InterruptedException e) {
663 readLogAction.setText(XDebugUIPlugin.getString("LogView.readLog.restore")); //$NON-NLS-1$
664 readLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.readLog.restore")); //$NON-NLS-1$
666 resetDialogButtons();
670 private void readLogFile() {
672 if (!inputFile.exists())
674 if (inputFile.length() > LogReader.MAX_FILE_LENGTH)
675 LogReader.parseLargeFile(inputFile, logs, memento);
677 LogReader.parseLogFile(inputFile, logs, memento);
680 public void logging(IStatus status, String plugin) {
681 if (!inputFile.equals(Platform.getLogFileLocation().toFile()))
692 private void pushStatus(IStatus status) {
693 LogEntry entry = new LogEntry(status);
694 LogReader.addEntry(entry, logs, memento, true);
698 private void asyncRefresh() {
702 private void asyncRefresh(final boolean activate) {
703 final Control control = tableTreeViewer.getControl();
704 if (control.isDisposed())
706 Display display = control.getDisplay();
707 final ViewPart view = this;
708 if (display != null) {
709 display.asyncExec(new Runnable() {
711 if (!control.isDisposed()) {
712 tableTreeViewer.refresh();
713 deleteLogAction.setEnabled(inputFile.exists() && inputFile.equals(Platform.getLogFileLocation().toFile()));
714 viewLogAction.setEnabled(inputFile.exists());
715 if (activate && activateViewAction.isChecked()) {
716 IWorkbenchPage page = XDebugCorePlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
718 page.bringToTop(view);
727 public void setFocus() {
728 if (tableTreeViewer != null && !tableTreeViewer.getTableTree().isDisposed())
729 tableTreeViewer.getTableTree().getTable().setFocus();
732 private void handleSelectionChanged(ISelection selection) {
733 updateStatus(selection);
734 copyAction.setEnabled(!selection.isEmpty());
735 propertiesAction.setEnabled(!selection.isEmpty());
738 private void updateStatus(ISelection selection) {
739 IStatusLineManager status = getViewSite().getActionBars().getStatusLineManager();
740 if (selection.isEmpty())
741 status.setMessage(null);
743 LogEntry entry = (LogEntry) ((IStructuredSelection) selection).getFirstElement();
744 status.setMessage(((LogViewLabelProvider) tableTreeViewer.getLabelProvider()).getColumnText(entry, 2));
748 private void copyToClipboard(ISelection selection) {
749 StringWriter writer = new StringWriter();
750 PrintWriter pwriter = new PrintWriter(writer);
751 if (selection.isEmpty())
753 LogEntry entry = (LogEntry) ((IStructuredSelection) selection).getFirstElement();
754 entry.write(pwriter);
756 String textVersion = writer.toString();
760 } catch (IOException e) {
762 if (textVersion.trim().length() > 0) {
763 // set the clipboard contents
764 clipboard.setContents(new Object[] { textVersion }, new Transfer[] { TextTransfer.getInstance() });
768 public void init(IViewSite site, IMemento memento) throws PartInitException {
769 super.init(site, memento);
771 this.memento = XMLMemento.createWriteRoot("LOGVIEW"); //$NON-NLS-1$
773 this.memento = memento;
777 private void initializeMemento() {
778 if (memento.getString(P_USE_LIMIT) == null)
779 memento.putString(P_USE_LIMIT, "true"); //$NON-NLS-1$
780 if (memento.getInteger(P_LOG_LIMIT) == null)
781 memento.putInteger(P_LOG_LIMIT, 50);
782 if (memento.getString(P_LOG_INFO) == null)
783 memento.putString(P_LOG_INFO, "true"); //$NON-NLS-1$
784 if (memento.getString(P_LOG_WARNING) == null)
785 memento.putString(P_LOG_WARNING, "true"); //$NON-NLS-1$
786 if (memento.getString(P_LOG_ERROR) == null)
787 memento.putString(P_LOG_ERROR, "true"); //$NON-NLS-1$
788 if (memento.getString(P_SHOW_ALL_SESSIONS) == null)
789 memento.putString(P_SHOW_ALL_SESSIONS, "true"); //$NON-NLS-1$
790 Integer width = memento.getInteger(P_COLUMN_1);
791 if (width == null || width.intValue() == 0)
792 memento.putInteger(P_COLUMN_1, 20);
793 width = memento.getInteger(P_COLUMN_2);
794 if (width == null || width.intValue() == 0)
795 memento.putInteger(P_COLUMN_2, 300);
796 width = memento.getInteger(P_COLUMN_3);
797 if (width == null || width.intValue() == 0)
798 memento.putInteger(P_COLUMN_3, 150);
799 width = memento.getInteger(P_COLUMN_4);
800 if (width == null || width.intValue() == 0)
801 memento.putInteger(P_COLUMN_4, 150);
802 if (memento.getString(P_ACTIVATE) == null)
803 memento.putString(P_ACTIVATE, "true"); //$NON-NLS-1$
806 public void saveState(IMemento memento) {
807 if (this.memento == null || memento == null)
809 this.memento.putInteger(P_COLUMN_1, column1.getWidth());
810 this.memento.putInteger(P_COLUMN_2, column2.getWidth());
811 this.memento.putInteger(P_COLUMN_3, column3.getWidth());
812 this.memento.putInteger(P_COLUMN_4, column4.getWidth());
813 this.memento.putString(P_ACTIVATE, activateViewAction.isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
814 memento.putMemento(this.memento);
817 private void addMouseListeners() {
818 Listener tableListener = new Listener() {
819 public void handleEvent(Event e) {
833 int[] tableEvents = new int[] { SWT.MouseDown, SWT.MouseMove, SWT.MouseHover };
834 for (int i = 0; i < tableEvents.length; i++) {
835 tableTreeViewer.getTableTree().getTable().addListener(tableEvents[i], tableListener);
839 private void makeHoverShell() {
840 Control control = tableTreeViewer.getControl();
841 textShell = new Shell(control.getShell(), SWT.NO_FOCUS | SWT.ON_TOP);
842 Display display = textShell.getDisplay();
843 textShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
844 GridLayout layout = new GridLayout(1, false);
845 int border = ((control.getShell().getStyle() & SWT.NO_TRIM) == 0) ? 0 : 1;
846 layout.marginHeight = border;
847 layout.marginWidth = border;
848 textShell.setLayout(layout);
849 textShell.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
850 Composite shellComposite = new Composite(textShell, SWT.NONE);
851 layout = new GridLayout();
852 layout.marginHeight = 0;
853 layout.marginWidth = 0;
854 shellComposite.setLayout(layout);
855 shellComposite.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_BEGINNING));
856 textLabel = new Text(shellComposite, SWT.WRAP | SWT.MULTI);
857 GridData gd = new GridData(GridData.FILL_BOTH);
859 gd.grabExcessHorizontalSpace = true;
860 textLabel.setLayoutData(gd);
861 Color c = control.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND);
862 textLabel.setBackground(c);
863 c = control.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND);
864 textLabel.setForeground(c);
865 textLabel.setEditable(false);
866 textShell.addDisposeListener(new DisposeListener() {
867 public void widgetDisposed(DisposeEvent e) {
868 onTextShellDispose(e);
873 void onTextShellDispose(DisposeEvent e) {
874 canOpenTextShell = true;
878 void onMouseDown(Event e) {
879 if (textShell != null && !textShell.isDisposed() && !textShell.isFocusControl()) {
881 canOpenTextShell = true;
885 void onMouseHover(Event e) {
886 if (!canOpenTextShell)
888 canOpenTextShell = false;
889 Point point = new Point(e.x, e.y);
890 TableTree table = tableTreeViewer.getTableTree();
891 TableTreeItem item = table.getItem(point);
894 String message = ((LogEntry) item.getData()).getStack();
898 textLabel.setText(message);
900 int y = point.y - (table.getItemHeight() * 2) - 20;
901 textShell.setLocation(table.toDisplay(x, y));
902 textShell.setSize(tableTreeViewer.getTableTree().getSize().x - x, 125);
907 void onMouseMove(Event e) {
908 if (textShell != null && !textShell.isDisposed()) {
910 canOpenTextShell = textShell.isDisposed() && e.x > column0.getWidth() && e.x < (column0.getWidth() + column1.getWidth());
912 canOpenTextShell = e.x > column0.getWidth() && e.x < (column0.getWidth() + column1.getWidth());
916 public Comparator getComparator() {
920 private void setComparator(byte sortType) {
921 if (sortType == DATE) {
922 comparator = new Comparator() {
923 public int compare(Object e1, Object e2) {
925 SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
926 Date date1 = formatter.parse(((LogEntry) e1).getDate());
927 Date date2 = formatter.parse(((LogEntry) e2).getDate());
928 if (DATE_ORDER == ASCENDING)
929 return date1.before(date2) ? -1 : 1;
930 return date1.after(date2) ? -1 : 1;
931 } catch (ParseException e) {
936 } else if (sortType == PLUGIN) {
937 comparator = new Comparator() {
938 public int compare(Object e1, Object e2) {
939 LogEntry entry1 = (LogEntry) e1;
940 LogEntry entry2 = (LogEntry) e2;
941 return collator.compare(entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER;
945 comparator = new Comparator() {
946 public int compare(Object e1, Object e2) {
947 LogEntry entry1 = (LogEntry) e1;
948 LogEntry entry2 = (LogEntry) e2;
949 return collator.compare(entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
955 private ViewerSorter getViewerSorter(byte sortType) {
956 if (sortType == PLUGIN) {
957 return new ViewerSorter() {
958 public int compare(Viewer viewer, Object e1, Object e2) {
959 LogEntry entry1 = (LogEntry) e1;
960 LogEntry entry2 = (LogEntry) e2;
961 return super.compare(viewer, entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER;
964 } else if (sortType == MESSAGE) {
965 return new ViewerSorter() {
966 public int compare(Viewer viewer, Object e1, Object e2) {
967 LogEntry entry1 = (LogEntry) e1;
968 LogEntry entry2 = (LogEntry) e2;
969 return super.compare(viewer, entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
973 return new ViewerSorter() {
974 public int compare(Viewer viewer, Object e1, Object e2) {
976 SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
977 Date date1 = formatter.parse(((LogEntry) e1).getDate());
978 Date date2 = formatter.parse(((LogEntry) e2).getDate());
979 if (DATE_ORDER == ASCENDING)
980 return date1.before(date2) ? -1 : 1;
981 return date1.after(date2) ? -1 : 1;
982 } catch (ParseException e) {
990 private void resetDialogButtons() {
991 ((EventDetailsDialogAction) propertiesAction).resetDialogButtons();