00001 package edu.rice.cs.hpc.traceviewer.main;
00002
00003 import java.util.concurrent.ExecutorService;
00004 import java.util.concurrent.Executors;
00005
00006 import org.eclipse.core.commands.ExecutionException;
00007 import org.eclipse.core.commands.operations.IOperationHistoryListener;
00008 import org.eclipse.core.commands.operations.IUndoableOperation;
00009 import org.eclipse.core.commands.operations.OperationHistoryEvent;
00010 import org.eclipse.core.commands.operations.OperationHistoryFactory;
00011 import org.eclipse.core.runtime.Status;
00012 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
00013 import org.eclipse.core.runtime.jobs.IJobChangeListener;
00014 import org.eclipse.jface.action.Action;
00015 import org.eclipse.swt.SWT;
00016 import org.eclipse.swt.events.DisposeEvent;
00017 import org.eclipse.swt.events.DisposeListener;
00018 import org.eclipse.swt.events.KeyEvent;
00019 import org.eclipse.swt.events.KeyListener;
00020 import org.eclipse.swt.events.PaintEvent;
00021 import org.eclipse.swt.graphics.GC;
00022 import org.eclipse.swt.graphics.Image;
00023 import org.eclipse.swt.graphics.ImageData;
00024 import org.eclipse.swt.graphics.Point;
00025 import org.eclipse.swt.graphics.Rectangle;
00026 import org.eclipse.swt.widgets.Composite;
00027 import org.eclipse.swt.widgets.Label;
00028 import org.eclipse.ui.IWorkbenchWindow;
00029 import org.eclipse.ui.services.ISourceProviderService;
00030
00031 import edu.rice.cs.hpc.data.experiment.extdata.IBaseData;
00032 import edu.rice.cs.hpc.traceviewer.operation.BufferRefreshOperation;
00033 import edu.rice.cs.hpc.traceviewer.operation.DepthOperation;
00034 import edu.rice.cs.hpc.traceviewer.operation.PositionOperation;
00035 import edu.rice.cs.hpc.traceviewer.operation.TraceOperation;
00036 import edu.rice.cs.hpc.traceviewer.operation.ZoomOperation;
00037 import edu.rice.cs.hpc.traceviewer.painter.AbstractTimeCanvas;
00038 import edu.rice.cs.hpc.traceviewer.painter.BufferPaint;
00039 import edu.rice.cs.hpc.traceviewer.painter.ISpaceTimeCanvas;
00040 import edu.rice.cs.hpc.traceviewer.painter.ImageTraceAttributes;
00041 import edu.rice.cs.hpc.traceviewer.painter.ResizeListener;
00042 import edu.rice.cs.hpc.traceviewer.services.ProcessTimelineService;
00043 import edu.rice.cs.hpc.traceviewer.spaceTimeData.Frame;
00044 import edu.rice.cs.hpc.traceviewer.spaceTimeData.Position;
00045 import edu.rice.cs.hpc.traceviewer.spaceTimeData.SpaceTimeDataController;
00046 import edu.rice.cs.hpc.traceviewer.data.timeline.ProcessTimeline;
00047 import edu.rice.cs.hpc.traceviewer.util.Utility;
00048 import edu.rice.cs.hpc.traceviewer.data.util.Constants;
00049 import edu.rice.cs.hpc.traceviewer.data.util.Debugger;
00050
00051
00052
00053
00054
00055
00056
00057
00058 public class SpaceTimeDetailCanvas extends AbstractTimeCanvas
00059 implements IOperationHistoryListener, ISpaceTimeCanvas
00060 {
00062 protected SpaceTimeDataController stData;
00063
00065 private Action homeButton;
00066
00068 private Action openButton;
00069
00071 private Action saveButton;
00072
00074 private Action tZoomInButton;
00075
00077 private Action tZoomOutButton;
00078
00080 private Action pZoomInButton;
00081
00083 private Action pZoomOutButton;
00084
00085 private Action goEastButton, goNorthButton, goWestButton, goSouthButton;
00086
00088 final private Point selectionTopLeft, selectionBottomRight;
00089
00091 private Composite labelGroup;
00092
00094 private Label timeLabel;
00095
00097 private Label processLabel;
00098
00100 private Label crossHairLabel;
00101
00103 private final static int MIN_PROC_DISP = 1;
00104
00105 final private ImageTraceAttributes oldAttributes;
00106
00107 final private ProcessTimelineService ptlService;
00108
00109 final IWorkbenchWindow window;
00110
00111 final private ExecutorService threadExecutor;
00112
00114 public SpaceTimeDetailCanvas(IWorkbenchWindow window, Composite _composite)
00115 {
00116 super(_composite, SWT.NO_BACKGROUND, RegionType.Rectangle );
00117 oldAttributes = new ImageTraceAttributes();
00118
00119 selectionTopLeft = new Point(0,0);
00120 selectionBottomRight = new Point(0,0);
00121 stData = null;
00122
00123 initMouseSelection();
00124
00125 ISourceProviderService service = (ISourceProviderService)window.
00126 getService(ISourceProviderService.class);
00127 ptlService = (ProcessTimelineService) service.
00128 getSourceProvider(ProcessTimelineService.PROCESS_TIMELINE_PROVIDER);
00129
00130 this.window = window;
00131
00132
00133 threadExecutor = Executors.newFixedThreadPool( Utility.getNumThreads(0) );
00134
00135 addDisposeListener( new DisposeListener() {
00136
00137 @Override
00138 public void widgetDisposed(DisposeEvent e) {
00139
00140 dispose();
00141 }
00142 });
00143 }
00144
00145
00146 private void initMouseSelection()
00147 {
00148 initSelectionRectangle();
00149 }
00150
00151
00152
00153
00154
00155 public void updateView(SpaceTimeDataController _stData) {
00156
00157 super.init();
00158
00159 if (this.stData == null)
00160 {
00161 addCanvasListener();
00162 OperationHistoryFactory.getOperationHistory().addOperationHistoryListener(this);
00163 }
00164
00165
00166 initSelectionRectangle();
00167
00168 this.stData = _stData;
00169
00170
00171 Position p = new Position(-1, -1);
00172 stData.getAttributes().setPosition(p);
00173 stData.getAttributes().setDepth(0);
00174
00175 this.home();
00176
00177 this.saveButton.setEnabled(true);
00178 this.openButton.setEnabled(true);
00179 }
00180
00181
00182
00183
00184
00185 private void addCanvasListener() {
00186
00187 addPaintListener(this);
00188
00189 addKeyListener( new KeyListener(){
00190 public void keyPressed(KeyEvent e) {}
00191
00192 public void keyReleased(KeyEvent e) {
00193 switch (e.keyCode) {
00194
00195 case SWT.ARROW_DOWN:
00196 goSouth();
00197 break;
00198 case SWT.ARROW_UP:
00199 goNorth();
00200 break;
00201 case SWT.ARROW_LEFT:
00202 goEast();
00203 break;
00204 case SWT.ARROW_RIGHT:
00205 goWest();
00206 break;
00207 }
00208 }
00209 });
00210
00211
00212
00213
00214
00215
00216
00217 final ResizeListener listener = new ResizeListener( new DetailBufferPaint() );
00218 addControlListener(listener);
00219 getDisplay().addFilter(SWT.MouseDown, listener);
00220 getDisplay().addFilter(SWT.MouseUp, listener);
00221 }
00222
00223
00224
00225
00226
00227
00228 public void zoom(long _topLeftTime, int _topLeftProcess, long _bottomRightTime, int _bottomRightProcess)
00229 {
00230 final ImageTraceAttributes attributes = stData.getAttributes();
00231 attributes.setTime(_topLeftTime, _bottomRightTime);
00232 attributes.assertTimeBounds(stData.getTimeWidth());
00233
00234 attributes.setProcess(_topLeftProcess, _bottomRightProcess);
00235 attributes.assertProcessBounds(stData.getTotalTraceCount());
00236
00237 final long numTimeDisplayed = this.getNumTimeUnitDisplayed();
00238 if (numTimeDisplayed < Constants.MIN_TIME_UNITS_DISP)
00239 {
00240 long begTime = _topLeftTime + (numTimeDisplayed - Constants.MIN_TIME_UNITS_DISP) / 2;
00241 long endTime = _topLeftTime + Constants.MIN_TIME_UNITS_DISP;
00242 attributes.setTime(begTime, endTime);
00243 }
00244
00245 final double numProcessDisp = this.getNumProcessesDisplayed();
00246 if (numProcessDisp < MIN_PROC_DISP)
00247 {
00248 int endProcess = _topLeftProcess + MIN_PROC_DISP;
00249 attributes.setProcess(_topLeftProcess, endProcess );
00250 }
00251
00252 updateButtonStates();
00253
00254
00255
00256
00257
00258 refresh(true);
00259 }
00260
00261
00262
00263
00264 private void initSelectionRectangle()
00265 {
00266 selectionTopLeft.x = 0;
00267 selectionTopLeft.y = 0;
00268 selectionBottomRight.x = 0;
00269 selectionBottomRight.y = 0;
00270 }
00271
00272
00273
00274
00275
00276
00277 public void paintControl(PaintEvent event)
00278 {
00279 if (this.stData == null)
00280 return;
00281
00282 super.paintControl(event);
00283
00284 final ImageTraceAttributes attributes = stData.getAttributes();
00285
00286
00287 long selectedTime = attributes.getPosition().time - attributes.getTimeBegin();
00288 int selectedProcess = attributes.getPosition().process - attributes.getProcessBegin();
00289
00290 int topPixelCrossHairX = (int)(Math.round(selectedTime*getScalePixelsPerTime())-10);
00291 int topPixelCrossHairY = (int)(Math.round((selectedProcess+.5)*getScalePixelsPerRank())-10);
00292
00293 event.gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
00294 event.gc.fillRectangle(topPixelCrossHairX,topPixelCrossHairY+8,20,4);
00295 event.gc.fillRectangle(topPixelCrossHairX+8,topPixelCrossHairY,4,20);
00296 }
00297
00298
00299
00300
00301 public void setButtons(Action[] toolItems)
00302 {
00303 homeButton = toolItems[0];
00304 openButton = toolItems[1];
00305 saveButton = toolItems[2];
00306 tZoomInButton = toolItems[5];
00307 tZoomOutButton = toolItems[6];
00308 pZoomInButton = toolItems[7];
00309 pZoomOutButton = toolItems[8];
00310
00311 goEastButton = toolItems[9];
00312 goNorthButton = toolItems[10];
00313 goSouthButton = toolItems[11];
00314 goWestButton = toolItems[12];
00315 }
00316
00317
00318
00319
00320
00321
00322 public void home()
00323 {
00324
00325
00326 Frame frame = new Frame(stData.getAttributes().getFrame());
00327 frame.begProcess = 0;
00328 frame.endProcess = stData.getTotalTraceCount();
00329 frame.begTime = 0;
00330 frame.endTime = stData.getTimeWidth();
00331
00332 notifyChanges(ZoomOperation.ActionHome, frame);
00333 }
00334
00335
00336
00337
00338
00339 public void open(Frame toBeOpened)
00340 {
00341 notifyChanges("Frame", toBeOpened);
00342 }
00343
00344
00345
00346
00347
00348
00349 public Frame save()
00350 {
00351 return stData.getAttributes().getFrame();
00352 }
00353
00354
00355
00356
00357
00358
00359
00360 public void processZoomIn()
00361 {
00362 final double SCALE = .4;
00363 final ImageTraceAttributes attributes = stData.getAttributes();
00364
00365 double yMid = (attributes.getProcessEnd()+attributes.getProcessBegin())/2.0;
00366
00367 final double numProcessDisp = attributes.getProcessInterval();
00368
00369 int p2 = (int) Math.ceil( yMid+numProcessDisp*SCALE );
00370 int p1 = (int) Math.floor( yMid-numProcessDisp*SCALE );
00371
00372 attributes.assertProcessBounds(stData.getTotalTraceCount());
00373
00374 if(p2 == attributes.getProcessEnd() && p1 == attributes.getProcessBegin())
00375 {
00376 if(numProcessDisp == 2)
00377 p2--;
00378 else if(numProcessDisp > 2)
00379 {
00380 p2--;
00381 p1++;
00382 }
00383 }
00384 final Frame frame = new Frame(stData.getAttributes().getFrame());
00385 frame.begProcess = p1;
00386 frame.endProcess = p2;
00387
00388 notifyChanges("Zoom-in ranks", frame);
00389 }
00390
00391
00392
00393
00394
00395 public void processZoomOut()
00396 {
00397 final double SCALE = .625;
00398 final ImageTraceAttributes attributes = stData.getAttributes();
00399
00400
00401
00402 double yMid = ((double)attributes.getProcessEnd() + (double)attributes.getProcessBegin())/2.0;
00403
00404 final double numProcessDisp = attributes.getProcessInterval();
00405
00406
00407 int p2 = (int) Math.min( stData.getTotalTraceCount(), Math.ceil( yMid+numProcessDisp*SCALE ) );
00408 int p1 = (int) Math.max( 0, Math.floor( yMid-numProcessDisp*SCALE ) );
00409
00410 if(p2 == attributes.getProcessEnd() && p1 == attributes.getProcessBegin())
00411 {
00412 if(numProcessDisp == 2)
00413 p2++;
00414 else if(numProcessDisp > 2)
00415 {
00416 p2++;
00417 p1--;
00418 }
00419 }
00420 final Frame frame = new Frame(stData.getAttributes().getFrame());
00421 frame.begProcess = p1;
00422 frame.endProcess = p2;
00423
00424 notifyChanges("Zoom-out ranks", frame);
00425 }
00426
00427
00428
00429
00430
00431
00432 public void timeZoomIn()
00433 {
00434 final double SCALE = .4;
00435 final ImageTraceAttributes attributes = stData.getAttributes();
00436
00437 long xMid = (attributes.getTimeEnd() + attributes.getTimeBegin()) / 2;
00438
00439 final long numTimeUnitsDisp = attributes.getTimeInterval();
00440
00441 long t2 = xMid + (long)(numTimeUnitsDisp * SCALE);
00442 long t1 = xMid - (long)(numTimeUnitsDisp * SCALE);
00443
00444 final Frame frame = new Frame(stData.getAttributes().getFrame());
00445 frame.begTime = t1;
00446 frame.endTime = t2;
00447
00448 notifyChanges("Zoom-in time", frame);
00449 }
00450
00451
00452
00453
00454
00455 public void timeZoomOut()
00456 {
00457 final double SCALE = 0.625;
00458 final ImageTraceAttributes attributes = stData.getAttributes();
00459
00460
00461
00462 long xMid = (attributes.getTimeEnd() + attributes.getTimeBegin()) / 2;
00463
00464 final long td2 = (long)(this.getNumTimeUnitDisplayed() * SCALE);
00465 long t2 = Math.min( stData.getTimeWidth(), xMid + td2);
00466 final long td1 = (long)(this.getNumTimeUnitDisplayed() * SCALE);
00467 long t1 = Math.max(0, xMid - td1);
00468
00469 final Frame frame = new Frame(stData.getAttributes().getFrame());
00470 frame.begTime = t1;
00471 frame.endTime = t2;
00472
00473 notifyChanges("Zoom-out time", frame);
00474 }
00475
00476
00477
00478
00479 @Override
00480 public double getScalePixelsPerTime()
00481 {
00482 return (double)stData.getAttributes().numPixelsH / (double)this.getNumTimeUnitDisplayed();
00483 }
00484
00485
00486
00487
00488 @Override
00489 public double getScalePixelsPerRank()
00490 {
00491 return (double)stData.getAttributes().numPixelsV / this.getNumProcessesDisplayed();
00492 }
00493
00494
00495
00496
00497 public void setDepth(int newDepth)
00498 {
00499 stData.getAttributes().setDepth(newDepth);
00500 refresh(false);
00501 }
00502
00503
00504
00505
00506
00507 public void setLabels(Composite _labelGroup)
00508 {
00509 labelGroup = _labelGroup;
00510
00511 timeLabel = new Label(labelGroup, SWT.LEFT);
00512 processLabel = new Label(labelGroup, SWT.CENTER);
00513 crossHairLabel = new Label(labelGroup, SWT.RIGHT);
00514 }
00515
00516
00517
00518
00519 private void adjustLabels()
00520 {
00521 final ImageTraceAttributes attributes = stData.getAttributes();
00522
00523 timeLabel.setText("Time Range: [" + (attributes.getTimeBegin()/1000)/1000.0 + "s, "
00524 + (attributes.getTimeEnd()/1000)/1000.0 + "s]");
00525 timeLabel.setSize(timeLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
00526
00527
00528 final IBaseData traceData = stData.getBaseData();
00529 if (traceData == null) {
00530
00531 System.out.println("Data null, skipping the rest.");
00532 return;
00533 }
00534 stData.getAttributes().assertProcessBounds(traceData.getNumberOfRanks());
00535
00536 final String processes[] = traceData.getListOfRanks();
00537
00538 int proc_start = attributes.getProcessBegin();
00539 if (proc_start < 0 || proc_start >= processes.length)
00540 proc_start = 0;
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 int proc_end = attributes.getProcessEnd() - 1;
00552 if (proc_end>=processes.length)
00553 proc_end = processes.length-1;
00554
00555 processLabel.setText("Rank Range: [" + processes[proc_start] + "," + processes[proc_end]+"]");
00556 processLabel.setSize(processLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
00557
00558 if(stData == null)
00559 crossHairLabel.setText("Select Sample For Cross Hair");
00560 else
00561 {
00562 final Position position = stData.getAttributes().getPosition();
00563 final long selectedTime = position.time;
00564 final int rank = position.process;
00565
00566 if ( rank >= 0 && rank < processes.length ) {
00567 crossHairLabel.setText("Cross Hair: (" + (selectedTime/1000)/1000.0 + "s, " + processes[rank] + ")");
00568 } else {
00569
00570 crossHairLabel.setText("Cross Hair: (" + (selectedTime/1000)/1000.0 + "s, ?)");
00571 }
00572 }
00573
00574 labelGroup.setSize(labelGroup.computeSize(SWT.DEFAULT, SWT.DEFAULT));
00575 }
00576
00577
00578
00579
00580 private void adjustSelection(Rectangle selection)
00581 {
00582 selectionTopLeft.x = Math.max(selection.x, 0);
00583 selectionTopLeft.y = Math.max(selection.y, 0);
00584
00585 final Rectangle view = getClientArea();
00586
00587 selectionBottomRight.x = Math.min(selection.width+selection.x, view.width-1);
00588 selectionBottomRight.y = Math.min(selection.height+selection.y, view.height-1);
00589
00590 if (selectionTopLeft.x < 0 || selectionBottomRight.x < 0 || view.x < 0) {
00591 Debugger.printDebug(1, "STDC Error: negative time " + view +
00592 " [" + selectionTopLeft.x + ", " + selectionBottomRight.x + "]");
00593 }
00594 }
00595
00596
00597
00598
00599
00600
00601 private void setDetail()
00602 {
00603 ImageTraceAttributes attributes = stData.getAttributes();
00604 int topLeftProcess = attributes.getProcessBegin() + (int) (selectionTopLeft.y / getScalePixelsPerRank());
00605 long topLeftTime = attributes.getTimeBegin() + (long)(selectionTopLeft.x / getScalePixelsPerTime());
00606
00607
00608
00609
00610
00611
00612 int bottomRightProcess = attributes.getProcessBegin() + (int) Math.ceil( (selectionBottomRight.y / getScalePixelsPerRank()) );
00613 long bottomRightTime = attributes.getTimeBegin() + (long)Math.ceil( (selectionBottomRight.x / getScalePixelsPerTime()) );
00614
00615
00616 final Frame frame = new Frame(stData.getAttributes().getFrame());
00617 frame.begTime = topLeftTime;
00618 frame.endTime = bottomRightTime;
00619 frame.begProcess = topLeftProcess;
00620 frame.endProcess = bottomRightProcess;
00621
00622 notifyChanges("Zoom", frame);
00623 }
00624
00625
00626 private boolean canGoEast() {
00627 return (stData.getAttributes().getTimeBegin() > 0);
00628 }
00629
00630 private boolean canGoWest() {
00631 return (stData.getAttributes().getTimeEnd()< this.stData.getTimeWidth());
00632 }
00633
00634 private boolean canGoNorth() {
00635 return (stData.getAttributes().getProcessBegin()>0);
00636 }
00637
00638 private boolean canGoSouth() {
00639 return (stData.getAttributes().getProcessEnd()<this.stData.getTotalTraceCount());
00640 }
00641
00642
00643
00644 private void updateButtonStates()
00645 {
00646 final ImageTraceAttributes attributes = stData.getAttributes();
00647
00648 this.tZoomInButton.setEnabled( this.getNumTimeUnitDisplayed() > Constants.MIN_TIME_UNITS_DISP );
00649 this.tZoomOutButton.setEnabled(attributes.getTimeBegin()>0 || attributes.getTimeEnd()<stData.getTimeWidth() );
00650
00651 this.pZoomInButton.setEnabled( getNumProcessesDisplayed() > MIN_PROC_DISP );
00652 this.pZoomOutButton.setEnabled( attributes.getProcessBegin()>0 || attributes.getProcessEnd()<stData.getTotalTraceCount());
00653
00654 this.goEastButton.setEnabled( canGoEast() );
00655 this.goWestButton.setEnabled( canGoWest() );
00656 this.goNorthButton.setEnabled( canGoNorth() );
00657 this.goSouthButton.setEnabled( canGoSouth() );
00658
00659 homeButton.setEnabled( attributes.getTimeBegin()>0 || attributes.getTimeEnd()<stData.getTimeWidth()
00660 || attributes.getProcessBegin()>0 || attributes.getProcessEnd()<stData.getTotalTraceCount() );
00661 }
00662
00663 final static private double SCALE_MOVE = 0.20;
00664
00665
00666
00667
00668 public void goEast()
00669 {
00670 if (!canGoEast())
00671 return;
00672
00673 final ImageTraceAttributes attributes = stData.getAttributes();
00674
00675 long topLeftTime = attributes.getTimeBegin();
00676 long bottomRightTime = attributes.getTimeEnd();
00677
00678 long deltaTime = bottomRightTime - topLeftTime;
00679 final long moveTime = (long)java.lang.Math.ceil(deltaTime * SCALE_MOVE);
00680 topLeftTime = topLeftTime - moveTime;
00681
00682 if (topLeftTime < 0) {
00683 topLeftTime = 0;
00684 }
00685 bottomRightTime = topLeftTime + deltaTime;
00686
00687 setTimeRange(topLeftTime, bottomRightTime);
00688
00689 updateButtonStates();
00690 }
00691
00692
00693
00694
00695 public void goWest()
00696 {
00697 if (!canGoWest())
00698 return;
00699
00700 final ImageTraceAttributes attributes = stData.getAttributes();
00701
00702 long topLeftTime = attributes.getTimeBegin();
00703 long bottomRightTime = attributes.getTimeEnd();
00704
00705 long deltaTime = bottomRightTime - topLeftTime;
00706 final long moveTime = (long)java.lang.Math.ceil(deltaTime * SCALE_MOVE);
00707 bottomRightTime = bottomRightTime + moveTime;
00708
00709 if (bottomRightTime > stData.getTimeWidth()) {
00710 bottomRightTime = stData.getTimeWidth();
00711 }
00712 topLeftTime = bottomRightTime - deltaTime;
00713
00714 setTimeRange(topLeftTime, bottomRightTime);
00715
00716 this.updateButtonStates();
00717 }
00718
00719
00720
00721
00722
00723
00724 public void setTimeRange(long topLeftTime, long bottomRightTime)
00725 {
00726 final Frame frame = new Frame(stData.getAttributes().getFrame());
00727 frame.begTime = topLeftTime;
00728 frame.endTime = bottomRightTime;
00729
00730 notifyChanges("Zoom H", frame);
00731 }
00732
00733
00734
00735
00736 public void goNorth() {
00737 if (!canGoNorth())
00738 return;
00739
00740 final ImageTraceAttributes attributes = stData.getAttributes();
00741
00742 int proc_begin = attributes.getProcessBegin();
00743 int proc_end = attributes.getProcessEnd();
00744 final int delta = proc_end - proc_begin;
00745 final int move = (int) java.lang.Math.ceil(delta * SCALE_MOVE);
00746
00747 proc_begin = proc_begin - move;
00748
00749 if (proc_begin < 0) {
00750 proc_begin = 0;
00751 }
00752 proc_end = proc_begin + delta;
00753 this.setProcessRange(proc_begin, proc_end);
00754 this.updateButtonStates();
00755 }
00756
00757
00758
00759
00760 public void goSouth() {
00761 if (!canGoSouth())
00762 return;
00763
00764 final ImageTraceAttributes attributes = stData.getAttributes();
00765
00766 int proc_begin = attributes.getProcessBegin();
00767 int proc_end = attributes.getProcessEnd();
00768 final int delta = proc_end - proc_begin;
00769 final int move = (int) java.lang.Math.ceil(delta * SCALE_MOVE);
00770
00771 proc_end = proc_end + move;
00772
00773 if (proc_end > stData.getTotalTraceCount()) {
00774 proc_end = stData.getTotalTraceCount();
00775 }
00776 proc_begin = proc_end - delta;
00777 this.setProcessRange(proc_begin, proc_end);
00778 this.updateButtonStates();
00779 }
00780
00781
00782
00783
00784
00785
00786 private void setProcessRange(int pBegin, int pEnd)
00787 {
00788 final ImageTraceAttributes attributes = stData.getAttributes();
00789 final Frame frame = new Frame(attributes.getFrame());
00790 frame.begProcess = pBegin;
00791 frame.endProcess = pEnd;
00792
00793 notifyChanges("Zoom V", frame);
00794 }
00795
00796 private Position updatePosition(Point mouseDown)
00797 {
00798 final ImageTraceAttributes attributes = stData.getAttributes();
00799 final Rectangle view = getClientArea();
00800 int selectedProcess;
00801
00802
00803 if(view.height > getNumProcessesDisplayed())
00804 {
00805 selectedProcess = (int)(attributes.getProcessBegin()+mouseDown.y/getScalePixelsPerRank());
00806 }
00807 else
00808 {
00809 selectedProcess = (int)(attributes.getProcessBegin()+(mouseDown.y*(getNumProcessesDisplayed()))/view.height);
00810 }
00811 long closeTime = attributes.getTimeBegin() + (long)(mouseDown.x / getScalePixelsPerTime());
00812
00813 if (closeTime > attributes.getTimeEnd()) {
00814 System.err.println("ERR STDC SCSSample time: " + closeTime +" max time: " +
00815 attributes.getTimeEnd() + "\t new: " + ((attributes.getTimeBegin() + attributes.getTimeEnd()) >> 1));
00816 closeTime = (attributes.getTimeBegin() + attributes.getTimeEnd()) >> 1;
00817 }
00818
00819 return new Position(closeTime, selectedProcess);
00820 }
00821
00822
00823 private long getNumTimeUnitDisplayed()
00824 {
00825 return (stData.getAttributes().getTimeInterval());
00826 }
00827
00828 private double getNumProcessesDisplayed()
00829 {
00830 return (stData.getAttributes().getProcessInterval());
00831 }
00832
00833
00834
00835
00836
00837
00838
00839
00840 public void refresh(boolean refreshData) {
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857 final Rectangle view = getClientArea();
00858
00859 final Image imageFinal = new Image(getDisplay(), view.width, view.height);
00860 final GC bufferGC = new GC(imageFinal);
00861 bufferGC.setBackground(Constants.COLOR_WHITE);
00862 bufferGC.fillRectangle(0,0,view.width,view.height);
00863
00864
00865
00866
00867
00868
00869
00870
00871 int numLines = Math.min(view.height, stData.getAttributes().getProcessInterval() );
00872 final Image imageOrig = new Image(getDisplay(), view.width, numLines);
00873
00874 final GC origGC = new GC(imageOrig);
00875 origGC.setBackground(Constants.COLOR_WHITE);
00876 origGC.fillRectangle(0,0,view.width, numLines);
00877
00878
00879
00880
00881
00882
00883 ImageTraceAttributes attributes = stData.getAttributes();
00884 final boolean changedBounds = (refreshData? refreshData : !attributes.sameTrace(oldAttributes) );
00885
00886 attributes.numPixelsH = view.width;
00887 attributes.numPixelsV = view.height;
00888
00889 oldAttributes.copy(attributes);
00890 if (changedBounds) {
00891 final int num_traces = Math.min(attributes.numPixelsV, attributes.getProcessInterval());
00892 ProcessTimeline []traces = new ProcessTimeline[ num_traces ];
00893 ptlService.setProcessTimeline(traces);
00894 }
00895
00896
00897
00898
00899
00900
00901 DetailViewPaint detailPaint = new DetailViewPaint(bufferGC, origGC, stData,
00902 attributes, changedBounds, window, this, threadExecutor);
00903
00904 detailPaint.setUser(true);
00905 detailPaint.addJobChangeListener(new IJobChangeListener() {
00906
00907 @Override
00908 public void sleeping(IJobChangeEvent event) {}
00909
00910 @Override
00911 public void scheduled(IJobChangeEvent event) {}
00912
00913 @Override
00914 public void running(IJobChangeEvent event) {}
00915
00916 @Override
00917 public void done(IJobChangeEvent event) {
00918 if (event.getResult() == Status.OK_STATUS)
00919 {
00920 donePainting(imageOrig, imageFinal, changedBounds);
00921 } else
00922 {
00923
00924 imageFinal.dispose();
00925 }
00926
00927 bufferGC.dispose();
00928 origGC.dispose();
00929 imageOrig.dispose();
00930 }
00931
00932 @Override
00933 public void awake(IJobChangeEvent event) {}
00934
00935 @Override
00936 public void aboutToRun(IJobChangeEvent event) {}
00937 });
00938 detailPaint.schedule();
00939 }
00940
00941
00942 private void donePainting(Image imageOrig, Image imageFinal, boolean refreshData)
00943 {
00944 if (imageBuffer != null) {
00945 imageBuffer.dispose();
00946 }
00947 imageBuffer = imageFinal;
00948
00949
00950 if (refreshData) {
00951 final String []ranks = stData.getBaseData().getListOfRanks();
00952 final Position p = stData.getAttributes().getPosition();
00953
00954 if (p.process > ranks.length-1) {
00955
00956 Position new_p = new Position( p.time, ranks.length >> 1 );
00957 notifyChangePosition(new_p);
00958 }
00959 }
00960 super.redraw();
00961
00962
00963
00964
00965
00966 notifyChangeBuffer(imageOrig.getImageData());
00967
00968 updateButtonStates();
00969 }
00970
00971
00972
00973
00974
00975
00976 public void dispose () {
00977 threadExecutor.shutdown();
00978 super.dispose();
00979 }
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994 private void notifyChanges(String label, Frame frame)
00995 {
00996 String sLabel = (label == null ? "Set region" : label);
00997 Debugger.printDebug(1, "STDC " + sLabel + " : " + frame);
00998
00999 try {
01000
01001 TraceOperation.getOperationHistory().execute(
01002 new ZoomOperation(sLabel, frame),
01003 null, null);
01004
01005 } catch (ExecutionException e) {
01006
01007 e.printStackTrace();
01008 }
01009 }
01010
01011
01012
01013
01014
01015
01016 private void notifyChangePosition(Position position)
01017 {
01018 try {
01019 TraceOperation.getOperationHistory().execute(
01020 new PositionOperation(position),
01021 null, null);
01022 } catch (ExecutionException e) {
01023 e.printStackTrace();
01024 }
01025 }
01026
01027
01028
01029
01030
01031
01032
01033 private void notifyChangeBuffer(ImageData imageData)
01034 {
01035
01036
01037
01038
01039
01040 BufferRefreshOperation brOp = new BufferRefreshOperation("refresh", imageData);
01041 try {
01042 TraceOperation.getOperationHistory().execute(brOp, null, null);
01043 } catch (ExecutionException e) {
01044 e.printStackTrace();
01045 }
01046 }
01047
01048
01049
01050
01051 private HistoryOperation historyOperation = new HistoryOperation();
01052
01053 @Override
01054 public void historyNotification(final OperationHistoryEvent event) {
01055 final IUndoableOperation operation = event.getOperation();
01056
01057
01058 if (operation.hasContext(TraceOperation.traceContext) ||
01059 operation.hasContext(PositionOperation.context))
01060 {
01061 int type = event.getEventType();
01062
01063
01064
01065
01066 switch (type)
01067 {
01068 case OperationHistoryEvent.ABOUT_TO_EXECUTE:
01069 case OperationHistoryEvent.ABOUT_TO_REDO:
01070 case OperationHistoryEvent.ABOUT_TO_UNDO:
01071 historyOperation.setOperation(operation);
01072
01073
01074
01075
01076
01077
01078 historyOperation.run();
01079 break;
01080 }
01081 }
01082 }
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096 private class DetailBufferPaint implements BufferPaint
01097 {
01098
01099 @Override
01100 public void rebuffering() {
01101
01102 final ImageTraceAttributes attr = stData.getAttributes();
01103 notifyChanges("Resize", attr.getFrame() );
01104 }
01105 }
01106
01107
01108
01109
01110
01111
01112 private class HistoryOperation implements Runnable
01113 {
01114 private IUndoableOperation operation;
01115
01116 public void setOperation(IUndoableOperation operation) {
01117 this.operation = operation;
01118 }
01119
01120 @Override
01121 public void run() {
01122
01123 if (operation instanceof ZoomOperation) {
01124 Frame frame = ((ZoomOperation)operation).getFrame();
01125 final ImageTraceAttributes attributes = stData.getAttributes();
01126
01127 Debugger.printDebug(1, "STDC: " + attributes + "\t New: " + frame);
01128
01129 stData.getAttributes().setFrame(frame);
01130 zoom(frame.begTime, frame.begProcess, frame.endTime, frame.endProcess);
01131 }
01132
01133 else if (operation instanceof PositionOperation) {
01134 Position p = ((PositionOperation)operation).getPosition();
01135 stData.getAttributes().setPosition(p);
01136
01137
01138 redraw();
01139 }
01140 else if (operation instanceof DepthOperation) {
01141 int depth = ((DepthOperation)operation).getDepth();
01142 setDepth(depth);
01143 }
01144 adjustLabels();
01145 }
01146 }
01147
01148 @Override
01149 protected void changePosition(Point point)
01150 {
01151 Position position = updatePosition(point);
01152 notifyChangePosition(position);
01153 }
01154
01155
01156 @Override
01157 protected void changeRegion(Rectangle region)
01158 {
01159
01160 if(getNumTimeUnitDisplayed() == Constants.MIN_TIME_UNITS_DISP)
01161 {
01162 if(getNumTimeUnitDisplayed() > MIN_PROC_DISP)
01163 {
01164 adjustSelection(region);
01165 setDetail();
01166 }
01167 }
01168 else
01169 {
01170 adjustSelection(region);
01171 setDetail();
01172 }
01173 }
01174 }