/******************************************************************************* * Copyright (c) 2004, 2010 BREDEX GmbH. * 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: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.client.ui.rcp.properties; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.EntityNotFoundException; import org.apache.commons.lang.StringUtils; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.window.Window; import org.eclipse.jubula.client.core.businessprocess.ProjectNameBP; import org.eclipse.jubula.client.core.events.DataChangedEvent; import org.eclipse.jubula.client.core.events.DataEventDispatcher; import org.eclipse.jubula.client.core.events.DataEventDispatcher.DataState; import org.eclipse.jubula.client.core.events.DataEventDispatcher.ProjectState; import org.eclipse.jubula.client.core.events.DataEventDispatcher.UpdateState; import org.eclipse.jubula.client.core.model.INodePO; import org.eclipse.jubula.client.core.model.IPersistentObject; import org.eclipse.jubula.client.core.model.IProjectPO; import org.eclipse.jubula.client.core.model.IProjectPropertiesPO; import org.eclipse.jubula.client.core.model.IReusedProjectPO; import org.eclipse.jubula.client.core.model.PoMaker; import org.eclipse.jubula.client.core.persistence.EditSupport; import org.eclipse.jubula.client.core.persistence.GeneralStorage; import org.eclipse.jubula.client.core.persistence.NodePM; import org.eclipse.jubula.client.core.persistence.PMException; import org.eclipse.jubula.client.core.persistence.ProjectPM; import org.eclipse.jubula.client.core.utils.TrackingUnit; import org.eclipse.jubula.client.ui.constants.ContextHelpIds; import org.eclipse.jubula.client.ui.rcp.Plugin; import org.eclipse.jubula.client.ui.rcp.businessprocess.CompletenessBP; import org.eclipse.jubula.client.ui.rcp.controllers.PMExceptionHandler; import org.eclipse.jubula.client.ui.rcp.factory.ControlFactory; import org.eclipse.jubula.client.ui.rcp.handlers.project.RefreshProjectHandler; import org.eclipse.jubula.client.ui.rcp.i18n.Messages; import org.eclipse.jubula.client.ui.rcp.provider.ControlDecorator; import org.eclipse.jubula.client.ui.rcp.search.query.DeprecatedModulesQuery; import org.eclipse.jubula.client.ui.rcp.widgets.CheckedIntText; import org.eclipse.jubula.client.ui.rcp.widgets.CheckedProjectNameText; import org.eclipse.jubula.client.ui.rcp.widgets.CheckedSignatureText; import org.eclipse.jubula.client.ui.rcp.widgets.CheckedText; import org.eclipse.jubula.client.ui.utils.ErrorHandlingUtil; import org.eclipse.jubula.client.ui.utils.LayoutUtil; import org.eclipse.jubula.client.ui.widgets.DirectCombo; import org.eclipse.jubula.client.ui.widgets.UIComponentHelper; import org.eclipse.jubula.tools.internal.constants.StringConstants; import org.eclipse.jubula.tools.internal.exception.Assert; import org.eclipse.jubula.tools.internal.exception.JBException; import org.eclipse.jubula.tools.internal.exception.ProjectDeletedException; import org.eclipse.jubula.tools.internal.i18n.I18n; import org.eclipse.jubula.tools.internal.messagehandling.MessageIDs; import org.eclipse.jubula.tools.internal.utils.EnvironmentUtils; import org.eclipse.search.ui.NewSearchUI; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; 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.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This is the class for the test data property page of a project. * * @author BREDEX GmbH * @created 08.02.2005 */ public class ProjectGeneralPropertyPage extends AbstractProjectPropertyPage { /** * @author BREDEX GmbH * @created Aug 21, 2007 */ public interface IOkListener { /** * The OK button has been pressed. */ public void okPressed() throws PMException; } /** number of columns = 1 */ private static final int NUM_COLUMNS_1 = 1; /** number of columns = 2 */ private static final int NUM_COLUMNS_2 = 2; /** number of columns = 2 */ private static final int NUM_COLUMNS_3 = 3; /** the logger */ private static Logger log = LoggerFactory .getLogger(ProjectGeneralPropertyPage.class); /** the m_text field for the project name */ private CheckedText m_projectNameTextField; /** the m_isReusable checkbox for if the project is reusable */ private Button m_isReusableCheckbox; /** the m_isProtected checkbox for if the project is protected */ private Button m_isProtectedCheckbox; /** the StateController */ private final WidgetModifyListener m_modifyListener = new WidgetModifyListener(); /** the StateController */ private final ToolkitComboSelectionListener m_toolkitComboListener = new ToolkitComboSelectionListener(); /** the Combo to select the toolkit */ private DirectCombo<String> m_projectToolkitCombo; /** the StateController for the markup combo */ private final MarkupComboSelectionListener m_markupComboListener = new MarkupComboSelectionListener(); /** the combo to select the MarkupLanguate */ private DirectCombo<String> m_projectMarkupCombo; /** the new project name */ private String m_newProjectName; /** Checkbox to decide if testresults should be deleted after specified days */ private Button m_cleanTestresults = null; /** textfield to specify days after which testresults should be deleted after from database */ private CheckedIntText m_cleanResultDays = null; /** Checkbox to decide if certain changes to the project should be tracked */ private Button m_isTrackingActivatedButton = null; /** group to specify how long changes should be stored */ private Group m_trackChangesTimespanSelection = null; /** textfield to specify how long tracked changes should be stored */ private CheckedIntText m_trackChangesSpan = null; /** textfield to specify what should be stored to identify who made a change */ private Composite m_trackChangesUnitSelection = null; /** group to specify what should be stored to identify who made a change */ private Group m_trackChangesSignatureSelection = null; /** textfield to specify what should be stored to identify who made a change */ private CheckedSignatureText m_trackChangesSignature = null; /** button to delete all tracked changes */ private Button m_deleteChanges = null; /** set of listeners to be informed when ok has been pressed */ private Set<IOkListener> m_okListenerList = new HashSet<IOkListener>(); /** * the projects description text field */ private Text m_projectDescriptionTextField; /** * the original / unmodified project properties */ private IProjectPropertiesPO m_origProjectProps; /** * the old project name */ private String m_oldProjectName; /** * @param es * the editSupport */ public ProjectGeneralPropertyPage(EditSupport es) { super(es); m_oldProjectName = getProject().getName(); m_origProjectProps = ((IProjectPropertiesPO) es.getOriginal()); } /** * {@inheritDoc} */ protected Control createContents(Composite parent) { Composite composite = createComposite(parent, NUM_COLUMNS_1, GridData.FILL, false); Composite projectNameComposite = createComposite(composite, NUM_COLUMNS_2, GridData.FILL, false); noDefaultAndApplyButton(); createEmptyLabel(projectNameComposite); createEmptyLabel(projectNameComposite); createProjectNameField(projectNameComposite); createProjectDescrField(projectNameComposite); createProjectVersionInfo(projectNameComposite); createProjectGuidInfo(projectNameComposite); createEmptyLabel(projectNameComposite); separator(projectNameComposite, NUM_COLUMNS_2); createEmptyLabel(projectNameComposite); createAutToolKit(projectNameComposite); createMarkupLanguage(projectNameComposite); separator(projectNameComposite, NUM_COLUMNS_2); createEmptyLabel(projectNameComposite); createIsReusable(projectNameComposite); createIsProtected(projectNameComposite); separator(projectNameComposite, NUM_COLUMNS_2); createEmptyLabel(projectNameComposite); createCleanTestResults(projectNameComposite); separator(projectNameComposite, NUM_COLUMNS_2); createTrackChangesEnablement(projectNameComposite); Composite trackChangesProperties = createComposite(composite, NUM_COLUMNS_3, GridData.FILL, false); createTrackChangesTimespanSelection(trackChangesProperties); createTrackChangesSignatureSelection(trackChangesProperties); createTrackChangesDeleteDataButton(trackChangesProperties); Composite innerComposite = new Composite(composite, SWT.NONE); GridLayout compositeLayout = new GridLayout(); compositeLayout.numColumns = NUM_COLUMNS_1; compositeLayout.marginHeight = 0; compositeLayout.marginWidth = 0; innerComposite.setLayout(compositeLayout); GridData compositeData = new GridData(); compositeData.horizontalSpan = NUM_COLUMNS_2; compositeData.horizontalAlignment = GridData.FILL; compositeData.grabExcessHorizontalSpace = true; innerComposite.setLayoutData(compositeData); addListener(); Plugin.getHelpSystem().setHelp(parent, ContextHelpIds.PROJECT_PROPERTY_PAGE); return composite; } /** * @param parent the parent composite */ private void createProjectVersionInfo(Composite parent) { Composite leftComposite = createComposite(parent, NUM_COLUMNS_1, GridData.BEGINNING, false); Composite rightComposite = createComposite(parent, 3, GridData.FILL, true); createLabel(leftComposite, Messages.ProjectPropertyPageProjectVersion); Text versionText = new Text(rightComposite, SWT.WRAP); GridData labelGrid = new GridData(GridData.FILL, GridData.CENTER, true, false, 1, 1); labelGrid.widthHint = 124; versionText.setLayoutData(labelGrid); versionText.setText(getProject().getVersionString()); versionText.setEditable(false); versionText.setBackground(rightComposite.getBackground()); } /** * @param parent the parent composite */ private void createProjectGuidInfo(Composite parent) { Composite leftComposite = createComposite(parent, NUM_COLUMNS_1, GridData.BEGINNING, false); Composite rightComposite = createComposite(parent, 3, GridData.FILL, true); ControlDecorator.createInfo(createLabel(leftComposite, Messages.ProjectPropertyPageProjectGuid), I18n.getString("ControlDecorator.ProjectPropertiesGUID"), false); //$NON-NLS-1$ Text guidText = new Text(rightComposite, SWT.WRAP); GridData labelGrid = new GridData(GridData.FILL, GridData.CENTER, true, false, 1, 1); labelGrid.widthHint = 124; guidText.setLayoutData(labelGrid); guidText.setText(getProject().getGuid()); guidText.setEditable(false); guidText.setBackground(rightComposite.getBackground()); } /** * @param parent * the parent composite */ private void createIsReusable(Composite parent) { Composite leftComposite = createComposite(parent, NUM_COLUMNS_1, GridData.BEGINNING, false); Composite rightComposite = createComposite(parent, NUM_COLUMNS_2, GridData.FILL, true); ControlDecorator.createInfo(createLabel(leftComposite, Messages.ProjectPropertyPageIsReusable), I18n.getString("ControlDecorator.NewProjectIsReusable"), false); //$NON-NLS-1$ m_isReusableCheckbox = new Button(rightComposite, SWT.CHECK); m_isReusableCheckbox.setSelection(m_origProjectProps.getIsReusable()); m_isReusableCheckbox.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { boolean isReusable = m_isReusableCheckbox.getSelection(); if (isReusable) { m_isProtectedCheckbox.setSelection(true); } } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); } /** * @param parent * the parent composite */ private void createIsProtected(Composite parent) { Composite leftComposite = createComposite(parent, NUM_COLUMNS_1, GridData.BEGINNING, false); Composite rightComposite = createComposite(parent, NUM_COLUMNS_2, GridData.FILL, true); ControlDecorator.createInfo(createLabel(leftComposite, Messages.ProjectPropertyPageIsProtected), I18n.getString("ControlDecorator.NewProjectIsProtected"), //$NON-NLS-1$ false); m_isProtectedCheckbox = new Button(rightComposite, SWT.CHECK); m_isProtectedCheckbox.setSelection(m_origProjectProps.getIsProtected()); } /** * Creates the textfield for the project name. * * @param parent * The parent composite. */ private void createProjectNameField(Composite parent) { Composite leftComposite = createComposite(parent, NUM_COLUMNS_1, GridData.BEGINNING, false); Composite rightComposite = createComposite(parent, NUM_COLUMNS_1, GridData.FILL, true); createLabel(leftComposite, Messages.ProjectPropertyPageProjectName); m_projectNameTextField = new CheckedProjectNameText(rightComposite, SWT.BORDER); m_projectNameTextField.setText(getProject().getName()); GridData textGridData = new GridData(); textGridData.grabExcessHorizontalSpace = true; textGridData.horizontalAlignment = GridData.FILL; LayoutUtil.addToolTipAndMaxWidth(textGridData, m_projectNameTextField); m_projectNameTextField.setLayoutData(textGridData); LayoutUtil.setMaxChar(m_projectNameTextField); } /** * Creates the textfield for the project description. * * @param parent * The parent composite. */ private void createProjectDescrField(Composite parent) { Composite leftComposite = createComposite(parent, NUM_COLUMNS_1, GridData.BEGINNING, false); Composite rightComposite = createComposite(parent, NUM_COLUMNS_1, GridData.FILL, true); createLabel(leftComposite, Messages.ProjectPropertyPageProjectDescr); m_projectDescriptionTextField = new Text(rightComposite, SWT.BORDER); m_projectDescriptionTextField.setText(StringUtils .defaultString(getProject().getComment())); GridData textGridData = new GridData(); textGridData.grabExcessHorizontalSpace = true; textGridData.horizontalAlignment = GridData.FILL; LayoutUtil.addToolTipAndMaxWidth( textGridData, m_projectDescriptionTextField); m_projectDescriptionTextField.setLayoutData(textGridData); LayoutUtil.setMaxChar(m_projectDescriptionTextField, IPersistentObject.MAX_STRING_LENGTH); } /** * @param parent the parent composite */ private void createMarkupLanguage(Composite parent) { Composite leftComposite = createComposite(parent, NUM_COLUMNS_1, GridData.BEGINNING, false); Composite rightComposite = createComposite(parent, NUM_COLUMNS_2, GridData.FILL, true); Label label = createLabel(leftComposite, Messages.ProjectPropertyPageMarkupLanguageLabel); ControlDecorator.createInfo(label, Messages.ProjectPropertyPageMarkupLanguageInfo, false); m_projectMarkupCombo = ControlFactory .createProjectMarkupLanguageCombo(rightComposite); GridData textGridData = new GridData(); textGridData.grabExcessHorizontalSpace = true; textGridData.horizontalAlignment = GridData.FILL; m_projectToolkitCombo.setLayoutData(textGridData); } /** * @param parent the parent composite */ private void createAutToolKit(Composite parent) { Composite leftComposite = createComposite(parent, NUM_COLUMNS_1, GridData.BEGINNING, false); Composite rightComposite = createComposite(parent, NUM_COLUMNS_2, GridData.FILL, true); createLabel(leftComposite, Messages.ProjectPropertyPageAutToolKitLabel); m_projectToolkitCombo = ControlFactory .createProjectToolkitCombo(rightComposite); m_projectToolkitCombo.setSelectedObject(getProject().getToolkit()); GridData textGridData = new GridData(); textGridData.grabExcessHorizontalSpace = true; textGridData.horizontalAlignment = GridData.FILL; m_projectToolkitCombo.setLayoutData(textGridData); } /** * reflect the enablement of checkbox to the corresponding textfield */ protected void enableCleanResultDaysTextfield() { enableSelectionAndEnablementDependent( m_cleanTestresults, m_cleanResultDays); } /** * @param parent The parent <code>Composite</code> */ private void createCleanTestResults(Composite parent) { m_cleanTestresults = new Button(parent, SWT.CHECK); m_cleanTestresults.setText(Messages .TestResultViewPreferencePageCleanResults); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalSpan = 1; gridData.grabExcessHorizontalSpace = false; m_cleanTestresults.setLayoutData(gridData); int testResultCleanupInterval = getProject() .getTestResultCleanupInterval(); m_cleanTestresults.setSelection(testResultCleanupInterval != IProjectPO.NO_CLEANUP); m_cleanTestresults.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { enableCleanResultDaysTextfield(); checkCompleteness(); } public void widgetDefaultSelected(SelectionEvent e) { // nothing here } }); m_cleanResultDays = new CheckedIntText( parent, SWT.BORDER, false, 1, Integer.MAX_VALUE); gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gridData.horizontalSpan = 1; gridData.grabExcessHorizontalSpace = false; gridData.widthHint = 80; m_cleanResultDays.setLayoutData(gridData); if (testResultCleanupInterval > 0) { m_cleanResultDays .setText(String.valueOf(testResultCleanupInterval)); } m_cleanResultDays.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { // nothing } public void keyReleased(KeyEvent e) { checkCompleteness(); } }); enableCleanResultDaysTextfield(); ControlDecorator.createInfo(m_cleanResultDays, I18n.getString("TestResultViewPreferencePage.cleanResultsInfo"), //$NON-NLS-1$ false); } /** * @param parent The parent <code>Composite</code> */ private void createTrackChangesEnablement(Composite parent) { m_isTrackingActivatedButton = new Button(parent, SWT.CHECK); m_isTrackingActivatedButton.setText(Messages .PrefPageTrackChanges); m_isTrackingActivatedButton.setSelection( m_origProjectProps.getIsTrackingActivated()); GridData gridData = new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false); gridData.horizontalSpan = 2; gridData.grabExcessHorizontalSpace = false; m_isTrackingActivatedButton.setLayoutData(gridData); ControlDecorator.createInfo(m_isTrackingActivatedButton, I18n.getString("TestResultViewPreferencePage.TrackChangesInfo"), //$NON-NLS-1$ false); m_isTrackingActivatedButton.addSelectionListener( new SelectionListener() { public void widgetSelected(SelectionEvent e) { if (m_isTrackingActivatedButton != null) { UIComponentHelper.setEnabledRecursive( m_trackChangesTimespanSelection, m_isTrackingActivatedButton.getSelection()); UIComponentHelper.setEnabledRecursive( m_trackChangesSignatureSelection, m_isTrackingActivatedButton.getSelection()); if (!m_isTrackingActivatedButton.getSelection()) { m_trackChangesSpan.setBackground(null); } else { m_trackChangesSpan.validate(); } } checkCompleteness(); } public void widgetDefaultSelected(SelectionEvent e) { // nothing here } }); } /** * @param parent The parent <code>Composite</code> */ private void createTrackChangesTimespanSelection(Composite parent) { m_trackChangesTimespanSelection = new Group(parent, SWT.NONE); GridData gridData = new GridData(GridData.FILL_BOTH); m_trackChangesTimespanSelection.setLayout(new GridLayout()); m_trackChangesTimespanSelection.setLayoutData(gridData); m_trackChangesTimespanSelection.setText( Messages.PrefPageTrackChangesTimespanSelectionText); m_trackChangesUnitSelection = new Composite( m_trackChangesTimespanSelection, SWT.NULL); m_trackChangesUnitSelection.setLayout(new GridLayout()); Button daysButton = new Button(m_trackChangesUnitSelection, SWT.RADIO); daysButton.setText("Days"); //$NON-NLS-1$ Button changesButton = new Button(m_trackChangesUnitSelection, SWT.RADIO); changesButton.setText("Changes"); //$NON-NLS-1$ SelectionListener listener = new SelectionListener() { public void widgetSelected(SelectionEvent e) { checkCompleteness(); } public void widgetDefaultSelected(SelectionEvent e) { checkCompleteness(); } }; daysButton.addSelectionListener(listener); changesButton.addSelectionListener(listener); TrackingUnit unit = m_origProjectProps.getTrackChangesUnit(); if (unit != null) { switch (unit) { case CHANGES: changesButton.setSelection(true); break; case DAYS: daysButton.setSelection(true); break; default: break; } } else { daysButton.setSelection(true); // set days as default } m_trackChangesSpan = new CheckedIntText(m_trackChangesTimespanSelection, SWT.BORDER, false, 1, Integer.MAX_VALUE); gridData = new GridData(SWT.BEGINNING, SWT.NONE, true, true); gridData.widthHint = 80; m_trackChangesSpan.setLayoutData(gridData); ControlDecorator.createInfo(m_trackChangesSpan, I18n.getString( "TestResultViewPreferencePage.cleanResultsTimeunitInfo"), //$NON-NLS-1$ false); Integer span = m_origProjectProps.getTrackChangesSpan(); if (span != null) { m_trackChangesSpan.setText(String.valueOf(span)); } else { // set 10 as default m_trackChangesSpan.setText("10"); //$NON-NLS-1$ } m_trackChangesSpan.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { // nothing } public void keyReleased(KeyEvent e) { checkCompleteness(); } }); if (m_isTrackingActivatedButton != null) { UIComponentHelper.setEnabledRecursive( m_trackChangesTimespanSelection, m_isTrackingActivatedButton.getSelection()); } m_trackChangesSpan.setBackground(null); } /** * @param parent The parent <code>Composite</code> */ private void createTrackChangesSignatureSelection(Composite parent) { m_trackChangesSignatureSelection = new Group(parent, SWT.NONE); m_trackChangesSignatureSelection.setLayout(new GridLayout()); GridData gridData = new GridData(GridData.FILL_BOTH); gridData.horizontalSpan = 2; gridData.grabExcessHorizontalSpace = true; m_trackChangesSignatureSelection.setLayoutData(gridData); m_trackChangesSignatureSelection.setText( Messages.PrefPageTrackChangesSignatureSelectionText); Label label = new Label(m_trackChangesSignatureSelection, SWT.WRAP); label.setText(Messages.PrefPageTrackChangesSignatureDescription); final GridData labelData = new GridData(); labelData.horizontalSpan = 2; labelData.grabExcessHorizontalSpace = false; labelData.horizontalAlignment = SWT.LEFT; labelData.widthHint = 400; label.setLayoutData(labelData); m_trackChangesSignature = new CheckedSignatureText( m_trackChangesSignatureSelection, SWT.BORDER); gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gridData.widthHint = 200; m_trackChangesSignature.setLayoutData(gridData); m_trackChangesSignature.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { // nothing } public void keyReleased(KeyEvent e) { checkCompleteness(); } }); String signature = m_origProjectProps.getTrackChangesSignature(); if (signature != null) { m_trackChangesSignature.setText(signature); } m_trackChangesSignatureSelection.pack(); if (m_isTrackingActivatedButton != null) { UIComponentHelper.setEnabledRecursive( m_trackChangesSignatureSelection, m_isTrackingActivatedButton.getSelection()); } parent.pack(); } /** * @param parent The parent <code>Composite</code> */ private void createTrackChangesDeleteDataButton(Composite parent) { m_deleteChanges = new Button(parent, SWT.PUSH); m_deleteChanges.setText(Messages .PrefPageTrackChangesDeleteData); GridData gridData = new GridData(SWT.END, SWT.BEGINNING, false, false); gridData.horizontalSpan = 1; gridData.grabExcessHorizontalSpace = false; m_deleteChanges.setLayoutData(gridData); m_deleteChanges.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { Dialog qDialog = new MessageDialog(getShell(), Messages.UtilsConfirmation, null, Messages.PrefPageTrackChangesDeleteDataQuestion, MessageDialog.QUESTION, new String[] {Messages.UtilsYes, Messages.UtilsNo}, 0); qDialog.setBlockOnOpen(true); qDialog.open(); if (qDialog.getReturnCode() == 0) { // delete all tracked changes try { PlatformUI.getWorkbench().getProgressService().run( true, false, new DeleteTrackedChangesOperation()); } catch (InvocationTargetException ite) { // nothing } catch (InterruptedException ie) { // nothing } } } }); } /** * Checks if Preference Page is complete and valid */ protected void checkCompleteness() { if (m_cleanResultDays.isEnabled() && m_cleanResultDays.getValue() <= 0) { setErrorMessage(Messages .TestResultViewPreferencePageCleanResultDaysEmpty); setValid(false); return; } if (m_trackChangesTimespanSelection.isEnabled()) { boolean unitSelected = false; for (Control child : m_trackChangesUnitSelection.getChildren()) { if (child instanceof Button) { Button bt = (Button) child; if (bt.getSelection()) { unitSelected = true; } } } if (!unitSelected) { setErrorMessage(Messages.PrefPageTrackChangesNoUnitSelected); setValid(false); return; } } if (m_trackChangesTimespanSelection.isEnabled() && m_trackChangesSpan.getValue() <= 0) { setErrorMessage(Messages.PrefPageTrackChangesTimespanEmpty); setValid(false); return; } final String trackChangesSignature = m_trackChangesSignature.getText(); if (m_trackChangesTimespanSelection.isEnabled() && !StringUtils.isEmpty(trackChangesSignature) && EnvironmentUtils .getProcessOrSystemProperty(trackChangesSignature) == null) { setErrorMessage(Messages.PrefPageTrackChangesSignatureInvalid); setValid(false); return; } setErrorMessage(null); setValid(true); } /** * {@inheritDoc} */ public boolean performOk() { try { Plugin.startLongRunning(Messages .RefreshTSBrowserActionProgressMessage); if (!m_oldProjectName.equals(m_newProjectName)) { if (ProjectPM.doesProjectNameExist(m_newProjectName)) { ErrorHandlingUtil.createMessageDialog( MessageIDs.E_PROJECTNAME_ALREADY_EXISTS, new Object[] { m_newProjectName }, null); return false; } } IProjectPO project = getProject(); storeProperties(); storeAutoTestResultCleanup(); if (!m_oldProjectName.equals(m_newProjectName)) { ProjectNameBP.getInstance().setName( getEditSupport().getSession(), project.getGuid(), m_newProjectName); } fireOkPressed(); Set<IReusedProjectPO> origReused = ((IProjectPropertiesPO)getEditSupport().getOriginal()) .getUsedProjects(); Set<IReusedProjectPO> newReused = new HashSet<IReusedProjectPO>( ((IProjectPropertiesPO)getEditSupport().getWorkVersion()) .getUsedProjects()); boolean needRefresh = !origReused.containsAll(newReused) || !newReused.containsAll(origReused); newReused.removeAll(origReused); getEditSupport().saveWorkVersion(); refreshAutMainList(); boolean doSearchQuery = false; doSearchQuery = handleReusedChanged(newReused, needRefresh); DataEventDispatcher ded = DataEventDispatcher.getInstance(); ded.fireProjectStateChanged(ProjectState.prop_modified); List<DataChangedEvent> events = new ArrayList<DataChangedEvent>(); // FIXME zeb This updates the Test Case Browser. Once we have separate // EditSupports for each property page, then we can use // "real" ReusedProjectPOs instead of a placeholder. events.add(new DataChangedEvent( PoMaker.createReusedProjectPO("1", 1, 1, null, null), //$NON-NLS-1$ DataState.ReuseChanged, UpdateState.notInEditor)); events.add(new DataChangedEvent(GeneralStorage.getInstance() .getProject(), DataState.Renamed, UpdateState.notInEditor)); ded.fireDataChangedListener( events.toArray(new DataChangedEvent[0])); CompletenessBP.getInstance().completeProjectCheck(); if (doSearchQuery) { NewSearchUI.runQueryInBackground(new DeprecatedModulesQuery()); } } catch (PMException e) { ErrorHandlingUtil.createMessageDialog(e, null, null); } catch (ProjectDeletedException e) { PMExceptionHandler.handleProjectDeletedException(); } catch (InterruptedException e) { ErrorHandlingUtil.createMessageDialog( new JBException(Messages.UnexpectedError, e, MessageIDs.E_UNEXPECTED_EXCEPTION)); } catch (InvocationTargetException e) { ErrorHandlingUtil.createMessageDialog( new JBException(Messages.UnexpectedError, e, MessageIDs.E_UNEXPECTED_EXCEPTION)); } Plugin.stopLongRunning(); return true; } /** * this method asks if it should be searched for used deprecated * modules {@link DeprecatedModulesQuery} and also refreshes the master * session if there was a change in the reused of projects. * @param newReused the list of new {@link IReusedProjectPO} * @param needRefresh whether a refresh of the project is needed * @return boolean which states if the search query should be done * @throws InvocationTargetException might occur during refresh * @throws InterruptedException might occur during refresh */ private boolean handleReusedChanged(Set<IReusedProjectPO> newReused, boolean needRefresh) throws InvocationTargetException, InterruptedException { boolean doSearchQuery = false; if (!newReused.isEmpty()) { doSearchQuery = openSearchForDeprecatedDialog(); } if (needRefresh) { PlatformUI.getWorkbench().getProgressService().run(false, false, new RefreshProjectHandler.RefreshProjectOperation()); } for (IReusedProjectPO reused : newReused) { try { IProjectPO reusedProject = ProjectPM.loadReusedProject(reused); } catch (JBException e) { // Could not refresh Component Name information for // reused project. Log the exception. log.error(Messages .ErrorWhileRetrievingReusedProjectInformation, e); } } return doSearchQuery; } /** * creates and opens a dialog if a search for the deprecated Modules * should be done * @return the boolean if the search should be done */ private boolean openSearchForDeprecatedDialog() { MessageDialog mdiag = new MessageDialog( PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), Messages.ProjectPropertyPageSearchForDeprProjModuleTitle, null, Messages.ProjectPropertyPageSearchForDeprProjModuleMsg, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0); mdiag.create(); Plugin.getHelpSystem().setHelp( PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), ContextHelpIds.SEARCH_FOR_DEPRECATED_MODULES_DIALOG); return (mdiag.open() == Window.OK); } /** * store properties into the database */ private void storeProperties() { IProjectPO project = getProject(); if (m_isReusableCheckbox != null) { project.setIsReusable(m_isReusableCheckbox.getSelection()); } if (m_isProtectedCheckbox != null) { project.setIsProtected(m_isProtectedCheckbox.getSelection()); } if (m_projectDescriptionTextField != null) { project.setComment(m_projectDescriptionTextField.getText()); } if (m_isTrackingActivatedButton != null) { project.setIsTrackingActivated( m_isTrackingActivatedButton.getSelection()); } if (m_trackChangesSignature != null) { project.getProjectProperties().setTrackChangesSignature( m_trackChangesSignature.getText()); } if (m_trackChangesSpan != null && m_trackChangesSpan.getText() != null && !m_trackChangesSpan.getText().equals("")) { //$NON-NLS-1$ project.getProjectProperties().setTrackChangesSpan( Integer.valueOf(m_trackChangesSpan.getText())); } if (m_trackChangesUnitSelection != null) { TrackingUnit unit = null; for (Control child : m_trackChangesUnitSelection.getChildren()) { if (child instanceof Button) { Button bt = (Button) child; if (bt.getSelection()) { String btText = bt.getText(); if (btText.equals("Days")) { //$NON-NLS-1$ unit = TrackingUnit.DAYS; } else if (btText.equals("Changes")) { //$NON-NLS-1$ unit = TrackingUnit.CHANGES; } } } } if (unit != null) { project.getProjectProperties().setTrackChangesUnit(unit); } } } /** * store preferences made for auto test result cleanup */ private void storeAutoTestResultCleanup() { if (m_cleanResultDays != null) { if (m_cleanTestresults != null) { boolean autoClean = m_cleanTestresults.getSelection(); if (autoClean) { getProject().setTestResultCleanupInterval( Integer.valueOf(m_cleanResultDays.getText())); } else { getProject().setTestResultCleanupInterval( IProjectPO.NO_CLEANUP); } } } } /** * Notify listeners that OK was pressed. */ private void fireOkPressed() throws PMException { for (IOkListener listener : m_okListenerList) { listener.okPressed(); } } /** * Refreshes the AutMainList of the Project. */ private void refreshAutMainList() throws ProjectDeletedException { try { GeneralStorage.getInstance().getMasterSession().refresh( GeneralStorage.getInstance().getProject().getAutCont()); } catch (EntityNotFoundException enfe) { // Occurs if any Object Mapping information has been deleted while // the Project Properties were being edited. // Refresh the entire master session to ensure that AUT settings // and Object Mappings are in sync GeneralStorage.getInstance().reloadMasterSession( new NullProgressMonitor()); } } /** * Adds necessary listeners. */ private void addListener() { m_projectNameTextField.addModifyListener(m_modifyListener); m_projectToolkitCombo.addSelectionListener(m_toolkitComboListener); m_projectMarkupCombo.addSelectionListener(m_markupComboListener); } /** * The action of the project name field. * @param isProjectNameVerified True, if the project name was verified. * @return false, if the project name field contents an error: * the project name starts or end with a blank, or the field is empty */ boolean modifyProjectNameFieldAction( boolean isProjectNameVerified) { boolean isCorrect = true; String projectName = m_projectNameTextField.getText(); int projectNameLength = projectName.length(); super.getShell().setText(Messages.ProjectPropertyPageShellTitle + projectName); if ((projectNameLength == 0) || (projectName .startsWith(StringConstants.SPACE)) || (projectName.charAt(projectNameLength - 1) == ' ')) { isCorrect = false; } if (isCorrect) { setErrorMessage(null); setMessage(Messages.PropertiesActionPage1, NONE); setValid(true); if (isProjectNameVerified) { m_newProjectName = projectName; } if (ProjectPM.doesProjectNameExist(projectName) && !m_oldProjectName.equals(projectName)) { setErrorMessage(Messages .ProjectSettingWizardPageDoubleProjectName); isCorrect = false; setValid(false); } } else { if (projectNameLength == 0) { setErrorMessage(Messages.ProjectWizardEmptyProject); setValid(false); } else { setErrorMessage(Messages.ProjectWizardNotValidProject); setValid(false); } } return isCorrect; } /** * This private inner class contains a new ModifyListener. * @author BREDEX GmbH * @created 11.07.2005 */ @SuppressWarnings("synthetic-access") private class WidgetModifyListener implements ModifyListener { /** * {@inheritDoc} */ public void modifyText(ModifyEvent e) { Object o = e.getSource(); if (o.equals(m_projectNameTextField)) { modifyProjectNameFieldAction(true); return; } } } /** * @author BREDEX GmbH */ private class MarkupComboSelectionListener implements SelectionListener { /** {@inheritDoc} */ public void widgetSelected(SelectionEvent e) { Object o = e.getSource(); if (o.equals(m_projectMarkupCombo)) { handleMarkupSelection(); return; } Assert.notReached(Messages.EventActivatedUnknownWidget + StringConstants.DOT); } /** * handles the selection of the markupLanguageCombo */ private void handleMarkupSelection() { final String newMarkup = m_projectMarkupCombo .getSelectedObject(); final IProjectPO project = getProject(); project.setMarkupLanguage(newMarkup); } /** {@inheritDoc} */ public void widgetDefaultSelected(SelectionEvent e) { Assert.notReached(Messages.EventActivatedUnknownWidget + StringConstants.DOT); } } /** * This private inner class contains a new SelectionListener. * @author BREDEX GmbH * @created 10.02.2005 */ @SuppressWarnings("synthetic-access") private class ToolkitComboSelectionListener implements SelectionListener { /** * {@inheritDoc} */ public void widgetSelected(SelectionEvent e) { Object o = e.getSource(); if (o.equals(m_projectToolkitCombo)) { handleAutToolkitSelection(); return; } Assert.notReached(Messages.EventActivatedUnknownWidget + StringConstants.DOT); } /** * Handles the selection of the autToolkitCombo */ private void handleAutToolkitSelection() { final String newToolkit = m_projectToolkitCombo .getSelectedObject(); final IProjectPO project = getProject(); project.setToolkit(newToolkit); } /** * {@inheritDoc} */ public void widgetDefaultSelected(SelectionEvent e) { Assert.notReached(Messages.EventActivatedUnknownWidget + StringConstants.DOT); } } /** * @param toAdd The listener to add. */ public void addOkListener(IOkListener toAdd) { m_okListenerList.add(toAdd); } /** * {@inheritDoc} */ public void setVisible(boolean visible) { refreshAutToolkitCombo(); super.setVisible(visible); } /** * Refreshes the m_autToolkitCombo. */ private void refreshAutToolkitCombo() { final Composite parent = m_projectToolkitCombo.getParent(); final DirectCombo<String> tmpCombo = ControlFactory .createProjectToolkitCombo(parent); m_projectToolkitCombo.setItems(tmpCombo.getValues(), Arrays.asList( tmpCombo.getItems())); tmpCombo.dispose(); m_projectToolkitCombo.setSelectedObject(getProject().getToolkit()); } /** * Operation for deleting tracked changes * * @author BREDEX GmbH */ private class DeleteTrackedChangesOperation implements IRunnableWithProgress { /** * {@inheritDoc} */ public void run(IProgressMonitor monitor) { final IProjectPO project = GeneralStorage.getInstance().getProject(); final Map<INodePO, Boolean> nodeToWasLockedMap; try { nodeToWasLockedMap = NodePM.cleanupTrackedChanges(monitor, project); List<INodePO> listOfLockedNodes = new ArrayList<>( nodeToWasLockedMap.size()); for (INodePO node: nodeToWasLockedMap.keySet()) { if (nodeToWasLockedMap.get(node).booleanValue()) { listOfLockedNodes.add(node); } } Display d = Plugin.getDisplay(); if (d != null && !d.isDisposed()) { fireDataChangedListeners(d, nodeToWasLockedMap); } if (!listOfLockedNodes.isEmpty()) { Object[] details = listOfLockedNodes.toArray(); String[] namesOfLockedNodes; final int maxNumberOfLockedNodesToDisplay = 10; if (details.length <= maxNumberOfLockedNodesToDisplay) { // not too many locked nodes to display them all namesOfLockedNodes = new String[details.length]; for (int i = 0; i < namesOfLockedNodes.length; i++) { namesOfLockedNodes[i] = ((INodePO)details[i]).getName(); } ErrorHandlingUtil.createMessageDialog( MessageIDs. I_COULD_NOT_DELETE_ALL_TRACKED_CHANGES, null, namesOfLockedNodes); } else { // too many locked nodes to display them all namesOfLockedNodes = new String[maxNumberOfLockedNodesToDisplay]; for (int i = 0; i < namesOfLockedNodes.length; i++) { namesOfLockedNodes[i] = ((INodePO)details[i]).getName(); } Object[] params = new Object[2]; params[0] = maxNumberOfLockedNodesToDisplay; params[1] = details.length; ErrorHandlingUtil.createMessageDialog( MessageIDs. I_COULD_NOT_DELETE_ALL_TRACKED_CHANGES_MANY, params, namesOfLockedNodes); } } } catch (PMException e) { ErrorHandlingUtil.createMessageDialog(e); } catch (ProjectDeletedException e) { ErrorHandlingUtil.createMessageDialog(e); } } } /** * Fires data state listeners for those nodes which were not locked * @param d the active Display * @param nodeToWasLockedMap the map indicating which nodes were locked */ private void fireDataChangedListeners(Display d, final Map<INodePO, Boolean> nodeToWasLockedMap) { d.syncExec(new Runnable() { public void run() { for (INodePO node : nodeToWasLockedMap.keySet()) { if (!nodeToWasLockedMap.get(node). booleanValue()) { DataEventDispatcher.getInstance(). fireDataChangedListener(node, DataState.StructureModified, UpdateState.all); } } } }); } }