Merge "Issue #1966 Check for modifications on close." into omaha_13.5.1

Former-commit-id: 3c19aebeb235e8bf24e286007b27d5e8263731c6
This commit is contained in:
Richard Peter 2013-06-19 16:41:27 -05:00 committed by Gerrit Code Review
commit 36ed7d5d2b
5 changed files with 328 additions and 16 deletions

View file

@ -495,4 +495,29 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
}
});
}
/**
* Reset modification flag.
*/
protected void clearModified() {
tableComp.clearModified();
}
/**
* Add listener to inform when modification flag is set.
*
* @param iModifyListener
*/
protected void addModifiedListener(IModifyListener iModifyListener) {
tableComp.addModifiedListener(iModifyListener);
}
/**
* Remove modification listener.
*
* @param iModifyListener
*/
protected void removeModifiedListener(IModifyListener iModifyListener) {
tableComp.removeModifiedListener(iModifyListener);
}
}

View file

@ -25,6 +25,8 @@ import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
@ -32,6 +34,7 @@ import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
@ -39,6 +42,7 @@ import com.raytheon.uf.common.archive.config.ArchiveConfigManager;
import com.raytheon.uf.common.archive.config.DisplayData;
import com.raytheon.uf.viz.archive.data.IArchiveTotals;
import com.raytheon.uf.viz.archive.ui.ArchiveTableComp.TableType;
import com.raytheon.uf.viz.core.VizApp;
/**
* Archive retention dialog.
@ -59,7 +63,7 @@ import com.raytheon.uf.viz.archive.ui.ArchiveTableComp.TableType;
* @version 1.0
*/
public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
IArchiveTotals {
IArchiveTotals, IModifyListener {
/** Current Archive/Category selection's minimum retention hours. */
private RetentionHours minRetention;
@ -73,8 +77,11 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
/** Displays the total size of selected items. */
private Label totalSizeLbl;
// TODO in the future, get this value from a user text box
protected static final String ARCHIVE_DIR = "/archive_dir";
/** Performs save action button. */
private Button saveBtn;
/** Flag set when user wants to close with unsaved modifications. */
boolean closeFlag = false;
/**
* Constructor.
@ -89,6 +96,11 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
this.tableType = TableType.Retention;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#constructShellLayout()
*/
@Override
protected Layout constructShellLayout() {
// Create the main layout for the shell.
@ -98,6 +110,13 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
return mainLayout;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org
* .eclipse.swt.widgets.Shell)
*/
@Override
protected void initializeComponents(Shell shell) {
setText("Archive Retention");
@ -162,11 +181,13 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
minRetention = new RetentionHours(1, minRetentionSpnr, minRetentionCbo) {
@Override
protected void handleTimeSelection() {
super.handleTimeSelection();
protected boolean handleTimeSelection() {
boolean state = super.handleTimeSelection();
getSelectedArchive().setRetentionHours(getHours());
return state;
}
};
minRetention.addModifyListener(this);
/*
* Bottom row of controls.
@ -190,11 +211,13 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
extRetention = new RetentionHours(1, extRetentionSpnr, extRetentionCbo) {
@Override
protected void handleTimeSelection() {
super.handleTimeSelection();
protected boolean handleTimeSelection() {
boolean state = super.handleTimeSelection();
getSelectedCategory().setRetentionHours(getHours());
return state;
}
};
extRetention.addModifyListener(this);
}
/**
@ -220,7 +243,7 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
// }
// });
Button saveBtn = new Button(actionControlComp, SWT.PUSH);
saveBtn = new Button(actionControlComp, SWT.PUSH);
saveBtn.setText(" Save ");
saveBtn.addSelectionListener(new SelectionAdapter() {
@Override
@ -228,8 +251,11 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
ArchiveConfigManager manager = ArchiveConfigManager
.getInstance();
manager.save();
saveBtn.setEnabled(false);
clearModified();
}
});
saveBtn.setEnabled(false);
gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
Button closeBtn = new Button(actionControlComp, SWT.PUSH);
@ -238,11 +264,33 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
closeBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
close();
if (verifyClose()) {
close();
} else {
e.doit = false;
}
}
});
}
/**
* When unsaved modifications this asks the user to verify the close.
*
* @return true when okay to close.
*/
private boolean verifyClose() {
boolean state = true;
if (isModified()) {
MessageBox box = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK
| SWT.CANCEL);
box.setText("Close Retention");
box.setMessage("Unsave changes.\nSelect OK to continue.");
state = box.open() == SWT.OK;
}
closeFlag = state;
return state;
}
/*
* (non-Javadoc)
*
@ -334,4 +382,80 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements
super.categoryComboSelection();
extRetention.setHours(getSelectedCategory().getRetentionHours());
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.archive.ui.IModifyListener#modified()
*/
@Override
public void modified() {
saveBtn.setEnabled(true);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#clearModified()
*/
@Override
public void clearModified() {
super.clearModified();
minRetention.clearModified();
extRetention.clearModified();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#preOpened()
*/
@Override
protected void preOpened() {
super.preOpened();
addModifiedListener(this);
shell.addShellListener(new ShellAdapter() {
@Override
public void shellClosed(ShellEvent e) {
if (closeFlag || !isModified()) {
return;
}
e.doit = false;
VizApp.runAsync(new Runnable() {
@Override
public void run() {
if (verifyClose()) {
close();
}
}
});
}
});
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#disposed()
*/
@Override
protected void disposed() {
minRetention.removeModifyListener(this);
extRetention.removeModifyListener(this);
removeModifiedListener(this);
super.disposed();
}
/**
* Indicate unsaved user changes.
*
* @return modified
*/
private boolean isModified() {
return (saveBtn != null) && !saveBtn.isDisposed()
&& saveBtn.isEnabled();
}
}

View file

@ -21,6 +21,7 @@ package com.raytheon.uf.viz.archive.ui;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.lang.ArrayUtils;
import org.eclipse.swt.SWT;
@ -95,6 +96,16 @@ public class ArchiveTableComp extends Composite {
/** Data for the currently display table */
private DisplayData[] tableData;
/**
* Modification state set to true only when user performs a modification.
*/
private boolean modifiedState = false;
/**
* Listeners to inform when user changes the modification state.
*/
private final List<IModifyListener> modifiedListeners = new CopyOnWriteArrayList<IModifyListener>();
/**
* Constructor.
*
@ -185,6 +196,7 @@ public class ArchiveTableComp extends Composite {
public void widgetSelected(SelectionEvent e) {
if (e.detail == SWT.CHECK) {
updateSelectionLabels();
setModified();
}
}
});
@ -382,6 +394,7 @@ public class ArchiveTableComp extends Composite {
for (TableItem ti : itemArray) {
ti.setChecked(check);
}
setModified();
updateSelectionLabels();
}
@ -427,4 +440,40 @@ public class ArchiveTableComp extends Composite {
table.setSortDirection(SWT.UP);
table.clearAll();
}
/**
* Check the modified state and inform listeners when it changes.
*/
private void setModified() {
if (!modifiedState) {
modifiedState = true;
for (IModifyListener iModifyListener : modifiedListeners) {
iModifyListener.modified();
}
}
}
/**
* Reset the modified state.
*/
public void clearModified() {
modifiedState = false;
}
/**
* Add listener that wants to be informed when the modified state is
* changed.
*
* @param iModifyListener
*/
public void addModifiedListener(IModifyListener iModifyListener) {
modifiedListeners.add(iModifyListener);
}
/*
* Remove the listener.
*/
public void removeModifiedListener(IModifyListener iModifyListener) {
modifiedListeners.remove(iModifyListener);
}
}

View file

@ -0,0 +1,44 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.archive.ui;
/**
* A Listner to inform when class is modified.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 18, 2013 1966 rferrel Initial creation
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public interface IModifyListener {
/*
* Method called to notify listener that a modification has happened.
*/
public void modified();
}

View file

@ -19,6 +19,9 @@
**/
package com.raytheon.uf.viz.archive.ui;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Combo;
@ -57,6 +60,21 @@ public class RetentionHours {
/** Combo box assume to determine use of Hours or Days. */
private Combo timeUnitCombo;
/**
* Keep track of previous time unit so recalculation only done when changed.
*/
private int prevTimeUnitSelected = 0;
/**
* Set when user modified values.
*/
private boolean modifyState = false;
/**
* Listeners to inform when user performs a modification.
*/
private final List<IModifyListener> listeners = new CopyOnWriteArrayList<IModifyListener>();
/**
* Constructor with default 7 day retention.
*/
@ -76,26 +94,46 @@ public class RetentionHours {
@Override
public void widgetSelected(SelectionEvent e) {
handleTimeSelection();
updateAndCheckTimeSelection();
}
});
timeUnitCombo.removeAll();
timeUnitCombo.add("Hours");
timeUnitCombo.add("Days");
timeUnitCombo.select(0);
timeUnitCombo.select(prevTimeUnitSelected);
timeUnitCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleTimeUnitSelection();
handleTimeSelection();
if (prevTimeUnitSelected != timeUnitCombo.getSelectionIndex()) {
prevTimeUnitSelected = timeUnitCombo.getSelectionIndex();
handleTimeUnitSelection();
updateAndCheckTimeSelection();
}
}
});
timeUnitCombo.setData(timeUnitCombo.getItem(timeUnitCombo
.getSelectionIndex()));
}
/**
* Update the retention hours and determine if modification listeners should
* be notified.
*/
private void updateAndCheckTimeSelection() {
// Make sure this is called so retention hours is updated properly.
boolean modified = handleTimeSelection();
// Do notification when state becomes true.
if (!modifyState && modified) {
modifyState = true;
for (IModifyListener iModifyListener : listeners) {
iModifyListener.modified();
}
}
}
/**
* Get retention in hours.
*
@ -120,11 +158,14 @@ public class RetentionHours {
if (timeUnitCombo.getItem(timeUnitCombo.getSelectionIndex()).equals(
"Days")) {
time /= TimeUtil.HOURS_PER_DAY;
if (time < minUnit) {
time = minUnit;
}
}
timeSpnr.setSelection(time);
// Based on the time unit retentionHours and GUI may need updating.
// Based on the time unit retentionHours may need updating.
handleTimeSelection();
}
@ -177,12 +218,41 @@ public class RetentionHours {
/**
* Adjust retention hours based on combo boxes current values.
*/
protected void handleTimeSelection() {
protected boolean handleTimeSelection() {
int time = timeSpnr.getSelection();
boolean modified = false;
if (timeUnitCombo.getItem(timeUnitCombo.getSelectionIndex()).equals(
"Days")) {
time *= TimeUtil.HOURS_PER_DAY;
}
retentionHours = time;
if (retentionHours != time) {
retentionHours = time;
modified = true;
}
return modified;
}
/**
* Reset the modify state.
*/
public void clearModified() {
modifyState = false;
}
/**
*
* @param iModifyListener
*/
public void addModifyListener(IModifyListener iModifyListener) {
listeners.add(iModifyListener);
}
/**
*
* @param iModifyListener
*/
public void removeModifyListener(IModifyListener iModifyListener) {
listeners.remove(iModifyListener);
}
}