ScopeViewActionsGUI.java

Go to the documentation of this file.
00001 
00004 package edu.rice.cs.hpc.viewer.scope;
00005 
00006 import java.io.BufferedWriter;
00007 import java.io.File;
00008 import java.io.FileWriter;
00009 import java.io.IOException;
00010 import java.util.ArrayList;
00011 import java.util.List;
00012 
00013 import org.eclipse.jface.dialogs.MessageDialog;
00014 import org.eclipse.jface.layout.*;
00015 import org.eclipse.swt.SWT;
00016 import org.eclipse.swt.SWTException;
00017 import org.eclipse.swt.events.SelectionAdapter;
00018 import org.eclipse.swt.events.SelectionEvent;
00019 import org.eclipse.swt.widgets.Composite;
00020 import org.eclipse.swt.widgets.CoolBar;
00021 import org.eclipse.swt.widgets.CoolItem;
00022 import org.eclipse.swt.widgets.Display;
00023 import org.eclipse.swt.widgets.FileDialog;
00024 import org.eclipse.swt.widgets.ToolBar;
00025 import org.eclipse.swt.widgets.ToolItem;
00026 import org.eclipse.swt.widgets.TreeColumn;
00027 import org.eclipse.swt.widgets.Shell;
00028 import org.eclipse.swt.widgets.Control;
00029 import org.eclipse.swt.widgets.TreeItem;
00030 import org.eclipse.swt.graphics.Color;
00031 import org.eclipse.swt.widgets.Label;
00032 
00033 import org.eclipse.ui.IWorkbenchWindow;
00034 import edu.rice.cs.hpc.data.experiment.Experiment;
00035 import edu.rice.cs.hpc.data.experiment.scope.Scope;
00036 import edu.rice.cs.hpc.viewer.resources.Icons;
00037 import edu.rice.cs.hpc.viewer.util.ColumnPropertiesDialog;
00038 import edu.rice.cs.hpc.data.experiment.scope.RootScope;
00039 import edu.rice.cs.hpc.viewer.util.Utilities;
00040 import edu.rice.cs.hpc.viewer.window.Database;
00041 import edu.rice.cs.hpc.viewer.window.ViewerWindow;
00042 import edu.rice.cs.hpc.viewer.window.ViewerWindowManager;
00043 import edu.rice.cs.hpc.data.experiment.metric.BaseMetric;
00044 
00050 public class ScopeViewActionsGUI implements IScopeActionsGUI {
00051 
00052     final static private String COLUMN_DATA_WIDTH = "w"; 
00053     //======================================================
00054     // ------ DATA ----------------------------------------
00055     //======================================================
00056     // GUI STUFFs
00057     protected ScopeTreeViewer   treeViewer;         // tree for the caller and callees
00058     protected ScopeViewActions objViewActions;
00059     protected Shell shell;
00060     protected IWorkbenchWindow objWindow;
00061 
00062     // variable declaration uniquely for coolbar
00063     protected ToolItem tiZoomin;        // zoom-in button
00064     protected ToolItem tiZoomout ;  // zoom-out button
00065     protected ToolItem tiColumns ;  // show/hide button
00066     protected ToolItem tiHotCallPath;
00067     protected ToolItem tiAddExtMetric;
00068     protected Label lblMessage;
00069     
00070     //------------------------------------DATA
00071     protected Scope nodeTopParent; // the current node which is on the top of the table (used as the aggregate node)
00072     protected Database  database;       // experiment data  
00073     protected RootScope         myRootScope;        // the root scope of this view
00074 
00075     // ----------------------------------- CONSTANTS
00076     final protected Color clrGREEN, clrYELLOW, clrRED, clrNORMAL;
00077     
00085     public ScopeViewActionsGUI(Shell objShell, IWorkbenchWindow window, Composite parent, 
00086             ScopeViewActions objActions) {
00087 
00088         this.objViewActions = objActions;
00089         this.shell = objShell;
00090         this.objWindow = window;
00091         
00092         this.clrNORMAL = shell.getBackground();
00093         final Display display = shell.getDisplay();
00094         
00095         this.clrYELLOW = display.getSystemColor(SWT.COLOR_YELLOW);
00096         this.clrRED = display.getSystemColor(SWT.COLOR_RED);
00097         this.clrGREEN = display.getSystemColor(SWT.COLOR_GREEN);
00098     }
00099 
00105     public Composite buildGUI(Composite parent, CoolBar coolbar) {
00106         Composite newParent = this.addTooBarAction(coolbar);
00107         this.finalizeToolBar(parent, coolbar);
00108 
00109         return newParent;
00110     }
00111 
00119     public void updateContent(Experiment exp, RootScope scope) {
00120         // save the new data and properties
00121         String sFilename = exp.getDefaultDirectory().getAbsolutePath();
00122         ViewerWindow vWin = ViewerWindowManager.getViewerWindow(this.objWindow);
00123         if (vWin == null) {
00124             System.out.printf("ScopeViewActionsGUI.updateContent: ViewerWindow class not found\n");
00125             return;
00126         }
00127         database = vWin.getDb(sFilename);
00128 
00129         this.myRootScope = scope;
00130 
00131         //this.setLevelText(scope.getTreeNode().iLevel);    // @TODO: initialized with root level
00132         
00133         // actions needed when a new experiment is loaded
00134         this.resizeTableColumns();  // we assume the data has been populated
00135         this.enableActions();
00136         // since we have a new content of experiment, we need to display 
00137         // the aggregate metrics
00138         this.displayRootExperiment();
00139     }
00140     
00141     //======================================================
00142     public void setTreeViewer(ScopeTreeViewer tree) {
00143         this.treeViewer = tree;
00144     }
00145 
00152     public void insertParentNode(Scope nodeParent) {
00153         Scope scope = nodeParent;
00154         
00155         // Bug fix: avoid using list of columns from the experiment
00156         // formerly: .. = this.myExperiment.getMetricCount() + 1;
00157         TreeColumn []columns = treeViewer.getTree().getColumns();
00158         int nbColumns = columns.length;     // columns in base metrics
00159         String []sText = new String[nbColumns];
00160         sText[0] = new String(scope.getName());
00161         
00162         // --- prepare text for base metrics
00163         // get the metrics for all columns
00164         for (int i=1; i< nbColumns; i++) {
00165             // we assume the column is not null
00166             Object o = columns[i].getData();
00167             if(o instanceof BaseMetric) {
00168                 BaseMetric metric = (BaseMetric) o;
00169                 sText[i] = metric.getMetricTextValue(scope.getMetricValue(metric));
00170             }
00171         }
00172         
00173         // draw the root node item
00174         Utilities.insertTopRow(treeViewer, Utilities.getScopeNavButton(scope), sText);
00175         this.nodeTopParent = nodeParent;
00176     }
00177     
00181     private void restoreParentNode() {
00182         if(this.nodeTopParent != null) {
00183             this.insertParentNode(this.nodeTopParent);
00184         }
00185     }
00189     protected void displayRootExperiment() {
00190         Scope  node = (Scope) this.myRootScope;
00191         this.insertParentNode(node);
00192     }
00193     
00198     public void resizeTableColumns() {
00199         // resize the column according to the data size
00200         TreeColumn []columns = treeViewer.getTree().getColumns(); 
00201         int nbCols = columns.length;
00202         for (int i=1; i<nbCols; i++) {
00203             TreeColumn column = columns[i];
00204             // do NOT resize if the column is hidden
00205             if(column.getWidth()>1)
00206                 column.pack();
00207         }
00208     }
00209 
00210     //======================================================
00211     // ................ GUI and LAYOUT ....................
00212     //======================================================
00213     
00217     public void showInfoMessage(String sMsg) {
00218         this.lblMessage.setBackground(this.clrGREEN);
00219         this.lblMessage.setText(sMsg);
00220     }
00221     
00227     public void showWarningMessagge(String sMsg) {
00228         this.lblMessage.setBackground(this.clrYELLOW);
00229         this.lblMessage.setText(sMsg);
00230     }
00231     
00237     public void showErrorMessage(String sMsg) {
00238         this.lblMessage.setBackground(this.clrRED);
00239         this.lblMessage.setText(" " + sMsg);
00240     }
00241 
00245     public void restoreMessage() {
00246         if(this.lblMessage != null && !lblMessage.isDisposed()) {
00247             this.lblMessage.setBackground(this.clrNORMAL);
00248             this.lblMessage.setText("");
00249         }
00250     }
00254     public void resetActions() {
00255         this.tiColumns.setEnabled(false);
00256         this.tiAddExtMetric.setEnabled(false);
00257         // disable zooms and hot-path buttons
00258         this.disableNodeButtons();
00259     }
00260     
00264     public void enableActions() {
00265         this.tiColumns.setEnabled(true);
00266         this.tiAddExtMetric.setEnabled(true);
00267     }
00268         
00273     public void hideMetricColumn(TreeColumn column) {
00274             
00275         int iWidth = column.getWidth();
00276         if(iWidth > 0) {
00277             Integer objWidth = Integer.valueOf(iWidth); 
00278             // Laks: bug no 131: we need to have special key for storing the column width
00279             column.setData(COLUMN_DATA_WIDTH,objWidth);
00280             column.setWidth(0);
00281         }
00282     }
00283     
00287     protected void showColumnsProperties() {
00288         
00289         ColumnPropertiesDialog objProp = new ColumnPropertiesDialog(objWindow.getShell(), 
00290                 treeViewer.getTree().getColumns());
00291         objProp.open();
00292         if(objProp.getReturnCode() == org.eclipse.jface.dialogs.IDialogConstants.OK_ID) {
00293             boolean result[] = objProp.getResult();
00294             boolean isAppliedToAllViews = objProp.getStatusApplication();
00295             // apply to all views ?
00296             if(isAppliedToAllViews) {
00297                 // apply the changes for all views
00298                 this.showHideColumnsAllViews(result);
00299             } else {
00300                 // apply the changes only in this view
00301                 this.setColumnsStatus(result);
00302             }
00303         }
00304     }
00305     
00310     private void showHideColumnsAllViews(boolean []status) {
00311         // get our database file and the and the class that contains its information
00312         // get the views created for our database
00313         BaseScopeView arrScopeViews[] = database.getExperimentView().getViews();
00314         for(int i=0; i<arrScopeViews.length; i++) {
00315             arrScopeViews[i].getViewActions().setColumnStatus(status);
00316         }
00317     }
00318     
00322     public void setColumnsStatus(boolean []status) {
00323 
00324         TreeColumn []columns = treeViewer.getTree().getColumns();
00325         
00326         // the number of table columns have to be bigger than the number of status
00327         // since the table also contains tree scope column
00328         
00329         assert columns.length > status.length;
00330         
00331         int i=0; // index for status
00332         
00333         for (TreeColumn column : columns) {
00334             if (column.getData() != null) {
00335                 // it must be metric column
00336                 if (status[i]) {
00337                     // display column
00338                     // Laks: bug no 131: we need to have special key for storing the column width
00339                     Object o = column.getData(COLUMN_DATA_WIDTH);
00340                     if((o != null) && (o instanceof Integer) ) {
00341                         int iWidth = ((Integer)o).intValue();
00342                         column.setWidth(iWidth);
00343                     }
00344                 } else {
00345                     // hide column
00346                     hideMetricColumn(column);
00347                 }
00348                 i++;
00349             }
00350         }
00351     }
00352     
00353     
00358     public void addMetricColumns(TreeColumn colMetric) {
00359         // when adding a new column, we have to refresh the viewer
00360         // and this means we have to recompute again the top row of the table
00361         this.restoreParentNode();
00362     }
00363     
00364 
00365     //======================================================
00366     // ................ BUTTON ............................
00367     //======================================================
00368 
00372     public void disableNodeButtons() {
00373         this.tiZoomin.setEnabled(false);
00374         this.tiZoomout.setEnabled(false);
00375         this.tiHotCallPath.setEnabled(false);
00376     }
00377 
00378     /*
00379      * (non-Javadoc)
00380      * @see edu.rice.cs.hpc.viewer.scope.IScopeActionsGUI#enableHotCallPath(boolean)
00381      */
00382     public void enableHotCallPath(boolean enabled) {
00383         this.tiHotCallPath.setEnabled(enabled);
00384     }
00385 
00386     /*
00387      * (non-Javadoc)
00388      * @see edu.rice.cs.hpc.viewer.scope.IScopeActionsGUI#enableZoomIn(boolean)
00389      */
00390     public void enableZoomIn(boolean enabled) {
00391         this.tiZoomin.setEnabled(enabled);
00392     }
00393 
00394     /*
00395      * (non-Javadoc)
00396      * @see edu.rice.cs.hpc.viewer.scope.IScopeActionsGUI#enableZoomOut(boolean)
00397      */
00398     public void enableZoomOut(boolean enabled) {
00399         this.tiZoomout.setEnabled(enabled);
00400     }
00401     
00402 
00403     //======================================================
00404     // ................ CREATION ............................
00405     //======================================================
00411     protected void createCoolItem(CoolBar coolBar, Control toolBar) {
00412         CoolItem coolItem = new CoolItem(coolBar, SWT.NULL);
00413         coolItem.setControl(toolBar);
00414         org.eclipse.swt.graphics.Point size =
00415             toolBar.computeSize( SWT.DEFAULT,
00416                                    SWT.DEFAULT);
00417         org.eclipse.swt.graphics.Point coolSize = coolItem.computeSize (size.x, size.y);
00418         coolItem.setSize(coolSize);     
00419     }
00420     
00421     /*
00422      * 
00423      */
00424     protected void finalizeToolBar(Composite parent, CoolBar coolBar) {
00425         // message text
00426         lblMessage = new Label(parent, SWT.NONE);
00427         lblMessage.setText("");
00428 
00429         // but the message label yes
00430         GridDataFactory.fillDefaults().grab(true, false).applyTo(lblMessage);
00431         // the coolbar part shouldn't be expanded 
00432         GridDataFactory.fillDefaults().grab(false, false).applyTo(coolBar);
00433         // now the toolbar area should be able to be expanded automatically
00434         GridDataFactory.fillDefaults().grab(true, false).applyTo(parent);
00435         // two kids for toolbar area: coolbar and message label
00436         GridLayoutFactory.fillDefaults().numColumns(2).generateLayout(parent);
00437 
00438     }
00445     protected Composite addTooBarAction(CoolBar coolbar) {
00446         // prepare the toolbar
00447         ToolBar toolbar = new ToolBar(coolbar, SWT.FLAT);
00448                 
00449         // zoom in
00450         tiZoomin = new ToolItem(toolbar, SWT.PUSH);
00451         tiZoomin.setToolTipText("Zoom-in the selected node");
00452         tiZoomin.setImage(Icons.getImage(Icons.Image_ZoomIn));
00453         tiZoomin.addSelectionListener(new SelectionAdapter() {
00454             public void widgetSelected(SelectionEvent e) {
00455             objViewActions.zoomIn();
00456             }
00457         });
00458         
00459         // zoom out
00460         tiZoomout = new ToolItem(toolbar, SWT.PUSH);
00461         tiZoomout.setToolTipText("Zoom-out the selected node");
00462         tiZoomout.setImage(Icons.getImage(Icons.Image_ZoomOut));
00463         tiZoomout.addSelectionListener(new SelectionAdapter() {
00464           public void widgetSelected(SelectionEvent e) {
00465               objViewActions.zoomOut();
00466           }
00467         });
00468         
00469         new ToolItem(toolbar, SWT.SEPARATOR);
00470         // hot call path
00471         this.tiHotCallPath= new ToolItem(toolbar, SWT.PUSH);
00472         tiHotCallPath.setToolTipText("Expand the hot path below the selected node");
00473         tiHotCallPath.setImage(Icons.getImage(Icons.Image_FlameIcon));
00474         tiHotCallPath.addSelectionListener(new SelectionAdapter() {
00475           public void widgetSelected(SelectionEvent e) {
00476               objViewActions.showHotCallPath();
00477           }
00478         });
00479         
00480         this.tiAddExtMetric = new ToolItem(toolbar, SWT.PUSH);
00481         tiAddExtMetric.setImage(Icons.getImage(Icons.Image_FnMetric));
00482         tiAddExtMetric.setToolTipText("Add a new derived metric");
00483         tiAddExtMetric.addSelectionListener(new SelectionAdapter(){
00484             public void widgetSelected(SelectionEvent e) {
00485                 objViewActions.addExtNewMetric();
00486             }
00487         });
00488 
00489         new ToolItem(toolbar, SWT.SEPARATOR);
00490         
00491         this.tiColumns = new ToolItem(toolbar, SWT.PUSH);
00492         tiColumns.setImage(Icons.getImage(Icons.Image_CheckColumns));
00493         tiColumns.setToolTipText("Hide/show columns");
00494         tiColumns.addSelectionListener(new SelectionAdapter() {
00495               public void widgetSelected(SelectionEvent e) {
00496                   showColumnsProperties();
00497               }
00498             });
00499         new ToolItem(toolbar, SWT.SEPARATOR);
00500         
00501         // ------------------------------- export CSV ------
00502         ToolItem tiCSV = new ToolItem(toolbar, SWT.PUSH);
00503         tiCSV.setImage( Icons.getImage(Icons.Image_SaveCSV) );
00504         tiCSV.setToolTipText( "Export the current view into a comma separated value file" );
00505         tiCSV.addSelectionListener( new SelectionAdapter() {
00506             public void widgetSelected(SelectionEvent e) {
00507                 exportCSV();
00508             }
00509         });
00510         
00511         // ------------ Text fonts
00512         // bigger font
00513         ToolItem tiFontBigger = new ToolItem (toolbar, SWT.PUSH);
00514         tiFontBigger.setImage(Icons.getImage(Icons.Image_FontBigger));
00515         tiFontBigger.setToolTipText("Increase font size");
00516         tiFontBigger.addSelectionListener( new SelectionAdapter() {
00517           public void widgetSelected(SelectionEvent e) {
00518               Utilities.increaseFont(objWindow);
00519           }
00520         });
00521 
00522         // smaller font
00523         ToolItem tiFontSmaller = new ToolItem (toolbar, SWT.PUSH);
00524         tiFontSmaller.setImage(Icons.getImage(Icons.Image_FontSmaller));
00525         tiFontSmaller.setToolTipText("Decrease font size");
00526         tiFontSmaller.addSelectionListener( new SelectionAdapter() {
00527           public void widgetSelected(SelectionEvent e) {
00528               Utilities.DecreaseFont(objWindow);
00529           }
00530         });
00531         
00532         // set the coolitem
00533         this.createCoolItem(coolbar, toolbar);
00534         
00535 
00536         return toolbar;
00537     }
00538 
00542     final private String COMMA_SEPARATOR = ",";
00543     
00547     protected void exportCSV() {
00548         
00549         Experiment experiment = database.getExperiment();
00550         
00551         FileDialog fileDlg = new FileDialog(this.shell, SWT.SAVE);
00552         fileDlg.setFileName(experiment.getName() + ".csv");
00553         fileDlg.setFilterExtensions(new String [] {"*.csv", "*.*"});
00554         fileDlg.setText("Save the data in the table to a file (CSV format)");
00555         final String sFilename = fileDlg.open();
00556         if ( (sFilename != null) && (sFilename.length()>0) ) {
00557             try {
00558                 this.shell.getDisplay().asyncExec( new Runnable() {
00559 
00560                     public void run() {
00561                         try {
00562                             // -----------------------------------------------------------------------
00563                             // Check if the status of the file
00564                             // -----------------------------------------------------------------------
00565                             File objFile = new File( sFilename );
00566                             if ( objFile.exists() ) {
00567                                 if ( !MessageDialog.openConfirm( shell, "File already exists" , 
00568                                     sFilename + ": file already exist. Do you want to replace it ?") )
00569                                     return;
00570                             }
00571                             // WARNING: java.io.File seems always fail to verify writable status on Linux !
00572                             /*
00573                             if ( !objFile.canWrite() ) {
00574                                 MessageDialog.openError( shell, "Error: Unable to write the file", 
00575                                         sFilename + ": File is not writable ! Please check if you have right to write in the directory." );
00576                                 return;
00577                             } */
00578 
00579                             // -----------------------------------------------------------------------
00580                             // prepare the file
00581                             // -----------------------------------------------------------------------
00582                             showInfoMessage( "Writing to file: "+sFilename);
00583                             FileWriter objWriter = new FileWriter( objFile );
00584                             BufferedWriter objBuffer = new BufferedWriter (objWriter);
00585                             
00586                             // -----------------------------------------------------------------------
00587                             // writing to the file
00588                             // -----------------------------------------------------------------------
00589                             
00590                             // write the title
00591                             String sTitle = treeViewer.getColumnTitle(0, COMMA_SEPARATOR);
00592                             objBuffer.write(sTitle + Utilities.NEW_LINE);
00593 
00594                             // write the top row items
00595                             String sTopRow[] = Utilities.getTopRowItems(treeViewer);
00596                             // tricky: add '"' for uniting the text in the spreadsheet
00597                             sTopRow[0] = "\"" + sTopRow[0] + "\"";  
00598                             sTitle = treeViewer.getTextBasedOnColumnStatus(sTopRow, COMMA_SEPARATOR, 0, 0);
00599                             objBuffer.write(sTitle + Utilities.NEW_LINE);
00600 
00601                             // write the content text
00602                             ArrayList<TreeItem> items = new ArrayList<TreeItem>();
00603                             internalCollectExpandedItems(items, treeViewer.getTree().getItems());
00604                             String sText = objViewActions.getContent( items.toArray(new TreeItem[items.size()]), 
00605                                     COMMA_SEPARATOR);
00606                             objBuffer.write(sText);
00607                             
00608                             // -----------------------------------------------------------------------
00609                             // End of the process
00610                             // -----------------------------------------------------------------------                          
00611                             objBuffer.close();
00612                             restoreMessage();
00613                         } catch (IOException e) {
00614                             e.printStackTrace();
00615                         }
00616                     }
00617                     
00618                 });
00619             } catch ( SWTException e ) {
00620                 e.printStackTrace();
00621             }
00622         }
00623     }
00624     
00630     private void internalCollectExpandedItems(List<TreeItem> result, TreeItem []items) {
00631         if (items != null)
00632             for (int i = 0; i < items.length; i++) {
00633                 TreeItem itemChild = items[i];
00634                 if (itemChild.getData() instanceof Scope)
00635                     result.add(itemChild);
00636                 if (itemChild.getExpanded())
00637                     internalCollectExpandedItems(result, itemChild.getItems());
00638             }
00639     }
00640     
00641 }

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1