blob: 2741156eefb0a4124ffea66103d2688e83eff2d5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2014 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Francois Chouinard - Initial API and implementation
* Marc-Andre Laperle - Add time zone preference
* Patrick Tasse - Updated for fraction of seconds
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ui.properties;
import java.util.Map;
import java.util.TimeZone;
import org.eclipse.jface.preference.ComboFieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.preference.RadioGroupFieldEditor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.tracecompass.internal.tmf.ui.Activator;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimePreferencesConstants;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimePreferences;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
/**
* The TMF timestamp format configuration page. This page is used to select the
* global timestamp and interval time formats (for display and parsing). The
* user can either pick a pre-defined format or enter his/her own.
*
* @author Francois Chouinard
*/
public class TmfTimestampFormatPage extends PreferencePage implements IWorkbenchPreferencePage, SelectionListener, IPropertyChangeListener {
// ------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------
// Date and Time formats
private static final String[][] fDateTimeFormats = new String[][] {
{ ITmfTimePreferencesConstants.DATE_YEAR_FMT, ITmfTimePreferencesConstants.DATE_YEAR_FMT },
{ ITmfTimePreferencesConstants.DATE_YEAR2_FMT, ITmfTimePreferencesConstants.DATE_YEAR2_FMT },
{ ITmfTimePreferencesConstants.DATE_MONTH_FMT, ITmfTimePreferencesConstants.DATE_MONTH_FMT },
{ ITmfTimePreferencesConstants.DATE_DAY_FMT, ITmfTimePreferencesConstants.DATE_DAY_FMT },
{ ITmfTimePreferencesConstants.DATE_JDAY_FMT, ITmfTimePreferencesConstants.DATE_JDAY_FMT },
{ ITmfTimePreferencesConstants.TIME_HOUR_FMT, ITmfTimePreferencesConstants.TIME_HOUR_FMT },
{ ITmfTimePreferencesConstants.TIME_MINUTE_FMT, ITmfTimePreferencesConstants.TIME_MINUTE_FMT },
{ ITmfTimePreferencesConstants.TIME_SECOND_FMT, ITmfTimePreferencesConstants.TIME_SECOND_FMT },
{ ITmfTimePreferencesConstants.TIME_ELAPSED_FMT + " (secs in epoch)", ITmfTimePreferencesConstants.TIME_ELAPSED_FMT }, //$NON-NLS-1$
{ "(none)", ITmfTimePreferencesConstants.TIME_NO_FMT }, //$NON-NLS-1$
};
// Sub-second formats
private static final String[][] fSubSecondFormats = new String[][] {
{ ITmfTimePreferencesConstants.SUBSEC_MILLI_FMT + " (ms)", ITmfTimePreferencesConstants.SUBSEC_MILLI_FMT }, //$NON-NLS-1$
{ ITmfTimePreferencesConstants.SUBSEC_MICRO_FMT + " (µs)", ITmfTimePreferencesConstants.SUBSEC_MICRO_FMT }, //$NON-NLS-1$
{ ITmfTimePreferencesConstants.SUBSEC_NANO_FMT + " (ns)", ITmfTimePreferencesConstants.SUBSEC_NANO_FMT }, //$NON-NLS-1$
};
// Date and Time delimiters
private static final String[][] fDateTimeDelimiters = new String[][] {
{ "(none)", ITmfTimePreferencesConstants.DELIMITER_NONE }, //$NON-NLS-1$
{ " (space)", ITmfTimePreferencesConstants.DELIMITER_SPACE }, //$NON-NLS-1$
{ ", (comma)", ITmfTimePreferencesConstants.DELIMITER_COMMA }, //$NON-NLS-1$
{ "- (dash)", ITmfTimePreferencesConstants.DELIMITER_DASH }, //$NON-NLS-1$
{ "_ (underline)", ITmfTimePreferencesConstants.DELIMITER_UNDERLINE }, //$NON-NLS-1$
{ ": (colon)", ITmfTimePreferencesConstants.DELIMITER_COLON }, //$NON-NLS-1$
{ "; (semicolon)", ITmfTimePreferencesConstants.DELIMITER_SEMICOLON }, //$NON-NLS-1$
{ "/ (slash)", ITmfTimePreferencesConstants.DELIMITER_SLASH }, //$NON-NLS-1$
{ "' (quote)", ITmfTimePreferencesConstants.DELIMITER_QUOTE }, //$NON-NLS-1$
{ "\" (dbl-quote)", ITmfTimePreferencesConstants.DELIMITER_DQUOT }, //$NON-NLS-1$
};
// Sub-Second delimiters
private static final String[][] fSubSecondDelimiters = new String[][] {
{ "(none)", ITmfTimePreferencesConstants.DELIMITER_NONE }, //$NON-NLS-1$
{ " (space)", ITmfTimePreferencesConstants.DELIMITER_SPACE }, //$NON-NLS-1$
{ ", (comma)", ITmfTimePreferencesConstants.DELIMITER_COMMA }, //$NON-NLS-1$
{ "- (dash)", ITmfTimePreferencesConstants.DELIMITER_DASH }, //$NON-NLS-1$
{ "_ (underline)", ITmfTimePreferencesConstants.DELIMITER_UNDERLINE }, //$NON-NLS-1$
{ ": (colon)", ITmfTimePreferencesConstants.DELIMITER_COLON }, //$NON-NLS-1$
{ "; (semicolon)", ITmfTimePreferencesConstants.DELIMITER_SEMICOLON }, //$NON-NLS-1$
{ "/ (slash)", ITmfTimePreferencesConstants.DELIMITER_SLASH }, //$NON-NLS-1$
{ "' (quote)", ITmfTimePreferencesConstants.DELIMITER_QUOTE }, //$NON-NLS-1$
{ "\" (dbl-quote)", ITmfTimePreferencesConstants.DELIMITER_DQUOT }, //$NON-NLS-1$
{ ". (period)", ITmfTimePreferencesConstants.DELIMITER_PERIOD }, //$NON-NLS-1$
};
// Time zones
@SuppressWarnings("nls")
private static final String[] timeZones = new String[] {
Messages.TmfTimestampFormatPage_LocalTime,
"GMT-12",
"GMT-11",
"GMT-10",
"GMT-9:30",
"GMT-9",
"GMT-7",
"GMT-6",
"GMT-5",
"GMT-4",
"GMT-3:30",
"GMT-3",
"GMT-2",
"GMT-1",
"GMT",
"GMT+1",
"GMT+2",
"GMT+3",
"GMT+3:30",
"GMT+4",
"GMT+4:30",
"GMT+5",
"GMT+5:30",
"GMT+6",
"GMT+7",
"GMT+8",
"GMT+9",
"GMT+9:30",
"GMT+10",
"GMT+10:30",
"GMT+11",
"GMT+11:30",
"GMT+12",
"GMT+13:00",
"GMT+14:00"
};
// ------------------------------------------------------------------------
// Attributes
// ------------------------------------------------------------------------
// General stuff
private Composite fPage;
private IPreferenceStore fPreferenceStore;
// Example section
private Composite fExampleSection;
private Text fPatternDisplay;
private Text fExampleDisplay;
// Timezone section
private ComboFieldEditor fCombo;
// Date/Time format section
private RadioGroupFieldEditor fDateTimeFields;
private RadioGroupFieldEditor fSSecFields;
// Delimiters section
private RadioGroupFieldEditor fDateFieldDelim;
private RadioGroupFieldEditor fTimeFieldDelim;
private RadioGroupFieldEditor fSSecFieldDelim;
// IPropertyChangeListener data
private String fProperty;
private String fChangedProperty;
private Map<String, String> fPreferenceMap;
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
/**
* The default constructor
*/
public TmfTimestampFormatPage() {
fPreferenceStore = getPreferenceStore();
fPreferenceMap = TmfTimePreferences.getPreferenceMap();
}
// ------------------------------------------------------------------------
// IWorkbenchPreferencePage
// ------------------------------------------------------------------------
@Override
protected IPreferenceStore doGetPreferenceStore() {
return Activator.getDefault().getCorePreferenceStore();
}
@Override
public void init(IWorkbench workbench) {
// Do nothing
}
// ------------------------------------------------------------------------
// PreferencePage
// ------------------------------------------------------------------------
@Override
protected Control createContents(Composite parent) {
// Overall preference page layout
GridLayout gl = new GridLayout();
gl.marginHeight = 0;
gl.marginWidth = 0;
parent.setLayout(gl);
fPage = new Composite(parent, SWT.NONE);
fPage.setLayout(new GridLayout());
fPage.setLayoutData(new GridData(
GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL));
// Example section
fExampleSection = new Composite(fPage, SWT.NONE);
fExampleSection.setLayout(new GridLayout(2, false));
fExampleSection.setLayoutData(new GridData(GridData.FILL_BOTH));
Label patternLabel = new Label(fExampleSection, SWT.HORIZONTAL);
patternLabel.setText("Current Format: "); //$NON-NLS-1$
fPatternDisplay = new Text(fExampleSection, SWT.BORDER | SWT.READ_ONLY);
fPatternDisplay.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Label exampleLabel = new Label(fExampleSection, SWT.NONE);
exampleLabel.setText("Sample Display: "); //$NON-NLS-1$
fExampleDisplay = new Text(fExampleSection, SWT.BORDER | SWT.READ_ONLY);
fExampleDisplay.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Label separator = new Label(fPage, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.SHADOW_NONE);
separator.setLayoutData(
new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));
// Time Zones
String[][] timeZoneIntervals = new String[timeZones.length][2];
timeZoneIntervals[0][0] = timeZones[0];
timeZoneIntervals[0][1] = fPreferenceStore.getDefaultString(ITmfTimePreferencesConstants.TIME_ZONE);
for (int i = 1; i < timeZones.length; i++) {
TimeZone tz = null;
try {
tz = TimeZone.getTimeZone(timeZones[i]);
timeZoneIntervals[i][0] = tz.getDisplayName();
timeZoneIntervals[i][1] = tz.getID();
} catch (NullPointerException e) {
Activator.getDefault().logError("TimeZone " + timeZones[i] + " does not exist.", e); //$NON-NLS-1$ //$NON-NLS-2$
}
}
fCombo = new ComboFieldEditor(ITmfTimePreferencesConstants.TIME_ZONE, "Time Zone", timeZoneIntervals, fPage); //$NON-NLS-1$
fCombo.setPreferenceStore(fPreferenceStore);
fCombo.load();
fCombo.setPropertyChangeListener(this);
// Date and Time section
fDateTimeFields = new RadioGroupFieldEditor(
ITmfTimePreferencesConstants.DATIME, "Date and Time format", 3, fDateTimeFormats, fPage, true); //$NON-NLS-1$
fDateTimeFields.setPreferenceStore(fPreferenceStore);
fDateTimeFields.load();
fDateTimeFields.setPropertyChangeListener(this);
// Sub-second section
fSSecFields = new RadioGroupFieldEditor(
ITmfTimePreferencesConstants.SUBSEC, "Sub-second format", 3, fSubSecondFormats, fPage, true); //$NON-NLS-1$
fSSecFields.setPreferenceStore(fPreferenceStore);
fSSecFields.load();
fSSecFields.setPropertyChangeListener(this);
// Separators section
fDateFieldDelim = new RadioGroupFieldEditor(
ITmfTimePreferencesConstants.DATE_DELIMITER, "Date delimiter", 5, fDateTimeDelimiters, fPage, true); //$NON-NLS-1$
fDateFieldDelim.setPreferenceStore(fPreferenceStore);
fDateFieldDelim.load();
fDateFieldDelim.setPropertyChangeListener(this);
fTimeFieldDelim = new RadioGroupFieldEditor(
ITmfTimePreferencesConstants.TIME_DELIMITER, "Time delimiter", 5, fDateTimeDelimiters, fPage, true); //$NON-NLS-1$
fTimeFieldDelim.setPreferenceStore(fPreferenceStore);
fTimeFieldDelim.load();
fTimeFieldDelim.setPropertyChangeListener(this);
fSSecFieldDelim = new RadioGroupFieldEditor(
ITmfTimePreferencesConstants.SSEC_DELIMITER, "Sub-Second Delimiter", 5, fSubSecondDelimiters, fPage, true); //$NON-NLS-1$
fSSecFieldDelim.setPreferenceStore(fPreferenceStore);
fSSecFieldDelim.load();
fSSecFieldDelim.setPropertyChangeListener(this);
refresh();
return fPage;
}
@Override
protected void performDefaults() {
fDateTimeFields.loadDefault();
fSSecFields.loadDefault();
fDateFieldDelim.loadDefault();
fTimeFieldDelim.loadDefault();
fSSecFieldDelim.loadDefault();
fCombo.loadDefault();
fPreferenceMap = TmfTimePreferences.getDefaultPreferenceMap();
displayExample();
}
@Override
protected void performApply() {
fDateTimeFields.store();
fSSecFields.store();
fDateFieldDelim.store();
fTimeFieldDelim.store();
fSSecFieldDelim.store();
fCombo.store();
TmfTimestampFormat.updateDefaultFormats();
TmfSignalManager.dispatchSignal(new TmfTimestampFormatUpdateSignal(null));
displayExample();
}
@Override
public boolean performOk() {
performApply();
return super.performOk();
}
// ------------------------------------------------------------------------
// SelectionListener
// ------------------------------------------------------------------------
@Override
public void widgetSelected(SelectionEvent e) {
// Do nothing
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// Do nothing
}
// ------------------------------------------------------------------------
// IPropertyChangeListener
// ------------------------------------------------------------------------
@Override
public void propertyChange(PropertyChangeEvent event) {
Object source = event.getSource();
Object value = event.getNewValue();
if (source instanceof RadioGroupFieldEditor && value instanceof String &&
!(value.equals(fChangedProperty) && source.equals(fProperty)))
{
fProperty = ((RadioGroupFieldEditor) source).getPreferenceName();
fChangedProperty = (String) value;
refresh();
}
}
// ------------------------------------------------------------------------
// Helper functions
// ------------------------------------------------------------------------
private void refresh() {
updatePatterns();
displayExample();
}
void updatePatterns() {
if (ITmfTimePreferencesConstants.DATIME.equals(fProperty) ||
ITmfTimePreferencesConstants.SUBSEC.equals(fProperty) ||
ITmfTimePreferencesConstants.DATE_DELIMITER.equals(fProperty) ||
ITmfTimePreferencesConstants.TIME_DELIMITER.equals(fProperty) ||
ITmfTimePreferencesConstants.SSEC_DELIMITER.equals(fProperty)) {
fPreferenceMap.put(fProperty, fChangedProperty);
}
}
private void displayExample() {
long ts = 1332170682500677380L;
String timePattern = TmfTimePreferences.computeTimePattern(fPreferenceMap);
fPatternDisplay.setText(timePattern);
fPatternDisplay.redraw();
fExampleDisplay.setText(new TmfTimestampFormat(timePattern).format(ts));
fExampleDisplay.redraw();
}
}