1 16 package com.google.gwt.dev.util.log; 17 18 import com.google.gwt.core.ext.UnableToCompleteException; 19 import com.google.gwt.dev.util.log.TreeItemLogger.LogEvent; 20 21 import org.eclipse.swt.SWT; 22 import org.eclipse.swt.custom.SashForm; 23 import org.eclipse.swt.dnd.Clipboard; 24 import org.eclipse.swt.dnd.TextTransfer; 25 import org.eclipse.swt.dnd.Transfer; 26 import org.eclipse.swt.events.DisposeEvent; 27 import org.eclipse.swt.events.DisposeListener; 28 import org.eclipse.swt.events.KeyAdapter; 29 import org.eclipse.swt.events.KeyEvent; 30 import org.eclipse.swt.events.SelectionEvent; 31 import org.eclipse.swt.events.SelectionListener; 32 import org.eclipse.swt.events.TreeEvent; 33 import org.eclipse.swt.events.TreeListener; 34 import org.eclipse.swt.graphics.Color; 35 import org.eclipse.swt.layout.FillLayout; 36 import org.eclipse.swt.widgets.Composite; 37 import org.eclipse.swt.widgets.Display; 38 import org.eclipse.swt.widgets.Text; 39 import org.eclipse.swt.widgets.Tree; 40 import org.eclipse.swt.widgets.TreeItem; 41 42 import java.io.PrintWriter ; 43 import java.io.StringWriter ; 44 45 48 public class TreeLoggerWidget extends Composite implements TreeListener, 49 SelectionListener { 50 51 private boolean autoScroll; 52 53 private final Text details; 54 55 private final TreeItemLogger logger; 56 57 private final Tree tree; 58 59 public TreeLoggerWidget(Composite parent) { 60 super(parent, SWT.NONE); 61 62 setLayout(new FillLayout()); 63 64 SashForm sash = new SashForm(this, SWT.VERTICAL); 67 68 tree = new Tree(sash, SWT.BORDER | SWT.SHADOW_IN); 71 tree.setLinesVisible(false); 72 tree.addSelectionListener(this); 73 tree.setFocus(); 74 tree.addKeyListener(new KeyAdapter() { 75 public void keyPressed(KeyEvent e) { 76 if (e.keyCode == 'c' && e.stateMask == SWT.CTRL) { 77 copyTreeSelectionToClipboard(tree); 80 } 81 } 82 }); 83 84 logger = new TreeItemLogger(); 85 86 details = new Text(sash, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY | SWT.BORDER 88 | SWT.V_SCROLL); 89 final Color detailsBgColor = new Color(null, 255, 255, 255); 90 details.setBackground(detailsBgColor); 91 details.addDisposeListener(new DisposeListener() { 92 public void widgetDisposed(DisposeEvent arg0) { 93 detailsBgColor.dispose(); 94 } 95 }); 96 97 sash.setWeights(new int[] {80, 20}); 98 99 initLogFlushTimer(parent.getDisplay()); 100 } 101 102 public void collapseAll() { 103 TreeItem[] items = tree.getItems(); 104 for (int i = 0, n = items.length; i < n; ++i) { 105 TreeItem item = items[i]; 106 collapseAll(item); 107 } 108 if (items.length > 0) { 109 tree.setSelection(new TreeItem[] {items[0]}); 110 } 111 } 112 113 public void collapseAll(TreeItem from) { 114 TreeItem[] items = from.getItems(); 115 for (int i = 0, n = items.length; i < n; ++i) { 116 TreeItem item = items[i]; 117 collapseAll(item); 118 } 119 from.setExpanded(false); 120 } 121 122 public void expandAll() { 123 TreeItem[] items = tree.getItems(); 124 for (int i = 0, n = items.length; i < n; ++i) { 125 TreeItem item = items[i]; 126 expandAll(item); 127 } 128 if (items.length > 0) { 129 tree.setSelection(new TreeItem[] {items[0]}); 130 } 131 } 132 133 public void expandAll(TreeItem from) { 134 from.setExpanded(true); 135 TreeItem[] items = from.getItems(); 136 for (int i = 0, n = items.length; i < n; ++i) { 137 TreeItem item = items[i]; 138 expandAll(item); 139 } 140 } 141 142 public boolean getAutoScroll() { 143 return autoScroll; 144 } 145 146 public AbstractTreeLogger getLogger() { 147 return logger; 148 } 149 150 public void removeAll() { 151 tree.removeAll(); 152 details.setText(""); 153 } 154 155 public void setAutoScroll(boolean autoScroll) { 156 this.autoScroll = autoScroll; 157 } 158 159 public synchronized void treeCollapsed(TreeEvent treeEvent) { 160 } 161 162 public synchronized void treeExpanded(TreeEvent treeEvent) { 163 } 164 165 public void widgetDefaultSelected(SelectionEvent event) { 166 } 167 168 public void widgetSelected(SelectionEvent event) { 169 syncDetailsPane((TreeItem) event.item); 170 } 171 172 protected void appendTreeItemText(PrintWriter result, TreeItem[] items, 173 int depth) { 174 for (int i = 0; i < items.length; i++) { 175 TreeItem item = items[i]; 176 for (int j = 0; j < depth; j++) { 177 result.print(" "); 178 } 179 result.println(item.getText()); 180 TreeItem[] children = item.getItems(); 181 if (children != null) { 182 appendTreeItemText(result, children, depth + 1); 183 } 184 } 185 } 186 187 protected void copyTreeSelectionToClipboard(Tree tree) { 188 TreeItem[] selected = tree.getSelection(); 189 StringWriter sw = new StringWriter (); 190 PrintWriter pw = new PrintWriter (sw, false); 191 if (selected != null) { 192 appendTreeItemText(pw, selected, 0); 193 } 194 pw.close(); 195 Clipboard cb = new Clipboard(tree.getDisplay()); 196 197 final Object [] cbText = new Object [] {sw.toString()}; 198 final Transfer[] cbFormat = new Transfer[] {TextTransfer.getInstance()}; 199 cb.setContents(cbText, cbFormat); 200 } 201 202 private final void initLogFlushTimer(final Display display) { 203 final int flushDelay = 1000; 204 205 display.timerExec(flushDelay, new Runnable () { 206 public void run() { 207 if (tree.isDisposed()) { 208 return; 209 } 210 211 if (logger.uiFlush(tree)) { 212 if (autoScroll) { 215 TreeItem lastItem = findLastVisibleItem(tree); 216 if (lastItem != null) { 217 tree.setSelection(new TreeItem[] {lastItem}); 218 tree.showItem(lastItem); 219 expandAllChildren(lastItem); 220 syncDetailsPane(lastItem); 221 } 222 } 223 } 224 225 display.timerExec(flushDelay, this); 226 } 227 228 private void expandAllChildren(TreeItem item) { 229 item.setExpanded(true); 230 for (int i = 0, n = item.getItemCount(); i < n; ++i) { 231 expandAllChildren(item.getItem(i)); 232 } 233 } 234 235 private TreeItem findLastVisibleItem(Tree tree) { 236 int n = tree.getItemCount() - 1; 237 if (n > 0) { 238 TreeItem item = tree.getItem(n); 239 if (item.getExpanded()) { 240 return findLastVisibleItem(item); 241 } else { 242 return item; 243 } 244 } else { 245 return null; 246 } 247 } 248 249 private TreeItem findLastVisibleItem(TreeItem item) { 250 int n = item.getItemCount() - 1; 251 if (n > 0) { 252 TreeItem child = item.getItem(n); 253 if (child.getExpanded()) { 254 return findLastVisibleItem(child); 255 } 256 } 257 return item; 258 } 259 }); 260 } 261 262 private void syncDetailsPane(TreeItem item) { 263 TreeItemLogger.LogEvent logEvent = null; 266 Object testLogEvent = item.getData(); 267 if (testLogEvent instanceof TreeItemLogger.LogEvent) { 268 logEvent = (LogEvent) testLogEvent; 269 } 270 271 StringBuffer sb = new StringBuffer (); 274 275 if (logEvent != null && logEvent.type != null) { 278 sb.append("["); 279 sb.append(logEvent.type.getLabel()); 280 sb.append("] "); 281 } 282 283 sb.append(item.getText()); 286 sb.append("\n"); 287 288 if (logEvent != null && logEvent.caught != null) { 291 if (!(logEvent.caught instanceof UnableToCompleteException)) { 292 String stackTrace = AbstractTreeLogger.getStackTraceAsString(logEvent.caught); 293 sb.append(stackTrace); 294 } 295 } 296 297 details.setText(sb.toString()); 298 } 299 } 300 | Popular Tags |