code: /*--------------------------------------------------------------*
    Copyright (C) 2006-2015 OpenSim Ltd.
  
    This file is distributed WITHOUT ANY WARRANTY. See the file
    'License' for details on this and other legal matters.
  *--------------------------------------------------------------*/
  
  package org.omnetpp.cdt;
  
  import org.eclipse.cdt.core.CCorePlugin;
  import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
  import org.eclipse.core.runtime.CoreException;
  import org.eclipse.core.runtime.IStatus;
  import org.eclipse.core.runtime.Status;
  import org.eclipse.core.runtime.preferences.InstanceScope;
  import org.eclipse.jface.preference.IPreferenceStore;
  import org.eclipse.jface.resource.ImageDescriptor;
  import org.eclipse.jface.resource.ImageRegistry;
  import org.eclipse.jface.viewers.DecorationOverlayIcon;
  import org.eclipse.jface.viewers.IDecoration;
  import org.eclipse.swt.graphics.Image;
  import org.eclipse.ui.plugin.AbstractUIPlugin;
  import org.eclipse.ui.preferences.ScopedPreferenceStore;
  import org.omnetpp.cdt.build.BuildSpecFolderRenameDetector;
  import org.omnetpp.cdt.build.MsgFileRemoveDetector;
  import org.omnetpp.cdt.cache.NewConfigConfigurer;
  import org.omnetpp.cdt.ui.ProjectFeaturesListener;
  import org.omnetpp.common.util.StringUtils;
  import org.osgi.framework.BundleContext;
  
  /**
   * The activator class controls the plug-in life cycle.
   * @author Andras
   */
  public class Activator extends AbstractUIPlugin {
  
      // The plug-in ID
      public static final String PLUGIN_ID = "org.omnetpp.cdt";
  
      // The shared instance
      private static Activator plugin;
  
      private ProjectFeaturesListener projectFeaturesListener = new ProjectFeaturesListener();
      private NewConfigConfigurer newConfigConfigurer = new NewConfigConfigurer();
      private BuildSpecFolderRenameDetector folderRenameDetector = new BuildSpecFolderRenameDetector();
      private MsgFileRemoveDetector msgFileRemoveDetector = new MsgFileRemoveDetector();
  
      /**
       * The constructor
       */
      public Activator() {
      }
  
      /*
       * (non-Javadoc)
       * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
       */
      public void start(BundleContext context) throws Exception {
          super.start(context);
          plugin = this;
  
          projectFeaturesListener.hookListeners();
          newConfigConfigurer.hookListeners();
          folderRenameDetector.hookListeners();
          msgFileRemoveDetector.hookListeners();
  
          // Set the default settings ifor CDT editors.
          // We will use spaces instead of tabs. This hack is needed because the
          // OMNeT++ code style profile is not applied by default when a new
          // workspace is created.
          // TODO we should implement the OMMeT++ style via an extension point.
          // See ToolFactory for hints on the extension point to use.
          IPreferenceStore ps = new ScopedPreferenceStore(InstanceScope.INSTANCE, CCorePlugin.PLUGIN_ID);
          ps.setDefault(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE);
      }
  
      /*
       * (non-Javadoc)
       * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
       */
      public void stop(BundleContext context) throws Exception {
          projectFeaturesListener.unhookListeners();
          newConfigConfigurer.unhookListeners();
          folderRenameDetector.unhookListeners();
          msgFileRemoveDetector.unhookListeners();
  
          plugin = null;
          super.stop(context);
      }
  
      /**
       * Returns the shared instance
       */
      public static Activator getDefault() {
          return plugin;
      }
  
      public static void log(int severity, String message) {
          getDefault().getLog().log(new Status(severity, PLUGIN_ID, message));
      }
  
      public static void logError(Throwable exception) {
          logError(exception.toString(), exception);
      }
  
      public static void logError(String message, Throwable exception) {
          if (plugin != null) {
              plugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, 0, message, exception));
          }
          else {
              System.err.println(message);
              exception.printStackTrace();
          }
      }
  
      public static CoreException wrapIntoCoreException(Throwable exception) {
          String msg = StringUtils.defaultIfEmpty(exception.getMessage(), exception.getClass().getSimpleName());
          return wrapIntoCoreException(msg, exception);
      }
  
      public static CoreException wrapIntoCoreException(String message, Throwable exception) {
          return new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, 0, message, exception));
      }
  
      /**
       * Returns an image descriptor for the image file at the given
       * plug-in relative path.
       */
      public static ImageDescriptor getImageDescriptor(String path) {
          return imageDescriptorFromPlugin(PLUGIN_ID, path);
      }
  
      /**
       * Creates an image. IMPORTANT: The image is NOT cached! Callers
       * are responsible for disposal of the image.
       */
      public static Image getImage(String path) {
          ImageDescriptor id = getImageDescriptor(path);
          if (id == null) {
              IllegalArgumentException e = new IllegalArgumentException("Cannot load image from: "+path);
              logError(e);
              throw e;
          }
          return id.createImage();
      }
  
      /**
       * Like getImage(), but the image gets cached in an internal image registry,
       * so clients do not need to (moreover, must not) dispose of the image.
       */
      public static Image getCachedImage(String path) {
          ImageRegistry imageRegistry = getDefault().getImageRegistry();
          Image image = imageRegistry.get(path);
          if (image==null) {
              image = getImage(path);
              imageRegistry.put(path, image);
          }
          return image;
      }
  
      /**
       * Decorates the given image with the overlay images (any element may be null),
       * and returns the result as a new image. The index of images in the overlayImagePath
       * array is determined by the {@link IDecoration#TOP_LEFT}, {@link IDecoration#TOP_RIGHT},
       * {@link IDecoration#BOTTOM_LEFT} and {@link IDecoration#BOTTOM_RIGHT} and
       * {@link IDecoration#UNDERLAY} constant values.
       * The result image gets cached in an internal image registry,
       * so clients do not need to (moreover, must not) dispose of the image.
       */
      public static Image getCachedDecoratedImage(String baseImagePath, String overlayImagePath[]) {
          Image baseImage = getCachedImage(baseImagePath);
          ImageDescriptor[] overlayDescs = new ImageDescriptor[overlayImagePath.length];
          String key = baseImagePath;
          // Calculate a unique key for the decorated image. If all decoration is null
          // the base image key is used and the base image will be returned from the registry.
          for (int i=0; i<overlayImagePath.length; i++)
              if (overlayImagePath[i] != null) {
                  overlayDescs[i] = getImageDescriptor(overlayImagePath[i]);
                  key += ":"+i+"="+overlayImagePath[i];
              }
          Image result = getDefault().getImageRegistry().get(key);
          if (result == null) {
              result = new DecorationOverlayIcon(baseImage, overlayDescs).createImage();
              getDefault().getImageRegistry().put(key, result);
          }
          return result;
      }
  
      public static NewConfigConfigurer getNewConfigConfigurer() {
          return getDefault().newConfigConfigurer;
      }
  }
  