Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.lm.ui/src/org/eclipse/emf/cdo/lm/ui/widgets/TimeStampComposite.java')
-rw-r--r--plugins/org.eclipse.emf.cdo.lm.ui/src/org/eclipse/emf/cdo/lm/ui/widgets/TimeStampComposite.java268
1 files changed, 268 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.cdo.lm.ui/src/org/eclipse/emf/cdo/lm/ui/widgets/TimeStampComposite.java b/plugins/org.eclipse.emf.cdo.lm.ui/src/org/eclipse/emf/cdo/lm/ui/widgets/TimeStampComposite.java
new file mode 100644
index 0000000000..bbebaa4ddd
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.lm.ui/src/org/eclipse/emf/cdo/lm/ui/widgets/TimeStampComposite.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2022 Eike Stepper (Loehne, Germany) 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.lm.ui.widgets;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.lm.internal.client.TimeStamp;
+import org.eclipse.emf.cdo.lm.ui.bundle.OM;
+
+import org.eclipse.net4j.util.CheckUtil;
+import org.eclipse.net4j.util.collection.ConcurrentArray;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+import java.util.Objects;
+
+/**
+ * @author Eike Stepper
+ */
+public class TimeStampComposite extends Composite
+{
+ private ConcurrentArray<ModifyListener> listeners = new ConcurrentArray<>()
+ {
+ @Override
+ protected ModifyListener[] newArray(int length)
+ {
+ return new ModifyListener[length];
+ }
+ };
+
+ private final Text text;
+
+ private final long minTimeStamp;
+
+ private final long maxTimeStamp;
+
+ private long timeStamp = CDOBranchPoint.INVALID_DATE;
+
+ private String error;
+
+ private boolean settingValue;
+
+ private static TimeStampSelectorContributor[] selectors = { new TimeStampSelectorContributor()
+ {
+ @Override
+ public boolean contributeTimeStampSelector(TimeStampComposite composite, Object context)
+ {
+ Button button = new Button(composite, SWT.PUSH);
+ button.setLayoutData(GridDataFactory.fillDefaults().create());
+ button.setText("Now");
+ button.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ composite.setTimeStamp(System.currentTimeMillis());
+ }
+ });
+
+ return true;
+ }
+ } };
+
+ public TimeStampComposite(Composite parent, int style, long minTimeStamp, long maxTimeStamp, Object context)
+ {
+ super(parent, style);
+
+ this.minTimeStamp = minTimeStamp;
+ this.maxTimeStamp = maxTimeStamp;
+
+ text = new Text(this, SWT.BORDER);
+ text.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).create());
+ text.addModifyListener(e -> {
+ if (!settingValue)
+ {
+ long oldValue = timeStamp;
+ String oldError = error;
+ validate();
+ notifyModifyListeners(oldValue, oldError);
+ }
+ });
+
+ text.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusLost(FocusEvent e)
+ {
+ if (timeStamp != CDOBranchPoint.INVALID_DATE)
+ {
+ String string = TimeStamp.toString(timeStamp);
+ String oldString = text.getText();
+ if (!Objects.equals(string, oldString))
+ {
+ try
+ {
+ settingValue = true;
+ text.setText(string);
+ }
+ finally
+ {
+ settingValue = false;
+ }
+ }
+ }
+ }
+ });
+
+ int columns = 1;
+ if (context != null)
+ {
+ for (int i = 0; i < selectors.length; i++)
+ {
+ TimeStampSelectorContributor selector = selectors[i];
+ if (selector.contributeTimeStampSelector(this, context))
+ {
+ ++columns;
+ }
+ }
+ }
+
+ setLayout(GridLayoutFactory.fillDefaults().numColumns(columns).create());
+ }
+
+ public void addModifyListener(ModifyListener listener)
+ {
+ CheckUtil.checkArg(listener, "listener"); //$NON-NLS-1$
+ listeners.add(listener);
+ }
+
+ public void removeModifyListener(ModifyListener listener)
+ {
+ CheckUtil.checkArg(listener, "listener"); //$NON-NLS-1$
+ listeners.remove(listener);
+ }
+
+ public long getTimeStamp()
+ {
+ return timeStamp;
+ }
+
+ public void setTimeStamp(long timeStamp)
+ {
+ if (this.timeStamp != timeStamp)
+ {
+ long oldValue = this.timeStamp;
+ String oldError = error;
+
+ this.timeStamp = timeStamp;
+ validateValue();
+
+ if (!text.isDisposed())
+ {
+ try
+ {
+ settingValue = true;
+ text.setText(TimeStamp.toString(timeStamp));
+ }
+ finally
+ {
+ settingValue = false;
+ }
+ }
+
+ notifyModifyListeners(oldValue, oldError);
+ }
+ }
+
+ public String getError()
+ {
+ return error;
+ }
+
+ protected void validate()
+ {
+ String string = text.getText();
+ error = null;
+
+ try
+ {
+ timeStamp = TimeStamp.parseTimeStamp(string);
+ }
+ catch (Exception ex)
+ {
+ timeStamp = CDOBranchPoint.INVALID_DATE;
+ error = ex.getMessage();
+ return;
+ }
+
+ validateValue();
+ }
+
+ private void validateValue()
+ {
+ error = null;
+
+ if (minTimeStamp != CDOBranchPoint.UNSPECIFIED_DATE && timeStamp < minTimeStamp)
+ {
+ timeStamp = CDOBranchPoint.INVALID_DATE;
+ error = "Time stamp must not be smaller than " + TimeStamp.toString(minTimeStamp);
+ return;
+ }
+
+ if (maxTimeStamp != CDOBranchPoint.UNSPECIFIED_DATE && timeStamp > maxTimeStamp)
+ {
+ timeStamp = CDOBranchPoint.INVALID_DATE;
+ error = "Time stamp must not be greater than " + TimeStamp.toString(maxTimeStamp);
+ return;
+ }
+ }
+
+ private void notifyModifyListeners(long oldValue, String oldError)
+ {
+ if (timeStamp != oldValue || !Objects.equals(error, oldError))
+ {
+ ModifyListener[] array = listeners.get();
+
+ for (int i = 0; i < array.length; i++)
+ {
+ try
+ {
+ ModifyListener listener = array[i];
+ if (listener != null)
+ {
+ listener.modifyTimeStamp(this, timeStamp, error);
+ }
+ }
+ catch (Exception ex)
+ {
+ OM.LOG.error(ex);
+ }
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ @FunctionalInterface
+ public interface ModifyListener
+ {
+ public void modifyTimeStamp(TimeStampComposite control, long timeStamp, String error);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ @FunctionalInterface
+ public interface TimeStampSelectorContributor
+ {
+ public boolean contributeTimeStampSelector(TimeStampComposite composite, Object context);
+ }
+}

Back to the top