/**
* This file Copyright (c) 2005-2008 Aptana, Inc. This program is
* dual-licensed under both the Aptana Public License and the GNU General
* Public license. You may elect to use one or the other of these licenses.
*
* This program is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. Redistribution, except as permitted by whichever of
* the GPL or APL you select, is prohibited.
*
* 1. For the GPL license (GPL), you can redistribute and/or modify this
* program under the terms of the GNU General Public License,
* Version 3, as published by the Free Software Foundation. You should
* have received a copy of the GNU General Public License, Version 3 along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Aptana provides a special exception to allow redistribution of this file
* with certain Eclipse Public Licensed code and certain additional terms
* pursuant to Section 7 of the GPL. You may view the exception and these
* terms on the web at http://www.aptana.com/legal/gpl/.
*
* 2. For the Aptana Public License (APL), this program and the
* accompanying materials are made available under the terms of the APL
* v1.0 which accompanies this distribution, and is available at
* http://www.aptana.com/legal/apl/.
*
* You may view the GPL, Aptana's exception and additional terms, and the
* APL in the file titled license.html at the root of the corresponding
* plugin containing this source file.
*
* Any modifications to this file must keep this entire header intact.
*/
package com.aptana.ide.editor.html.preview;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
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.graphics.RGB;
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.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
import com.aptana.ide.editor.html.BrowserExtensionLoader;
import com.aptana.ide.editor.html.HTMLPlugin;
import com.aptana.ide.editor.html.MultiPageHTMLEditor;
import com.aptana.ide.editor.html.preferences.IPreferenceConstants;
import com.aptana.ide.editors.UnifiedEditorsPlugin;
import com.aptana.ide.editors.unified.ContributedBrowser;
import com.aptana.ide.editors.unified.UnifiedColorManager;
import com.aptana.ide.server.core.IServer;
/**
* @author Kevin Sawicki (ksawicki@aptana.com)
*/
public class PreviewConfigurationPage extends BasePreviewConfigurationPage
{
/**
* DEFAULT_PREVIEW_NAME
*/
public static final String DEFAULT_PREVIEW_NAME = "New Preview"; //$NON-NLS-1$
private Map<String, Button> buttons = new HashMap<String, Button>();
private Composite displayArea;
private Composite browserArea;
private Composite editArea;
private PreviewTypeSelectionBlock block;
private Button save;
private Button cancel;
private Label status;
private Label nameLabel;
private Text nameText;
private ProgressListener listener;
private Listener locListener;
private Event lastEvent = null;
/**
* Creates a new preview configuration page
*
* @param editor
*/
public PreviewConfigurationPage(MultiPageHTMLEditor editor)
{
super(editor);
this.title = DEFAULT_PREVIEW_NAME;
this.url = this.editor.getURL();
this.type = HTMLPreviewPropertyPage.FILE_BASED_TYPE;
this.value = null;
block = new PreviewTypeSelectionBlock();
block.setEditor(editor);
locListener = new Listener()
{
public void handleEvent(Event event)
{
if (lastEvent == null || event.time > lastEvent.time)
{
lastEvent = event;
if (event.data instanceof Image)
{
PreviewConfigurationPage.this.editor.setTabIcon(PreviewConfigurationPage.this,
(Image) event.data);
String addOn = event.text;
if (addOn != null)
{
PreviewConfigurationPage.this.editor.setTabTooltip(PreviewConfigurationPage.this, url + " " //$NON-NLS-1$
+ event.text);
}
}
}
}
};
listener = new ProgressListener()
{
public void completed(ProgressEvent event)
{
BrowserExtensionLoader.getDecorator(browser, locListener);
}
public void changed(ProgressEvent event)
{
}
};
}
/**
* Creates the preview page control
*
* @param parent -
* parent of preview page
*/
public void createControl(Composite parent)
{
displayArea = new Composite(parent, SWT.NONE);
GridLayout daLayout = new GridLayout(1, false);
daLayout.marginHeight = 0;
daLayout.marginWidth = 0;
displayArea.setLayout(daLayout);
displayArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
this.editArea = new Composite(displayArea, SWT.NONE);
GridLayout eaLayout = new GridLayout(1, false);
eaLayout.marginWidth = 10;
eaLayout.marginHeight = 10;
editArea.setLayout(eaLayout);
editArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
this.browserArea = new Composite(displayArea, SWT.NONE);
GridData baData = new GridData(SWT.FILL, SWT.FILL, true, true);
baData.exclude = true;
GridLayout baLayout = new GridLayout(1, false);
baLayout.marginHeight = 0;
baLayout.marginWidth = 0;
this.browserArea.setLayout(baLayout);
this.browserArea.setLayoutData(baData);
this.browserArea.setVisible(false);
Composite optionsArea = createConfigurationSection(this.editArea);
createStartActionSection(optionsArea);
createBrowserSection(optionsArea);
createButtonSection(this.editArea);
block.updateControls();
validate();
}
/**
* @see com.aptana.ide.editor.html.preview.IPreviewConfigurationPage#run(java.lang.String)
*/
public boolean run(String actionID)
{
boolean run = false;
try
{
if (IWorkbenchActionDefinitionIds.CUT.equals(actionID))
{
if (this.nameText.isFocusControl())
{
this.nameText.cut();
run = true;
}
else if (block.getStartURLText().isFocusControl())
{
block.getStartURLText().cut();
run = true;
}
else if (block.getCurrentURLText().isFocusControl())
{
run = true;
}
}
else if (IWorkbenchActionDefinitionIds.PASTE.equals(actionID))
{
if (this.nameText.isFocusControl())
{
this.nameText.paste();
run = true;
}
else if (block.getStartURLText().isFocusControl())
{
block.getStartURLText().paste();
run = true;
}
else if (block.getCurrentURLText().isFocusControl())
{
run = true;
}
}
else if (IWorkbenchActionDefinitionIds.COPY.equals(actionID))
{
if (this.nameText.isFocusControl())
{
this.nameText.copy();
run = true;
}
else if (block.getStartURLText().isFocusControl())
{
block.getStartURLText().copy();
run = true;
}
else if (block.getCurrentURLText().isFocusControl())
{
block.getCurrentURLText().copy();
run = true;
}
}
}
catch (Exception e)
{
run = false;
}
catch (Error e)
{
run = false;
}
return run;
}
/**
* Sets the browser object and its name albe
*
* @param browser
* @param label
*/
public void setBrowser(ContributedBrowser browser, String label)
{
Button button = (Button) buttons.get(label);
if (button != null && !button.isDisposed())
{
button.setSelection(true);
Iterator iter = buttons.values().iterator();
while (iter.hasNext())
{
Button other = (Button) iter.next();
if (other != button && other != null)
{
other.setSelection(false);
}
}
}
if (this.browser != null)
{
this.browser.dispose();
this.browser.removeProgressListener(listener);
}
this.browserLabel = label;
this.browser = browser;
this.created = false;
}
/**
* Sets the title of the preview page
*
* @param title
*/
public void setTitle(String title)
{
if (this.nameText != null && !this.nameText.isDisposed())
{
this.nameText.setText(title);
}
super.setTitle(title);
}
/**
* Displays the edit area of this preview page
*/
public void showEditArea()
{
GridData eaData = (GridData) editArea.getLayoutData();
eaData.exclude = false;
GridData baData = (GridData) browserArea.getLayoutData();
baData.exclude = true;
this.browserArea.setVisible(false);
this.editArea.setVisible(true);
displayArea.layout(true, true);
}
/**
* Displays the browser area of this preview page
*/
public void showBrowserArea()
{
GridData eaData = (GridData) editArea.getLayoutData();
eaData.exclude = true;
GridData baData = (GridData) browserArea.getLayoutData();
baData.exclude = false;
this.browserArea.setVisible(true);
this.editArea.setVisible(false);
displayArea.layout(true, true);
Button button = (Button) buttons.get(this.browserLabel);
if (button != null && !button.isDisposed())
{
button.setSelection(true);
Iterator iter = buttons.values().iterator();
while (iter.hasNext())
{
Button other = (Button) iter.next();
if (other != button && other != null)
{
other.setSelection(false);
}
}
}
block.refreshURLs();
block.updateControls();
block.updateCurrentURL();
this.validate();
}
/**
* @see com.aptana.ide.editor.html.preview.BasePreviewConfigurationPage#getURL()
*/
public String getURL()
{
return block.getCurrentURLText().getText();
}
/**
* Sets the url of the preview page
*
* @param url
*/
public void setURL(String url)
{
if (this.browser != null)
{
if (!created)
{
created = true;
this.browser.createControl(browserArea);
this.browser.addProgressListener(listener);
browserArea.layout(true, true);
}
if (block.getFileButton().getSelection())
{
this.url = url;
}
else if (block.getServerButton().getSelection())
{
Object data = block.getServerText().getData();
if (data != null && data instanceof IServer)
{
String serverURL = HTMLPreviewHelper.getServerURL((IServer) data, editor.getEditorInput(), block
.getServerAppendButton().getSelection());
if (serverURL != null)
{
this.url = serverURL;
}
}
}
else if (block.getServerButton().getSelection())
{
Object data = block.getServerText().getData();
if (data != null && data instanceof ILaunchConfiguration)
{
String configURL = HTMLPreviewHelper.getConfigURL((ILaunchConfiguration) data, editor
.getEditorInput());
if (configURL != null)
{
this.url = configURL;
}
}
}
else
{
this.url = block.getStartURLText().getText();
if (block.getStartURLAppendButton().getSelection())
{
IEditorInput input = this.editor.getEditorInput();
this.url = HTMLPreviewHelper.getAbsoluteURL(value, input,
HTMLPreviewPropertyPage.APPENDED_ABSOLUTE_BASED_TYPE.equals(type));
}
if (this.url == null || this.url.length() == 0)
{
this.url = url;
}
}
block.getCurrentURLText().setText(this.url);
editor.setTabTooltip(this, this.url);
this.browser.setURL(this.url);
}
}
/**
* Saves the browser settings
*/
public void saveBrowserSettings()
{
Iterator<Button> iter = this.buttons.values().iterator();
while (iter.hasNext())
{
Button b = iter.next();
if (b.getSelection())
{
this.browserLabel = b.getText();
break;
}
}
IExtensionRegistry reg = Platform.getExtensionRegistry();
IExtensionPoint ep = reg.getExtensionPoint(UnifiedEditorsPlugin.BROWSER_EXTENSION_POINT);
IExtension[] extensions = ep.getExtensions();
boolean found = false;
for (int i = 0; i < extensions.length && !found; i++)
{
IConfigurationElement[] ce = extensions[i].getConfigurationElements();
for (int j = 0; j < ce.length && !found; j++)
{
String browserClass = ce[j].getAttribute(UnifiedEditorsPlugin.CLASS_ATTR);
String name = BrowserExtensionLoader.getBrowserLabel(ce[j]);
if (browserClass != null && name != null && name.equals(browserLabel))
{
found = true;
Object obj;
try
{
obj = ce[j].createExecutableExtension(UnifiedEditorsPlugin.CLASS_ATTR);
if (obj instanceof ContributedBrowser)
{
this.setBrowser((ContributedBrowser) obj, name);
}
}
catch (CoreException e)
{
}
}
}
}
}
/**
* Saves the page
*/
public void save()
{
if (block.getServerButton().getSelection())
{
if (block.getServerAppendButton().getSelection())
{
this.type = HTMLPreviewPropertyPage.APPENDED_SERVER_BASED_TYPE;
}
else
{
this.type = HTMLPreviewPropertyPage.SERVER_BASED_TYPE;
}
}
else if (block.getConfigurationButton().getSelection())
{
this.type = HTMLPreviewPropertyPage.CONFIG_BASED_TYPE;
}
else if (block.getStartURLButton().getSelection())
{
if (block.getStartURLAppendButton().getSelection())
{
this.type = HTMLPreviewPropertyPage.APPENDED_ABSOLUTE_BASED_TYPE;
}
else
{
this.type = HTMLPreviewPropertyPage.ABSOLUTE_BASED_TYPE;
}
}
else
{
this.type = HTMLPreviewPropertyPage.FILE_BASED_TYPE;
}
if (block.getServerButton().getSelection())
{
Object obj = block.getServerText().getData();
if (obj != null && obj instanceof IServer)
{
this.value = ((IServer) obj).getId();
}
else
{
this.value = block.getServerText().getText();
}
}
else if (block.getConfigurationButton().getSelection())
{
this.value = block.getConfigurationText().getText();
}
else if (block.getStartURLButton().getSelection())
{
this.value = block.getStartURLText().getText().trim();
}
else
{
IEditorInput input = editor.getEditorInput();
if (input instanceof IFileEditorInput)
{
value = ((IFileEditorInput) input).getFile().getLocation().makeAbsolute().toOSString();
}
}
if (block.getStartURLButton().getSelection())
{
block.saveURLs();
}
saveBrowserSettings();
title = nameText.getText();
editor.setPreviewPageText(this.index, this.title);
setURL(this.url);
block.setType(this.type);
block.setValue(this.value);
editor.savePreviewsPages();
showBrowserArea();
}
private void createButtonSection(Composite parent)
{
Composite buttons = new Composite(parent, SWT.NONE);
GridLayout bLayout = new GridLayout(3, false);
bLayout.marginHeight = 0;
bLayout.marginWidth = 0;
buttons.setLayout(bLayout);
GridData bData = new GridData(SWT.FILL, SWT.FILL, true, false);
buttons.setLayoutData(bData);
save = new Button(buttons, SWT.PUSH);
save.setText(Messages.PreviewConfigurationPage_LBL_Save);
save.setToolTipText(Messages.PreviewConfigurationPage_TTP_Save);
save.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
save();
}
});
save.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
cancel = new Button(buttons, SWT.PUSH);
cancel.setText(Messages.PreviewConfigurationPage_LBL_Cancel);
cancel.setToolTipText(Messages.PreviewConfigurationPage_TTP_Cancel);
cancel.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
if (created)
{
showBrowserArea();
}
else
{
// This case if when add is added and then cancel is selected. The page will be removed since it was
// never saved since being added and so cancel seems appropriate to remove
if (editor != null && index >= 0 && index < editor.getPageCount())
{
editor.removePage(index);
}
}
}
});
cancel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
status = new Label(buttons, SWT.LEFT);
status.setForeground(UnifiedColorManager.getInstance().getColor(new RGB(255, 0, 0)));
status.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
}
private Composite createConfigurationSection(Composite parent)
{
Group group = new Group(parent, SWT.FLAT | SWT.SHADOW_IN);
group.setText(Messages.PreviewConfigurationPage_LBL_OptionsGroup);
group.setFont(parent.getFont());
group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
GridLayout layout = new GridLayout(2, false);
layout.marginHeight *= 2;
layout.marginWidth *= 2;
group.setLayout(layout);
nameLabel = new Label(group, SWT.LEFT);
nameLabel.setText(Messages.PreviewConfigurationPage_LBL_PreviewName);
nameText = new Text(group, SWT.SINGLE | SWT.BORDER);
nameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
nameText.setText(title);
nameText.addModifyListener(new ModifyListener()
{
public void modifyText(ModifyEvent e)
{
validate();
}
});
return group;
}
/**
* Generates a new preview name
*
* @return - unique name
*/
public String generateNewPreviewName()
{
IFile file = getFile();
String name = null;
if (file != null)
{
try
{
String names = file.getPersistentProperty(new QualifiedName("", //$NON-NLS-1$
HTMLPreviewPropertyPage.HTML_PREVIEW_ADDON_NAMES));
if (names != null)
{
String[] splitNames = names.split(HTMLPreviewPropertyPage.PREFERENCE_DELIMITER);
boolean foundName = false;
name = DEFAULT_PREVIEW_NAME;
int tries = 1;
while (!foundName)
{
for (int i = 0; i < splitNames.length; i++)
{
if (name.equals(splitNames[i]))
{
name = DEFAULT_PREVIEW_NAME + " " + tries; //$NON-NLS-1$
tries++;
break;
}
else if (i + 1 == splitNames.length)
{
foundName = true;
break;
}
}
}
}
else
{
name = DEFAULT_PREVIEW_NAME;
}
}
catch (CoreException e)
{
name = DEFAULT_PREVIEW_NAME;
}
}
else
{
name = DEFAULT_PREVIEW_NAME;
}
return name;
}
private void validate()
{
IFile file = getFile();
String name = nameText.getText();
boolean error = false;
if (name.trim().length() == 0)
{
error = true;
status.setText(Messages.PreviewConfigurationPage_LBL_Status_Name);
}
else if (block.getStartURLButton().getSelection())
{
if (block.getStartURLText().getText().trim().length() == 0)
{
status.setText(Messages.PreviewConfigurationPage_LBL_Status_URL);
error = true;
}
}
else if (file != null)
{
try
{
String names = file.getPersistentProperty(new QualifiedName("", //$NON-NLS-1$
HTMLPreviewPropertyPage.HTML_PREVIEW_ADDON_NAMES));
if (names != null)
{
String[] splitNames = names.split(HTMLPreviewPropertyPage.PREFERENCE_DELIMITER);
for (int i = 0; i < splitNames.length; i++)
{
if (!splitNames[i].equals(title) && name.equals(splitNames[i]))
{
status.setText(Messages.PreviewConfigurationPage_LBL_Status_NameExists);
error = true;
break;
}
}
}
}
catch (CoreException e)
{
}
}
save.setEnabled(!error);
if (!error)
{
status.setText(""); //$NON-NLS-1$
}
}
private IFile getFile()
{
IFile file = null;
IEditorInput input = this.editor.getEditorInput();
if (input instanceof FileEditorInput)
{
file = ((FileEditorInput) input).getFile();
}
return file;
}
private IProject getProject()
{
IProject project = null;
IFile file = getFile();
if (file != null)
{
project = file.getProject();
}
return project;
}
private void createBrowserSection(Composite parent)
{
Group group = new Group(parent, SWT.FLAT | SWT.SHADOW_IN);
group.setText(Messages.PreviewConfigurationPage_LBL_BrowserGroup);
group.setFont(parent.getFont());
GridData gData = new GridData(SWT.FILL, SWT.FILL, true, false);
gData.horizontalSpan = 2;
group.setLayoutData(gData);
GridLayout layout = new GridLayout(1, false);
layout.marginHeight *= 2;
layout.marginWidth *= 2;
group.setLayout(layout);
List labels = BrowserExtensionLoader.getAllBrowserLabels();
for (int i = 0; i < labels.size(); i++)
{
String label = (String) labels.get(i);
final Button browserButton = new Button(group, SWT.RADIO);
Image image = BrowserExtensionLoader.getBrowserImage(label);
if (image != null)
{
browserButton.setImage(image);
}
browserButton.setText(label);
if (i == 0)
{
browserLabel = label;
browserButton.setSelection(true);
}
buttons.put(label, browserButton);
}
}
private void createStartActionSection(Composite parent)
{
block.createStartActionSection(parent, this.type, this.value);
ModifyListener validator = new ModifyListener()
{
public void modifyText(ModifyEvent e)
{
validate();
}
};
block.getStartURLButton().addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
validate();
}
});
block.getStartURLText().addModifyListener(validator);
}
/**
* Gets the control of the preview page
*
* @return - control
*/
public Control getControl()
{
return this.displayArea;
}
private ILaunchConfiguration getWorkspaceConfig()
{
ILaunchConfiguration config = null;
IPreferenceStore store = HTMLPlugin.getDefault().getPreferenceStore();
String configName = store.getString(IPreferenceConstants.HTMLEDITOR_RUNCONFIG_PREVIEW_PREFERENCE);
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType type = launchManager
.getLaunchConfigurationType("com.aptana.ide.debug.core.jsLaunchConfigurationType"); //$NON-NLS-1$
try
{
ILaunchConfiguration[] configs = launchManager.getLaunchConfigurations(type);
if (configs != null)
{
for (int i = 0; i < configs.length; i++)
{
if (configs[i].getName().equals(configName))
{
config = configs[i];
break;
}
}
}
}
catch (CoreException e)
{
config = null;
}
return config;
}
/**
* @return the config
*/
public ILaunchConfiguration getConfig()
{
ILaunchConfiguration config = null;
IProject project = getProject();
if (project != null)
{
try
{
String override = project.getPersistentProperty(new QualifiedName("", //$NON-NLS-1$
HTMLPreviewPropertyPage.HTML_PREVIEW_OVERRIDE));
if (HTMLPreviewPropertyPage.TRUE.equals(override))
{
String configName = project.getPersistentProperty(new QualifiedName("", //$NON-NLS-1$
HTMLPreviewPropertyPage.HTML_PREVIEW_CONFIG));
if (configName != null)
{
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType type = launchManager
.getLaunchConfigurationType("com.aptana.ide.debug.core.jsLaunchConfigurationType"); //$NON-NLS-1$
ILaunchConfiguration[] configs = launchManager.getLaunchConfigurations(type);
if (configs != null)
{
for (int i = 0; i < configs.length; i++)
{
if (configs[i].getName().equals(configName))
{
config = configs[i];
break;
}
}
}
}
}
else
{
config = getWorkspaceConfig();
}
}
catch (CoreException e)
{
config = null;
}
}
else
{
config = getWorkspaceConfig();
}
return config;
}
/**
* @see com.aptana.ide.editor.html.preview.IPreviewConfigurationPage#isDeletable()
*/
public boolean isDeletable()
{
return true;
}
/**
* @see com.aptana.ide.editor.html.preview.IPreviewConfigurationPage#isReadOnly()
*/
public boolean isReadOnly()
{
return false;
}
}