/*******************************************************************************
* Copyright (c) 2009 IBM Corporation 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:
* IBM Corporation - initial API and implementation
* Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.ui.preferences;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.php.internal.ui.PHPUIMessages;
import org.eclipse.php.internal.ui.PHPUiPlugin;
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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
public class NewPHPManualSiteDialog extends StatusDialog {
private static final String[] FILE_EXT = { "php", "htm", "html" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
private static final boolean isWindows = System.getProperty("os.name").startsWith("Windows"); //$NON-NLS-1$ //$NON-NLS-2$
private static final String FILE_PROTO = "file://"; //$NON-NLS-1$
private static final String CHM_PROTO = "mk:@MSITStore:"; //$NON-NLS-1$
private static final Pattern LANG_DETECT_PATTERN = Pattern.compile("/([a-z_]*)/function\\."); //$NON-NLS-1$
protected Text name;
protected Text url;
private Button okButton;
private boolean enableOK = false;
private List configs;
private PHPManualConfig edited;
private PHPManualConfig result;
private Button remoteSiteBtn;
private Button localDirectoryBtn;
private Button chmFileBtn;
private Text localDir;
private Text chmFile;
private Button dirBrowseButton;
private Button chmBrowseButton;
private Label fileExtLabel;
private Combo fileExtCombo;
public NewPHPManualSiteDialog(Shell parentShell, PHPManualConfig edited, List configs) {
super(parentShell);
this.configs = new ArrayList(configs.size());
for (int i = 0; i < configs.size(); i++) {
PHPManualConfig config = (PHPManualConfig) configs.get(i);
if (!config.equals(edited)) {
this.configs.add(config);
}
}
this.edited = edited;
if (edited != null) {
setTitle(PHPUIMessages.NewPHPManualSiteDialog_updateTitle);
} else {
setTitle(PHPUIMessages.NewPHPManualSiteDialog_newTitle);
}
}
public PHPManualConfig getResult() {
return result;
}
protected void setResult(PHPManualConfig result) {
this.result = result;
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
// super.createButtonBar(parent);
okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
okButton.setEnabled(enableOK);
}
@Override
protected Control createDialogArea(Composite parent) {
initializeDialogUnits(parent);
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = 10;
layout.marginWidth = 15;
layout.verticalSpacing = 10;
composite.setLayout(layout);
GridData data = new GridData();
data.widthHint = 400;
composite.setLayoutData(data);
// --------- Site Name: ---------------------
Composite siteNameGroup = new Composite(composite, SWT.NONE);
layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
siteNameGroup.setLayout(layout);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
siteNameGroup.setLayoutData(data);
Label label = new Label(siteNameGroup, SWT.NONE);
label.setText(PHPUIMessages.NewPHPManualSiteDialog_name);
name = new Text(siteNameGroup, SWT.BORDER);
data = new GridData(GridData.FILL_HORIZONTAL);
name.setLayoutData(data);
name.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
verifyComplete();
}
});
// --------- Remote Site: ---------------------
remoteSiteBtn = new Button(composite, SWT.RADIO);
remoteSiteBtn.setText(PHPUIMessages.NewPHPManualSiteDialog_remoteSiteURL);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
remoteSiteBtn.setLayoutData(data);
remoteSiteBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boolean enabled = remoteSiteBtn.getSelection();
url.setEnabled(enabled);
if (enabled) {
fileExtCombo.select(0);
}
}
});
url = new Text(composite, SWT.BORDER);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalIndent = convertWidthInCharsToPixels(3);
data.horizontalSpan = 2;
url.setLayoutData(data);
url.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
verifyComplete();
}
});
// --------- Local Directory: ---------------------
localDirectoryBtn = new Button(composite, SWT.RADIO);
localDirectoryBtn.setText(PHPUIMessages.NewPHPManualSiteDialog_localDirectory);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
localDirectoryBtn.setLayoutData(data);
localDirectoryBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boolean enabled = localDirectoryBtn.getSelection();
localDir.setEnabled(enabled);
dirBrowseButton.setEnabled(enabled);
if (enabled) {
fileExtCombo.select(2);
}
}
});
localDir = new Text(composite, SWT.BORDER);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalIndent = convertWidthInCharsToPixels(3);
localDir.setLayoutData(data);
localDir.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
verifyComplete();
}
});
dirBrowseButton = new Button(composite, SWT.NULL);
data = new GridData();
data.widthHint = 50;
data.horizontalAlignment = SWT.END;
dirBrowseButton.setLayoutData(data);
dirBrowseButton.setText("..."); //$NON-NLS-1$
dirBrowseButton.setAlignment(SWT.CENTER);
dirBrowseButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
DirectoryDialog dialog = new DirectoryDialog(
PHPUiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.OPEN);
dialog.setText(PHPUIMessages.NewPHPManualSiteDialog_chooseDir);
String directoryAsString = dialog.open();
if (directoryAsString == null) {
return;
}
localDir.setText(directoryAsString);
}
});
// --------- Site Name: ---------------------
if (isWindows) {
chmFileBtn = new Button(composite, SWT.RADIO);
chmFileBtn.setText(PHPUIMessages.NewPHPManualSiteDialog_windowsCHMFile);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
chmFileBtn.setLayoutData(data);
chmFileBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boolean enabled = chmFileBtn.getSelection();
chmFile.setEnabled(enabled);
chmBrowseButton.setEnabled(enabled);
if (enabled) {
fileExtCombo.select(2);
}
}
});
chmFile = new Text(composite, SWT.BORDER);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalIndent = convertWidthInCharsToPixels(3);
chmFile.setLayoutData(data);
chmFile.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
verifyComplete();
}
});
chmBrowseButton = new Button(composite, SWT.NULL);
data = new GridData();
data.widthHint = 50;
data.horizontalAlignment = SWT.END;
chmBrowseButton.setLayoutData(data);
chmBrowseButton.setText("..."); //$NON-NLS-1$
chmBrowseButton.setAlignment(SWT.CENTER);
chmBrowseButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
FileDialog dialog = new FileDialog(
PHPUiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.OPEN);
dialog.setText(PHPUIMessages.NewPHPManualSiteDialog_chooseCHMFile);
dialog.setFilterExtensions(new String[] { "*.chm" }); //$NON-NLS-1$
String fileAsString = dialog.open();
if (fileAsString == null) {
return;
}
chmFile.setText(fileAsString);
}
});
}
Composite fileExtGroup = new Composite(composite, SWT.NONE);
layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
fileExtGroup.setLayout(layout);
data = new GridData();
data.horizontalSpan = 2;
fileExtGroup.setLayoutData(data);
fileExtLabel = new Label(fileExtGroup, SWT.NONE);
data = new GridData(GridData.FILL_HORIZONTAL);
fileExtLabel.setLayoutData(data);
fileExtLabel.setText(PHPUIMessages.NewPHPManualSiteDialog_fileExtension);
fileExtCombo = new Combo(fileExtGroup, SWT.READ_ONLY);
fileExtCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
verifyComplete();
}
});
fileExtCombo.setItems(FILE_EXT);
fileExtCombo.select(0);
initializeFields();
Dialog.applyDialogFont(composite);
return composite;
}
protected void initializeFields() {
if (edited != null) {
name.setText(edited.getLabel());
fileExtCombo.setText(edited.getExtension());
String urlStr = edited.getUrl();
if (isWindows && urlStr.startsWith(CHM_PROTO)) {
urlStr = urlStr.substring(CHM_PROTO.length());
int sepIdx = urlStr.indexOf("::"); //$NON-NLS-1$
if (sepIdx != -1) {
urlStr = urlStr.substring(0, sepIdx);
}
chmFile.setText(urlStr);
chmFileBtn.setSelection(true);
} else if (urlStr.startsWith(FILE_PROTO)) {
urlStr = urlStr.substring(FILE_PROTO.length());
localDir.setText(urlStr);
localDirectoryBtn.setSelection(true);
} else {
url.setText(urlStr);
}
} else {
url.setText("http://www.php.net/manual/en"); //$NON-NLS-1$
remoteSiteBtn.setSelection(true);
}
remoteSiteBtn.notifyListeners(SWT.Selection, new Event());
localDirectoryBtn.notifyListeners(SWT.Selection, new Event());
if (isWindows) {
chmFileBtn.notifyListeners(SWT.Selection, new Event());
}
}
private void verifyComplete() {
if (okButton == null) {
return;
}
if (StringUtils.isBlank(name.getText())) {
okButton.setEnabled(false);
this.updateStatus(new Status(IStatus.ERROR, PHPUiPlugin.getPluginId(), IStatus.OK,
PHPUIMessages.NewPHPManualSiteDialog_siteNotSpecified, null));
return;
}
if (isDuplicate()) {
return;
} else {
okButton.setEnabled(true);
this.updateStatus(new Status(IStatus.OK, PHPUiPlugin.getPluginId(), IStatus.OK, "", null)); //$NON-NLS-1$
}
if (remoteSiteBtn.getSelection()) {
try {
String urlStr = url.getText().trim();
new URL(URLDecoder.decode(urlStr, "UTF-8")); //$NON-NLS-1$
result = new PHPManualConfig(name.getText(), urlStr, fileExtCombo.getText(), false);
} catch (Exception e) {
okButton.setEnabled(false);
this.updateStatus(new Status(IStatus.ERROR, PHPUiPlugin.getPluginId(), IStatus.OK,
PHPUIMessages.NewPHPManualSiteDialog_incorrectUrl, null));
return;
}
} else if (localDirectoryBtn.getSelection()) {
String localDirStr = localDir.getText().trim();
if (!new File(localDirStr).isDirectory()) {
okButton.setEnabled(false);
this.updateStatus(new Status(IStatus.ERROR, PHPUiPlugin.getPluginId(), IStatus.OK,
PHPUIMessages.NewPHPManualSiteDialog_dirDoesntExist, null));
return;
}
result = new PHPManualConfig(name.getText(), FILE_PROTO + localDirStr, fileExtCombo.getText(), false);
} else if (isWindows) {
String chmFileStr = chmFile.getText().trim();
if (!new File(chmFileStr).isFile()) {
okButton.setEnabled(false);
this.updateStatus(new Status(IStatus.ERROR, PHPUiPlugin.getPluginId(), IStatus.OK,
PHPUIMessages.NewPHPManualSiteDialog_fileDoesntExist, null));
return;
}
result = new PHPManualConfig(name.getText(), CHM_PROTO + chmFileStr + detectCHMLanguageSuffix(chmFileStr),
fileExtCombo.getText(), false);
}
}
private boolean isDuplicate() {
if (configs == null) {
return false;
}
for (int i = 0; i < configs.size(); i++) {
if (!isCurrentlyEditedSiteBookmark(i)) {
PHPManualConfig config = (PHPManualConfig) configs.get(i);
if (config.getLabel().equals(name.getText().trim())) {
okButton.setEnabled(false);
this.updateStatus(new Status(IStatus.ERROR, PHPUiPlugin.getPluginId(), IStatus.OK,
PHPUIMessages.NewPHPManualSiteDialog_nameAlreadyInUse, null));
return true;
}
}
}
return false;
}
protected boolean isCurrentlyEditedSiteBookmark(int index) {
return false;
}
@Override
protected void updateButtonsEnableState(IStatus status) {
if (okButton != null && !okButton.isDisposed() && name.getText().trim().length() != 0)
okButton.setEnabled(!status.matches(IStatus.ERROR));
}
private String detectCHMLanguageSuffix(String chmFile) {
StringBuilder suffix = new StringBuilder("::/"); //$NON-NLS-1$
char[] buf = new char[8192];
try {
FileReader r = new FileReader(chmFile);
try {
while (r.ready()) {
r.read(buf);
Matcher m = LANG_DETECT_PATTERN.matcher(new String(buf));
if (m.find()) {
suffix.append(m.group(1));
break;
}
}
} finally {
r.close();
}
} catch (Exception e) {
}
return suffix.toString();
}
}