diff options
author | Leo Ufimtsev | 2014-07-02 17:24:04 +0000 |
---|---|---|
committer | Jeff Johnston | 2014-08-27 21:44:04 +0000 |
commit | 5a908cc21a80e432b6e2412c824c9431d6f5454c (patch) | |
tree | f9ca8a0d26f3101b788fc5955207a733f6dd516f | |
parent | 5e5080f55237775b162ae213cb51303f37e218a2 (diff) | |
download | org.eclipse.linuxtools-5a908cc21a80e432b6e2412c824c9431d6f5454c.tar.gz org.eclipse.linuxtools-5a908cc21a80e432b6e2412c824c9431d6f5454c.tar.xz org.eclipse.linuxtools-5a908cc21a80e432b6e2412c824c9431d6f5454c.zip |
Bug 408543 - Implemented Shared api for enabling checkboxes
programatically
This code is used buy subsequent commits of Gcov/Gprof.
- CProjectBuildHelpers.java :
Contains methods to programtically enable project settings
of the currently active configuration,
also methods to identify project types
also methods to rebuild projects. (needed after enabling settings)
- MessageDialogSyncedRunnable.java:
Extended MessageDialogue to work from background threads.
- TitleAreaDialogWithRadioButtons.java:
Message Dialogue with radio options. Neat way to seperate
GUI and functional code.
Change-Id: Ia37d709059b4b14ffd59f8a3dfd134025d417b78
Signed-off-by: Leo Ufimtsev <lufimtse@redhat.com>
Reviewed-on: https://git.eclipse.org/r/32438
Tested-by: Hudson CI
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
Tested-by: Jeff Johnston <jjohnstn@redhat.com>
9 files changed, 995 insertions, 2 deletions
diff --git a/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/internal/profiling/launch/provider/launch/messages.properties b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/internal/profiling/launch/provider/launch/messages.properties index 76f3567ada..c0d6a538cf 100644 --- a/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/internal/profiling/launch/provider/launch/messages.properties +++ b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/internal/profiling/launch/provider/launch/messages.properties @@ -8,7 +8,12 @@ ProjectSettings_0=Project Settings PreferenceLink_0=<a>Configure Workspace Settings...</a> ProviderLaunchConfigurationPrompt_0=This project has one or more Profile {0} configurations set up for the executable selected, \ but none of these profiling configurations use the current default tool for Profile {0} which is set to use {1}. \n\n\ -Do you want to create and use a new profiling configuration that uses {1}? +Do you want to create and use a new profiling configuration that uses {1}? \n\n\ +To prevent this dialogue from appearing each time, edit your project, set the default {0} tool\n\ +to a tool you already have used in an existing configuration for the profiling category.\n\ + - Right click project -> Properties -> C/C++ General -> Profiling Categories -> {0} tab \n\ + - check: "Enable project-specific settings" \n\ + - select your {0} tool. ProviderNoProfilers_title_0=No profiler plug-ins installed ProviderNoProfilers_msg_0=There are no profiling tool plug-ins installed which are supported by the profiling framework. No profiling will be performed. ProviderProfilerMissing_title_0=Missing profiling plug-in diff --git a/profiling/org.eclipse.linuxtools.profiling.ui/META-INF/MANIFEST.MF b/profiling/org.eclipse.linuxtools.profiling.ui/META-INF/MANIFEST.MF index 2d5c891e43..daa4b65012 100644 --- a/profiling/org.eclipse.linuxtools.profiling.ui/META-INF/MANIFEST.MF +++ b/profiling/org.eclipse.linuxtools.profiling.ui/META-INF/MANIFEST.MF @@ -6,7 +6,11 @@ Bundle-Version: 3.1.0.qualifier Bundle-Activator: org.eclipse.linuxtools.internal.profiling.ui.ProfileUIPlugin Bundle-Vendor: %Bundle-Vendor.0 Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime + org.eclipse.core.runtime, + org.eclipse.ui.workbench, + org.eclipse.cdt.managedbuilder.core, + org.eclipse.cdt.autotools.core, + org.eclipse.cdt.core Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin diff --git a/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/BooleanWithGetSet.java b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/BooleanWithGetSet.java new file mode 100644 index 0000000000..6af77d1326 --- /dev/null +++ b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/BooleanWithGetSet.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * lufimtse : Leo Ufimtsev lufimtse@redhat.com + *******************************************************************************/ + +package org.eclipse.linuxtools.profiling.ui; + +/** + * <h1> Wrapper with get/set functionality for a boolean.</h1> + * + * <p> + * The package-local {@link MessageDialogSyncedRunnable MessageDialogSyncedRunnable} class relies <br> + * upon a way to set/get a boolean (it is used to transfer a boolean between synced threads). <br> + * This class was created for this purpose. + * </p> + * @since 3.1.0 + */ +public class BooleanWithGetSet { + private boolean val; + + /** + * <h1> Boolean Constructor. </h1> + * Pass in a boolean to construct this class. + * + * @param val true/false boolean + */ + public BooleanWithGetSet(boolean val) { + this.val = val; + } + + /** + * <h1> Get Value. </h1> + * Retrieve the boolean value of this instance. + * + * @return boolean value of this instance + */ + public boolean getVal() { + return this.val; + } + + /** + * <h1> Set value </h1> + * Set the content of the boolean class. + * + * @param val true/false + */ + public void setVal(boolean val) { + this.val = val; + } +}
\ No newline at end of file diff --git a/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/CProjectBuildHelpers.java b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/CProjectBuildHelpers.java new file mode 100644 index 0000000000..94f3b21a00 --- /dev/null +++ b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/CProjectBuildHelpers.java @@ -0,0 +1,543 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc. : Initial Implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.profiling.ui; + +import org.eclipse.cdt.autotools.core.AutotoolsNewProjectNature; +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfigurationManager; +import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration; +import org.eclipse.cdt.internal.autotools.core.configure.IConfigureOption; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IResourceInfo; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.swt.widgets.Display; + +/** + * <h1> C and C++ Project configuration and build helpers. </h1> + * <p> This class is focused on automating the proccess of enabling profing plugins. <br> + * Used primarily for gcov & gprof. </p> + * + * <p> + * It supports c/c++ in Managed & Autotools projects, <br> + * by providing the following functionality : <br> + * <ul> + * <li> Identify project type & differentiate C from C++ </li> + * <li> Check if a flag is set </li> + * <li> Enable a build-flag prog </li> + * <li> Rebuild a project </li> + * </ul> + *</p> + * + * <p> Common steps: <br> + * <ol> + * <li> Check project type (Managed/Autools) (getProjectType) </li> + * <li> Find out if it's C/C++, determine option ID to check (isCppType ..) </li> + * <li> Check if option (e.g -pg) is checked by the user (iOptionChecked ...) </li> + * <li> If not, prompt the user to have it checked. See {@link MessageDialogSyncedRunnable MessageDialogSyncedRunnable} ) </li> + * <li> If user agrees, programatically set the option. (SetOptionIn ..) </li> + * <li> Rebuild the project </li> + * <li> Continue with launch. </li> + * </ol> + * For an example, see <code> org.eclipse.linuxtools.internal.gprof.launch.GprofLaunchConfigurationDelegate </code>. + * @since 3.1 + */ +public class CProjectBuildHelpers { + + /** + * <h1>Custom Project Type enumirator.</h1> + * + * <p> + * Used in conjunctin with {@link CProjectBuildHelpers#getProjectType getProjectType} <br> + * Check the return value against these constants.<br> + * </p> + * + * <p> + * Can be set to one of the following: + * <ul> + * <li> AUTO_TOOLS </li> + * <li> MANAGED_MAKEFILE </li> + * <li> OTHER </li> + * </ul> + * </p> + */ + public static enum ProjectBuildType { + AUTO_TOOLS, MANAGED_MAKEFILE, OTHER + } + + /** + * <h1>Finds out the type of the project as defined by {@link ProjectBuildType ProjectBuildType}.</h1> + * + * <p> + * A project can be of different types.<br> + * Common types are: + * <ul> + * - <li>Autotools</li> + * - <li>Managed Make project</li> + * - <li>Manual Makefiles</li> + * </ul> + * </p> + * + * <p> + * Some dialogues (initially in gCov & gProf) distinguish between these when displaying dialogues. This code is used + * by these dialogues. + * </p> + * + * <p> + * The method was writen with extensibility in mind. <br> + * Other routines check for autotools/Managed make, and if those are not present, then it shows generic advice about + * adding flags. MAKEFILE per-se isn't really checked. I.e this means that it should be safe to add additional + * project types. + * </p> + * + * @param project project for which you want to get the type. + * @return (enum) projectType : <br> + * AUTO_TOOLS, <br> + * MANAGED_MAKEFILE, <br> + * OTHER <br> + */ + public static ProjectBuildType getProjectType(IProject project) { + // AUTOTOOLS + // Autotools has an 'Autotools' nature by which we can identify it. + if (isAutoTools(project)) { + return ProjectBuildType.AUTO_TOOLS; + } + + IConfiguration defaultConfiguration = helperGetActiveConfiguration(project); + IBuilder builder = defaultConfiguration.getBuilder(); + Boolean projIsManaged = builder.isManagedBuildOn(); + + // MANAGED PROJECT + if (projIsManaged) { + return ProjectBuildType.MANAGED_MAKEFILE; + } + else { + return ProjectBuildType.OTHER; //E.g a manual makefile. + } + } + + /** + * <h1>Differentiate C++ from C projects.</h1> + * + * <p> + * Projects can be c or cpp based.<br> + * Cpp projects have a ccnature as well as a cnature, <br> + * where as C projects only have a cnature. <br> + * </p> + * @param project the IProject project which will be read to check if it is c or cpp. + * @return true if it has a cpp nature. + */ + public static boolean isCppType(IProject project) { + try { + if (project.hasNature(CCProjectNature.CC_NATURE_ID)) { + return true; + } + else { + return false; + } + } catch (CoreException ex) { + //This should almost never happen unless the user manually edited the .project file. + MessageDialogSyncedRunnable.openErrorSyncedRunnable(ProfilingMessages.errorTitle, ProfilingMessages.errorGetProjectType); + return false; + } + } + + /** + * <h1>Differentiates C from C++ projects.</h1> + * + * <p> + * Projects can be c or cpp based.<br> + * Cpp projects have a ccnature as well as a cnature, <br> + * where as C projects only have a cnature. + * </p> + * @param project the IProject project which will be read to check if it is c or cpp. + * @return true if it has a c nature BUT NOT a cpp nature. + */ + public static boolean isCType(IProject project) { + try { + // has C & has not CPP + if (project.hasNature(CProjectNature.C_NATURE_ID) + && !project.hasNature(CCProjectNature.CC_NATURE_ID)) { + return true; + } else { + return false; + } + } catch (CoreException e) { + // should never really reach this. + MessageDialogSyncedRunnable.openErrorSyncedRunnable(ProfilingMessages.errorTitle, ProfilingMessages.errorGetProjectType); + return false; + } + } + + /** + * <h1>Autotools projects have an Autotools Nature.</h1> + * + * @param project IProject that you're dealing with. + * @return true if the project has an autotools nautre. + */ + public static boolean isAutoTools(IProject project) { + try { + if (project.hasNature(AutotoolsNewProjectNature.AUTOTOOLS_NATURE_ID)) { // this guy throws. + return true; + } else { + return false; + } + } catch (CoreException e) { + // should never really reach this unless .cproject is broken. + MessageDialogSyncedRunnable.openErrorSyncedRunnable(ProfilingMessages.errorTitle, ProfilingMessages.errorGetProjectType); + return false; + } + } + + /** + * <h1>Check if an option is set in the CDT settings.</h1> + * + * <p> + * Commonly used when launching a plugin and you want to check if flags are set correctly. + * </p> + * + * <p> + * An example of an option id is: {@code gnu.cpp.compiler.option.debugging.gprof } To find the option id, check/uncheck it in + * your project. Then inspect the .cproject file. + * </p> + * + * <p> + * This method serves as a model to easily add similar methods. find what subclasses the iPrefernce store, it is + * likley that your desired option is in one of those stores. + * </p> + * @param project the IProject project which will be read to check if it is c or cpp. + * @param optionIDString for example <code> gnu.cpp.compiler.option.debugging.codecov </code> + * @return true if the option is set. + */ + public static boolean isOptionCheckedInCDT(IProject project, String optionIDString) { + //Set Tool Name. + String parentToolName = helperGetToolName(project); + if (parentToolName == null) { + return false; + } + return isOptionCheckedInCDT(project, optionIDString, parentToolName); + } + + /** + * <h1>Check if an option is set</h1> + * Same as {@link #isOptionCheckedInCDT(IProject project, String optionIDString) isOptionChecked_inCDT }, + * except you specify tool name manually. <br> + * + * (e.g you need to check something that's not supported in the implementation above. + * @param project the IProject project which will be read to check if it is c or cpp + * @param optionIDString for example <code> gnu.cpp.compiler.option.debugging.codecov </code> + * @param parentToolName name of the parent tool. see {@link #helperGetToolName helper_GetToolName} + * @return true if the option is set + */ + public static boolean isOptionCheckedInCDT(IProject project, String optionIDString, String parentToolName) { + + IConfiguration activeConf = helperGetActiveConfiguration(project); + + //Get Compiler tool. + ITool gccCompileriTool = helperGetGccCompilerTool(parentToolName, activeConf); + + //(Get immutable option: This is like a 'templete' that we will use to get the actual option) + IOption optionTemplate = gccCompileriTool.getOptionById(optionIDString); + + //Check that we got a good option. + if (optionTemplate == null) { + MessageDialogSyncedRunnable.openErrorSyncedRunnable(ProfilingMessages.errorTitle, ProfilingMessages.errorGetOptionTemplate); + return false; + } + + // Get Actual Option + // (Now we acquire the actual option from which we can read the value) + try { + IOption mutableOptionToSet = gccCompileriTool.getOptionToSet(optionTemplate, false); + return (boolean) mutableOptionToSet.getValue(); + } catch (BuildException e) { + //This is reached if the template that was provided was bad. + MessageDialogSyncedRunnable.openErrorSyncedRunnable(ProfilingMessages.errorTitle, ProfilingMessages.errorGetOptionForWriting); + } + return false; + + } + + /** + * <h1> Enable a checkbox in the tools preference store and save to disk.</h1> + * <p> + * The tools prefernce store is where most compiler build flags are stored. <br> + * More specifically for 'debug' flags like gprof and gCov + * </p> + * + * <p> + * If you don't know how to get your IProject, see example: <br> + * <code> org.eclipse.linuxtools.internal.gprof.launch.GprofLaunchConfigurationDelegate.getProject() </code> + * <p> + * + * <p> + * Related wiki: + * <a href="https://wiki.eclipse.org/CDT/Developer/Code_Snippets#Programmatically_set_an_option_in_the_project_settings"> + * Programmaticall check option wiki page. </a> + * </p> + * + * @param project + * I project for which to set the flag + * @param optionIDString + * ID of option as defined in plugin.xml. e.g gnu.cpp.compiler.option.debugging.gprof + * @param value + * true or false + * @return false if something went wrong. True otherwise + */ + public static boolean setOptionInCDT(IProject project, String optionIDString, boolean value) { + // Set Tool Name. + String parentToolName = helperGetToolName(project); + if (parentToolName == null) { + return false; + } + return setOptionInCDT(project, optionIDString, value, parentToolName); + } + + /** + * <h1>Set Option in CDT</h1> + * Same as {@link #setOptionInCDT(IProject project, String optionIDString, boolean value) setOption_in } <br> + * except you can specify the parent tool manually (in case current implementation does not support what yon need. + * + * @param project an IProject + * @param optionIDString ID of option as defined in plugin.xml. e.g gnu.cpp.compiler.option.debugging.gprof + * @param value true/false + * @param parentToolName + * Name of the tool where the option resides. E.g 'GCC C Compiler' or 'GCC C++ Compiler'. <br> + * To find out, check/uncheck an option, inspect the .cproject file, look for the option,<br> + * then see what tool it's under. See the name property + * @return true if all went well, false otherwise + */ + public static boolean setOptionInCDT(IProject project, String optionIDString, boolean value, String parentToolName) { + + // Get configuration + IConfiguration activeConf = helperGetActiveConfiguration(project); + + // Get the ITool the option. + ITool gccCompileriTool = helperGetGccCompilerTool(parentToolName, activeConf); + + // Get Template Opiton. + //Get Option ~Immutable. This is like a 'templete' that we will base the actual option on. + IOption optionTemplate = gccCompileriTool.getOptionById(optionIDString); + + //Check that we got a good option template. + if (optionTemplate == null) { + //This could fail if the specified option doesn't exist or is miss-spelled. + MessageDialogSyncedRunnable.openErrorSyncedRunnable(ProfilingMessages.errorTitle, ProfilingMessages.errorGetOptionTemplate); + return false; + } + + // Get Actual Option + // + // Now we acquire an option that can be 'set' to something. + // In contrast to the immutable option above, if the user never checked/unchecked the option by hand, + // then the first time 'set' of this option will work correctly. Whereas + // the immutable option would only work if the user checked/unchecked the option by hand before. + IOption mutableOptionToSet = null; + try { + mutableOptionToSet = gccCompileriTool.getOptionToSet(optionTemplate, false); + mutableOptionToSet.setValue(value); + } catch (BuildException e) { + //This is reached if the template that was provided was bad. + MessageDialogSyncedRunnable.openErrorSyncedRunnable(ProfilingMessages.errorTitle, ProfilingMessages.errorGetOptionForWriting); + } + + // get resource info. (where things are saved to). + IResourceInfo resourceInfo = activeConf.getResourceInfos()[0]; + + // Mark the option as enabled in the build manager. + ManagedBuildManager.setOption(resourceInfo, gccCompileriTool, mutableOptionToSet, + true); + + // Save this business to disk. + ManagedBuildManager.saveBuildInfo(project, true); + return true; + } + + + /** + * <h1>Option enabled check</h1> + * <p> Check to see if an option is enabled in the .autotools configuration.</p> + * + * @param project the IProject project which will be read to check if it is c or cpp. + * @param optionId copy & paste directly from .autotools. pick the 'ID' field value. + * @return true if it is*/ + public static boolean isOptionCheckedInAutotoolsPrefStore(final IProject project, final String optionId) { + + //We define a 'final' variable that will be accessible in the runnable object. + final BooleanWithGetSet userChoiceBool = new BooleanWithGetSet(false); + + // need to run this in the ui thread otherwise get SWT Exceptions + // based on concurrency issues. + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + + //Code copied from private methd: SetAutotoolsStringOptionValue.setOptionValue() + //Except I added a line to save the configuration to disk as well. + AutotoolsConfigurationManager.getInstance().syncConfigurations(project); + ICConfigurationDescription cfgds = CoreModel.getDefault() + .getProjectDescription(project).getActiveConfiguration(); + if (cfgds != null) { + IAConfiguration iaConfig = AutotoolsConfigurationManager.getInstance() + .getConfiguration(project, cfgds.getId()); + + //Read option value + IConfigureOption option = iaConfig.getOption(optionId); + String optValString = option.getValue(); + boolean optVal = Boolean.parseBoolean(optValString); + userChoiceBool.setVal(optVal); + } + } + }); + + return userChoiceBool.getVal(); + } + + /** + * <h1>Set Autotools option & write to disk.</h1> + * + * <p> Set an option (as well as flags) in the .autotools configuration & update gui. <br> + * It is oblivious as to whether the option ID is an option or a flag, it just looks at the ID in the xml. </p> + * + * <p> It is designed so that it can be ran from a background thread. + * It syncs with the GUI thread to avoid concurrency exceptions. </p> + * + * <p> *this modifies gui checkbox options* <b>as well as</b> *saving the option to disk*. </p> + * + * @param project the IProject project which will be read to check if it is c or cpp. + * @param optId Id of option to set. Take directly out of .autotools. a 'flag' is also an option. + * @param optVal string value of the option. e.g "true" "1234"; + */ + public static void setOptionInAutotools(final IProject project, final String optId, final String optVal) { + + // need to run this in the ui thread otherwise get SWT Exceptions + // based on concurrency issues. + Display.getDefault().syncExec(new Runnable() { + @Override + public void run() { + + //Code copied from private methd: SetAutotoolsStringOptionValue.setOptionValue() + //Except I added a line to save the configuration to disk as well. + AutotoolsConfigurationManager.getInstance().syncConfigurations(project); + ICConfigurationDescription cfgds = CoreModel.getDefault(). + getProjectDescription(project).getActiveConfiguration(); + + if (cfgds != null) { + IAConfiguration iaConfig = AutotoolsConfigurationManager.getInstance() + .getConfiguration(project, cfgds.getId()); + + //Set option value. + iaConfig.setOption(optId, optVal); + + //Save option to disk. + AutotoolsConfigurationManager.getInstance().saveConfigs(project); + } + } + }); + } + + /** + * <h1>Trigger a re-build of the project.</h1> + * + * <p> Given a project, it finds the active configuration and rebuilds the project. </p> + * + * <p> This works with C/C++ Managed Builds as well as Autotools.</p> + * + * <p>Most useful for when you have added a flag to a project programatically and want to rebuild + * the project so that the program is rebuild with that flag. The Rebuild triggers an update of the makefile + * automatically.</p> + * + * @param project to rebuild + */ + public static void rebuildProject(IProject project) { + //rebuild does not generate an analysis file (e.g gmon.out) But since -pg flag is added, profiling support is added to the binary. + try { + IBuildConfiguration buildConfiguration = project.getActiveBuildConfig(); + + //force a full rebuild which is usually needed for when you add profiling flags to the builud options. + project.build(buildConfiguration, IncrementalProjectBuilder.FULL_BUILD, null); + } catch (CoreException e) { + + //This is a very rare occurance. Usually rebuilds don't fail if they worked the first time. + MessageDialogSyncedRunnable.openErrorSyncedRunnable(ProfilingMessages.errorTitle, ProfilingMessages.errorRebuilding); + } + } + + /* + * PRIVATE HELPERS BELOW + */ + + /** + * <p>Helper to get the active build configuration.</p> + * @param project IProject for which to get the configuration. + * @return IConfiguration of that project. + */ + private static IConfiguration helperGetActiveConfiguration(IProject project) { + IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project); + return buildInfo.getDefaultConfiguration(); + } + + /** + * <p> For a project, retrieve the parent toolname underwhich we expect the tool to be under.</p> + * + * @param project IProject for which to get the tool name. + * @return name of the parent tool. + */ + private static String helperGetToolName(IProject project) { + String toolName = null; + if (isCppType(project)) { + toolName = "GCC C++ Compiler"; //$NON-NLS-1$ + } else if (isCType(project)) { + toolName = "GCC C Compiler"; //$NON-NLS-1$ + } else { + //This should happen only if project natures are broken. Maybe the .project file is corrupted. + MessageDialogSyncedRunnable.openErrorSyncedRunnable(ProfilingMessages.errorTitle, ProfilingMessages.errorGetProjectToolname); + return null; + } + return toolName; + } + + /** + * <h1>Get the tool that holds the option 'template'.</h1> + * + * <p> Each option has a parent tool. this aquires the 'ITool' <br> + * based on it's name from the active configuration. </p> + * + * <p> The parent tool is later read to aquire the option template, which is used to set an option. </p> + * + * @param parentToolName a string represeting the parent of the option. (like 'GCC C++ Compiler'). + * @param the current active configuration of the project, from which we should be able to find the ITool name. + * @return the parent 'ITool' instance. + */ + private static ITool helperGetGccCompilerTool(String parentToolName, IConfiguration activeConf) { + ITool[] tools = activeConf.getTools(); + ITool gccCompileriTool = null; + for (ITool iTool : tools) { + if (iTool.getName().equals(parentToolName)) { + gccCompileriTool = iTool; + break; + } + } + return gccCompileriTool; + } +} diff --git a/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/MessageDialogSyncedRunnable.java b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/MessageDialogSyncedRunnable.java new file mode 100644 index 0000000000..73db88df0f --- /dev/null +++ b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/MessageDialogSyncedRunnable.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc. : Initial Implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.profiling.ui; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +/** + * <h1>UI sycned Message Dialogue </h1> + * <p> + * This class is for launching common messages <b>from background threads</b> and <b>getting a return value. + * </p> + * <p> + * When you're not in a U.I thread, getting the 'shell' causes a runtime exception. <br> + * Never the less, sometimes you need user feedback when executing a background job. <br> + * (e.g missing flags when launching a profiling tools, ask the user if he wants the flag to be added). <br> + * This class aims to implement wrappers for the standard openTYPE message dialogues so that <br> + * they could be launched from any background thread. + * </p> + * + * <p> Note, methods in this subclass have a postfix of 'SyncedRunnable'. + * @since 3.1 + */ +public class MessageDialogSyncedRunnable extends MessageDialog { + + /** + * Calls parent, identical to parent implementation in all respects. <br> + * <p> Neccessary to supress compiler warnings. Use static methods in this class instead </p> + * <p> For details and paramater description, please see: <br> </p> + * {@link org.eclipse.jface.dialogs.MessageDialog#MessageDialog(Shell, String, Image, String, int, String[], int) } + */ + protected MessageDialogSyncedRunnable(Shell parentShell, String dialogTitle, + Image dialogTitleImage, String dialogMessage, int dialogImageType, + String[] dialogButtonLabels, int defaultIndex) { + super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, + dialogButtonLabels, defaultIndex); + } + + /** + * <h1>Open Question Dialogue.</h1> + * <p> + * Identical to parent implementation {@link MessageDialog#openQuestion(Shell, String, String) openQuestion} <br> + * except that you do not need to provide a shell. + * </p> + * <p> + * Convenience method to open a simple Yes/No question dialog. + * </p> + * + * @param title the dialog's title, or <code>null</code> if none + * @param message the message + * @return <code>true </code> if the user presses the Yes button, + * <code>false</code> otherwise + */ + public static boolean openQuestionSyncedRunnable(final String title, final String message) { + return openInSyncedRunnable(DialogueType.QUESTION, title, message); + } + + /** + * <h1>Open Confirmation Dialogue. </h1> + * <p> + * Identical to parent implementation {@link MessageDialog#openConfirm(Shell, String, String) openConfirm}<br> + * except that you do not need to provide a shell. + * </p> + * + * <p> Convenience method to open a simple confirm (OK/Cancel) dialog. </p> + * + * @param title the dialog's title, or <code>null</code> if none + * @param message the message + * @return <code>true</code> if the user presses the OK button, + * <code>false</code> otherwise + */ + public static boolean openConfirmSyncedRunnable(final String title, final String message) { + return openInSyncedRunnable(DialogueType.CONFIRMATION, title, message); + } + + /** + * <h1>Open Information Dialogue.</h1> + * <p> + * Identical to parent implementation {@link MessageDialog#openInformation(Shell, String, String) openInformation} <br> + * except that you do not need to provide a shell. + * </p> + * <p> + * Convenience method to open a simple confirm (OK/Cancel) dialog. + * </p> + * + * @param title the dialog's title, or <code>null</code> if none + * @param message the message + */ + public static void openInformationSyncedRunnable(final String title, final String message) { + //We discard boolean and don't return anything. + openInSyncedRunnable(DialogueType.INFO, title, message); + } + + /** + * <h1>Open Error Dialogue.</h1> + * <p> + * Identical to parent implementation {@link MessageDialog#openError(Shell, String, String) openError}<br> + * except that you do not need to provide a shell: + * </p> + *<p> + *Convenience method to open a standard error dialog. + *</p> + * + * @param title the dialog's title, or <code>null</code> if none + * @param message the message + */ + public static void openErrorSyncedRunnable(final String title, final String message) { + //We discard boolean and don't return anything. + openInSyncedRunnable(DialogueType.ERROR, title, message); + } + + private static enum DialogueType {INFO, ERROR, CONFIRMATION, QUESTION} + + /* To prevent code duplication... */ + private static boolean openInSyncedRunnable(final DialogueType type, final String title, final String message) { + + //We define a 'final' variable that will be accessible in the runnable object. + final BooleanWithGetSet userChoiceBool = new BooleanWithGetSet(false); + + //To generate U.I, we make a syncronised call the U.I thread, + //otherwise we get an U.I exception. + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + @Override + public void run() { + Shell parent = PlatformUI.getWorkbench().getDisplay().getActiveShell(); + switch (type) { + case INFO: + MessageDialog.openInformation(parent, title, message); + break; + case ERROR: + MessageDialog.openError(parent, title, message); + break; + case CONFIRMATION: + boolean okPressed = MessageDialog.openConfirm(parent, title, message); + userChoiceBool.setVal(okPressed); + break; + case QUESTION: + boolean okPressedQ = MessageDialog.openQuestion(parent, title, message); + userChoiceBool.setVal(okPressedQ); + break; + default: + break; + } + return; + }}); + return userChoiceBool.getVal(); + } +} diff --git a/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/ProfilingMessages.java b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/ProfilingMessages.java new file mode 100644 index 0000000000..db5b940332 --- /dev/null +++ b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/ProfilingMessages.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc. + *******************************************************************************/ +package org.eclipse.linuxtools.profiling.ui; + +import org.eclipse.osgi.util.NLS; + +/** + * @since 3.1 + */ +public class ProfilingMessages extends NLS { + + public static String + errorTitle, + errorGetProjectType, + errorGetOptionTemplate, + errorGetOptionForWriting, + errorRebuilding, + errorGetProjectToolname; + + static { + NLS.initializeMessages(ProfilingMessages.class.getName(), ProfilingMessages.class); + } + +} diff --git a/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/ProfilingMessages.properties b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/ProfilingMessages.properties new file mode 100644 index 0000000000..a25a5290db --- /dev/null +++ b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/ProfilingMessages.properties @@ -0,0 +1,16 @@ +############################################################################### +# Copyright (c) 2012, 2014 Red Hat Inc. and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Red Hat Inc +############################################################################### +errorTitle=Error Occured +errorGetProjectType=Error getting project type +errorGetOptionTemplate=Could not aquire option template +errorGetOptionForWriting=Failed to get option for writing +errorRebuilding=Failed to rebuild the project +errorGetProjectToolname=Failed to find tool name for project
\ No newline at end of file diff --git a/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/TitleAreaDialogWithRadioButtons.java b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/TitleAreaDialogWithRadioButtons.java new file mode 100644 index 0000000000..ed2e34c887 --- /dev/null +++ b/profiling/org.eclipse.linuxtools.profiling.ui/src/org/eclipse/linuxtools/profiling/ui/TitleAreaDialogWithRadioButtons.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc. : Initial Implementation + *******************************************************************************/ +package org.eclipse.linuxtools.profiling.ui; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + + +/** + * <h1> Dialogue with radio options. </h1> + * + * <p> + * This is useful if you need to ask the user to choose one of 'multiple options' instead of a 'yes/no'. <br> + * It also looks cleaner than having multiple buttons at the bottom of the screen. + * </p> + * + * <p> + * Please see the <a href="https://wiki.eclipse.org/File:TitleAreaDialogWithRadioButtonsExample.png">Screen shot</a> + * to see what it looks like. </p> + * + * <p> + * Please see <a href="https://wiki.eclipse.org/Eclipse_Plug-in_Development_FAQ/TitleAreaDialogWithRadioButtons""> wiki page </a> + * for additional details & example usage code + * </p> + * @since 3.1 + */ +public class TitleAreaDialogWithRadioButtons extends TitleAreaDialog { + + private String selectedButton; + private String title, bodyMsg; + private int msgType; + private List<Entry<String, String>> userButtonList; // ButtonID , Button Label + private List<Button> widgetButtonList; + + /** + * <h1> Construct dialogue. </h1> + * <p> + * Specify paramaters, then use open. + * </p> + * <p> + * Please see <a href="https://wiki.eclipse.org/Eclipse_Plug-in_Development_FAQ/TitleAreaDialogWithRadioButtons""> wiki page </a> + * for additional details & example. + * </p> + * + * @param parentShell Parent Shell + * @param title Title of the dialogue + * @param bodyMsg Body message of the dialogue + * @param userButtonList A list of SimpleEntry<String,String> mapping ButtonIDs and their visable text. + * (see <a href="https://wiki.eclipse.org/Eclipse_Plug-in_Development_FAQ/TitleAreaDialogWithRadioButtons#Example_usage"> wiki example </a> for details) + * @param msgType 'IMessageProvider.INFORMATION ' Can be one of: NONE ERROR INFORMATION WARNING + */ + public TitleAreaDialogWithRadioButtons( + Shell parentShell, String title, String bodyMsg, + List<Entry<String, String>> userButtonList, + int msgType) { //for type see: IMessageProvider + + super(parentShell); + + // Set the Buttons that will be used listed. + this.userButtonList = userButtonList; + + //Set labels. + this.title = title; + this.bodyMsg = bodyMsg; + + //set type + this.msgType = msgType; + + // avoid help button poping up. + this.setHelpAvailable(false); + + selectedButton = null; + } + + @Override + public void create() { + + super.create(); + + //The 'Message' of a TitleArea dialogue only spans 1-2 lines. Then text is cut off. + //It is not very efficient for longer messages. + //Thus we utilize it as a 'title' and instaed we appeng a label to act as body. (see below). + setMessage(this.title, this.msgType); + //setTitle(); //not used. + + //Set the size of the dialogue. + //We avoid hard-coding size, instead we tell it to figure out the most optimal size. + //this.getShell().setSize(650, 550); //Hard-Coded = bad. + this.getShell().setSize(getInitialSize()); + } + + /** + * <h1> Get selected button.</h1> + * <p> + * Return the buttonID of the button that the user selected if he pressed ok. <br> + * This is the first element of the (id | label) tuple. + * </p> + * + * @return ButtonID of selected button + */ + public String getSelectedButton() { + return selectedButton; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite area = (Composite) super.createDialogArea(parent); + Composite container = new Composite(area, SWT.NONE); + container.setLayoutData(new GridData(GridData.FILL_BOTH)); + GridLayout layout = new GridLayout(1, false); + container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + container.setLayout(layout); + + //Append a label to act as message body + Label label = new Label(container, 0); + label.setText(this.bodyMsg); + + //Add Radio buttons to dialogue. + widgetButtonList = new ArrayList<>(); + int buttonCount = 1; + for (Entry<String, String> usrbutton : userButtonList) { + Button tmpButton = new Button(container, SWT.RADIO); + tmpButton.setText(usrbutton.getValue()); + + if (buttonCount == 1) { + tmpButton.setSelection(true); //Make first button be auto-selected. + buttonCount++; + } + widgetButtonList.add(tmpButton); + } + return area; + } + + // save content of the Text fields because they get disposed + // as soon as the Dialog closes + protected void saveInput() { + + //Figure out which button was selected and set 'selectedButton' to it's key. + for (int i = 0; i < widgetButtonList.size(); i++) { + if (widgetButtonList.get(i).getSelection()) { + selectedButton = userButtonList.get(i).getKey(); + } + } + } + + /** + * <p> + * Called when the ok button is pressed. <br> + * Saves the state of the radio buttons prior to deconstruction. + * </p> + */ + @Override + protected void okPressed() { + saveInput(); // save input. + super.okPressed(); // close dialogue + } + +} diff --git a/releng/org.eclipse.linuxtools.target/linuxtools-e4.4.target b/releng/org.eclipse.linuxtools.target/linuxtools-e4.4.target index 65387ff254..1576ee238c 100644 --- a/releng/org.eclipse.linuxtools.target/linuxtools-e4.4.target +++ b/releng/org.eclipse.linuxtools.target/linuxtools-e4.4.target @@ -14,6 +14,7 @@ </location> <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit"> <unit id="org.eclipse.cdt.sdk.feature.group" version="0.0.0"/> +<unit id="org.eclipse.cdt.autotools.feature.group" version="0.0.0"/> <repository location="http://download.eclipse.org/tools/cdt/releases/8.4"/> </location> <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit"> |