package org.syncany.gui.wizard;
import java.io.File;
import org.eclipse.swt.SWT;
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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.syncany.config.Config;
import org.syncany.gui.Panel;
import org.syncany.gui.util.I18n;
import org.syncany.gui.util.SWTResourceManager;
import org.syncany.gui.util.WidgetDecorator;
/**
* @author Vincent Wiencek <vwiencek@gmail.com>
* @author Philipp C. Heckel <philipp.heckel@gmail.com>
*/
public class FolderSelectPanel extends Panel {
public enum SelectFolderValidationMethod {
NO_APP_FOLDER, APP_FOLDER
};
private Text localDir;
private Label descriptionLabel;
private Label warningImageLabel;
private Label warningMessageLabel;
private SelectFolderValidationMethod validationMethod;
private boolean firstValidationDone;
public FolderSelectPanel(WizardDialog wizardParentDialog, Composite parent, int style) {
super(wizardParentDialog, parent, style);
this.createControls();
this.firstValidationDone = false;
}
private void createControls() {
// Main composite
GridLayout mainCompositeGridLayout = new GridLayout(3, false);
mainCompositeGridLayout.marginTop = 15;
mainCompositeGridLayout.marginLeft = 10;
mainCompositeGridLayout.marginRight = 20;
setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
setLayout(mainCompositeGridLayout);
// Title and description
Label titleLabel = new Label(this, SWT.WRAP);
titleLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 3, 1));
titleLabel.setText(I18n.getText("org.syncany.gui.wizard.FolderSelectPanel.title"));
WidgetDecorator.title(titleLabel);
descriptionLabel = new Label(this, SWT.WRAP);
descriptionLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 3, 1));
WidgetDecorator.normal(descriptionLabel);
// Label "Folder:"
GridData selectFolderLabelGridDate = new GridData(SWT.LEFT, SWT.CENTER, false, false);
selectFolderLabelGridDate.verticalIndent = WidgetDecorator.VERTICAL_INDENT;
selectFolderLabelGridDate.horizontalSpan = 3;
Label selectFolderLabel = new Label(this, SWT.WRAP);
selectFolderLabel.setLayoutData(selectFolderLabelGridDate);
selectFolderLabel.setText(I18n.getText("org.syncany.gui.wizard.FolderSelectPanel.selectFolderLabel"));
// Textfield "Folder"
GridData folderTextGridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
folderTextGridData.verticalIndent = 0;
folderTextGridData.horizontalSpan = 2;
folderTextGridData.minimumWidth = 200;
localDir = new Text(this, SWT.BORDER);
localDir.setLayoutData(folderTextGridData);
localDir.setBackground(WidgetDecorator.WHITE);
localDir.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
if (firstValidationDone) {
validatePanel(false);
}
}
});
WidgetDecorator.normal(localDir);
// Button "Select ..."
Button selectFolderButton = new Button(this, SWT.FLAT);
selectFolderButton.setText(I18n.getText("org.syncany.gui.wizard.FolderSelectPanel.selectLocalFolderButton"));
selectFolderButton.setLayoutData(new GridData(SWT.LEFT, SWT.BOTTOM, false, false, 1, 1));
selectFolderButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onSelectFolderClick();
}
});
WidgetDecorator.normal(selectFolderLabel);
// Warning message and label
String warningImageResource = "/" + WizardDialog.class.getPackage().getName().replace(".", "/") + "/warning-icon.png";
Image warningImage = SWTResourceManager.getImage(warningImageResource);
warningImageLabel = new Label(this, SWT.NONE);
warningImageLabel.setImage(warningImage);
warningImageLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1));
warningImageLabel.setVisible(false);
warningMessageLabel = new Label(this, SWT.WRAP);
warningMessageLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
warningMessageLabel.setVisible(false);
WidgetDecorator.bold(warningMessageLabel);
}
public void reset(SelectFolderValidationMethod validationMethod) {
this.validationMethod = validationMethod;
firstValidationDone = false;
localDir.setText("");
hideWarning();
}
public void setDescriptionText(final String descriptionTextStr) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (!descriptionLabel.isDisposed()) {
descriptionLabel.setText(descriptionTextStr);
}
layout();
}
});
}
@Override
public boolean validatePanel() {
return validatePanel(true);
}
private boolean validatePanel(boolean allowAskFolderCreate) {
firstValidationDone = true;
switch (validationMethod) {
case APP_FOLDER:
return isValidAppFolder();
case NO_APP_FOLDER:
return isValidNoAppFolder(allowAskFolderCreate);
default:
throw new RuntimeException("Invalid validation method: " + validationMethod);
}
}
private boolean isValidNoAppFolder(boolean allowAskFolderCreate) {
File selectedDir = new File(localDir.getText());
File appDir = new File(selectedDir, Config.DIR_APPLICATION);
if (localDir.getText().isEmpty()) {
showWarning(I18n.getText("org.syncany.gui.wizard.FolderSelectPanel.errorInvalidFolder"));
WidgetDecorator.markAsInvalid(localDir);
return false;
}
else if (appDir.exists()) {
showWarning(I18n.getText("org.syncany.gui.wizard.FolderSelectPanel.errorInitializedFolder"));
WidgetDecorator.markAsInvalid(localDir);
return false;
}
else {
if (!selectedDir.isDirectory()) {
boolean allowCreate = allowAskFolderCreate && askCreateFolder(getShell(), selectedDir);
if (allowCreate) {
if (selectedDir.mkdirs()) {
hideWarning();
WidgetDecorator.markAsValid(localDir);
return true;
}
else {
showWarning(I18n.getText("org.syncany.gui.wizard.FolderSelectPanel.errorCannotCreateFolder"));
WidgetDecorator.markAsInvalid(localDir);
return false;
}
}
else {
hideWarning();
WidgetDecorator.markAsValid(localDir);
return false;
}
}
else {
hideWarning();
WidgetDecorator.markAsValid(localDir);
return true;
}
}
}
private boolean isValidAppFolder() {
File selectedDir = new File(localDir.getText());
File appDir = new File(selectedDir, Config.DIR_APPLICATION);
if (appDir.exists()) {
hideWarning();
return true;
}
else {
showWarning(I18n.getText("org.syncany.gui.wizard.FolderSelectPanel.errorNoValidFolder"));
return false;
}
}
private void showWarning(String warningStr) {
warningImageLabel.setVisible(true);
warningMessageLabel.setVisible(true);
warningMessageLabel.setText(warningStr);
WidgetDecorator.markAsInvalid(localDir);
}
private void hideWarning() {
warningImageLabel.setVisible(false);
warningMessageLabel.setVisible(false);
WidgetDecorator.markAsValid(localDir);
}
private boolean askCreateFolder(Shell shell, File selectedDir) {
MessageBox dialog = new MessageBox(shell, SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL);
dialog.setText(I18n.getText("org.syncany.gui.wizard.FolderSelectPanel.askCreate.title"));
dialog.setMessage(I18n.getText("org.syncany.gui.wizard.FolderSelectPanel.askCreate.description", selectedDir.getAbsolutePath()));
int returnCode = dialog.open();
if (returnCode == SWT.OK) {
return true;
}
return false;
}
private void onSelectFolderClick() {
DirectoryDialog directoryDialog = new DirectoryDialog(getShell());
directoryDialog.setFilterPath(localDir.getText());
String selectedFolder = directoryDialog.open();
if (selectedFolder != null && selectedFolder.length() > 0) {
localDir.setText(selectedFolder);
validatePanel();
}
}
public File getFolder() {
return new File(localDir.getText());
}
}