1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
13 import java.io.IOException;
14 import java.io.PrintWriter;
15 import java.io.StringWriter;
16 import java.text.Collator;
17 import java.text.ParseException;
18 import java.text.SimpleDateFormat;
19 import java.util.Arrays;
20 import java.util.Comparator;
21 import java.util.Date;
23 //import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
24 import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin;
25 import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPluginImages;
27 import org.eclipse.core.runtime.IAdaptable;
28 import org.eclipse.jface.dialogs.Dialog;
29 import org.eclipse.jface.dialogs.IDialogConstants;
30 import org.eclipse.jface.dialogs.IDialogSettings;
31 import org.eclipse.jface.viewers.ISelection;
32 import org.eclipse.jface.viewers.ISelectionProvider;
33 import org.eclipse.jface.viewers.IStructuredSelection;
34 import org.eclipse.jface.viewers.StructuredSelection;
35 import org.eclipse.jface.viewers.TreeViewer;
36 //import org.eclipse.jface.viewers.TableTreeViewer;
37 import org.eclipse.swt.SWT;
38 import org.eclipse.swt.custom.SashForm;
39 import org.eclipse.swt.dnd.Clipboard;
40 import org.eclipse.swt.dnd.TextTransfer;
41 import org.eclipse.swt.dnd.Transfer;
42 import org.eclipse.swt.graphics.Image;
43 import org.eclipse.swt.graphics.Point;
44 import org.eclipse.swt.layout.GridData;
45 import org.eclipse.swt.layout.GridLayout;
46 import org.eclipse.swt.widgets.Button;
47 import org.eclipse.swt.widgets.Composite;
48 import org.eclipse.swt.widgets.Control;
49 import org.eclipse.swt.widgets.Label;
50 import org.eclipse.swt.widgets.Shell;
51 import org.eclipse.swt.widgets.Text;
52 import org.eclipse.ui.ISharedImages;
53 import org.eclipse.ui.PlatformUI;
55 public class EventDetailsDialog extends Dialog {
56 private LogEntry entry, parentEntry;
57 private LogViewLabelProvider labelProvider;
58 private static int COPY_ID = 22;
59 private /*Table*/TreeViewer provider;
60 private int elementNum, totalElementCount;
61 private LogEntry[] entryChildren;
62 private int childIndex = 0;
63 private boolean isOpen;
65 private Label dateLabel;
66 private Label severityImageLabel;
67 private Label severityLabel;
69 private Text stackTraceText;
70 private Text sessionDataText;
71 private Clipboard clipboard;
72 private Button copyButton;
73 private Button backButton;
74 private Button nextButton;
75 private Image imgNextEnabled;
76 private Image imgPrevEnabled;
77 private Image imgCopyEnabled;
78 private SashForm sashForm;
81 private static int ASCENDING = 1;
82 private Comparator comparator = null;
83 private Collator collator;
85 // location configuration
86 private IDialogSettings dialogSettings;
87 private Point dialogLocation;
88 private Point dialogSize;
89 private int[] sashWeights;
91 // externalize strings
92 private String EVENT_NO_STACK = "EventDetailsDialog.noStack"; //$NON-NLS-1$
93 private String EVENT_PREVIOUS = "EventDetailsDialog.previous"; //$NON-NLS-1$
94 private String EVENT_NEXT = "EventDetailsDialog.next"; //$NON-NLS-1$
95 private String EVENT_COPY = "EventDetailsDialog.copy"; //$NON-NLS-1$
99 * shell in which dialog is displayed
101 protected EventDetailsDialog(Shell parentShell, IAdaptable selection, ISelectionProvider provider) {
103 labelProvider = new LogViewLabelProvider();
104 this.provider = (/*Table*/TreeViewer) provider;
105 this.entry = (LogEntry)selection;
106 setShellStyle(SWT.MODELESS | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.CLOSE | SWT.BORDER | SWT.TITLE);
107 clipboard = new Clipboard(parentShell.getDisplay());
110 collator = Collator.getInstance();
114 private void initialize() {
115 elementNum = getParentElementNum();
116 totalElementCount = provider.getTree().getItemCount() - getVisibleChildrenCount();
117 parentEntry = (LogEntry) entry.getParent(entry);
119 setEntryChildren(parentEntry);
124 private void resetChildIndex(){
125 for (int i = 0; i<entryChildren.length; i++){
126 if (entryChildren[i].getMessage().equals(entry.getMessage())
127 && entryChildren[i].getDate().equals(entry.getDate())
128 && entryChildren[i].getPluginId().equals(entry.getPluginId())
129 && entryChildren[i].getSeverity() == entry.getSeverity()
130 && entryChildren[i].getSeverityText().equals(entry.getSeverityText())){
137 private void createImages(){
139 PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY).createImage(
141 //imgNextDisabled. = PHPDegugCorePluginImages.DESC_NEXT_EVENT_DISABLED.createImage(true);
142 //imgPrevDisabled = PHPDegugCorePluginImages.DESC_PREV_EVENT_DISABLED.createImage(true);
143 imgPrevEnabled = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_PREV_EVENT);
144 imgNextEnabled = XDebugUIPluginImages.get(XDebugUIPluginImages.DESC_NEXT_EVENT);
147 private boolean isChild(LogEntry entry) {
148 return entry.getParent(entry) != null;
151 public boolean isOpen(){
157 if (sashWeights == null){
158 int width = getSashForm().getClientArea().width;
163 sashWeights = new int[]{width, getSashForm().getClientArea().width-width};
165 getSashForm().setWeights(sashWeights);
169 public boolean close() {
172 imgCopyEnabled.dispose();
173 imgNextEnabled.dispose();
174 imgPrevEnabled.dispose();
175 return super.close();
178 public void create() {
182 if (dialogLocation != null)
183 getShell().setLocation(dialogLocation);
186 if (dialogSize != null)
187 getShell().setSize(dialogSize);
189 getShell().setSize(500,550);
192 applyDialogFont(buttonBar);
193 getButton(IDialogConstants.OK_ID).setFocus();
196 protected void buttonPressed(int buttonId) {
197 if (IDialogConstants.OK_ID == buttonId)
199 else if (IDialogConstants.CANCEL_ID == buttonId)
201 else if (IDialogConstants.BACK_ID == buttonId)
203 else if (IDialogConstants.NEXT_ID == buttonId)
205 else if (COPY_ID == buttonId)
209 protected void backPressed() {
210 if (isChild(entry)) {
211 if (childIndex > 0) {
213 entry = entryChildren[childIndex];
217 if (elementNum - 1 >= 0)
219 entry = (LogEntry) provider.getTree().getItem(elementNum).getData();
221 setEntrySelectionInTable();
224 protected void nextPressed() {
225 if (isChild(entry) && childIndex < entryChildren.length-1) {
227 entry = entryChildren[childIndex];
228 } else if (elementNum + 1 < totalElementCount){
230 entry = (LogEntry) provider.getTree().getItem(elementNum).getData(); //getElementAt(elementNum);
231 } else { // at end of list but can branch into child elements - bug 58083
232 setEntryChildren(entry);
233 entry = entryChildren[0];
235 setEntrySelectionInTable();
238 protected void copyPressed() {
239 StringWriter writer = new StringWriter();
240 PrintWriter pwriter = new PrintWriter(writer);
242 entry.write(pwriter);
244 String textVersion = writer.toString();
248 } catch (IOException e) {
250 // set the clipboard contents
251 clipboard.setContents(new Object[] { textVersion }, new Transfer[] { TextTransfer.getInstance()});
254 public void setComparator(Comparator comparator){
255 this.comparator = comparator;
258 private void setComparator(byte sortType, final int sortOrder){
259 if (sortType == LogView.DATE){
260 comparator = new Comparator(){
261 public int compare(Object e1, Object e2) {
263 SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
264 Date date1 = formatter.parse(((LogEntry)e1).getDate());
265 Date date2 = formatter.parse(((LogEntry)e2).getDate());
266 if (sortOrder == ASCENDING)
267 return date1.before(date2) ? -1 : 1;
268 return date1.after(date2) ? -1 : 1;
269 } catch (ParseException e) {
274 } else if (sortType == LogView.PLUGIN){
275 comparator = new Comparator(){
276 public int compare(Object e1, Object e2) {
277 LogEntry entry1 = (LogEntry)e1;
278 LogEntry entry2 = (LogEntry)e2;
279 return collator.compare(entry1.getPluginId(), entry2.getPluginId()) * sortOrder;
283 comparator = new Comparator(){
284 public int compare(Object e1, Object e2) {
285 LogEntry entry1 = (LogEntry)e1;
286 LogEntry entry2 = (LogEntry)e2;
287 return collator.compare(entry1.getMessage(), entry2.getMessage()) * sortOrder;
293 public void resetSelection(IAdaptable selectedEntry, byte sortType, int sortOrder){
294 setComparator(sortType, sortOrder);
295 resetSelection(selectedEntry);
298 public void resetSelection(IAdaptable selectedEntry){
299 if (entry.equals(selectedEntry) &&
300 elementNum == getParentElementNum()){
304 entry = (LogEntry)selectedEntry;
309 public void resetButtons(){
310 backButton.setEnabled(false);
311 nextButton.setEnabled(false);
314 private void setEntrySelectionInTable(){
315 ISelection selection = new StructuredSelection(entry);
316 provider.setSelection(selection);
319 public void updateProperties() {
321 parentEntry = (LogEntry) entry.getParent(entry);
322 setEntryChildren(parentEntry);
327 totalElementCount = provider.getTree().getItemCount() - getVisibleChildrenCount();
328 dateLabel.setText(entry.getDate());
329 severityImageLabel.setImage(labelProvider.getColumnImage(entry, 1));
330 severityLabel.setText(entry.getSeverityText());
331 msgText.setText(entry.getMessage());
332 String stack = entry.getStack();
334 stackTraceText.setText(stack);
336 stackTraceText.setText(XDebugUIPlugin.getString(EVENT_NO_STACK));
338 LogSession session = entry.getSession();
339 if (session != null && session.getSessionData() != null)
340 sessionDataText.setText(session.getSessionData());
345 private void updateButtons(){
346 boolean isAtEnd = elementNum == totalElementCount - 1;
348 backButton.setEnabled(true);
349 boolean isLastChild = childIndex == entryChildren.length-1;
350 nextButton.setEnabled(!isLastChild || !isAtEnd || entry.hasChildren());
352 backButton.setEnabled(elementNum != 0);
353 nextButton.setEnabled(!isAtEnd || entry.hasChildren());
357 private void setEntryChildren(LogEntry parent){
358 Object[] children = parent.getChildren(parent);
359 if (comparator != null)
360 Arrays.sort(children, comparator);
361 entryChildren = new LogEntry[children.length];
363 System.arraycopy(children,0,entryChildren,0,children.length);
366 private int getParentElementNum(){
367 LogEntry itemEntry = (LogEntry)((IStructuredSelection)provider.getSelection()).getFirstElement();
368 itemEntry = getRootEntry(itemEntry);
370 for (int i = 0; i<provider.getTree().getItemCount()/* getTableTree().getItemCount()*/; i++){
372 LogEntry littleEntry = (LogEntry)provider.getTree().getItem(i).getData();// getElementAt(i);
373 if (itemEntry.equals(littleEntry)){
376 } catch (Exception e){
382 private LogEntry getRootEntry(LogEntry entry){
385 return getRootEntry((LogEntry)entry.getParent(entry));
387 public SashForm getSashForm(){
390 private int getVisibleChildrenCount(){
391 Object[] elements = provider.getVisibleExpandedElements();
392 LogEntry[] expandedElements = new LogEntry[elements.length];
393 System.arraycopy(elements, 0, expandedElements, 0, elements.length);
395 for (int i = 0; i<expandedElements.length; i++){
396 count += expandedElements[i].getChildren(expandedElements[i]).length;
401 protected Control createDialogArea(Composite parent) {
402 Composite container = new Composite(parent, SWT.NONE);
403 GridLayout layout = new GridLayout();
404 layout.numColumns = 1;
405 container.setLayout(layout);
406 GridData gd = new GridData(GridData.FILL_BOTH);
407 container.setLayoutData(gd);
409 createDetailsSection(container);
410 createSashForm(container);
411 createStackSection(getSashForm());
412 createSessionSection(getSashForm());
415 Dialog.applyDialogFont(container);
419 private void createSashForm(Composite parent){
420 sashForm = new SashForm(parent, SWT.VERTICAL);
421 GridLayout layout = new GridLayout();
422 layout.marginHeight = layout.marginWidth = 0;
423 sashForm.setLayout(layout);
424 sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
427 private void createToolbarButtonBar(Composite parent) {
428 Composite comp = new Composite(parent, SWT.NONE);
429 GridLayout layout = new GridLayout();
430 layout.marginWidth = layout.marginHeight = 0;
431 layout.numColumns = 1;
432 comp.setLayout(layout);
433 comp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
435 Composite container = new Composite(comp, SWT.NONE);
436 layout = new GridLayout();
437 layout.marginWidth = 0;
438 layout.marginHeight = 10;
439 layout.numColumns = 1;
440 container.setLayout(layout);
441 container.setLayoutData(new GridData(GridData.FILL_BOTH));
443 backButton = createButton(container, IDialogConstants.BACK_ID, "", false); //$NON-NLS-1$
444 GridData gd = new GridData(GridData.FILL_HORIZONTAL);
445 gd.horizontalSpan = 3;
447 backButton.setLayoutData(gd);
448 backButton.setToolTipText(XDebugUIPlugin.getString(EVENT_PREVIOUS));
449 backButton.setImage(imgPrevEnabled);
451 nextButton = createButton(container, IDialogConstants.NEXT_ID, "", false); //$NON-NLS-1$
453 gd.horizontalSpan = 3;
455 nextButton.setLayoutData(gd);
456 nextButton.setToolTipText(XDebugUIPlugin.getString(EVENT_NEXT));
457 nextButton.setImage(imgNextEnabled);
459 copyButton = createButton(container, COPY_ID, "", false); //$NON-NLS-1$
461 gd.horizontalSpan = 3;
463 copyButton.setLayoutData(gd);
464 copyButton.setImage(imgCopyEnabled);
465 copyButton.setToolTipText(XDebugUIPlugin.getString(EVENT_COPY));
468 protected void createButtonsForButtonBar(Composite parent) {
469 // create OK button only by default
470 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
473 private void createDetailsSection(Composite parent) {
474 Composite container = new Composite(parent, SWT.NONE);
475 GridLayout layout = new GridLayout();
476 layout.numColumns = 2;
477 container.setLayout(layout);
478 container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
480 createTextSection(container);
481 createToolbarButtonBar(container);
484 private void createTextSection(Composite parent) {
485 Composite textContainer = new Composite(parent, SWT.NONE);
486 GridLayout layout = new GridLayout();
487 layout.numColumns = 3;
488 layout.marginHeight = layout.marginWidth = 0;
489 textContainer.setLayout(layout);
490 textContainer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
492 Label label = new Label(textContainer, SWT.NONE);
493 label.setText(XDebugUIPlugin.getString("EventDetailsDialog.date")); //$NON-NLS-1$
494 dateLabel = new Label(textContainer, SWT.NULL);
495 GridData gd = new GridData(GridData.FILL_HORIZONTAL);
496 gd.horizontalSpan = 2;
497 dateLabel.setLayoutData(gd);
499 label = new Label(textContainer, SWT.NONE);
500 label.setText(XDebugUIPlugin.getString("EventDetailsDialog.severity")); //$NON-NLS-1$
501 severityImageLabel = new Label(textContainer, SWT.NULL);
502 severityLabel = new Label(textContainer, SWT.NULL);
503 gd = new GridData(GridData.FILL_HORIZONTAL);
504 severityLabel.setLayoutData(gd);
506 label = new Label(textContainer, SWT.NONE);
507 label.setText(XDebugUIPlugin.getString("EventDetailsDialog.message")); //$NON-NLS-1$
508 gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
509 label.setLayoutData(gd);
510 msgText = new Text(textContainer, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP | SWT.BORDER);
511 msgText.setEditable(false);
512 gd = new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_BEGINNING | GridData.GRAB_VERTICAL);
513 gd.horizontalSpan = 2;
515 gd.grabExcessVerticalSpace = true;
516 msgText.setLayoutData(gd);
519 private void createStackSection(Composite parent) {
520 Composite container = new Composite(parent, SWT.NONE);
521 GridLayout layout = new GridLayout();
522 layout.marginHeight = 0;
523 layout.marginWidth = 6;
524 container.setLayout(layout);
525 GridData gd = new GridData(GridData.FILL_BOTH);
527 container.setLayoutData(gd);
529 Label label = new Label(container, SWT.NULL);
530 label.setText(XDebugUIPlugin.getString("EventDetailsDialog.exception")); //$NON-NLS-1$
531 gd = new GridData(GridData.FILL_HORIZONTAL);
532 gd.horizontalSpan = 3;
533 label.setLayoutData(gd);
535 stackTraceText = new Text(container, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
536 gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL);
537 gd.grabExcessHorizontalSpace = true;
538 stackTraceText.setLayoutData(gd);
539 stackTraceText.setEditable(false);
542 private void createSessionSection(Composite parent) {
543 Composite container = new Composite(parent, SWT.NONE);
544 GridLayout layout = new GridLayout();
545 layout.marginHeight = 0;
546 layout.marginWidth = 6;
547 container.setLayout(layout);
548 GridData gd = new GridData(GridData.FILL_HORIZONTAL);
550 container.setLayoutData(gd);
552 Label line = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
553 gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
555 line.setLayoutData(gd);
557 Label label = new Label(container, SWT.NONE);
558 label.setText(XDebugUIPlugin.getString("EventDetailsDialog.session")); //$NON-NLS-1$
559 gd = new GridData(GridData.FILL_HORIZONTAL);
560 label.setLayoutData(gd);
561 sessionDataText = new Text(container, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL );
562 gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL);
563 gd.grabExcessHorizontalSpace = true;
564 sessionDataText.setLayoutData(gd);
565 sessionDataText.setEditable(false);
568 //--------------- configuration handling --------------
571 * Stores the current state in the dialog settings.
574 private void storeSettings() {
575 writeConfiguration();
578 * Returns the dialog settings object used to share state
579 * between several event detail dialogs.
581 * @return the dialog settings to be used
583 private IDialogSettings getDialogSettings() {
584 // IDialogSettings settings= XDebugCorePlugin.getDefault().getDialogSettings();
585 IDialogSettings settings = getDialogSettings();
586 dialogSettings= settings.getSection(getClass().getName());
587 if (dialogSettings == null)
588 dialogSettings= settings.addNewSection(getClass().getName());
589 return dialogSettings;
593 * Initializes itself from the dialog settings with the same state
594 * as at the previous invocation.
596 private void readConfiguration() {
597 IDialogSettings s= getDialogSettings();
599 int x= s.getInt("x"); //$NON-NLS-1$
600 int y= s.getInt("y"); //$NON-NLS-1$
601 dialogLocation= new Point(x, y);
603 x = s.getInt("width"); //$NON-NLS-1$
604 y = s.getInt("height"); //$NON-NLS-1$
605 dialogSize = new Point(x,y);
607 sashWeights = new int[2];
608 sashWeights[0] = s.getInt("sashWidth1"); //$NON-NLS-1$
609 sashWeights[1] = s.getInt("sashWidth2"); //$NON-NLS-1$
611 } catch (NumberFormatException e) {
612 dialogLocation= null;
618 private void writeConfiguration(){
619 IDialogSettings s = getDialogSettings();
620 Point location = getShell().getLocation();
621 s.put("x", location.x); //$NON-NLS-1$
622 s.put("y", location.y); //$NON-NLS-1$
624 Point size = getShell().getSize();
625 s.put("width", size.x); //$NON-NLS-1$
626 s.put("height", size.y); //$NON-NLS-1$
628 sashWeights = getSashForm().getWeights();
629 s.put("sashWidth1", sashWeights[0]); //$NON-NLS-1$
630 s.put("sashWidth2", sashWeights[1]); //$NON-NLS-1$