/** | |
******************************************************************************** | |
* Copyright (c) 2017 Robert Bosch GmbH and others. | |
* | |
* This program and the accompanying materials are made | |
* available under the terms of the Eclipse Public License 2.0 | |
* which is available at https://www.eclipse.org/legal/epl-2.0/ | |
* | |
* SPDX-License-Identifier: EPL-2.0 | |
* | |
* Contributors: | |
* Robert Bosch GmbH - initial API and implementation | |
******************************************************************************** | |
*/ | |
package org.eclipse.app4mc.sca.ui.preferences; | |
import java.io.File; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.Map; | |
import org.eclipse.app4mc.sca.logging.manager.LogFactory.LoggerType; | |
import org.eclipse.app4mc.sca.logging.manager.Logmanager; | |
import org.eclipse.app4mc.sca.ui.util.SCAToolsPreferenceConstants; | |
import org.eclipse.jface.layout.GridDataFactory; | |
import org.eclipse.jface.preference.PreferenceDialog; | |
import org.eclipse.swt.SWT; | |
import org.eclipse.swt.events.KeyEvent; | |
import org.eclipse.swt.events.KeyListener; | |
import org.eclipse.swt.events.SelectionAdapter; | |
import org.eclipse.swt.events.SelectionEvent; | |
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.DirectoryDialog; | |
import org.eclipse.swt.widgets.Group; | |
import org.eclipse.swt.widgets.Label; | |
import org.eclipse.swt.widgets.Text; | |
import org.eclipse.ui.IWorkbench; | |
/** | |
* This class implements SCA Tools Preference page UI using SWT controls. User can configure the logger type using | |
* this preference page.The logger types available are 1)Eclipse Console 2)Error log 3)Problems log 4)Log file | |
*/ | |
public class SCAPreferencePage extends AbstractSCAToolsPreferencePage { | |
private Group loggerType; | |
private StringBuilder scaLoggerType; | |
private Label logFileDirectoryLabel; | |
private Text logFileDirectoryText; | |
private Button browse; | |
private Label logFileNameLabel; | |
private Text logFileNameText; | |
private Composite composite; | |
private Composite compositeForCheckBox; | |
private Button[] checkBoxButtons; | |
private Button debugModeButton; | |
private Map<String, String> selectedCheckBox; | |
private HashSet<String> selectedButtons; | |
/** | |
* Error message | |
*/ | |
private String errorMessage = "Log File name should end with .log"; | |
/** | |
* Initializes this preference page for the given workbench.This method is called automatically as the preference page | |
* is being created and initialized | |
* | |
* @param workbench the workbench | |
*/ | |
@Override | |
public void init(final IWorkbench workbench) { | |
setPreferenceStore(org.eclipse.app4mc.sca.util.Activator.getDefault().getPreferenceStore()); | |
setDescription(SCAToolsPreferenceConstants.PREFERENCE_PAGE_DESCRIPTION); | |
} | |
/** | |
* This method will be called everytime the SCA Tools preference page is loaded. All the UI controls are created | |
* inside this method. Listeners are added to the UI controls. The UI controls are also initialized with approrpriate | |
* values. | |
* | |
* @param parent The composite on which the UI controls are created | |
* @return parent after all the UI controls are created | |
*/ | |
@Override | |
protected Control createContents(final Composite parent) { | |
initializeMap(); | |
new Label(parent, SWT.NONE).setLayoutData(new GridData(SWT.NONE, SWT.NONE, true, false, 5, -1)); | |
this.selectedButtons = new HashSet<String>(); | |
// creating the main composite on which the other controls are laid | |
Composite mainComposite = new Composite(parent, SWT.NULL); | |
GridLayout mainCompositeLayout = new GridLayout(); | |
mainCompositeLayout.numColumns = 1; | |
mainCompositeLayout.marginHeight = 0; | |
mainCompositeLayout.marginWidth = 0; | |
mainComposite.setLayout(mainCompositeLayout); | |
// creating the group for check box buttons and the text boxes | |
this.loggerType = new Group(mainComposite, SWT.SHADOW_OUT); | |
this.loggerType.setText("Logger Types"); | |
GridLayout layout = new GridLayout(5, false); | |
this.loggerType.setLayout(layout); | |
GridDataFactory.defaultsFor(this.loggerType).grab(true, false).span(2, 1).applyTo(this.loggerType); | |
GridDataFactory.defaultsFor(mainComposite).grab(true, true).span(2, 1).applyTo(mainComposite); | |
new Label(this.loggerType, SWT.NONE).setLayoutData(new GridData(SWT.NONE, SWT.NONE, true, false, 5, -1)); | |
// creating the composite inside the group for the check box buttons alone | |
this.checkBoxButtons = new Button[4]; | |
this.compositeForCheckBox = new Composite(this.loggerType, SWT.NONE); | |
GridLayout gridLayoutForCheckBox = new GridLayout(5, false); | |
this.compositeForCheckBox.setLayout(gridLayoutForCheckBox); | |
this.compositeForCheckBox.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | |
GridData gridDataForCheckBox = (GridData) this.compositeForCheckBox.getLayoutData(); | |
gridDataForCheckBox.grabExcessHorizontalSpace = true; | |
gridLayoutForCheckBox.horizontalSpacing = 8; | |
for (int i = 0; i < this.checkBoxButtons.length; i++) { | |
this.checkBoxButtons[i] = new Button(this.compositeForCheckBox, SWT.CHECK); | |
this.checkBoxButtons[i].setLayoutData(new GridData(SWT.HORIZONTAL)); | |
} | |
this.checkBoxButtons[0].setText(SCAToolsPreferenceConstants.ECLIPSE_CONSOLE); | |
this.checkBoxButtons[1].setText(SCAToolsPreferenceConstants.ERROR_LOG); | |
this.checkBoxButtons[2].setText(SCAToolsPreferenceConstants.PROBLEMS_LOG); | |
this.checkBoxButtons[3].setText(SCAToolsPreferenceConstants.LOG_FILE); | |
new Label(this.loggerType, SWT.NONE).setLayoutData(new GridData(SWT.NONE, SWT.NONE, true, false, 5, -1)); | |
// creating another composite inside the group for the text boxes | |
this.composite = new Composite(this.loggerType, SWT.NONE); | |
GridLayout gridLayout = new GridLayout(3, false); | |
this.composite.setLayout(gridLayout); | |
this.composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | |
GridData gridData = (GridData) this.composite.getLayoutData(); | |
gridData.grabExcessHorizontalSpace = true; | |
gridLayout.horizontalSpacing = 8; | |
gridLayout.verticalSpacing = 15; | |
this.logFileNameLabel = new Label(this.composite, SWT.SINGLE | SWT.LEFT); | |
this.logFileNameText = new Text(this.composite, SWT.SINGLE | SWT.BORDER); | |
this.logFileNameLabel.setText("Log File name"); | |
this.logFileNameLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, -1)); | |
this.logFileNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, -1)); | |
this.logFileDirectoryLabel = new Label(this.composite, SWT.SINGLE); | |
this.logFileDirectoryText = new Text(this.composite, SWT.SINGLE | SWT.BORDER); | |
this.browse = new Button(this.composite, SWT.PUSH); | |
this.logFileDirectoryLabel.setText("Log File Directory"); | |
this.browse.setText("Browse"); | |
this.logFileDirectoryLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, -1)); | |
this.logFileDirectoryText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, -1)); | |
this.browse.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, -1)); | |
Group modeGroup = new Group(mainComposite, SWT.SHADOW_OUT); | |
modeGroup.setText("Debug Mode"); | |
layout = new GridLayout(5, false); | |
modeGroup.setLayout(layout); | |
modeGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | |
this.debugModeButton = new Button(modeGroup, SWT.CHECK); | |
this.debugModeButton.setText(SCAToolsPreferenceConstants.DEBUG_MODE_LABEL); | |
// initializing the controls | |
initializeValues(); | |
// adding listeners to the controls | |
addListeners(); | |
return parent; | |
} | |
/** | |
* This method will be called when the user presses Ok button. Preferences are stored in the preference store. | |
* | |
* @return true after saving the preferences to the preference store | |
*/ | |
@Override | |
public boolean performOk() { | |
super.performOk(); | |
savePreferences(); | |
return true; | |
} | |
/** | |
* This method checks if the log file name ends with .log extension when the user clicks on the "Log File" check box | |
* button and sets the approriate error message. It also disables the Ok and Apply button whenever there is an error message set. | |
*/ | |
private void validate() { | |
this.errorMessage = null; | |
if (this.selectedButtons.isEmpty()) { | |
this.errorMessage = "At least one logging mechanisms should be selected"; | |
} | |
if (this.selectedButtons.contains(SCAToolsPreferenceConstants.LOG_FILE)) { | |
validatelogFile(); | |
} | |
if (this.selectedButtons.contains(SCAToolsPreferenceConstants.LOG_FILE) && | |
!(new File(this.logFileDirectoryText.getText())).exists()) { | |
this.errorMessage = "Log File directory does not exist"; | |
} | |
setErrorMessage(this.errorMessage); | |
disableOrEnableOkAndApplyButton(); | |
} | |
/** | |
* This methods adds the appropriate listeners to the UI controls of this preference page and it also reacts to the | |
* corrosponding events. | |
*/ | |
private void addListeners() { | |
addKeyListenerToTextBox(this.logFileNameText); | |
addKeyListenerToTextBox(this.logFileDirectoryText); | |
this.browse.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(final SelectionEvent event) { | |
DirectoryDialog directoryDialog = new DirectoryDialog(SCAPreferencePage.this.loggerType.getShell()); | |
directoryDialog.setMessage("Select a directory"); | |
String path = directoryDialog.open(); | |
if (path != null) { | |
SCAPreferencePage.this.logFileDirectoryText.setText(path); | |
} | |
} | |
}); | |
SelectionAdapter selectionListener = new SelectionAdapter() { | |
@Override | |
public void widgetSelected(final SelectionEvent event) { | |
Button b = ((Button) event.widget); | |
if (b.getSelection()) { | |
SCAPreferencePage.this.selectedButtons.add(b.getText()); | |
} | |
else { | |
if (SCAPreferencePage.this.selectedButtons.contains(b.getText())) { | |
SCAPreferencePage.this.selectedButtons.remove(b.getText()); | |
} | |
} | |
enableOrDisableText(SCAPreferencePage.this.selectedButtons); | |
validate(); | |
} | |
}; | |
for (Button b : this.checkBoxButtons) { | |
b.addSelectionListener(selectionListener); | |
} | |
} | |
/** | |
* This method sets the default values to the UI controls of this preference page. The default log file name is | |
* "sca.log" ,the default log file directory is user home directory and the default check box button selected is | |
* "Error log" | |
*/ | |
private void setDefaultsControls() { | |
this.selectedButtons.clear(); | |
for (Button rButton : this.checkBoxButtons) { | |
if (SCAToolsPreferenceConstants.ERROR_LOG.equals(rButton.getText())) { | |
rButton.setSelection(true); | |
this.selectedButtons.add(rButton.getText()); | |
} | |
else { | |
rButton.setSelection(false); | |
} | |
} | |
this.logFileNameLabel.setEnabled(false); | |
this.logFileNameText.setEnabled(false); | |
this.logFileDirectoryLabel.setEnabled(false); | |
this.logFileDirectoryText.setEnabled(false); | |
this.browse.setEnabled(false); | |
} | |
/** | |
* Sets the controls with the default values form the preference.ini file | |
*/ | |
private void setValuesToDefault() { | |
this.logFileNameText.setText(getPreferenceStore().getDefaultString(SCAToolsPreferenceConstants.TEXT_LOGFILENAME)); | |
this.logFileDirectoryText | |
.setText(getPreferenceStore().getDefaultString(SCAToolsPreferenceConstants.TEXT_LOGFILEDIRECTORY)); | |
} | |
/** | |
* This method will be called when the user clicks on "Restore defaults" button.It basically sets the default values | |
* of the UI controls. | |
*/ | |
@Override | |
protected void performDefaults() { | |
setDefaultsControls(); | |
setValuesToDefault(); | |
validate(); | |
} | |
/** | |
* This method gets the values of the check box buttons selected, the log file name and the log file directory and | |
* save them in the preference store | |
*/ | |
private void savePreferences() { | |
this.scaLoggerType = new StringBuilder(); | |
for (Map.Entry<String, String> entry : this.selectedCheckBox.entrySet()) { | |
String key = entry.getKey(); | |
String value = entry.getValue(); | |
if (this.selectedButtons.contains(value)) { | |
this.scaLoggerType = this.scaLoggerType.append(key + ";"); | |
} | |
} | |
this.scaLoggerType = | |
new StringBuilder(this.scaLoggerType.substring(0, this.scaLoggerType.length() - 1)); | |
getPreferenceStore().setValue(SCAToolsPreferenceConstants.SCA_LOGGER, this.scaLoggerType.toString()); | |
getPreferenceStore().setValue(SCAToolsPreferenceConstants.TEXT_LOGFILENAME, this.logFileNameText.getText()); | |
getPreferenceStore().setValue(SCAToolsPreferenceConstants.TEXT_LOGFILEDIRECTORY, | |
this.logFileDirectoryText.getText()); | |
getPreferenceStore().setValue(SCAToolsPreferenceConstants.DEBUG_MODE, this.debugModeButton.getSelection()); | |
Logmanager.getInstance().setDebugMode(this.debugModeButton.getSelection()); | |
} | |
/** | |
* This method enables or disables the text controls depending on the check boxes that are selected the text controls | |
* are enabled when user clicks on "Log file" check box button. | |
* | |
* @param selected Set of check boxes that are selected | |
*/ | |
private void enableOrDisableText(final HashSet<String> selected) { | |
this.logFileDirectoryText.setEnabled(false); | |
this.logFileDirectoryLabel.setEnabled(false); | |
this.logFileNameText.setEnabled(false); | |
this.logFileNameLabel.setEnabled(false); | |
this.browse.setEnabled(false); | |
if (selected.contains(SCAToolsPreferenceConstants.LOG_FILE)) { | |
this.logFileDirectoryText.setEnabled(true); | |
this.logFileDirectoryLabel.setEnabled(true); | |
this.logFileNameText.setEnabled(true); | |
this.logFileNameLabel.setEnabled(true); | |
this.browse.setEnabled(true); | |
} | |
} | |
/** | |
* The method initializes the UI controls. It checks if there are any values stored in preference store, if yes the UI | |
* controls are set to those present in preference store else they are set to the defalt values | |
*/ | |
private void initializeValues() { | |
this.logFileNameText.setText(getPreferenceStore().getString(SCAToolsPreferenceConstants.TEXT_LOGFILENAME)); | |
this.logFileDirectoryText.setText(getPreferenceStore().getString(SCAToolsPreferenceConstants.TEXT_LOGFILEDIRECTORY)); | |
String selectedLoggers = getPreferenceStore().getString(SCAToolsPreferenceConstants.SCA_LOGGER); | |
if (selectedLoggers.isEmpty()) { | |
setDefaultsControls(); | |
} | |
else { | |
String[] buttons = (selectedLoggers.split(";")); | |
for (String s : buttons) { | |
this.selectedButtons.add(this.selectedCheckBox.get(s)); | |
} | |
} | |
initializeDebugMode(getPreferenceStore().getString(SCAToolsPreferenceConstants.DEBUG_MODE)); | |
for (Button b : this.checkBoxButtons) { | |
if (this.selectedButtons.contains(b.getText())) { | |
b.setSelection(true); | |
} | |
else { | |
b.setSelection(false); | |
} | |
} | |
enableOrDisableText(this.selectedButtons); | |
validate(); | |
} | |
/** | |
* Initializes the debug check box based on the give value | |
* | |
* @param value String | |
*/ | |
private void initializeDebugMode(final String value) { | |
if ("true".equals(value)) { | |
this.debugModeButton.setSelection(true); | |
Logmanager.getInstance().setDebugMode(true); | |
} | |
else { | |
this.debugModeButton.setSelection(false); | |
Logmanager.getInstance().setDebugMode(false); | |
} | |
} | |
/** | |
* This method disables the Ok and Apply button whenever there is an error message set. | |
*/ | |
private void disableOrEnableOkAndApplyButton() { | |
Button okButton = null; | |
PreferenceDialog iPreferencePageContainer = (PreferenceDialog) getContainer(); | |
Composite buttons = (Composite) iPreferencePageContainer.buttonBar; | |
Control[] allbuttons = buttons.getChildren(); | |
Composite compositeForButtons = (Composite) allbuttons[1]; | |
for (Control b : compositeForButtons.getChildren()) { | |
if (b instanceof Button) { | |
Button presentButton = (Button) b; | |
if ("OK".equals(presentButton.getText())) { | |
okButton = presentButton; | |
} | |
} | |
} | |
Button applyButton = getApplyButton(); | |
if ((okButton != null) && (applyButton != null)) { | |
if (getErrorMessage() != null) { | |
okButton.setEnabled(false); | |
applyButton.setEnabled(false); | |
} | |
else { | |
okButton.setEnabled(true); | |
applyButton.setEnabled(true); | |
} | |
} | |
} | |
/** | |
* This method will be called whenever the "Log File" check box button is selected. This method validates the Log File | |
* Name and Log File Directory text boxes and sets the error message whenever applicable. | |
*/ | |
private void validatelogFile() { | |
if (this.logFileNameText.getText().endsWith(".log") && (new File(this.logFileDirectoryText.getText())).exists()) { | |
setErrorMessage(null); | |
} | |
else { | |
if (!this.logFileNameText.getText().endsWith(".log")) { | |
this.errorMessage = "Log File name should end with .log"; | |
setErrorMessage(this.errorMessage); | |
} | |
} | |
} | |
private void addKeyListenerToTextBox(final Text t) { | |
t.addKeyListener(new KeyListener() { | |
@Override | |
public void keyReleased(final KeyEvent e) { | |
validate(); | |
} | |
@Override | |
public void keyPressed(final KeyEvent e) { | |
validate(); | |
} | |
}); | |
} | |
private void initializeMap() { | |
this.selectedCheckBox = new HashMap<String, String>(); | |
this.selectedCheckBox.put(LoggerType.ECLIPSE_CONSOLE.toString(), SCAToolsPreferenceConstants.ECLIPSE_CONSOLE); | |
this.selectedCheckBox.put(LoggerType.ERROR_LOG.toString(), SCAToolsPreferenceConstants.ERROR_LOG); | |
this.selectedCheckBox.put(LoggerType.PROBLEMS_LOG.toString(), SCAToolsPreferenceConstants.PROBLEMS_LOG); | |
this.selectedCheckBox.put(LoggerType.TEXT_FILE.toString(), SCAToolsPreferenceConstants.LOG_FILE); | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
@Override | |
public String getToolId() { | |
return SCAToolsPreferenceConstants.SCA_TOOL_ID; | |
} | |
} |