/******************************************************************************* * Copyright (c) 2005, 2009 IBM Corporation 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: * IBM Corporation - initial implementation *******************************************************************************/ package org.eclipse.epf.authoring.ui.forms; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.draw2d.ColorConstants; import org.eclipse.emf.edit.provider.ComposedAdapterFactory; import org.eclipse.epf.authoring.ui.AuthoringUIHelpContexts; import org.eclipse.epf.authoring.ui.AuthoringUIImages; import org.eclipse.epf.authoring.ui.AuthoringUIPlugin; import org.eclipse.epf.authoring.ui.AuthoringUIResources; import org.eclipse.epf.authoring.ui.editors.ConfigurationEditor; import org.eclipse.epf.authoring.ui.editors.ConfigurationEditorInput; import org.eclipse.epf.authoring.ui.providers.CategoryContentProvider; import org.eclipse.epf.authoring.ui.providers.CategoryLabelProvider; import org.eclipse.epf.authoring.ui.providers.ConfigPackageContentProvider; import org.eclipse.epf.authoring.ui.providers.ConfigPackageLabelProvider; import org.eclipse.epf.authoring.ui.providers.HideUncheckedViewerFilter; import org.eclipse.epf.authoring.ui.util.AuthoringAccessibleListener; import org.eclipse.epf.authoring.ui.util.ConfigurationMarkerHelper; import org.eclipse.epf.authoring.ui.views.ConfigurationView; import org.eclipse.epf.authoring.ui.views.MethodContainerCheckedTreeViewer; import org.eclipse.epf.authoring.ui.views.MethodContainerCheckedTreeViewer2; import org.eclipse.epf.library.IConfigurationManager; import org.eclipse.epf.library.ILibraryManager; import org.eclipse.epf.library.LibraryService; import org.eclipse.epf.library.configuration.ConfigurationData; import org.eclipse.epf.library.configuration.ConfigurationHelper; import org.eclipse.epf.library.configuration.ConfigurationProperties; import org.eclipse.epf.library.configuration.closure.ClosureListener; import org.eclipse.epf.library.configuration.closure.ConfigurationClosure; import org.eclipse.epf.library.configuration.closure.IConfigurationError; import org.eclipse.epf.library.edit.IPluginUIPackageContextChangedListener; import org.eclipse.epf.library.edit.PluginUIPackageContext; import org.eclipse.epf.library.edit.TngAdapterFactory; import org.eclipse.epf.library.edit.command.IActionManager; import org.eclipse.epf.library.edit.command.MethodElementSetPropertyCommand; import org.eclipse.epf.library.edit.navigator.ConfigContentPackageItemProvider; import org.eclipse.epf.library.edit.navigator.ConfigContentPackageItemProvider.LeafElementsItemProvider; import org.eclipse.epf.library.edit.navigator.ConfigPageCategoriesItemProvider; import org.eclipse.epf.library.edit.navigator.ContentItemProvider; import org.eclipse.epf.library.edit.navigator.MethodPackagesItemProvider; import org.eclipse.epf.library.edit.ui.UserInteractionHelper; import org.eclipse.epf.library.edit.util.ConfigurationUtil; import org.eclipse.epf.library.edit.util.MethodConfigurationPropUtil; import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper; import org.eclipse.epf.library.edit.util.MethodElementUtil; import org.eclipse.epf.library.edit.util.PropUtil; import org.eclipse.epf.library.edit.util.TngUtil; import org.eclipse.epf.library.events.ILibraryChangeListener; import org.eclipse.epf.library.util.LibraryUtil; import org.eclipse.epf.ui.util.SWTUtil; import org.eclipse.epf.uma.ContentCategory; import org.eclipse.epf.uma.ContentPackage; import org.eclipse.epf.uma.CustomCategory; import org.eclipse.epf.uma.MethodConfiguration; import org.eclipse.epf.uma.MethodElement; import org.eclipse.epf.uma.MethodPackage; import org.eclipse.epf.uma.MethodPlugin; import org.eclipse.epf.uma.ProcessComponent; import org.eclipse.epf.uma.util.UmaUtil; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; 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.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.editor.FormPage; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.forms.widgets.TableWrapData; import org.eclipse.ui.forms.widgets.TableWrapLayout; import org.eclipse.ui.ide.IGotoMarker; public class ConfigurationPage extends FormPage implements IGotoMarker { // public static final String TOUCHED_BY_CONFIG_EDITOR = "TouchedByConfigEditor"; //$NON-NLS-1$ public static final String TOUCHED_BY_CONFIG_EDITOR = MethodConfigurationPropUtil.TOUCHED_BY_CONFIG_EDITOR; private String formPrefix = AuthoringUIResources.ConfigurationPage_FormPrefix; private MethodConfiguration config = null; private ConfigurationClosure closure = null; private MethodContainerCheckedTreeViewer configViewer; private ConfigPackageContentProvider contProvider; private ConfigPackageLabelProvider labelProvider; private MethodContainerCheckedTreeViewer2 addCategoryViewer; private MethodContainerCheckedTreeViewer2 subCategoryViewer; private HideUncheckedViewerFilter configViewerHideUncheckedFilter; private HideUncheckedViewerFilter addCategoryHideUncheckedFilter; private HideUncheckedViewerFilter subCategoryHideUncheckedFilter; private ComposedAdapterFactory adapterFactory = TngAdapterFactory.INSTANCE.createConfigPage_LibraryComposedAdapterFactory(); private ILibraryChangeListener libListener = null; private static final ConfigurationMarkerHelper markerHelper = ConfigurationMarkerHelper.INSTANCE; boolean isDirty = false; protected ISelection currentSelection = StructuredSelection.EMPTY; private IActionManager actionMgr; ScrolledForm form = null; private Button updateOnClick; private Button noUpdateOnClick; private Button closureButton; private Button fixWarningButton; private Button refreshButton; private Button hideButton; private Text elemDespContentText; private ConfigurationProperties configProperties; private Button hideErrorButton; private Button hideWarnButton; private Button hideInfoButton; private ShowErrorJob showErrorJob = new ShowErrorJob(AuthoringUIResources.Configuration_Problem_Refresh); //$NON-NLS-1$ protected ISelectionChangedListener treeSelectionListener = new ISelectionChangedListener() { /** * Handles the selection of an item in the tree viewer * * @param event ISelection */ public void selectionChanged(final SelectionChangedEvent event) { BusyIndicator.showWhile(ConfigurationPage.this.getSite().getShell().getDisplay(), new Runnable() { public void run() { IStructuredSelection selection= (IStructuredSelection) event.getSelection(); Object selectedElement= selection.getFirstElement(); selectedElement = TngUtil.unwrap(selectedElement); if (selectedElement == null) { return; } else if (elemDespContentText != null) { // display selected element's description String briefDesc = getConfigData().getSelectionInfo(selectedElement); elemDespContentText.setText(briefDesc != null ? briefDesc : ""); //$NON-NLS-1$ } } }); } }; private static final ClosureListener closureListener = new ClosureListener() { @Override public void errorAdded(MethodConfiguration config, IConfigurationError error) { IConfigurationManager configMgr = LibraryService.getInstance().getConfigurationManager(config); if (configMgr.getConfigurationProperties().toHide(error)) { return; } markerHelper.createMarker(config, error); } @Override public void errorRemoved(MethodConfiguration config, IConfigurationError error) { markerHelper.deleteMarker(config, error); } @Override public void errorUpdated(MethodConfiguration config, IConfigurationError error) { markerHelper.adjustMarker(null, config, error); } }; private IPluginUIPackageContextChangedListener layoutListener = new IPluginUIPackageContextChangedListener() { public void layoutChanged(boolean isFlat) { refreshViewers(); } }; /** * Creates an instance * @param editor */ public ConfigurationPage(FormEditor editor) { super(editor, AuthoringUIResources.ConfigurationPage_Description1, AuthoringUIResources.ConfigurationPage_Description2); } /** * @see org.eclipse.ui.forms.editor.FormPage#createFormContent(org.eclipse.ui.forms.IManagedForm) */ protected void createFormContent(IManagedForm managedForm) { // create form toolkit form = managedForm.getForm(); form.setText(formPrefix + config.getName()); FormToolkit toolkit = managedForm.getToolkit(); TableWrapLayout layout = new TableWrapLayout(); form.getBody().setLayout(layout); Section treeSection = toolkit.createSection(form.getBody(), Section.DESCRIPTION | Section.TWISTIE | Section.EXPANDED | Section.TITLE_BAR); treeSection.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB)); treeSection.setText(AuthoringUIResources.ConfigurationPage_ConfigContent); treeSection.setDescription(AuthoringUIResources.ConfigurationPage_ConfigContentDescription); treeSection.setLayout(new GridLayout()); createContent(toolkit, treeSection); addListeners(); // finally set the input. setInput(LibraryService.getInstance().getCurrentMethodLibrary()); initializeViewersSelection(); } /** * @see org.eclipse.ui.forms.editor.FormPage#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput) */ public void init(IEditorSite site, IEditorInput input) { setSite(site); setInput(input); ConfigurationEditorInput configInput = (ConfigurationEditorInput) input; config = configInput.getConfiguration(); actionMgr = ((ConfigurationEditor) getEditor()).getActionManager(); configProperties = LibraryService.getInstance() .getConfigurationManager(config).getConfigurationProperties(); getConfigData().setBeingEdit(true); } /** * Create tree content * @param toolkit * @param section */ public void createContent(FormToolkit toolkit, Section section) { Composite sectionClient = toolkit.createComposite(section); sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH)); section.setClient(sectionClient); GridLayout layout = new GridLayout(2, true); sectionClient.setLayout(layout); PlatformUI.getWorkbench().getHelpSystem().setHelp( sectionClient.getParent(), AuthoringUIHelpContexts.CONFIGURATION_EDITOR_ALL_CONTEXT); Composite buttonComposite = toolkit.createComposite(sectionClient); GridLayout gridLayout = new GridLayout(6, false); buttonComposite.setLayout(gridLayout); GridData gridData = new GridData(GridData.FILL_BOTH); gridData.horizontalSpan = 2; buttonComposite.setLayoutData(gridData); Composite radioComposite = toolkit.createComposite(buttonComposite); gridLayout = new GridLayout(); radioComposite.setLayout(gridLayout); gridData = new GridData(GridData.FILL_BOTH); gridData.horizontalSpan = 1; radioComposite.setLayoutData(gridData); updateOnClick = toolkit.createButton(radioComposite, AuthoringUIResources.ConfigurationPage_updateOnClick, SWT.RADIO); updateOnClick.setToolTipText(AuthoringUIResources.ConfigurationPage_updateOnClickToolTip); updateOnClick.setLayoutData(new GridData(SWT.BEGINNING, SWT.DEFAULT, false, false)); updateOnClick.getAccessible().addAccessibleListener(new AuthoringAccessibleListener( AuthoringUIResources.ConfigurationPage_updateOnClickToolTip)); updateOnClick.setSelection(configProperties.isUpdateOnClick()); noUpdateOnClick = toolkit.createButton(radioComposite, AuthoringUIResources.ConfigurationPage_noUpdateOnClick, SWT.RADIO); noUpdateOnClick.setToolTipText(AuthoringUIResources.ConfigurationPage_noUpdateOnClickToolTip); noUpdateOnClick.setLayoutData(new GridData(SWT.BEGINNING, SWT.DEFAULT, false, false)); noUpdateOnClick.getAccessible().addAccessibleListener(new AuthoringAccessibleListener( AuthoringUIResources.ConfigurationPage_noUpdateOnClickToolTip)); noUpdateOnClick.setSelection(configProperties.isNoUpdateOnClick()); Group group = new Group(buttonComposite, SWT.NONE); group.setLayout(new GridLayout(1, false)); GridData data = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); group.setLayoutData(data); group.setText(AuthoringUIResources.configProblemViewOptionsText); hideErrorButton = SWTUtil.createCheckbox(group, AuthoringUIResources.hideErrosText); hideWarnButton = SWTUtil.createCheckbox(group, AuthoringUIResources.hideWarningsText); hideInfoButton = SWTUtil.createCheckbox(group,AuthoringUIResources.hideInfosText); hideErrorButton.setSelection(configProperties.isHideErrors()); hideWarnButton.setSelection(configProperties.isHideWarnings()); hideInfoButton.setSelection(configProperties.isHideInfos()); hideButton = toolkit.createButton(buttonComposite, "", SWT.PUSH //$NON-NLS-1$ | GridData.HORIZONTAL_ALIGN_END); hideButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage( "hideUncheckedElem.gif")); //$NON-NLS-1$ hideButton.setToolTipText(AuthoringUIResources.ConfigurationPage_hideToolTip); hideButton.setLayoutData(new GridData(GridData.END)); hideButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener( AuthoringUIResources.ConfigurationPage_hideToolTip)); fixWarningButton = toolkit.createButton(buttonComposite, "", SWT.PUSH); //$NON-NLS-1$ fixWarningButton.setImage(AuthoringUIPlugin.getDefault() .getSharedImage("addref_co.gif")); //$NON-NLS-1$ fixWarningButton.setToolTipText(AuthoringUIResources.ConfigurationPage_AddMissingToolTip); fixWarningButton.setLayoutData(new GridData(GridData.END)); fixWarningButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener( AuthoringUIResources.ConfigurationPage_AddMissingToolTip)); // Add the closure button. closureButton = toolkit.createButton(buttonComposite, "", SWT.PUSH); //$NON-NLS-1$ closureButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage( "closure_co.gif")); //$NON-NLS-1$ closureButton.setToolTipText(AuthoringUIResources.ConfigurationPage_MakeClosureToolTip); closureButton.setLayoutData(new GridData(GridData.END)); closureButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener( AuthoringUIResources.ConfigurationPage_MakeClosureToolTip)); // closureButton.setText(""); refreshButton = toolkit.createButton(buttonComposite, "", SWT.PUSH); //$NON-NLS-1$ refreshButton.setImage(AuthoringUIImages.IMG_REFRESH); refreshButton.setToolTipText(AuthoringUIResources.refreshButton_text); { GridData gd = new GridData(GridData.END | GridData.HORIZONTAL_ALIGN_END); gd.horizontalAlignment = 3; gd.horizontalSpan = 1; refreshButton.setLayoutData(gd); } refreshButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener( AuthoringUIResources.refreshButton_text)); // Create Viewer and Handle Listener for the viewer. createViewers(toolkit, sectionClient); Label elemDespLabel = toolkit .createLabel(sectionClient, AuthoringUIResources.ConfigurationPage_Description); GridData gd1 = new GridData(); gd1.horizontalSpan = 6; elemDespLabel.setLayoutData(gd1); elemDespContentText = toolkit.createText(sectionClient, "", SWT.NONE //$NON-NLS-1$ | SWT.MULTI | SWT.READ_ONLY | SWT.WRAP); GridData gd2 = new GridData(GridData.FILL_BOTH); gd2.grabExcessHorizontalSpace = true; gd2.horizontalSpan = 6; gd2.heightHint = 50; toolkit.paintBordersFor(sectionClient); toolkit.paintBordersFor(buttonComposite); elemDespContentText.setLayoutData(gd2); // set text widget to viewers so they can update description field configViewer.addSelectionChangedListener(treeSelectionListener); addCategoryViewer.addSelectionChangedListener(treeSelectionListener); subCategoryViewer.addSelectionChangedListener(treeSelectionListener); hideButton.setEnabled(true); hideButton.setVisible(true); refreshButton.setEnabled(true); refreshButton.setVisible(true); fixWarningButton.setEnabled(true); fixWarningButton.setVisible(true); closureButton.setEnabled(true); closureButton.setVisible(true); } private void initializeViewersSelection() { initializeConfigFactory(); initConfigViewer(); // read from config and check the appropriate items in the CC viewers List<ContentCategory> addCats = new ArrayList<ContentCategory>(config.getAddedCategory()); initializeViewerSelection(addCategoryViewer, addCats); List<ContentCategory> subCats = new ArrayList<ContentCategory>(config.getSubtractedCategory()); initializeViewerSelection(subCategoryViewer, subCats); } private void initConfigViewer() { configViewer.setConfigData(getConfigData()); List<MethodPackage> packages = new ArrayList<MethodPackage>(config.getMethodPackageSelection()); List<MethodPlugin> plugins = new ArrayList<MethodPlugin>(config.getMethodPluginSelection()); initializeConfigViewerSelection(configViewer, packages, plugins); setStateForCategoriesUIFolder(configViewer, plugins); } /** * This method is only meant for configuration viewer since there are lot * of special cases taken care in this. * * @param viewer * @param packages * @param plugins */ private void initializeConfigViewerSelection(ContainerCheckedTreeViewer viewer, List<MethodPackage> packages, List<MethodPlugin> plugins) { boolean oldCode = ConfigContentPackageItemProvider.oldCode; // We need to do following 2 lines because viewer.setChecked doesn't // work correctly // for content packages if viewer setCheckedElements is not run before // Somehow setCheckedElements initializes something... // for process package viwer.setChecked works fine. if (oldCode) { viewer.setCheckedElements(packages.toArray()); } else { List pksWithLeafs = new ArrayList(); for (MethodPackage element : packages) { pksWithLeafs.add(element); try { Object leaf = contProvider.getLeafElementsNode(element); if (leaf != null) { pksWithLeafs.add(leaf); } } catch (Exception e) { } } viewer.setCheckedElements(pksWithLeafs.toArray()); } viewer.setCheckedElements((new ArrayList()).toArray()); if (!packages.isEmpty()) { List<LeafElementsItemProvider> uncheckedLeafs = new ArrayList<LeafElementsItemProvider>(); for (MethodPackage element : packages) { try { if (!contProvider.hasChildren(element)) { viewer.setChecked(element, true); } if (!oldCode) { // System.out.println("LD> element: " + element); LeafElementsItemProvider leaf = contProvider.getLeafElementsNode(element); if (leaf != null) { if (element instanceof ContentPackage && !getConfigData().elementsUnslected( (ContentPackage) element)) { viewer.setChecked(leaf, true); } else { uncheckedLeafs.add(leaf); } } } } catch (Exception e) { } } if (viewer instanceof MethodContainerCheckedTreeViewer) { ((MethodContainerCheckedTreeViewer) viewer).handleLeafCrayChecks(uncheckedLeafs); } } // special case for Method Content when plugin is selected but there are // no method content packages IContentProvider contProvider = viewer.getContentProvider(); if (contProvider instanceof ConfigPackageContentProvider) { ConfigPackageContentProvider configContProvider = (ConfigPackageContentProvider) contProvider; for (MethodPlugin plugin : plugins) { Object[] children = configContProvider.getChildren(plugin); traverse(viewer, children, configContProvider); } } } /** * This traverse is only called for plugins when they are included in the configuration. * This method checks special method packages UI folder if there are no method content packages and plugin is * selected. * * @param viewer * @param items * @param configContProvider */ private void traverse(ContainerCheckedTreeViewer viewer, Object[] items, ConfigPackageContentProvider configContProvider) { for (Object child: items) { Object[] children = configContProvider.getChildren(child); if (child instanceof MethodPackagesItemProvider) { // for MethodPackages if there are no content pacakges then select this UI folder too if plugin is // selected. We only call this traverse method for selected plugins, so you don't need to check again // if plugin is selected if (children.length == 0) { viewer.setChecked(child, true); } break; } if (child instanceof ContentItemProvider) { // No need to traverse other than contentItem provider traverse(viewer, children, configContProvider); } } } /** * Set state for categories UI folder. * If plugin is selected, categories UI folder should be selected. There are no methods to disable TreeItem. * We achieve similar look and feel by changing background/foreground color. * @param viewer * @param plugins */ private void setStateForCategoriesUIFolder(ContainerCheckedTreeViewer viewer, List<MethodPlugin>plugins) { for (MethodPlugin plugin : plugins) { // if plugin is selected then select categories folder as well if (viewer.getGrayed(plugin)) { try { Object[] children = contProvider.getChildren(plugin); for (Object child : children) { if (child instanceof ConfigPageCategoriesItemProvider){ viewer.setChecked(child, true); } } } catch (Exception e) { } } // make categories folder enabled/disbled. Tree t = viewer.getTree(); TreeItem[] items = t.getItems(); for (TreeItem parent : items) { if (parent.getData().equals(plugin)) { TreeItem[] childItems = parent.getItems(); for (TreeItem child : childItems) { if (child.getData() instanceof ConfigPageCategoriesItemProvider) { if (viewer.getChecked(plugin)) child.setForeground(ColorConstants.gray); else child.setForeground(ColorConstants.black); } } } } } } private void initializeViewerSelection(ContainerCheckedTreeViewer viewer, List<? extends Object> elements) { if (!elements.isEmpty()) viewer.setCheckedElements(elements.toArray()); } private void createViewers(FormToolkit toolkit, Composite sectionClient) { Composite configViewerLabelComposite = toolkit.createComposite(sectionClient); GridData gd = new GridData(SWT.FILL, SWT.END, true, false); configViewerLabelComposite.setLayoutData(gd); gd.horizontalSpan = 1; configViewerLabelComposite.setLayout(new GridLayout(3, false)); Composite addCatsViewerLabelComposite = toolkit.createComposite(sectionClient); gd = new GridData(SWT.FILL, SWT.END, true, false); addCatsViewerLabelComposite.setLayoutData(gd); gd.horizontalSpan = 1; addCatsViewerLabelComposite.setLayout(new GridLayout(3, false)); // create the library tree viewer configViewer = new MethodContainerCheckedTreeViewer(sectionClient); gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL); gd.heightHint = 200; gd.verticalSpan = 3; configViewer.getTree().setLayoutData(gd); contProvider = new ConfigPackageContentProvider(adapterFactory); configViewer.setContentProvider(contProvider); labelProvider = new ConfigPackageLabelProvider(contProvider); configViewer.setLabelProvider(labelProvider); createViewerLabelAndButtons(toolkit, configViewerLabelComposite, AuthoringUIResources.ConfigurationPage_TreeTitleLabel, configViewer); addCategoryViewer = new MethodContainerCheckedTreeViewer2(sectionClient); gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL); gd.heightHint= 200; addCategoryViewer.getTree().setLayoutData(gd); addCategoryViewer.setContentProvider(new CategoryContentProvider(adapterFactory, config)); addCategoryViewer.setLabelProvider(new CategoryLabelProvider(adapterFactory)); createViewerLabelAndButtons(toolkit, addCatsViewerLabelComposite, AuthoringUIResources.ConfigurationPage_AddCategoriesTitleLabel, addCategoryViewer); Composite subCatsViewerLabelComposite = toolkit.createComposite(sectionClient); gd = new GridData(SWT.FILL, SWT.END, true, false); subCatsViewerLabelComposite.setLayoutData(gd); gd.horizontalSpan = 1; subCatsViewerLabelComposite.setLayout(new GridLayout(3, false)); subCategoryViewer = new MethodContainerCheckedTreeViewer2(sectionClient); gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL); gd.heightHint= 200; subCategoryViewer.getTree().setLayoutData(gd); subCategoryViewer.setContentProvider(new CategoryContentProvider(adapterFactory, config)); subCategoryViewer.setLabelProvider(new CategoryLabelProvider(adapterFactory)); createViewerLabelAndButtons(toolkit, subCatsViewerLabelComposite, AuthoringUIResources.ConfigurationPage_SubCategoriesTitleLabel, subCategoryViewer); // add listener so the 2 Category viewers are in sync // that is, when an item is checked in one, it is unchecked in the other addCategoryViewer.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(final CheckStateChangedEvent event) { //Potentially long operation - show a busy cursor BusyIndicator.showWhile(subCategoryViewer.getTree().getDisplay(), new Runnable() { public void run() { if (event.getChecked()) subCategoryViewer.setChecked(event.getElement(), false); } }); } }); subCategoryViewer.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(final CheckStateChangedEvent event) { //Potentially long operation - show a busy cursor BusyIndicator.showWhile(addCategoryViewer.getTree().getDisplay(), new Runnable() { public void run() { if (event.getChecked()) addCategoryViewer.setChecked(event.getElement(), false); } }); } }); } private void createViewerLabelAndButtons(FormToolkit toolkit, Composite parent, String text, final TreeViewer viewer) { Label label = toolkit.createLabel(parent, text); GridData gd = new GridData(SWT.FILL, SWT.END, true, false); label.setLayoutData(gd); Button expandButton = toolkit.createButton(parent, null, SWT.PUSH); gd = new GridData(SWT.RIGHT, SWT.END, false, false); expandButton.setLayoutData(gd); expandButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage("expandall.gif")); //$NON-NLS-1$ expandButton.setToolTipText(AuthoringUIResources.FilterDialog_ExpandAll); expandButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener( AuthoringUIResources.FilterDialog_ExpandAll)); expandButton.addSelectionListener(new SelectionListener(){ public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } public void widgetSelected(SelectionEvent e) { viewer.expandAll(); } }); Button collapseButton = toolkit.createButton(parent, null, SWT.PUSH); gd = new GridData(SWT.RIGHT, SWT.END, false, false); collapseButton.setLayoutData(gd); collapseButton.setImage(AuthoringUIPlugin.getDefault().getSharedImage("collapseall.gif")); //$NON-NLS-1$ collapseButton.setToolTipText(AuthoringUIResources.FilterDialog_CollapseAll); collapseButton.getAccessible().addAccessibleListener(new AuthoringAccessibleListener( AuthoringUIResources.FilterDialog_CollapseAll)); collapseButton.addSelectionListener(new SelectionListener(){ public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } public void widgetSelected(SelectionEvent e) { viewer.collapseAll(); } }); } private void reInitializeConfigFactory() { // the following may not be the most efficient way // need a fast way to update the closure // System.out.println("$$$ reInit closure for config add notification!"); createConfigurationClosure(); } private void createConfigurationClosure() { closure = new ConfigurationClosure(actionMgr, config); closure.addListener(closureListener); if (labelProvider != null) { labelProvider.setClosure(closure); } } /** * Set input for connfiguration viewer * @param input */ private void setInput(Object input) { configViewer.setInput(input); addCategoryViewer.setInput(input); subCategoryViewer.setInput(input); configViewer.expandAll(); configViewer.collapseAll(); addCategoryViewer.expandAll(); addCategoryViewer.collapseAll(); subCategoryViewer.expandAll(); subCategoryViewer.collapseAll(); // updateCheckStates(); } private void refreshViewers() { configViewer.refresh(); addCategoryViewer.refresh(); subCategoryViewer.refresh(); } protected void showHideElements() { configViewerHideUncheckedFilter.toggleHideUnchecked(); addCategoryHideUncheckedFilter.toggleHideUnchecked(); subCategoryHideUncheckedFilter.toggleHideUnchecked(); refreshViewers(); // updateCheckStates(); // neded to have this to update the check status } /** * Initialize configuration factory */ public void initializeConfigFactory() { // loading the configuration closure might be slow, // display a progress bar org.eclipse.epf.library.edit.util.IRunnableWithProgress runnable = new org.eclipse.epf.library.edit.util.IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { createConfigurationClosure(); } }; UserInteractionHelper.runWithProgress(runnable, AuthoringUIResources.ConfigurationPage_LoadingMessage); configViewerHideUncheckedFilter = new HideUncheckedViewerFilter(configViewer); configViewer.addFilter(configViewerHideUncheckedFilter); addCategoryHideUncheckedFilter = new HideUncheckedViewerFilter(addCategoryViewer); addCategoryViewer.addFilter(addCategoryHideUncheckedFilter); subCategoryHideUncheckedFilter = new HideUncheckedViewerFilter(subCategoryViewer); subCategoryViewer.addFilter(subCategoryHideUncheckedFilter); } private void addListeners() { updateOnClick.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleButtonWidgetSelected(e, MethodElementPropertyHelper.CONFIG_UPDATE_ON_CLICK); } }); noUpdateOnClick.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleButtonWidgetSelected(e, MethodElementPropertyHelper.CONFIG_NO_UPDATE_ON_CLICK); } }); hideErrorButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleButtonWidgetSelected(e, MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_ERRORS); } }); hideWarnButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleButtonWidgetSelected(e, MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_WARNINGS); } }); hideInfoButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleButtonWidgetSelected(e, MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_INFOS); } }); closureButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { BusyIndicator.showWhile(form.getDisplay(), new Runnable() { public void run() { makeClosure(); } }); }; }); fixWarningButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { BusyIndicator.showWhile(form.getDisplay(), new Runnable() { public void run() { fixWarning(); } }); }; }); refreshButton.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { BusyIndicator.showWhile(form.getDisplay(), new Runnable() { public void run() { // Comment out the following "saveConfiguration()" which was added at version 1.3 // - not sure why. So leave the commented out trace here for easy future reference. // saveConfiguration(); showErrors(); } }); } public void widgetDefaultSelected(SelectionEvent e) { } }); hideButton.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { showHideElements(); } public void widgetDefaultSelected(SelectionEvent e) { } }); // add a check state change listener ICheckStateListener configCheckStateListener = new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent evt) { BusyIndicator.showWhile(form.getDisplay(), new Runnable() { public void run() { collapseConfigView(); // save configurtion saveConfiguration(); if (updateOnClick.getSelection()) { // update the closure error showErrors(); } actionMgr.execute(new MethodElementSetPropertyCommand(config, TOUCHED_BY_CONFIG_EDITOR, Boolean.TRUE.toString())); } }); } }; ICheckStateListener catsCheckStateListener = new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent event) { BusyIndicator.showWhile(form.getDisplay(), new Runnable() { public void run() { collapseConfigView(); saveContentCategorySelectionsToConfiguration(); if (updateOnClick.getSelection()) { // update the closure error showErrors(); } } }); } }; configViewer.addCheckStateListener(configCheckStateListener); addCategoryViewer.addCheckStateListener(catsCheckStateListener); subCategoryViewer.addCheckStateListener(catsCheckStateListener); // listen to the library changes and automatically update the // configuration view libListener = new ILibraryChangeListener() { public void libraryChanged(int option, Collection<Object> changedItems) { // for performance reason, we should not response to every // library change // only cover package and plugin changes if (option == ILibraryChangeListener.OPTION_DELETED || option == ILibraryChangeListener.OPTION_NEWCHILD || option == ILibraryChangeListener.OPTION_NEWCHILD) { if (changedItems != null && changedItems.size() > 0) { Object o = changedItems.toArray()[0]; if (o instanceof MethodPlugin || o instanceof ProcessComponent || o instanceof MethodPackage || o instanceof CustomCategory) { reInitializeConfigFactory(); refreshViewers(); // updateCheckStates(); showErrors(); } } } } }; ILibraryManager manager = LibraryService.getInstance().getCurrentLibraryManager(); if (manager != null) { manager.addListener(libListener); } // listen to plugin presentation layout changes PluginUIPackageContext.INSTANCE.addListener(layoutListener); } private void collapseConfigView() { collapseConfigView(config); } public static void collapseConfigView(MethodConfiguration config) { final ConfigurationView configView = ConfigurationView.getView(); if (configView == null) { return; } if (! config.getName().equals(configView.getCurrentConfig())) { return; } PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { public void run() { if (configView.getViewer() instanceof TreeViewer) { ((TreeViewer) configView.getViewer()).collapseAll(); } } }); } class ShowErrorJob extends Job { public ShowErrorJob(String name) { super(name); } @Override protected IStatus run(IProgressMonitor monitor) { List<Object> invalid0 = null; List<Object> updateInvalid0 = null; try { canDisposeClosure = false; closure.setAbortCheckError(false); // save the previous invalid elements // final List<Object> invalid = closure.getInvalidElements(); invalid0 = closure.getInvalidElements(); closure.checkError(); if (closure.isAbortCheckError()) { return Status.OK_STATUS; } updateInvalid0 = closure.getInvalidElements(); } finally { canDisposeClosure = true; if (disposed) { closure.dispose(); } } final List<Object> invalid = invalid0; final List<Object> updateInvalid = updateInvalid0; PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { if (configViewerHideUncheckedFilter.isHideUnchecked()) { configViewer.refresh(); } else { // get the new error elements, add to the previous error elements, // and update them to update the error/warning images // invalid.addAll(closure.getInvalidElements()); invalid.addAll(updateInvalid); // also add the UI folders ConfigPackageContentProvider cp = (ConfigPackageContentProvider) configViewer .getContentProvider(); invalid.addAll(cp.getUIElements()); configViewer.update(invalid.toArray(), null); } } }); return Status.OK_STATUS; } } public void showErrorsOnSave() { if (updateOnClick != null && ! updateOnClick.getSelection()) { showErrors(); } } private void showErrors() { if (closure == null || closure.isAbortCheckError()) { return; } closure.setAbortCheckError(true); showErrorJob.cancel(); showErrorJob.schedule(); } //old code for showErrors method protected void showErrors_old() { // save the previous invalid elements List<Object> invalid = closure.getInvalidElements(); closure.checkError(); if (configViewerHideUncheckedFilter.isHideUnchecked()) { configViewer.refresh(); } else { // get the new error elements, add to the previous error elements, // and update them to update the error/warning images invalid.addAll(closure.getInvalidElements()); // also add the UI folders ConfigPackageContentProvider cp = (ConfigPackageContentProvider) configViewer .getContentProvider(); invalid.addAll(cp.getUIElements()); configViewer.update(invalid.toArray(), null); } } /** * Make configuration closure * */ protected void makeClosure() { if (! ConfigurationHelper.getDelegate().makeClosure(config)) { closure.fixErrors(); } configViewer.refresh(); initConfigViewer(); //refreshViewers(); // updateCheckStates(); //saveConfiguration(); } /** * Fix all warnings */ protected void fixWarning() { if (! ConfigurationHelper.getDelegate().makeClosure(config)) { closure.fixProblems(); } configViewer.refresh(); initConfigViewer(); //refreshViewers(); // updateCheckStates(); //saveConfiguration(); } private ConfigurationData getConfigData() { ConfigurationData configData = LibraryService.getInstance() .getConfigurationManager(config) .getConfigurationData(); return configData; } /** * Save configuration * @return * True if configuration is save successfully, false otherwise */ public boolean saveConfiguration() { getConfigData().setEnableUpdate(false); boolean ret = doSaveConfiguration(); getConfigData().setEnableUpdate(true); return ret; } private boolean doSaveConfiguration() { boolean oldNotify = config.eDeliver(); try { List<MethodPackage> oldPackages = new ArrayList<MethodPackage>(config.getMethodPackageSelection()); List<MethodPlugin> oldPlugins = new ArrayList<MethodPlugin>(config.getMethodPluginSelection()); Set<MethodPackage> newPackages = getCheckedMethodPackages(configViewer.getCheckedElements()); Set<MethodPlugin> newPlugins = getCheckedMethodPlugins(configViewer.getCheckedElements()); Set<MethodPackage> elementsUnslectedPkgs = configViewer.getElementsUnslectedPkgs(newPackages, contProvider); // set categories checked for plugins selected List<MethodPlugin> plugins = new ArrayList<MethodPlugin>(); plugins.addAll(newPlugins); plugins.addAll(oldPlugins); setStateForCategoriesUIFolder(configViewer, plugins); oldPackages.removeAll(newPackages); oldPlugins.removeAll(newPlugins); newPackages.removeAll(config.getMethodPackageSelection()); newPlugins.removeAll(config.getMethodPluginSelection()); if (ConfigurationUtil.removeCollFromMethodPluginList(actionMgr, config, oldPlugins) == false) return false; if (ConfigurationUtil.removeCollFromMethodPackageList(actionMgr, config, oldPackages) == false) return false; if (ConfigurationUtil.addCollToMethodPluginList(actionMgr, config, newPlugins) == false) return false; if (ConfigurationUtil.addCollToMethodPackageList(actionMgr, config, newPackages) == false) return false; getConfigData().updatePackageSelections(actionMgr, elementsUnslectedPkgs, oldPackages, newPackages); // validate before save LibraryUtil.validateMethodConfiguration(actionMgr, config); actionMgr.execute(new MethodElementSetPropertyCommand(config, TOUCHED_BY_CONFIG_EDITOR, Boolean.TRUE.toString())); setDoneLoadCheckPkgs(); return true; } finally { config.eSetDeliver(oldNotify); } } private void setDoneLoadCheckPkgs() { Set<MethodPackage> doneLoadCheckPkgs = new HashSet<MethodPackage>(); for (MethodPlugin plugin : config.getMethodPluginSelection()) { collectDoneLoadCheckPkgs(plugin.getMethodPackages(), doneLoadCheckPkgs); } MethodConfigurationPropUtil propUtil = MethodConfigurationPropUtil.getMethodConfigurationPropUtil(actionMgr); propUtil.setDoneLoadCheckPkgs(config, doneLoadCheckPkgs); } private void collectDoneLoadCheckPkgs(List<MethodPackage> pkgs, Set<MethodPackage> doneLoadCheckPkgs) { PropUtil propUtil = PropUtil.getPropUtil(); for (MethodPackage pkg : pkgs) { Boolean b = propUtil.getBooleanValue(pkg, PropUtil.Pkg_loadCheck); if (b != null && b.booleanValue()) { doneLoadCheckPkgs.add(pkg); } collectDoneLoadCheckPkgs(pkg.getChildPackages(), doneLoadCheckPkgs); } } /** * Save configuration * @return * True if configuration is save successfully, false otherwise */ public boolean saveContentCategorySelectionsToConfiguration() { List<ContentCategory> oldAddCats = new ArrayList<ContentCategory>(config.getAddedCategory()); List<ContentCategory> oldSubCats = new ArrayList<ContentCategory>(config.getSubtractedCategory()); Set<ContentCategory> newAddCats = getCheckedContentCategories(addCategoryViewer.getCheckButNotGrayedElements()); Set<ContentCategory> newSubCats = getCheckedContentCategories(subCategoryViewer.getCheckButNotGrayedElements()); oldAddCats.removeAll(newAddCats); oldSubCats.removeAll(newSubCats); newAddCats.removeAll(config.getAddedCategory()); newSubCats.removeAll(config.getSubtractedCategory()); if (ConfigurationUtil.removeCollFromAddedCategoryList(actionMgr, config, oldAddCats) == false) return false; if (!newAddCats.isEmpty()) { if (ConfigurationUtil.addCollToAddedCategoryList(actionMgr, config, newAddCats) == false) return false; Map<String, MethodElement> pluginMap = MethodElementUtil.buildMap(config.getMethodPluginSelection()); HashSet<MethodPlugin> newAddedPlugins = new HashSet<MethodPlugin>(); for (Iterator<ContentCategory> it = newAddCats.iterator(); it.hasNext(); ) { ContentCategory cat = it.next(); MethodPlugin plugin = UmaUtil.getMethodPlugin(cat); if (! pluginMap.containsKey(plugin.getGuid())) { if (! newAddedPlugins.contains(plugin)) { newAddedPlugins.add(plugin); } } } if (! newAddedPlugins.isEmpty()) { if (ConfigurationUtil.addCollToMethodPluginList(actionMgr, config, newAddedPlugins) == false) return false; LibraryUtil.validateMethodConfiguration(actionMgr, config); } } if (ConfigurationUtil.removeCollFromSubtractedCategoryList(actionMgr, config, oldSubCats) == false) return false; if (ConfigurationUtil.addCollToSubtractedCategoryList(actionMgr, config, newSubCats) == false) return false; actionMgr.execute(new MethodElementSetPropertyCommand(config, TOUCHED_BY_CONFIG_EDITOR, Boolean.TRUE.toString())); return true; } protected Set<ContentCategory> getCheckedContentCategories(Object[] checkedItems) { Set<ContentCategory> result = new HashSet<ContentCategory>(); for (int i = 0; i < checkedItems.length; i++) { Object item = TngUtil.unwrap(checkedItems[i]); if (item instanceof ContentCategory) { // if (config.getMethodPluginSelection().contains(LibraryUtil.getMethodPlugin((ContentCategory)item))) { result.add((ContentCategory)item); // } } } return result; } protected Set<MethodPackage> getCheckedMethodPackages(Object[] checkedItems) { Set<MethodPackage> result = new HashSet<MethodPackage>(); for (int i = 0; i < checkedItems.length; i++) { Object item = TngUtil.unwrap(checkedItems[i]); if (item instanceof MethodPackage) { result.add((MethodPackage)item); } } return result; } protected Set<MethodPlugin> getCheckedMethodPlugins(Object[] checkedItems) { Set<MethodPlugin> result = new HashSet<MethodPlugin>(); for (int i = 0; i < checkedItems.length; i++) { Object item = TngUtil.unwrap(checkedItems[i]); if (item instanceof MethodPlugin) { result.add((MethodPlugin)item); } } return result; } private boolean disposed = false; private boolean canDisposeClosure = true; public void dispose() { disposed = true; super.dispose(); getConfigData().setBeingEdit(false, getEditor().isDirty()); if (libListener != null) { ILibraryManager manager = LibraryService.getInstance().getCurrentLibraryManager(); if (manager != null) { manager.removeListener(libListener); } } if (layoutListener != null) { PluginUIPackageContext.INSTANCE.removeListener(layoutListener); } if (closure != null) { if (canDisposeClosure) { closure.dispose(); closure = null; } } if (adapterFactory != null) { adapterFactory.dispose(); adapterFactory = null; } markerHelper.removeAllMarkers(config); } public void gotoMarker(IMarker marker) { // select problem in main viewer MethodElement e = ConfigurationMarkerHelper.INSTANCE.getErrorMethodElement(marker); if (e != null && configViewer != null) { configViewer.setSelection(new StructuredSelection(LibraryUtil.getSelectable(e)), true); } } public void doQuickFix(IMarker marker) { if ( marker == null ) { return; } MethodElement element = markerHelper.getCauseMethodElement(marker); if ( element == null ) { return; } if ( closure.getConfigurationManager().getConfigurationData().isElementSubtracted(element)) { String message = AuthoringUIResources.bind( AuthoringUIResources.configurationPage_QuickfixError_reason1, (new String[] {LibraryUtil.getTypeName(element)})); AuthoringUIPlugin.getDefault().getMsgDialog() .displayWarning( AuthoringUIResources.configurationPage_quickfixError_title, message); return; } Object owner = LibraryUtil.getSelectable(element); configViewer.setChecked(owner, true); saveConfiguration(); showErrors(); } private void handleButtonWidgetSelected(SelectionEvent e, String key) { Object obj = e.getSource(); if (obj instanceof Button) { Button button = (Button) obj; String value = button.getSelection() ? Boolean.TRUE.toString() : Boolean.FALSE.toString(); actionMgr.execute(new MethodElementSetPropertyCommand(config, key, value)); } } }