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.phpdt.internal.debug.core.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.phpdt.internal.debug.core.PHPDegugCorePluginImages;
31 import net.sourceforge.phpdt.internal.debug.core.PHPDebugCorePlugin;
33 import org.eclipse.core.runtime.ILogListener;
34 import org.eclipse.core.runtime.IProgressMonitor;
35 import org.eclipse.core.runtime.IStatus;
36 import org.eclipse.core.runtime.Path;
37 import org.eclipse.core.runtime.Platform;
38 import org.eclipse.jface.action.Action;
39 import org.eclipse.jface.action.IMenuListener;
40 import org.eclipse.jface.action.IMenuManager;
41 import org.eclipse.jface.action.IStatusLineManager;
42 import org.eclipse.jface.action.IToolBarManager;
43 import org.eclipse.jface.action.MenuManager;
44 import org.eclipse.jface.action.Separator;
45 import org.eclipse.jface.dialogs.MessageDialog;
46 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
47 import org.eclipse.jface.operation.IRunnableWithProgress;
48 import org.eclipse.jface.viewers.ColumnPixelData;
49 import org.eclipse.jface.viewers.DoubleClickEvent;
50 import org.eclipse.jface.viewers.IDoubleClickListener;
51 import org.eclipse.jface.viewers.ISelection;
52 import org.eclipse.jface.viewers.ISelectionChangedListener;
53 import org.eclipse.jface.viewers.IStructuredSelection;
54 import org.eclipse.jface.viewers.ITreeViewerListener;
55 import org.eclipse.jface.viewers.SelectionChangedEvent;
56 import org.eclipse.jface.viewers.TableLayout;
57 import org.eclipse.jface.viewers.TableTreeViewer;
58 import org.eclipse.jface.viewers.TreeExpansionEvent;
59 import org.eclipse.jface.viewers.Viewer;
60 import org.eclipse.jface.viewers.ViewerSorter;
61 import org.eclipse.swt.SWT;
62 import org.eclipse.swt.custom.BusyIndicator;
63 import org.eclipse.swt.custom.TableTree;
64 import org.eclipse.swt.custom.TableTreeItem;
65 import org.eclipse.swt.dnd.Clipboard;
66 import org.eclipse.swt.dnd.TextTransfer;
67 import org.eclipse.swt.dnd.Transfer;
68 import org.eclipse.swt.events.DisposeEvent;
69 import org.eclipse.swt.events.DisposeListener;
70 import org.eclipse.swt.events.SelectionAdapter;
71 import org.eclipse.swt.events.SelectionEvent;
72 import org.eclipse.swt.graphics.Color;
73 import org.eclipse.swt.graphics.Font;
74 import org.eclipse.swt.graphics.FontData;
75 import org.eclipse.swt.graphics.Point;
76 import org.eclipse.swt.layout.GridData;
77 import org.eclipse.swt.layout.GridLayout;
78 import org.eclipse.swt.program.Program;
79 import org.eclipse.swt.widgets.Composite;
80 import org.eclipse.swt.widgets.Control;
81 import org.eclipse.swt.widgets.Display;
82 import org.eclipse.swt.widgets.Event;
83 import org.eclipse.swt.widgets.FileDialog;
84 import org.eclipse.swt.widgets.Listener;
85 import org.eclipse.swt.widgets.Menu;
86 import org.eclipse.swt.widgets.Shell;
87 import org.eclipse.swt.widgets.Table;
88 import org.eclipse.swt.widgets.TableColumn;
89 import org.eclipse.swt.widgets.TableItem;
90 import org.eclipse.swt.widgets.Text;
91 import org.eclipse.ui.IActionBars;
92 import org.eclipse.ui.IMemento;
93 import org.eclipse.ui.ISharedImages;
94 import org.eclipse.ui.IViewPart;
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";
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(PHPDebugCorePlugin.getResourceString("LogView.column.severity")); //$NON-NLS-1$
363 column2 = new TableColumn(table, SWT.NULL);
364 column2.setText(PHPDebugCorePlugin.getResourceString("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(PHPDebugCorePlugin.getResourceString("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(PHPDebugCorePlugin.getResourceString("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(PHPDegugCorePluginImages.DESC_PROPERTIES);
425 propertiesAction.setDisabledImageDescriptor(PHPDegugCorePluginImages.DESC_PROPERTIES_DISABLED);
426 propertiesAction.setToolTipText(PHPDebugCorePlugin.getResourceString("LogView.properties.tooltip")); //$NON-NLS-1$
427 propertiesAction.setEnabled(false);
428 clearAction = new Action(PHPDebugCorePlugin.getResourceString("LogView.clear")) { //$NON-NLS-1$
433 clearAction.setImageDescriptor(PHPDegugCorePluginImages.DESC_CLEAR);
434 clearAction.setDisabledImageDescriptor(PHPDegugCorePluginImages.DESC_CLEAR_DISABLED);
435 clearAction.setToolTipText(PHPDebugCorePlugin.getResourceString("LogView.clear.tooltip")); //$NON-NLS-1$
436 clearAction.setText(PHPDebugCorePlugin.getResourceString("LogView.clear")); //$NON-NLS-1$
437 readLogAction = new Action(PHPDebugCorePlugin.getResourceString("LogView.readLog.restore")) { //$NON-NLS-1$
439 inputFile = Platform.getLogFileLocation().toFile();
443 readLogAction.setToolTipText(PHPDebugCorePlugin.getResourceString("LogView.readLog.restore.tooltip")); //$NON-NLS-1$
444 readLogAction.setImageDescriptor(PHPDegugCorePluginImages.DESC_READ_LOG);
445 readLogAction.setDisabledImageDescriptor(PHPDegugCorePluginImages.DESC_READ_LOG_DISABLED);
446 deleteLogAction = new Action(PHPDebugCorePlugin.getResourceString("LogView.delete")) { //$NON-NLS-1$
451 deleteLogAction.setToolTipText(PHPDebugCorePlugin.getResourceString("LogView.delete.tooltip")); //$NON-NLS-1$
452 deleteLogAction.setImageDescriptor(PHPDegugCorePluginImages.DESC_REMOVE_LOG);
453 deleteLogAction.setDisabledImageDescriptor(PHPDegugCorePluginImages.DESC_REMOVE_LOG_DISABLED);
454 deleteLogAction.setEnabled(inputFile.exists() && inputFile.equals(Platform.getLogFileLocation().toFile()));
455 copyAction = new Action(PHPDebugCorePlugin.getResourceString("LogView.copy")) { //$NON-NLS-1$
457 copyToClipboard(tableTreeViewer.getSelection());
460 copyAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
461 filterAction = new Action(PHPDebugCorePlugin.getResourceString("LogView.filter")) { //$NON-NLS-1$
466 filterAction.setToolTipText(PHPDebugCorePlugin.getResourceString("LogView.filter")); //$NON-NLS-1$
467 filterAction.setImageDescriptor(PHPDegugCorePluginImages.DESC_FILTER);
468 filterAction.setDisabledImageDescriptor(PHPDegugCorePluginImages.DESC_FILTER_DISABLED);
469 exportAction = new Action(PHPDebugCorePlugin.getResourceString("LogView.export")) { //$NON-NLS-1$
474 exportAction.setToolTipText(PHPDebugCorePlugin.getResourceString("LogView.export.tooltip")); //$NON-NLS-1$
475 exportAction.setImageDescriptor(PHPDegugCorePluginImages.DESC_EXPORT);
476 exportAction.setDisabledImageDescriptor(PHPDegugCorePluginImages.DESC_EXPORT_DISABLED);
477 importAction = new Action(PHPDebugCorePlugin.getResourceString("LogView.import")) { //$NON-NLS-1$
482 importAction.setToolTipText(PHPDebugCorePlugin.getResourceString("LogView.import.tooltip")); //$NON-NLS-1$
483 importAction.setImageDescriptor(PHPDegugCorePluginImages.DESC_IMPORT);
484 importAction.setDisabledImageDescriptor(PHPDegugCorePluginImages.DESC_IMPORT_DISABLED);
485 activateViewAction = new Action(PHPDebugCorePlugin.getResourceString("LogView.activate")) { //$NON-NLS-1$
489 activateViewAction.setChecked(memento.getString(P_ACTIVATE).equals("true")); //$NON-NLS-1$
490 viewLogAction = new Action(PHPDebugCorePlugin.getResourceString("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(PHPDegugCorePluginImages.DESC_OPEN_LOG);
514 viewLogAction.setDisabledImageDescriptor(PHPDegugCorePluginImages.DESC_OPEN_LOG_DISABLED);
515 viewLogAction.setEnabled(inputFile.exists());
516 viewLogAction.setToolTipText(PHPDebugCorePlugin.getResourceString("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(PHPDebugCorePlugin.getResourceString("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(PHPDebugCorePlugin.getResourceString("LogView.readLog.reload")); //$NON-NLS-1$
549 readLogAction.setToolTipText(PHPDebugCorePlugin.getResourceString("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 = PHPDebugCorePlugin.getFormattedMessage("LogView.confirmOverwrite.message", //$NON-NLS-1$
569 outputFile.toString());
570 if (!MessageDialog.openQuestion(getViewSite().getShell(), exportAction.getText(), message))
573 copy(inputFile, outputFile);
577 private void copy(File inputFile, File outputFile) {
578 BufferedReader reader = null;
579 BufferedWriter writer = null;
581 reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), "UTF-8")); //$NON-NLS-1$
582 writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")); //$NON-NLS-1$
583 while (reader.ready()) {
584 writer.write(reader.readLine());
585 writer.write(System.getProperty("line.separator")); //$NON-NLS-1$
587 } catch (IOException e) {
594 } catch (IOException e1) {
599 private void handleFilter() {
600 FilterDialog dialog = new FilterDialog(PHPDebugCorePlugin.getActiveWorkbenchShell(), memento);
602 dialog.getShell().setText(PHPDebugCorePlugin.getResourceString("LogView.FilterDialog.title")); //$NON-NLS-1$
603 if (dialog.open() == FilterDialog.OK)
607 private void doDeleteLog() {
608 String title = PHPDebugCorePlugin.getResourceString("LogView.confirmDelete.title"); //$NON-NLS-1$
609 String message = PHPDebugCorePlugin.getResourceString("LogView.confirmDelete.message"); //$NON-NLS-1$
610 if (!MessageDialog.openConfirm(tableTreeViewer.getControl().getShell(), title, message))
612 if (inputFile.delete()) {
615 resetDialogButtons();
619 public void fillContextMenu(IMenuManager manager) {
620 manager.add(copyAction);
621 manager.add(new Separator());
622 manager.add(clearAction);
623 manager.add(deleteLogAction);
624 manager.add(viewLogAction);
625 manager.add(readLogAction);
626 manager.add(new Separator());
627 manager.add(exportAction);
628 manager.add(importAction);
629 manager.add(new Separator());
630 ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
631 manager.add(propertiesAction);
634 public LogEntry[] getLogs() {
635 return (LogEntry[]) logs.toArray(new LogEntry[logs.size()]);
638 protected void handleClear() {
639 BusyIndicator.showWhile(tableTreeViewer.getControl().getDisplay(), new Runnable() {
643 resetDialogButtons();
648 protected void reloadLog() {
649 IRunnableWithProgress op = new IRunnableWithProgress() {
650 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
651 monitor.beginTask(PHPDebugCorePlugin.getResourceString("LogView.operation.reloading"), //$NON-NLS-1$
652 IProgressMonitor.UNKNOWN);
656 ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell());
658 pmd.run(true, true, op);
659 } catch (InvocationTargetException e) {
660 } catch (InterruptedException e) {
662 readLogAction.setText(PHPDebugCorePlugin.getResourceString("LogView.readLog.restore")); //$NON-NLS-1$
663 readLogAction.setToolTipText(PHPDebugCorePlugin.getResourceString("LogView.readLog.restore")); //$NON-NLS-1$
665 resetDialogButtons();
669 private void readLogFile() {
671 if (!inputFile.exists())
673 if (inputFile.length() > LogReader.MAX_FILE_LENGTH)
674 LogReader.parseLargeFile(inputFile, logs, memento);
676 LogReader.parseLogFile(inputFile, logs, memento);
679 public void logging(IStatus status, String plugin) {
680 if (!inputFile.equals(Platform.getLogFileLocation().toFile()))
691 private void pushStatus(IStatus status) {
692 LogEntry entry = new LogEntry(status);
693 LogReader.addEntry(entry, logs, memento, true);
697 private void asyncRefresh() {
701 private void asyncRefresh(final boolean activate) {
702 final Control control = tableTreeViewer.getControl();
703 if (control.isDisposed())
705 Display display = control.getDisplay();
706 final ViewPart view = this;
707 if (display != null) {
708 display.asyncExec(new Runnable() {
710 if (!control.isDisposed()) {
711 tableTreeViewer.refresh();
712 deleteLogAction.setEnabled(inputFile.exists() && inputFile.equals(Platform.getLogFileLocation().toFile()));
713 viewLogAction.setEnabled(inputFile.exists());
714 if (activate && activateViewAction.isChecked()) {
715 IWorkbenchPage page = PHPDebugCorePlugin.getActivePage();
717 page.bringToTop(view);
726 public void setFocus() {
727 if (tableTreeViewer != null && !tableTreeViewer.getTableTree().isDisposed())
728 tableTreeViewer.getTableTree().getTable().setFocus();
731 private void handleSelectionChanged(ISelection selection) {
732 updateStatus(selection);
733 copyAction.setEnabled(!selection.isEmpty());
734 propertiesAction.setEnabled(!selection.isEmpty());
737 private void updateStatus(ISelection selection) {
738 IStatusLineManager status = getViewSite().getActionBars().getStatusLineManager();
739 if (selection.isEmpty())
740 status.setMessage(null);
742 LogEntry entry = (LogEntry) ((IStructuredSelection) selection).getFirstElement();
743 status.setMessage(((LogViewLabelProvider) tableTreeViewer.getLabelProvider()).getColumnText(entry, 2));
747 private void copyToClipboard(ISelection selection) {
748 StringWriter writer = new StringWriter();
749 PrintWriter pwriter = new PrintWriter(writer);
750 if (selection.isEmpty())
752 LogEntry entry = (LogEntry) ((IStructuredSelection) selection).getFirstElement();
753 entry.write(pwriter);
755 String textVersion = writer.toString();
759 } catch (IOException e) {
761 if (textVersion.trim().length() > 0) {
762 // set the clipboard contents
763 clipboard.setContents(new Object[] { textVersion }, new Transfer[] { TextTransfer.getInstance() });
767 public void init(IViewSite site, IMemento memento) throws PartInitException {
768 super.init(site, memento);
770 this.memento = XMLMemento.createWriteRoot("LOGVIEW"); //$NON-NLS-1$
772 this.memento = memento;
776 private void initializeMemento() {
777 if (memento.getString(P_USE_LIMIT) == null)
778 memento.putString(P_USE_LIMIT, "true"); //$NON-NLS-1$
779 if (memento.getInteger(P_LOG_LIMIT) == null)
780 memento.putInteger(P_LOG_LIMIT, 50);
781 if (memento.getString(P_LOG_INFO) == null)
782 memento.putString(P_LOG_INFO, "true"); //$NON-NLS-1$
783 if (memento.getString(P_LOG_WARNING) == null)
784 memento.putString(P_LOG_WARNING, "true"); //$NON-NLS-1$
785 if (memento.getString(P_LOG_ERROR) == null)
786 memento.putString(P_LOG_ERROR, "true"); //$NON-NLS-1$
787 if (memento.getString(P_SHOW_ALL_SESSIONS) == null)
788 memento.putString(P_SHOW_ALL_SESSIONS, "true"); //$NON-NLS-1$
789 Integer width = memento.getInteger(P_COLUMN_1);
790 if (width == null || width.intValue() == 0)
791 memento.putInteger(P_COLUMN_1, 20);
792 width = memento.getInteger(P_COLUMN_2);
793 if (width == null || width.intValue() == 0)
794 memento.putInteger(P_COLUMN_2, 300);
795 width = memento.getInteger(P_COLUMN_3);
796 if (width == null || width.intValue() == 0)
797 memento.putInteger(P_COLUMN_3, 150);
798 width = memento.getInteger(P_COLUMN_4);
799 if (width == null || width.intValue() == 0)
800 memento.putInteger(P_COLUMN_4, 150);
801 if (memento.getString(P_ACTIVATE) == null)
802 memento.putString(P_ACTIVATE, "true"); //$NON-NLS-1$
805 public void saveState(IMemento memento) {
806 if (this.memento == null || memento == null)
808 this.memento.putInteger(P_COLUMN_1, column1.getWidth());
809 this.memento.putInteger(P_COLUMN_2, column2.getWidth());
810 this.memento.putInteger(P_COLUMN_3, column3.getWidth());
811 this.memento.putInteger(P_COLUMN_4, column4.getWidth());
812 this.memento.putString(P_ACTIVATE, activateViewAction.isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
813 memento.putMemento(this.memento);
816 private void addMouseListeners() {
817 Listener tableListener = new Listener() {
818 public void handleEvent(Event e) {
832 int[] tableEvents = new int[] { SWT.MouseDown, SWT.MouseMove, SWT.MouseHover };
833 for (int i = 0; i < tableEvents.length; i++) {
834 tableTreeViewer.getTableTree().getTable().addListener(tableEvents[i], tableListener);
838 private void makeHoverShell() {
839 Control control = tableTreeViewer.getControl();
840 textShell = new Shell(control.getShell(), SWT.NO_FOCUS | SWT.ON_TOP);
841 Display display = textShell.getDisplay();
842 textShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
843 GridLayout layout = new GridLayout(1, false);
844 int border = ((control.getShell().getStyle() & SWT.NO_TRIM) == 0) ? 0 : 1;
845 layout.marginHeight = border;
846 layout.marginWidth = border;
847 textShell.setLayout(layout);
848 textShell.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
849 Composite shellComposite = new Composite(textShell, SWT.NONE);
850 layout = new GridLayout();
851 layout.marginHeight = 0;
852 layout.marginWidth = 0;
853 shellComposite.setLayout(layout);
854 shellComposite.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_BEGINNING));
855 textLabel = new Text(shellComposite, SWT.WRAP | SWT.MULTI);
856 GridData gd = new GridData(GridData.FILL_BOTH);
858 gd.grabExcessHorizontalSpace = true;
859 textLabel.setLayoutData(gd);
860 Color c = control.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND);
861 textLabel.setBackground(c);
862 c = control.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND);
863 textLabel.setForeground(c);
864 textLabel.setEditable(false);
865 textShell.addDisposeListener(new DisposeListener() {
866 public void widgetDisposed(DisposeEvent e) {
867 onTextShellDispose(e);
872 void onTextShellDispose(DisposeEvent e) {
873 canOpenTextShell = true;
877 void onMouseDown(Event e) {
878 if (textShell != null && !textShell.isDisposed() && !textShell.isFocusControl()) {
880 canOpenTextShell = true;
884 void onMouseHover(Event e) {
885 if (!canOpenTextShell)
887 canOpenTextShell = false;
888 Point point = new Point(e.x, e.y);
889 TableTree table = tableTreeViewer.getTableTree();
890 TableTreeItem item = table.getItem(point);
893 String message = ((LogEntry) item.getData()).getStack();
897 textLabel.setText(message);
899 int y = point.y - (table.getItemHeight() * 2) - 20;
900 textShell.setLocation(table.toDisplay(x, y));
901 textShell.setSize(tableTreeViewer.getTableTree().getSize().x - x, 125);
906 void onMouseMove(Event e) {
907 if (textShell != null && !textShell.isDisposed()) {
909 canOpenTextShell = textShell.isDisposed() && e.x > column0.getWidth() && e.x < (column0.getWidth() + column1.getWidth());
911 canOpenTextShell = e.x > column0.getWidth() && e.x < (column0.getWidth() + column1.getWidth());
915 public Comparator getComparator() {
919 private void setComparator(byte sortType) {
920 if (sortType == DATE) {
921 comparator = new Comparator() {
922 public int compare(Object e1, Object e2) {
924 SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
925 Date date1 = formatter.parse(((LogEntry) e1).getDate());
926 Date date2 = formatter.parse(((LogEntry) e2).getDate());
927 if (DATE_ORDER == ASCENDING)
928 return date1.before(date2) ? -1 : 1;
929 return date1.after(date2) ? -1 : 1;
930 } catch (ParseException e) {
935 } else if (sortType == PLUGIN) {
936 comparator = new Comparator() {
937 public int compare(Object e1, Object e2) {
938 LogEntry entry1 = (LogEntry) e1;
939 LogEntry entry2 = (LogEntry) e2;
940 return collator.compare(entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER;
944 comparator = new Comparator() {
945 public int compare(Object e1, Object e2) {
946 LogEntry entry1 = (LogEntry) e1;
947 LogEntry entry2 = (LogEntry) e2;
948 return collator.compare(entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
954 private ViewerSorter getViewerSorter(byte sortType) {
955 if (sortType == PLUGIN) {
956 return new ViewerSorter() {
957 public int compare(Viewer viewer, Object e1, Object e2) {
958 LogEntry entry1 = (LogEntry) e1;
959 LogEntry entry2 = (LogEntry) e2;
960 return super.compare(viewer, entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER;
963 } else if (sortType == MESSAGE) {
964 return new ViewerSorter() {
965 public int compare(Viewer viewer, Object e1, Object e2) {
966 LogEntry entry1 = (LogEntry) e1;
967 LogEntry entry2 = (LogEntry) e2;
968 return super.compare(viewer, entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
972 return new ViewerSorter() {
973 public int compare(Viewer viewer, Object e1, Object e2) {
975 SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
976 Date date1 = formatter.parse(((LogEntry) e1).getDate());
977 Date date2 = formatter.parse(((LogEntry) e2).getDate());
978 if (DATE_ORDER == ASCENDING)
979 return date1.before(date2) ? -1 : 1;
980 return date1.after(date2) ? -1 : 1;
981 } catch (ParseException e) {
989 private void resetDialogButtons() {
990 ((EventDetailsDialogAction) propertiesAction).resetDialogButtons();