/*
FileEntry.java
(c) 2015 Edward Swartz
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
*/
package v9t9.gui.client.swt.shells.disk;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.graphics.Image;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.ejs.gui.common.FontUtils;
import v9t9.gui.EmulatorGuiData;
import ejs.base.properties.IProperty;
/**
* @author ejs
*
*/
public abstract class FileEntry extends BaseSettingEntry implements IEntryHistoryListener {
protected Combo combo;
protected Label icon;
protected Image doesNotExistImage;
protected Image blankImage;
protected EntryHistory entryHistory;
private String historyId;
/**
* @param dialog_
* @param parent
* @param setting_
* @param style
*/
public FileEntry(IDeviceSelectorDialog dialog_, Composite parent,
IProperty setting_, int style) {
super(dialog_, parent, setting_, style);
doesNotExistImage = EmulatorGuiData.loadImage(getDisplay(), "icons/error.png");
// blankImage = new Image(getDisplay(), doesNotExistImage.getBounds());
entryHistory = dialog_.getEntryHistory();
historyId = "DiskSelector." + getHistoryName();
}
protected final void validatePath() {
String path = setting.getString();
File file = path != null && !path.isEmpty() ? new File(path) : null;
String err = file != null ? validateFile(file) : "Provide a file path";
if (err == null) {
icon.setImage(blankImage);
icon.setToolTipText("");
// if (combo.indexOf(path) < 0 && file.exists()) {
// // only store history for real places
// combo.add(path);
// setHistory(historyId, combo.getItems());
// }
} else {
icon.setImage(doesNotExistImage);
icon.setToolTipText(err);
}
}
/**
* Validate the given file, returning a string for error
* @param file
* @return error or <code>null</code>
*/
protected abstract String validateFile(File file);
@Override
protected void createControls(final Composite parent) {
GridLayoutFactory.fillDefaults().spacing(2,0).numColumns(8).applyTo(this);
int emSize = FontUtils.measureText(getDisplay(), getFont(), "M").x;
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (doesNotExistImage != null)
doesNotExistImage.dispose();
if (blankImage != null)
blankImage.dispose();
doesNotExistImage = null;
blankImage = null;
entryHistory.removeListener(FileEntry.this);
}
});
Label label = new Label(parent, SWT.NONE);
// assume all the labels are the same size
String text = setting.getLabel() + ": ";
label.setText(text);
GridDataFactory.fillDefaults().hint(text.length()*emSize*2/3, -1).align(SWT.LEFT, SWT.CENTER).applyTo(label);
label.setToolTipText(setting.getDescription());
icon = new Label(parent, SWT.NONE);
icon.setImage(blankImage);
GridDataFactory.fillDefaults().minSize(16, 16).hint(16, 16).applyTo(icon);
combo = new Combo(parent, SWT.BORDER | SWT.DROP_DOWN);
GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(combo);
combo.setToolTipText(setting.getDescription());
String[] history = entryHistory.getItems(historyId);
if (history != null) {
combo.setItems(history);
}
entryHistory.addListener(this);
String str = setting.getString();
combo.setText(str != null ? str : "");
combo.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
updateEntry();
}
});
combo.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
updateEntry();
commitEntry();
}
});
combo.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.character == '\r') {
updateEntry();
commitEntry();
e.doit = false;
}
}
});
final Button browse = new Button(parent, SWT.PUSH);
GridDataFactory.fillDefaults().hint(emSize*10, -1).grab(false, false).applyTo(browse);
browse.setText("Browse...");
browse.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleBrowse(setting);
}
});
final Button eject = new Button(parent, SWT.PUSH);
eject.setImage(EmulatorGuiData.loadImage(getDisplay(), "icons/icon_clear.gif"));
eject.setToolTipText("Clear the entry and remove from history");
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(false, false).applyTo(eject);
eject.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String current = combo.getText();
combo.setText("");
String[] items = entryHistory.getItems(historyId);
List<String> l = new ArrayList<String>(Arrays.asList(items));
l.remove(current);
entryHistory.setHistory(historyId, l.toArray(new String[l.size()]));
updateEntry();
}
});
getDisplay().asyncExec(new Runnable() {
public void run() {
updateEntry();
}
});
}
protected abstract void handleBrowse(IProperty setting);
protected void updateEntry() {
String text = combo.getText();
String path;
if (!text.isEmpty()) {
File dir = new File(combo.getText());
path = dir.getAbsolutePath();
} else {
path = "";
}
switchPath(combo, path);
updateSetting();
}
protected void commitEntry() {
String text = combo.getText();
if (text.isEmpty())
return;
File dir = new File(combo.getText());
String path = dir.getAbsolutePath();
if (combo.indexOf(path) < 0) {
combo.add(path);
entryHistory.setHistory(historyId, combo.getItems());
}
}
protected abstract void switchPath(Combo combo, String path);
protected abstract String getHistoryName();
/* (non-Javadoc)
* @see v9t9.gui.client.swt.shells.disk.IEntryHistoryListener#historyChanged(java.lang.String, java.lang.String[])
*/
@Override
public void historyChanged(final String historyId, final String[] items) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (isDisposed())
return;
if (historyId.equals(FileEntry.this.historyId)) {
String current = combo.getText();
combo.setItems(items);
combo.setText(current);
}
}
});
}
}