diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/RegexErrorParserTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/RegexErrorParserTests.java index 0757de8ef6d..95aa32c7ce2 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/RegexErrorParserTests.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/RegexErrorParserTests.java @@ -403,10 +403,17 @@ public class RegexErrorParserTests extends TestCase { assertEquals(firstName, retrieved2.getName()); assertTrue(retrieved2 instanceof ErrorParserNamedWrapper); assertEquals(dummy2, ((ErrorParserNamedWrapper)retrieved2).getErrorParser()); + + IErrorParserNamed retrieved2_ext = ErrorParserManager.getErrorParserExtensionCopy(firstId); + assertNotNull(retrieved2_ext); + assertEquals(firstName, retrieved2_ext.getName()); + assertEquals(firstErrorParser, retrieved2_ext); } // reset available parsers { ErrorParserManager.setUserDefinedErrorParsers(null); + String[] userDefinedIds = ErrorParserManager.getUserDefinedErrorParserIds(); + assertNull(userDefinedIds); String all = ErrorParserManager.toDelimitedString(ErrorParserManager.getErrorParserAvailableIds()); assertEquals(false, all.contains(TESTING_ID)); @@ -431,6 +438,9 @@ public class RegexErrorParserTests extends TestCase { // reset parsers { ErrorParserManager.setUserDefinedErrorParsers(null); + String[] userDefinedIds = ErrorParserManager.getUserDefinedErrorParserIds(); + assertNull(userDefinedIds); + String all = ErrorParserManager.toDelimitedString(ErrorParserManager.getErrorParserAvailableIds()); String extensions = ErrorParserManager.toDelimitedString(ErrorParserManager.getErrorParserExtensionIds()); assertEquals(all, extensions); @@ -439,6 +449,9 @@ public class RegexErrorParserTests extends TestCase { ErrorParserManager.setUserDefinedErrorParsers(new IErrorParserNamed[] { new ErrorParserNamedWrapper(TESTING_ID, TESTING_NAME, new DummyErrorParser()), }); + String userDefinedIds = ErrorParserManager.toDelimitedString(ErrorParserManager.getUserDefinedErrorParserIds()); + assertEquals(TESTING_ID, userDefinedIds); + String all = ErrorParserManager.toDelimitedString(ErrorParserManager.getErrorParserAvailableIds()); String extensions = ErrorParserManager.toDelimitedString(ErrorParserManager.getErrorParserExtensionIds()); assertFalse(all.equals(extensions)); diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java index 74b862247ec..aa5fe227db2 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java @@ -164,7 +164,7 @@ public class ErrorParserManager extends OutputStream { } fErrorParsers = new LinkedHashMap(parsersIDs.length); for (String parsersID : parsersIDs) { - IErrorParser errorParser = ErrorParserExtensionManager.getErrorParserCopy(parsersID); + IErrorParser errorParser = getErrorParserCopy(parsersID); if (errorParser!=null) { fErrorParsers.put(parsersID, new IErrorParser[] {errorParser} ); } @@ -748,6 +748,14 @@ outer: return hasErrors; } + /** + * @return default error parsers IDs to be used if error parser list is empty. + * @since 5.3 + */ + public static String[] getUserDefinedErrorParserIds() { + return ErrorParserExtensionManager.getUserDefinedErrorParserIds(); + } + /** * Set and store in workspace area user defined error parsers. * @@ -797,14 +805,24 @@ outer: /** * @param id - ID of error parser - * @return cloned copy of error parser. Note that {@link ErrorParserNamedWrapper} returns - * shallow copy with the same instance of underlying error parser. + * @return cloned copy of error parser or {@code null}. + * Note that {@link ErrorParserNamedWrapper} returns shallow copy with the same instance + * of underlying error parser. * @since 5.2 */ public static IErrorParserNamed getErrorParserCopy(String id) { - return ErrorParserExtensionManager.getErrorParserCopy(id); + return ErrorParserExtensionManager.getErrorParserCopy(id, false); } + /** + * @param id - ID of error parser + * @return cloned copy of error parser as defined by its extension point or {@code null}. + * @since 5.3 + */ + public static IErrorParserNamed getErrorParserExtensionCopy(String id) { + return ErrorParserExtensionManager.getErrorParserCopy(id, true); + } + /** * @param ids - array of error parser IDs * @return error parser IDs delimited with error parser delimiter ";" diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/ErrorParserExtensionManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/ErrorParserExtensionManager.java index d59b07e112c..45b6a9706f2 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/ErrorParserExtensionManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/ErrorParserExtensionManager.java @@ -20,11 +20,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.List; +import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; -import java.util.Map.Entry; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -44,7 +43,9 @@ import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.core.errorparsers.ErrorParserNamedWrapper; import org.eclipse.cdt.core.errorparsers.RegexErrorParser; import org.eclipse.cdt.core.errorparsers.RegexErrorPattern; +import org.eclipse.cdt.core.resources.ResourcesUtil; import org.eclipse.cdt.internal.core.XmlUtil; +import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; @@ -101,6 +102,34 @@ public class ErrorParserExtensionManager { private static LinkedHashMap fUserDefinedErrorParsers = null; private static List fDefaultErrorParserIds = null; + private static class ErrorParserComparator implements Comparator { + // For the error parsers taken from platform extensions following sorting order applies: + // - first regular error parsers + // - then deprecated ones + // - then contributed by test plugin + // inside the same category sort by parser name + public int compare(IErrorParserNamed errorParser1, IErrorParserNamed errorParser2) { + final String TEST_PLUGIN_ID="org.eclipse.cdt.core.tests"; //$NON-NLS-1$ + final String DEPRECATED=CCorePlugin.getResourceString("CCorePlugin.Deprecated"); //$NON-NLS-1$ + + boolean isTestPlugin1 = errorParser1.getId().startsWith(TEST_PLUGIN_ID); + boolean isTestPlugin2 = errorParser2.getId().startsWith(TEST_PLUGIN_ID); + if (isTestPlugin1==true && isTestPlugin2==false) + return 1; + if (isTestPlugin1==false && isTestPlugin2==true) + return -1; + + boolean isDeprecated1 = errorParser1.getName().contains(DEPRECATED); + boolean isDeprecated2 = errorParser2.getName().contains(DEPRECATED); + if (isDeprecated1==true && isDeprecated2==false) + return 1; + if (isDeprecated1==false && isDeprecated2==true) + return -1; + + return errorParser1.getName().compareTo(errorParser2.getName()); + } + } + static { loadUserDefinedErrorParsers(); loadDefaultErrorParserIds(); @@ -122,12 +151,12 @@ public class ErrorParserExtensionManager { } if (doc!=null) { - Set errorParsers = new LinkedHashSet(); - loadErrorParserExtensions(doc, errorParsers); + Set sortedErrorParsers = new TreeSet(new ErrorParserComparator()); + loadErrorParserExtensions(doc, sortedErrorParsers); - if (errorParsers.size()>0) { + if (sortedErrorParsers.size()>0) { fUserDefinedErrorParsers = new LinkedHashMap(); - for (IErrorParserNamed errorParser : errorParsers) { + for (IErrorParserNamed errorParser : sortedErrorParsers) { fUserDefinedErrorParsers.put(errorParser.getId(), errorParser); } } @@ -212,34 +241,7 @@ public class ErrorParserExtensionManager { * @noreference This method is not intended to be referenced by clients. */ synchronized public static void loadErrorParserExtensions() { - Set sortedErrorParsers = new TreeSet(new Comparator() { - // For the error parsers taken from platform extensions following sorting order applies: - // - first regular error parsers - // - then deprecated ones - // - then contributed by test plugin - // inside the same category sort by parser name - public int compare(IErrorParserNamed errorParser1, IErrorParserNamed errorParser2) { - final String TEST_PLUGIN_ID="org.eclipse.cdt.core.tests"; //$NON-NLS-1$ - final String DEPRECATED=CCorePlugin.getResourceString("CCorePlugin.Deprecated"); //$NON-NLS-1$ - - boolean isTestPlugin1 = errorParser1.getId().startsWith(TEST_PLUGIN_ID); - boolean isTestPlugin2 = errorParser2.getId().startsWith(TEST_PLUGIN_ID); - if (isTestPlugin1==true && isTestPlugin2==false) - return 1; - if (isTestPlugin1==false && isTestPlugin2==true) - return -1; - - boolean isDeprecated1 = errorParser1.getName().contains(DEPRECATED); - boolean isDeprecated2 = errorParser2.getName().contains(DEPRECATED); - if (isDeprecated1==true && isDeprecated2==false) - return 1; - if (isDeprecated1==false && isDeprecated2==true) - return -1; - - return errorParser1.getName().compareTo(errorParser2.getName()); - } - }); - + Set sortedErrorParsers = new TreeSet(new ErrorParserComparator()); loadErrorParserExtensions(Platform.getExtensionRegistry(), sortedErrorParsers); fExtensionErrorParsers.clear(); @@ -287,15 +289,44 @@ public class ErrorParserExtensionManager { */ private static void recalculateAvailableErrorParsers() { fAvailableErrorParsers.clear(); - if (fUserDefinedErrorParsers!=null) { - fAvailableErrorParsers.putAll(fUserDefinedErrorParsers); - } - for (IErrorParserNamed errorParser : fExtensionErrorParsers.values()) { - String id = errorParser.getId(); - if (!fAvailableErrorParsers.containsKey(id)) { - fAvailableErrorParsers.put(id, errorParser); + // put default parsers on top of the list + List ids = new ArrayList(); + if (fDefaultErrorParserIds!=null) { + for (String id : fDefaultErrorParserIds) { + IErrorParserNamed errorParser = null; + if (fUserDefinedErrorParsers!=null) { + errorParser = fUserDefinedErrorParsers.get(id); + } + if (errorParser==null) { + errorParser = fExtensionErrorParsers.get(id); + } + if (errorParser!=null) { + fAvailableErrorParsers.put(id, errorParser); + ids.add(id); + } } } + // then the rest in the order defined by comparator + Set sortedErrorParsers = new TreeSet(new ErrorParserComparator()); + + if (fUserDefinedErrorParsers!=null) { + for (String id : fUserDefinedErrorParsers.keySet()) { + if (!ids.contains(id)) { + IErrorParserNamed errorParser = fUserDefinedErrorParsers.get(id); + sortedErrorParsers.add(errorParser); + } + } + } + for (String id : fExtensionErrorParsers.keySet()) { + if (!ids.contains(id)) { + IErrorParserNamed errorParser = fExtensionErrorParsers.get(id); + sortedErrorParsers.add(errorParser); + } + } + + for (IErrorParserNamed errorParser : sortedErrorParsers) { + fAvailableErrorParsers.put(errorParser.getId(), errorParser); + } } /** @@ -456,6 +487,7 @@ public class ErrorParserExtensionManager { transformer.transform(source, result); fileStream.close(); + ResourcesUtil.refreshWorkspaceFiles(URIUtil.toURI(location)); } /** @@ -627,7 +659,7 @@ public class ErrorParserExtensionManager { * Return error parser as stored in internal list. * * @noreference This method is not intended to be referenced by clients. - * Use {@link #getErrorParserCopy(String)} instead. + * Use {@link #getErrorParserCopy(String, boolean)} instead. * * @param id - ID of error parser * @return internal instance of error parser @@ -662,9 +694,11 @@ public class ErrorParserExtensionManager { if (errorParsers==null) { fUserDefinedErrorParsers = null; } else { + Set sortedErrorParsers = new TreeSet(new ErrorParserComparator()); + sortedErrorParsers.addAll(Arrays.asList(errorParsers)); fUserDefinedErrorParsers= new LinkedHashMap(); // set customized list - for (IErrorParserNamed errorParser : errorParsers) { + for (IErrorParserNamed errorParser : sortedErrorParsers) { fUserDefinedErrorParsers.put(errorParser.getId(), errorParser); } } @@ -686,6 +720,15 @@ public class ErrorParserExtensionManager { return fExtensionErrorParsers.keySet().toArray(new String[0]); } + /** + * @return default error parsers IDs to be used if error parser list is empty. + */ + public static String[] getUserDefinedErrorParserIds() { + if (fUserDefinedErrorParsers!=null) + return fUserDefinedErrorParsers.keySet().toArray(new String[0]); + return null; + } + /** * Set and store default error parsers IDs to be used if error parser list is empty. * @@ -711,6 +754,7 @@ public class ErrorParserExtensionManager { } else { fDefaultErrorParserIds = new ArrayList(Arrays.asList(ids)); } + recalculateAvailableErrorParsers(); } /** @@ -725,11 +769,12 @@ public class ErrorParserExtensionManager { /** * @param id - ID of error parser + * @param isExtension - if {@code true} get unmodified copy of error parser defined as extension * @return cloned copy of error parser. Note that {@link ErrorParserNamedWrapper} returns * shallow copy with the same instance of underlying error parser. */ - public static IErrorParserNamed getErrorParserCopy(String id) { - IErrorParserNamed errorParser = fAvailableErrorParsers.get(id); + public static IErrorParserNamed getErrorParserCopy(String id, boolean isExtension) { + IErrorParserNamed errorParser = isExtension ? fExtensionErrorParsers.get(id) : fAvailableErrorParsers.get(id); try { if (errorParser instanceof RegexErrorParser) { @@ -743,5 +788,4 @@ public class ErrorParserExtensionManager { return errorParser; } - } diff --git a/core/org.eclipse.cdt.ui/icons/obj16/extension_obj.gif b/core/org.eclipse.cdt.ui/icons/obj16/extension_obj.gif new file mode 100644 index 00000000000..7f3f595bc5e Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/extension_obj.gif differ diff --git a/core/org.eclipse.cdt.ui/icons/obj16/flask.png b/core/org.eclipse.cdt.ui/icons/obj16/flask.png new file mode 100644 index 00000000000..6340e7caf46 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/flask.png differ diff --git a/core/org.eclipse.cdt.ui/icons/obj16/person-me.gif b/core/org.eclipse.cdt.ui/icons/obj16/person-me.gif new file mode 100644 index 00000000000..fa074fb83a9 Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/obj16/person-me.gif differ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java index c17da489c67..23f6102adf8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.java @@ -143,6 +143,7 @@ public class Messages extends NLS { public static String ErrorParsTab_label_DefaultRegexErrorParserName; public static String ErrorParsTab_label_EnterName; public static String ErrorParsTab_message_ConfirmReset; + public static String ErrorParsTab_Reset; public static String ErrorParsTab_title_Add; public static String ErrorParsTab_title_ConfirmReset; public static String ErrorParsTab_title_Edit; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties index 52dadb6e672..e0044ac0666 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/Messages.properties @@ -209,6 +209,7 @@ ErrorParsTab_error_IllegalCharacter=Special character ''{0}'' is not allowed ErrorParsTab_label_EnterName=Enter name of new error parser: ErrorParsTab_label_DefaultRegexErrorParserName=Regex Error Parser ErrorParsTab_message_ConfirmReset=Are you sure you want to delete all customized error parsers? +ErrorParsTab_Reset=Reset ErrorParsTab_title_Add=Add Regex Error Parser ErrorParsTab_title_ConfirmReset=Confirm Resetting Error Parsers ErrorParsTab_title_Edit=Edit Regex Error Parser name diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CDTSharedImages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CDTSharedImages.java index cf665f23c24..10950c25a31 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CDTSharedImages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CDTSharedImages.java @@ -39,6 +39,10 @@ import org.eclipse.swt.graphics.Image; *
* and {@link org.eclipse.ui.ide.IDE.SharedImages}. *

+ *

+ * Note that org.eclipse.cdt.ui.tests.misc.CDTSharedImagesTests will verify + * existence of the images defined here. + *

* * @noextend This class is not intended to be subclassed by clients. * @noinstantiate This class is not intended to be instantiated by clients. @@ -115,6 +119,10 @@ public class CDTSharedImages { public static final String IMG_OBJS_IMPORT_SETTINGS = "icons/obj16/import_settings_wiz.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_EXPORT_SETTINGS = "icons/obj16/export_settings_wiz.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_INCCONT = "icons/obj16/incc_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_EXTENSION = "icons/obj16/extension_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_USER = "icons/obj16/person-me.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_CDT_TESTING = "icons/obj16/flask.png"; //$NON-NLS-1$ + public static final String IMG_OBJS_NLS_NEVER_TRANSLATE = "icons/obj16/never_translate.gif"; //$NON-NLS-1$ // Breakpoint images @@ -169,6 +177,8 @@ public class CDTSharedImages { // overlays public static final String IMG_OVR_WARNING = "icons/ovr16/warning_co.gif"; //$NON-NLS-1$ public static final String IMG_OVR_ERROR = "icons/ovr16/error_co.gif"; //$NON-NLS-1$ + public static final String IMG_OVR_SETTING = "icons/ovr16/setting_nav.gif"; //$NON-NLS-1$ + public static final String IMG_OVR_INACTIVE = "icons/ovr16/inactive_co.gif"; //$NON-NLS-1$ /** * The method finds URL of the image corresponding to the key which could be project-relative path diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/RegexErrorParserOptionPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/RegexErrorParserOptionPage.java index a1917b4e4aa..91dc9f5aa83 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/RegexErrorParserOptionPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/RegexErrorParserOptionPage.java @@ -11,6 +11,9 @@ package org.eclipse.cdt.ui.dialogs; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; @@ -90,6 +93,8 @@ public final class RegexErrorParserOptionPage extends AbstractCOptionPage { private RegexErrorParser fErrorParser; private boolean fEditable; + private List fListeners = new ArrayList(); + /** * Provides generic implementation for overridden methods. * One purpose is to make it easier for subclasses to operate with {@link RegexErrorPattern}, @@ -245,6 +250,7 @@ public final class RegexErrorParserOptionPage extends AbstractCOptionPage { fErrorParser = null; initializeTable(); + fireEvent(); } }); @@ -673,9 +679,11 @@ public final class RegexErrorParserOptionPage extends AbstractCOptionPage { moveItem(false); break; default: - break; + return; } + applyPatterns(); updateButtons(); + fireEvent(); } private void addErrorPattern() { @@ -714,13 +722,8 @@ public final class RegexErrorParserOptionPage extends AbstractCOptionPage { fTableViewer.insert(item, newPos); fTable.setSelection(newPos); } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performApply(org.eclipse.core.runtime.IProgressMonitor) - */ - @Override - public void performApply(IProgressMonitor monitor) throws CoreException { + + private void applyPatterns() { if (fErrorParser!=null && fEditable) { fErrorParser.clearPatterns(); for (TableItem tableItem : fTable.getItems()) { @@ -732,6 +735,16 @@ public final class RegexErrorParserOptionPage extends AbstractCOptionPage { } } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performApply(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void performApply(IProgressMonitor monitor) throws CoreException { + applyPatterns(); + } + /* * (non-Javadoc) * @@ -741,4 +754,24 @@ public final class RegexErrorParserOptionPage extends AbstractCOptionPage { public void performDefaults() { // ErrorParsTas.performDefaults() will do all the work } + + /** + * @since 5.3 + */ + public void addListener(Listener listener){ + fListeners.add(listener); + } + + /** + * @since 5.3 + */ + public void removeListener(Listener listener){ + fListeners.remove(listener); + } + + private void fireEvent() { + for (Listener listener : fListeners) { + listener.handleEvent(new Event()); + } + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ErrorParsTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ErrorParsTab.java index 2770c7e3aa9..3a71d7747ef 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ErrorParsTab.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ErrorParsTab.java @@ -11,11 +11,13 @@ *******************************************************************************/ package org.eclipse.cdt.ui.newui; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -28,6 +30,7 @@ import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.IDecoration; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.Viewer; @@ -37,9 +40,12 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.PlatformUI; @@ -47,12 +53,14 @@ import org.osgi.service.prefs.BackingStoreException; import com.ibm.icu.text.MessageFormat; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.IErrorParserNamed; import org.eclipse.cdt.core.errorparsers.RegexErrorParser; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICMultiConfigDescription; import org.eclipse.cdt.core.settings.model.ICResourceDescription; +import org.eclipse.cdt.ui.CDTSharedImages; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.dialogs.ICOptionPage; import org.eclipse.cdt.ui.dialogs.IInputStatusValidator; @@ -87,6 +95,7 @@ public class ErrorParsTab extends AbstractCPropertyTab { MOVEUP_STR, MOVEDOWN_STR, }; + private static final String RESET_STR = Messages.ErrorParsTab_Reset; private static final String OOPS = "OOPS"; //$NON-NLS-1$ @@ -94,6 +103,8 @@ public class ErrorParsTab extends AbstractCPropertyTab { private CheckboxTableViewer fTableViewer; private ICConfigurationDescription fCfgDesc; + private static Map fExtensionErrorParsers = null; + private final Map fAvailableErrorParsers = new LinkedHashMap(); private final Map fOptionsPageMap = new HashMap(); private ICOptionPage fCurrentOptionsPage = null; @@ -156,6 +167,34 @@ public class ErrorParsTab extends AbstractCPropertyTab { } return OOPS; } + + @Override + public Image getImage(Object element) { + final String TEST_PLUGIN_ID = "org.eclipse.cdt.core.tests"; //$NON-NLS-1$ + final String DEPRECATED = CCorePlugin.getResourceString("CCorePlugin.Deprecated"); //$NON-NLS-1$ + if (element instanceof String) { + String id = (String) element; + String[] extIds = ErrorParserManager.getErrorParserExtensionIds(); + if (Arrays.asList(extIds).contains(id)) { + String imageKey = CDTSharedImages.IMG_OBJS_EXTENSION; + if (id.startsWith(TEST_PLUGIN_ID)) + imageKey = CDTSharedImages.IMG_OBJS_CDT_TESTING; + + String[] overlayKeys = new String[5]; + IErrorParserNamed errorParser = fAvailableErrorParsers.get(id); + IErrorParserNamed errorParserExt = fExtensionErrorParsers.get(id); + if (!errorParser.equals(errorParserExt)) { + overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_SETTING; + } else if (errorParser.getName().contains(DEPRECATED)) { + overlayKeys[IDecoration.TOP_RIGHT] = CDTSharedImages.IMG_OVR_INACTIVE; + } + return CDTSharedImages.getImageOverlaid(imageKey, overlayKeys); + } + return CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_USER); + } + return null; + } + }); fTableViewer.addCheckStateListener(new ICheckStateListener() { @@ -191,6 +230,14 @@ public class ErrorParsTab extends AbstractCPropertyTab { } private void initMapParsers() { + if (fExtensionErrorParsers==null) { + fExtensionErrorParsers = new LinkedHashMap(); + String[] idsExt = ErrorParserManager.getErrorParserExtensionIds(); + for (String idExt : idsExt) { + IErrorParserNamed errorParserExt = ErrorParserManager.getErrorParserExtensionCopy(idExt); + fExtensionErrorParsers.put(idExt, errorParserExt); + } + } fAvailableErrorParsers.clear(); fOptionsPageMap.clear(); for (String id : ErrorParserManager.getErrorParserAvailableIds()) { @@ -220,7 +267,7 @@ public class ErrorParsTab extends AbstractCPropertyTab { displaySelectedOptionPage(); } - private void initializeOptionsPage(String id) { + private void initializeOptionsPage(final String id) { IErrorParserNamed errorParser = fAvailableErrorParsers.get(id); if (errorParser!=null) { String name = errorParser.getName(); @@ -229,6 +276,12 @@ public class ErrorParsTab extends AbstractCPropertyTab { if (errorParser instanceof RegexErrorParser) { // allow to edit only for Build Settings Preference Page (where cfgd==null) RegexErrorParserOptionPage optionsPage = new RegexErrorParserOptionPage((RegexErrorParser) errorParser, isErrorParsersEditable()); + optionsPage.addListener(new Listener() { + public void handleEvent(Event event) { + fTableViewer.refresh(id); + updateButtons(); + } + }); fOptionsPageMap.put(id, optionsPage); optionsPage.setContainer(page); optionsPage.createControl(fCompositeForOptionsPage); @@ -382,15 +435,25 @@ public class ErrorParsTab extends AbstractCPropertyTab { if (n < 0) return; - fTableViewer.remove(fTableViewer.getElementAt(n)); + String id = (String)fTableViewer.getElementAt(n); + if (fExtensionErrorParsers.containsKey(id)) { + // Reset + fAvailableErrorParsers.put(id, ErrorParserManager.getErrorParserExtensionCopy(id)); + fTableViewer.refresh(id); + initializeOptionsPage(id); + displaySelectedOptionPage(); + } else { + // Delete + fTableViewer.remove(id); + + int last = fTable.getItemCount() - 1; + if (n>last) + n = last; + if (n>=0) + fTable.setSelection(n); - int last = fTable.getItemCount() - 1; - if (n>last) - n = last; - if (n>=0) - fTable.setSelection(n); - - saveChecked(); + saveChecked(); + } } /* (non-Javadoc) @@ -416,6 +479,15 @@ public class ErrorParsTab extends AbstractCPropertyTab { return false; } + /** + * Check if error parser with this id shown to user differs from error parser defined as extension. + */ + private boolean isModified(String id) { + IErrorParserNamed errorParser = fAvailableErrorParsers.get(id); + IErrorParserNamed errorParserExt = fExtensionErrorParsers.get(id); + return ! errorParser.equals(errorParserExt); + } + /* (non-Javadoc) * @see org.eclipse.cdt.ui.newui.AbstractCPropertyTab#updateButtons() */ @@ -427,11 +499,17 @@ public class ErrorParsTab extends AbstractCPropertyTab { boolean selected = pos >= 0 && pos <= last; String id = (String)fTableViewer.getElementAt(pos); + boolean isExtensionId = isExtensionId(id); + boolean canDelete = !isExtensionId && isErrorParsersEditable(); + boolean canReset = isExtensionId && isErrorParsersEditable() && isModified(id); + + buttonSetText(BUTTON_DELETE, isExtensionId ? RESET_STR : DEL_STR); + buttonSetEnabled(BUTTON_ADD, isErrorParsersEditable()); buttonSetEnabled(BUTTON_EDIT, isErrorParsersEditable() && selected); - buttonSetEnabled(BUTTON_DELETE, isErrorParsersEditable() && selected && !isExtensionId(id)); - buttonSetEnabled(BUTTON_MOVEUP, selected && pos != 0); - buttonSetEnabled(BUTTON_MOVEDOWN, selected && pos != last); + buttonSetEnabled(BUTTON_DELETE, (canDelete || canReset) && selected); + buttonSetEnabled(BUTTON_MOVEUP, selected && pos!=0); + buttonSetEnabled(BUTTON_MOVEDOWN, selected && pos!=last); } @@ -471,13 +549,13 @@ public class ErrorParsTab extends AbstractCPropertyTab { if (fCfgDesc==null) { // Build Settings page try { - IErrorParserNamed[] errorParsers = new IErrorParserNamed[fTable.getItemCount()]; - int i=0; + List errorParsersList = new ArrayList(fTable.getItemCount()); for (TableItem item : fTable.getItems()) { if (item.getData() instanceof String) { String id = (String) item.getData(); - errorParsers[i] = fAvailableErrorParsers.get(id); - i++; + if (isModified(id)) { + errorParsersList.add(fAvailableErrorParsers.get(id)); + } } } @@ -485,8 +563,8 @@ public class ErrorParsTab extends AbstractCPropertyTab { String[] checkedErrorParserIds = new String[checkedElements.length]; System.arraycopy(checkedElements, 0, checkedErrorParserIds, 0, checkedElements.length); - ErrorParserManager.setUserDefinedErrorParsers(errorParsers); ErrorParserManager.setDefaultErrorParserIds(checkedErrorParserIds); + ErrorParserManager.setUserDefinedErrorParsers(errorParsersList.toArray(new IErrorParserNamed[errorParsersList.size()])); } catch (BackingStoreException e) { CUIPlugin.log(Messages.ErrorParsTab_error_OnApplyingSettings, e); } catch (CoreException e) {