Utilities.java

Go to the documentation of this file.
00001 
00004 package edu.rice.cs.hpc.viewer.util;
00005 
00006 import java.util.ArrayList;
00007 
00008 import org.eclipse.swt.SWT;
00009 import org.eclipse.swt.graphics.Device;
00010 import org.eclipse.swt.graphics.Font;
00011 import org.eclipse.swt.graphics.FontData;
00012 
00013 import org.eclipse.swt.widgets.Display;
00014 import org.eclipse.swt.widgets.Event;
00015 import org.eclipse.swt.widgets.Listener;
00016 import org.eclipse.swt.widgets.Tree;
00017 import org.eclipse.swt.widgets.TreeItem;
00018 import org.eclipse.jface.preference.IPreferenceStore;
00019 import org.eclipse.jface.preference.PreferenceConverter;
00020 import org.eclipse.jface.viewers.TreeViewer;
00021 import org.eclipse.swt.graphics.Image;
00022 import org.eclipse.swt.graphics.Color;
00023 import org.eclipse.ui.IViewReference;
00024 import org.eclipse.ui.IWorkbenchPage;
00025 import org.eclipse.ui.IWorkbenchPart;
00026 import org.eclipse.ui.IWorkbenchWindow;
00027 import org.eclipse.ui.preferences.ScopedPreferenceStore;
00028 
00029 import edu.rice.cs.hpc.data.experiment.Experiment;
00030 import edu.rice.cs.hpc.data.experiment.source.FileSystemSourceFile;
00031 import edu.rice.cs.hpc.data.experiment.source.SourceFile;
00032 import edu.rice.cs.hpc.data.experiment.scope.CallSiteScope;
00033 import edu.rice.cs.hpc.data.experiment.scope.CallSiteScopeType;
00034 import edu.rice.cs.hpc.data.experiment.scope.LineScope;
00035 import edu.rice.cs.hpc.data.experiment.scope.ProcedureScope;
00036 import edu.rice.cs.hpc.data.experiment.scope.Scope;
00037 import edu.rice.cs.hpc.data.util.OSValidator;
00038 
00039 import edu.rice.cs.hpc.viewer.editor.SourceCodeEditor;
00040 import edu.rice.cs.hpc.viewer.framework.Activator;
00041 import edu.rice.cs.hpc.viewer.resources.Icons;
00042 import edu.rice.cs.hpc.viewer.scope.BaseScopeView;
00043 import edu.rice.cs.hpc.viewer.scope.ScopeTreeViewer;
00044 import edu.rice.cs.hpc.viewer.window.Database;
00045 import edu.rice.cs.hpc.viewer.window.ViewerWindow;
00046 import edu.rice.cs.hpc.viewer.window.ViewerWindowManager;
00047 
00054 public class Utilities {
00055     //special font for the metric columns. It supposed to be fixed font
00056     static public Font fontMetric;
00057     /* generic font for view and editor */
00058     static public Font fontGeneral;
00059     
00060     // special color for the top row
00061     static public Color COLOR_TOP;
00062     
00063     static public String NEW_LINE = System.getProperty("line.separator");
00064     
00070     static public void setFontMetric(Display display) {
00071         COLOR_TOP = new Color(display, 255,255,204);
00072         
00073         ScopedPreferenceStore objPref = (ScopedPreferenceStore)Activator.getDefault().getPreferenceStore();
00074         FontData []objFontMetric = display.getSystemFont().getFontData();
00075         FontData []objFontGeneric = display.getSystemFont().getFontData();
00076         
00077         if (OSValidator.isWindows())
00078             // On Windows 7 Courier New has better look 
00079             objFontMetric[0].setName("Courier New"); 
00080         else
00081             // For most platforms, Courier is fine 
00082             objFontMetric[0].setName("Courier"); 
00083 
00084         // get the font for metrics columns based on user preferences
00085         if (objPref != null) {
00086             // bug fix: for unknown reason, the second instance of hpcviewer cannot find the key
00087             //  solution: check if the key exist or not IPreferenceStore.STRING_DEFAULT_DEFAULT.equals
00088             String sValue = objPref.getString (PreferenceConstants.P_FONT_METRIC); 
00089             if ( !IPreferenceStore.STRING_DEFAULT_DEFAULT.equals(sValue) )
00090                 objFontMetric = PreferenceConverter.getFontDataArray(objPref, PreferenceConstants.P_FONT_METRIC);
00091             else 
00092                 // bug fix: if user hasn't set the preference, we set it for him/her
00093                 PreferenceConverter.setValue(objPref, PreferenceConstants.P_FONT_METRIC, objFontMetric);
00094             
00095             sValue = objPref.getString (PreferenceConstants.P_FONT_GENERIC);
00096             if ( !IPreferenceStore.STRING_DEFAULT_DEFAULT.equals(sValue) )
00097                 objFontGeneric = PreferenceConverter.getFontDataArray(objPref, PreferenceConstants.P_FONT_GENERIC);
00098             else 
00099                 // bug fix: if user hasn't set the preference, we set it for him/her
00100                 PreferenceConverter.setValue(objPref, PreferenceConstants.P_FONT_METRIC, objFontMetric);
00101         }
00102         // create font for general purpose (view, editor, ...)
00103         Utilities.fontGeneral = new Font (display, objFontGeneric);
00104         
00105         Utilities.fontMetric = new Font(display, objFontMetric);
00106     }
00107 
00114     static public void setFontMetric(IWorkbenchWindow window, FontData objFontMetric[], FontData objFontGeneric[]) {
00115         FontData []myFontMetric = Utilities.fontMetric.getFontData();
00116         boolean isMetricFontChanged = isDifferentFontData(myFontMetric, objFontMetric);
00117         if (isMetricFontChanged) {
00118             Device device = Utilities.fontMetric.getDevice();
00119             Utilities.fontMetric.dispose();
00120             Utilities.fontMetric = new Font(device, objFontMetric);
00121         }
00122         
00123         FontData []myFontGeneric = Utilities.fontGeneral.getFontData();
00124         boolean isGenericFontChange = isDifferentFontData(myFontGeneric, objFontGeneric);
00125         if (isGenericFontChange) {
00126             Device device = Utilities.fontGeneral.getDevice();
00127             Utilities.fontGeneral.dispose();
00128             Utilities.fontGeneral = new Font(device, objFontGeneric);
00129         }
00130         
00131         if (isMetricFontChanged || isGenericFontChange) {
00132             // a font has been changed. we need to refresh the view
00133             resetAllViews (window);
00134             
00135             // refresh other windows too
00136             for (int i=0; i<ViewerWindowManager.size(); i++) {
00137                 ViewerWindow vw = ViewerWindowManager.getViewerWindow(i);
00138                 if (vw.getWinObj()!=window) {
00139                     resetAllViews(vw.getWinObj());
00140                 }
00141             }
00142             // set the fonts in the preference store to the new fonts
00143             // if we got here from a preference page update this was already done by the font field editor but 
00144             // if we got here from a tool bar button then we need the new values to be put into the preference store
00145             // in addition this call will fire a property changed event which other non-Rice views can listen for and
00146             // use it to refresh their views (without this event the SWT code throws lots of invalid argument exceptions
00147             // because it tries to repaint the non-Rice views using the font that the Rice code has just disposed).
00148             Utilities.storePreferenceFonts();
00149         }
00150     }
00151     
00152     
00153     /*****
00154      * check if two font data are equal (name, height and style)
00155      * 
00156      * @param fontTarget
00157      * @param fontSource
00158      * @return
00159      */
00160     static public boolean isDifferentFontData(FontData fontTarget[], FontData fontSource[]) {
00161         boolean isChanged = false;
00162         for (int i=0; i<fontTarget.length; i++) {
00163             if (i < fontSource.length) {
00164                 FontData source = fontSource[i];
00165                 // bug: if the height is not common, we just do nothing, consider everything work fine
00166                 if (source.getHeight()<4 || source.getHeight()>99)
00167                     return false;
00168                 
00169                 FontData target = fontTarget[i];
00170                 isChanged = !( target.getName().equals(source.getName()) &&
00171                         (target.getHeight()==source.getHeight()) && 
00172                         (target.getStyle()==source.getStyle()) ) ;
00173                 
00174                 if (isChanged)
00175                     // no need to continue the loop
00176                     return isChanged;
00177             }
00178         }
00179         return isChanged;
00180     }
00181     
00182     /****
00183      * remove all the allocated resources
00184      */
00185     static public void dispose() {
00186         try {
00187             Utilities.fontGeneral.dispose();
00188             Utilities.fontMetric.dispose();
00189             COLOR_TOP.dispose();
00190             
00191         } catch (Exception e) {
00192             
00193         }
00194     }
00195     
00196     /****
00197      * Store the new fonts into the workspace registry
00198      */
00199     static private void storePreferenceFonts() {
00200         ScopedPreferenceStore objPref = (ScopedPreferenceStore)Activator.getDefault().getPreferenceStore();
00201         PreferenceConverter.setValue(objPref, PreferenceConstants.P_FONT_GENERIC, Utilities.fontGeneral.getFontData());
00202         PreferenceConverter.setValue(objPref, PreferenceConstants.P_FONT_METRIC, Utilities.fontMetric.getFontData());
00203     }
00204     
00209     static private void resetAllViews(IWorkbenchWindow window) {
00210 
00211         ViewerWindow vWin = ViewerWindowManager.getViewerWindow(window);
00212         if (vWin == null) {
00213             System.out.printf("Utilities.resetAllViews: ViewerWindow class not found\n");
00214             return;
00215         }
00216 
00217         final TreeItemManager objItemManager = new TreeItemManager();
00218         
00219         // first, we need to refresh the visible view
00220         final ArrayList<BaseScopeView> visible_view = Utilities.getTopView(window);
00221         if (visible_view != null && visible_view.size()>0) {
00222             for (BaseScopeView view : visible_view) {
00223                 Utilities.resetView(objItemManager, view.getTreeViewer());
00224             }
00225         }
00226         
00227         // find each open database so we can reset its views
00228         for (Database db : vWin.getDatabases()) {
00229             // get the views created for our database
00230             if (db == null) {
00231                 continue;       // not open just skip it
00232             }
00233 
00234             final BaseScopeView arrViews[] = db.getExperimentView().getViews();
00235             
00236             // next, using helper thread to refresh other views
00237             window.getShell().getDisplay().asyncExec( new Runnable() {
00238                 public void run() {
00239                     
00240                     // refresh all the views except the visible one 
00241                     // we will prioritize the visible view to be refreshed first
00242                     for(int i=0;i<arrViews.length;i++) {
00243                         if (!visible_view.contains(arrViews[i])) {
00244                             ScopeTreeViewer tree = (ScopeTreeViewer) arrViews[i].getTreeViewer();
00245                             
00246                             // reset the view
00247                             Utilities.resetView(objItemManager, tree);
00248                         }
00249                     }
00250                 }
00251             });
00252         }
00253     }
00254 
00255     /****
00256      * Find the first visible scope view (the view can be active or not)
00257      * @return the visible view, null if there is no view
00258      */
00259     static ArrayList<BaseScopeView> getTopView(IWorkbenchWindow window) {
00260         IWorkbenchPage page = window.getActivePage();
00261         IViewReference [] viewRefs = page.getViewReferences();
00262         ArrayList<BaseScopeView> listViews = new ArrayList<BaseScopeView>(viewRefs.length);
00263         
00264         for(int i=0;i<viewRefs.length;i++) {
00265             IWorkbenchPart part = viewRefs[i].getPart(false);
00266             if (page.isPartVisible(part)) {
00267                 if (part instanceof BaseScopeView) {
00268                     listViews.add((BaseScopeView)part);
00269                 }
00270             }
00271         }
00272 
00273         return listViews;
00274     }
00275     
00276     static public void resetView ( TreeViewer tree )
00277     {
00278         TreeItemManager objItem = new TreeItemManager();
00279         resetView(objItem, tree);
00280     }
00281     
00288     static private void resetView ( TreeItemManager objItemManager, TreeViewer tree) {
00289         resetViewRowHeight(tree);
00290         // save the context first
00291         objItemManager.saveContext(tree);
00292         // refresh
00293         tree.refresh();
00294         // restore the context
00295         objItemManager.restoreContext(tree);
00296     }
00297     
00302     static public void listenerToResetRowHeight ( TreeViewer tree ) {
00303         if (OSValidator.isWindows()) { 
00304             Tree treeItem = tree.getTree();
00305             // resize the table row height using a MeasureItem listener
00306             Listener measurementListener = new Listener() {
00307                 public void handleEvent(Event event) {
00308                     final ScopedPreferenceStore objPref = (ScopedPreferenceStore)Activator.getDefault().getPreferenceStore();
00309                     FontData []objFontsMetric = PreferenceConverter.getFontDataArray(objPref, PreferenceConstants.P_FONT_METRIC);
00310                     FontData []objFontsGeneric = PreferenceConverter.getFontDataArray(objPref, PreferenceConstants.P_FONT_GENERIC);
00311                     // get font height (from preferences) for each font
00312                     int objFontMetricHeight = objFontsMetric[0].getHeight();
00313                     int objFontGenericHeight = objFontsGeneric[0].getHeight();
00314                     event.height = objFontMetricHeight>objFontGenericHeight?objFontMetricHeight:objFontGenericHeight + 10;
00315                 } // end handleEvent
00316             }; // end measurementListener
00317             treeItem.addListener(SWT.MeasureItem, measurementListener);
00318         }
00319     }
00320     
00325     static public void resetViewRowHeight ( TreeViewer tree ) {
00326         if (!OSValidator.isWindows()) { 
00327             int saveWidth = tree.getTree().getColumn(0).getWidth();
00328             tree.getTree().getColumn(0).setWidth(saveWidth==0?1:0);
00329             tree.getTree().getColumn(0).setWidth(saveWidth);
00330         }
00331     }
00332     
00337     static private void setFontMetric(IWorkbenchWindow window, int iFontSize) {
00338             FontData []myFontGeneric = Utilities.fontGeneral.getFontData();
00339             int iSize = myFontGeneric[0].getHeight() + iFontSize;
00340             myFontGeneric[0].setHeight(iSize);
00341             
00342             FontData []myFontMetric = Utilities.fontMetric.getFontData();
00343             iSize = myFontMetric[0].getHeight() + iFontSize;
00344             myFontMetric[0].setHeight(iSize);
00345             
00346             setFontMetric(window, myFontMetric, myFontGeneric);
00347             
00348     }
00349     
00354     static public void increaseFont(IWorkbenchWindow window) {
00355         Utilities.setFontMetric(window, +1);
00356     }
00357 
00358     
00363     static public void DecreaseFont(IWorkbenchWindow window) {
00364         Utilities.setFontMetric(window, -1);
00365     }
00366 
00373     static public void insertTopRow(TreeViewer treeViewer, Image imgScope, String []arrText) {
00374         if(arrText == null)
00375             return;
00376         TreeItem item = new TreeItem(treeViewer.getTree(), SWT.BOLD, 0);
00377         if(imgScope != null)
00378             item.setImage(0,imgScope);
00379 
00380         // Laksono 2009.03.09: add background for the top row to distinguish with other scopes
00381         item.setBackground(Utilities.COLOR_TOP);
00382         // make monospace font for all metric columns
00383         item.setFont(Utilities.fontMetric);
00384         item.setFont(0, Utilities.fontGeneral); // The tree has the original font
00385         // put the text on the table
00386         item.setText(arrText);
00387         // set the array of text as the item data 
00388         // we will use this information when the table is sorted (to restore the original top row)
00389         item.setData(arrText);
00390     }
00391 
00397     public static String[] getTopRowItems( TreeViewer treeViewer ) {
00398         TreeItem item = treeViewer.getTree().getItem(0);
00399         String []sText= null; // have to do this to avoid error in compilation;
00400         if(item.getData() instanceof Scope) {
00401             // the table has been zoomed-out
00402         } else {
00403             // the table is in original form or flattened or zoom-in
00404             Object o = item.getData();
00405             if(o != null) {
00406                 Object []arrObj = (Object []) o;
00407                 if(arrObj[0] instanceof String) {
00408                     sText = (String[]) item.getData(); 
00409                 }
00410             }
00411         }
00412         return sText;
00413     }
00420     static public Image getScopeNavButton(Scope scope) {
00421         if (scope instanceof CallSiteScope) {
00422             CallSiteScope scopeCall = (CallSiteScope) scope;
00423             LineScope lineScope = (LineScope) (scopeCall).getLineScope();
00424             if (((CallSiteScope) scope).getType() == CallSiteScopeType.CALL_TO_PROCEDURE) {
00425                 if(Utilities.isFileReadable(lineScope))
00426                     return Icons.getImage(Icons.Image_CallTo);
00427                 else
00428                     return Icons.getImage(Icons.Image_CallToDisabled);
00429             } else {
00430                 if(Utilities.isFileReadable(lineScope))
00431                     return Icons.getImage(Icons.Image_CallFrom);
00432                 else
00433                     return Icons.getImage(Icons.Image_CallFromDisabled);
00434             }
00435         }
00436         return null;
00437     }
00438     
00439     static public Image getInlineNavButton(ProcedureScope proc)
00440     {
00441         if (proc.isAlien()) {
00442             boolean readable = Utilities.isFileReadable(proc);
00443             if (readable) {
00444                 return Icons.getImage(Icons.Image_InlineTo);
00445             } else {
00446                 return Icons.getImage(Icons.Image_InlineToDisabled);
00447             }
00448         }
00449         return null;
00450     }
00451 
00461     static public boolean isFileReadable(Scope scope) {
00462         // check if the source code availability is already computed
00463         if(scope.iSourceCodeAvailability == Scope.SOURCE_CODE_UNKNOWN) {
00464             SourceFile newFile = ((SourceFile)scope.getSourceFile());
00465             if (newFile != null) {
00466                 if( (newFile != SourceFile.NONE)
00467                         || ( newFile.isAvailable() )  ) {
00468                         if (newFile instanceof FileSystemSourceFile) {
00469                             FileSystemSourceFile objFile = (FileSystemSourceFile) newFile;
00470                             if(objFile != null) {
00471                                 // find the availability of the source code
00472                                 if (objFile.isAvailable()) {
00473                                     scope.iSourceCodeAvailability = Scope.SOURCE_CODE_AVAILABLE;
00474                                     return true;
00475                                 } 
00476                             }
00477                         }
00478                     }
00479             }
00480         } else
00481             // the source code availability is already computed, we just reuse it
00482             return (scope.iSourceCodeAvailability == Scope.SOURCE_CODE_AVAILABLE);
00483         // in this level, we don't think the source code is available
00484         scope.iSourceCodeAvailability = Scope.SOURCE_CODE_NOT_AVAILABLE;
00485         return false;
00486     }
00487     
00488     
00489     /****
00490      * return the current active experiment. 
00491      * If there's only one opened database, then return the experiment
00492      * Otherwise, check for the database of the current active view or editor,
00493      *  assuming there's one active view/editor.
00494      *  (return null if no part is active)
00495      *  
00496      * @param window
00497      * @return
00498      */
00499     static public Experiment getActiveExperiment(IWorkbenchWindow window) {
00500 
00501         final ViewerWindow vw = ViewerWindowManager.getViewerWindow(window);
00502         
00503         if (vw == null)
00504             return null;
00505         
00506         final int numDB = vw.getOpenDatabases();
00507         Experiment experiment = null;
00508         
00509         // try to find the current database
00510         if (numDB == 1)
00511         {
00512             // only one opened database
00513             experiment = vw.getExperiments()[0];
00514         }else
00515         {
00516             // multiple databases are opened:
00517             // need to select an experiment to show
00518             IWorkbenchPart part = window.getActivePage().getActivePart();
00519             if (part instanceof BaseScopeView)
00520             {
00521                 experiment = ((BaseScopeView)part).getExperiment();
00522                 
00523             } else if (part instanceof SourceCodeEditor)
00524             {
00525                 experiment = ((SourceCodeEditor)part).getExperiment();
00526             }
00527         }
00528         return experiment;
00529     }
00530 }

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1