package org.syncany.gui.wizard;
import java.io.File;
import java.lang.reflect.Type;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
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.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.syncany.gui.util.SWTResourceManager;
import org.syncany.gui.util.WidgetDecorator;
import org.syncany.plugins.Plugin;
import org.syncany.plugins.Plugins;
import org.syncany.plugins.transfer.StorageException;
import org.syncany.plugins.transfer.TransferPlugin;
import org.syncany.plugins.transfer.TransferPluginOption;
import org.syncany.plugins.transfer.TransferPluginOptions;
import org.syncany.plugins.transfer.TransferSettings;
import org.syncany.util.EnvironmentUtil;
/**
* @author Philipp C. Heckel <philipp.heckel@gmail.com>
*/
public class PluginSelectComposite extends Composite {
private static final Logger logger = Logger.getLogger(PluginSelectComposite.class.getSimpleName());
private static final String PLUGIN_ICON_RESOURCE_FORMAT = "/" + Plugin.class.getPackage().getName().replace('.', '/') + "/%s/icon24.png";
private Table pluginTable;
private List<TransferPlugin> plugins;
private TransferPlugin selectedPlugin;
public PluginSelectComposite(Composite parent, int style) {
super(parent, style);
this.plugins = Plugins.list(TransferPlugin.class);
this.selectedPlugin = null;
this.createControls();
}
private void createControls() {
// Main composite
GridLayout mainCompositeGridLayout = new GridLayout(1, true);
mainCompositeGridLayout.marginTop = 0;
mainCompositeGridLayout.marginLeft = 0;
mainCompositeGridLayout.marginRight = 0;
mainCompositeGridLayout.marginBottom = 0;
mainCompositeGridLayout.horizontalSpacing = 0;
mainCompositeGridLayout.verticalSpacing = 0;
setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
setLayout(mainCompositeGridLayout);
// Plugin list
GridData pluginTableGridData = new GridData(SWT.FILL, SWT.FILL, true, true);
pluginTableGridData.verticalIndent = 0;
pluginTableGridData.horizontalIndent = 0;
pluginTable = new Table(this, SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
pluginTable.setHeaderVisible(false);
pluginTable.setLayoutData(pluginTableGridData);
if (EnvironmentUtil.isWindows()) {
pluginTable.setBackground(WidgetDecorator.WHITE);
}
pluginTable.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
// Set selected plugin
if (pluginTable.getSelectionIndex() >= 0) {
TableItem tableItem = pluginTable.getItem(pluginTable.getSelectionIndex());
selectedPlugin = (TransferPlugin) tableItem.getData();
}
else {
selectedPlugin = null;
}
// Fix flickering images
pluginTable.redraw();
}
});
pluginTable.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
PluginSelectComposite.this.notifyListeners(SWT.FocusIn, new Event());
}
});
pluginTable.addListener(SWT.MeasureItem, new Listener() {
public void handleEvent(Event event) {
event.height = 30; // Row height workaround
}
});
pluginTable.getVerticalBar().addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
pluginTable.redraw(); // Fix flickering images (when scrolling)
}
});
TableColumn pluginTableColumnImage = new TableColumn(pluginTable, SWT.CENTER);
pluginTableColumnImage.setWidth(30);
TableColumn pluginTableColumnText = new TableColumn(pluginTable, SWT.LEFT);
pluginTableColumnText.setWidth(320); // Only relevant on Windows
for (TransferPlugin plugin : plugins) {
if (isSupportedPlugin(plugin)) {
String pluginImageResource = String.format(PLUGIN_ICON_RESOURCE_FORMAT, plugin.getId());
Image image = SWTResourceManager.getImage(pluginImageResource);
TableItem tableItem = new TableItem(pluginTable, SWT.NONE);
tableItem.setImage(0, image);
tableItem.setText(1, plugin.getName());
tableItem.setData(plugin);
}
}
}
private boolean isSupportedPlugin(TransferPlugin plugin) {
try {
TransferSettings pluginSettings = plugin.createEmptySettings();
List<TransferPluginOption> pluginOptions = TransferPluginOptions.getOrderedOptions(pluginSettings.getClass());
for (TransferPluginOption pluginOption : pluginOptions) {
if (pluginOption.isVisible()) {
Type optionType = pluginOption.getType();
boolean optionSupported = optionType == String.class
|| optionType == int.class
|| optionType == File.class
|| (optionType instanceof Class && ((Class<?>) optionType).isEnum());
if (!optionSupported) {
logger.log(Level.FINE, "- Plugin '" + plugin.getId() + "' is NOT supported by the GUI; reason is option '" + pluginOption.getName() + "' of type '" + pluginOption.getType() + "'.");
return false;
}
}
}
logger.log(Level.FINE, "- Plugin '" + plugin.getId() + "' is supported by the GUI.");
return true;
}
catch (StorageException e) {
logger.log(Level.FINE, "- Plugin '" + plugin.getId() + "' is NOT supported by the GUI; reason is an exception.", e);
return false;
}
}
public TransferPlugin getSelectedPlugin() {
return selectedPlugin;
}
public void clearSelection() {
pluginTable.deselectAll();
selectedPlugin = null;
}
}