// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.debug.ui.propertypages; import java.util.Collection; import java.util.List; import org.chromium.debug.core.ChromiumDebugPlugin; import org.chromium.debug.core.model.DebugTargetImpl; import org.chromium.debug.core.model.VmResource; import org.chromium.debug.core.util.AccuratenessProperty; import org.chromium.debug.core.util.ChromiumDebugPluginUtil; import org.chromium.debug.core.util.ScriptTargetMapping; import org.chromium.debug.ui.ChromiumJavascriptDecorator; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.PropertyPage; /** * A ui for properties of JS file. Both Virtual project and a regular workspace * files (.js or .html) are supported. */ public class ScriptFilePage extends PropertyPage { private Runnable storeValueCallback = null; @Override protected Control createContents(Composite parent) { Composite main; { main = new Composite(parent, SWT.NONE); GridLayout topLayout = new GridLayout(); topLayout.numColumns = 1; main.setLayout(topLayout); main.setLayoutData(new GridData(GridData.FILL_BOTH)); } IAdaptable adaptable = this.getElement(); IFile file = (IFile) adaptable.getAdapter(IFile.class); List<? extends ScriptTargetMapping> mappingList = ChromiumDebugPlugin.getScriptTargetMapping(file); Control mappingControl; if (mappingList.size() == 1 && isVProjectFile(file, mappingList.get(0))) { mappingControl = buildVProjectFileUi(mappingList.get(0), main); } else { mappingControl = buildWorkspaceFileUi(mappingList, main, file); } mappingControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); return main; } private boolean isVProjectFile(IFile file, ScriptTargetMapping mapping) { // TODO: Consider calling mapping.isVirtualProjectResource() instead. IProject project = file.getProject(); if (project == null) { return false; } boolean hasNature; try { hasNature = project.hasNature(ChromiumDebugPluginUtil.JS_DEBUG_PROJECT_NATURE); } catch (CoreException e) { throw new RuntimeException(e); } // TODO(peter.rybin): here we can check that mapping refers to the same project. return hasNature; } private Composite buildWorkspaceFileUi(final List<? extends ScriptTargetMapping> mappingList, Composite parent, final IFile file) { Composite main; { main = new Composite(parent, SWT.NONE); GridLayout topLayout = new GridLayout(); topLayout.numColumns = 1; main.setLayout(topLayout); } new Label(main, SWT.NONE).setText(Messages.ScriptFilePage_CURRENTLY_LINKED_TO_LABEL); String[] launchLabels = new String[mappingList.size()]; for (int i = 0; i < launchLabels.length; i++) { DebugTargetImpl debugTarget = mappingList.get(i).getConnectedTargetData().getDebugTarget(); launchLabels[i] = debugTarget.getLaunch().getLaunchConfiguration().getName(); } final Combo typesCombo = new Combo(main, SWT.READ_ONLY); typesCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); typesCombo.setFont(parent.getFont()); typesCombo.setItems(launchLabels); if (launchLabels.length > 0) { typesCombo.select(0); final ScriptProperties properties = buildScriptProperties(main); fillScriptProperties(properties, mappingList.get(0)); typesCombo.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { int index = typesCombo.getSelectionIndex(); fillScriptProperties(properties, mappingList.get(index)); } }); } String[] pathSegments = file.getFullPath().segments(); final int oldAccuratenessValue; try { oldAccuratenessValue = AccuratenessProperty.read(file); } catch (CoreException e) { throw new RuntimeException(e); } // Padding. new Label(main, SWT.NONE); Group autoDetectLookupGroup; { autoDetectLookupGroup = new Group(main, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 1; autoDetectLookupGroup.setLayout(layout); } autoDetectLookupGroup.setText(Messages.ScriptFilePage_AUTODETECT_PARAMETER); autoDetectLookupGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); final AccuratenessControl accuratenessControl = new AccuratenessControl(autoDetectLookupGroup, pathSegments, oldAccuratenessValue); storeValueCallback = new Runnable() { private int storedValue = oldAccuratenessValue; @Override public void run() { int value = accuratenessControl.getAccuratenessValue(); if (storedValue == value) { return; } String valueString = AccuratenessProperty.Parser.write(value); try { file.setPersistentProperty(AccuratenessProperty.KEY, valueString); } catch (CoreException e) { throw new RuntimeException(e); } storedValue = value; } }; return main; } public boolean performOk() { if (storeValueCallback != null) { storeValueCallback.run(); } return super.performOk(); } private Composite buildVProjectFileUi(ScriptTargetMapping mapping, Composite parent) { Composite main = new Composite(parent, SWT.NONE); GridLayout topLayout = new GridLayout(); topLayout.numColumns = 1; main.setLayout(topLayout); ScriptProperties properties = buildScriptProperties(main); fillScriptProperties(properties, mapping); return main; } private void fillScriptProperties(ScriptProperties properties, ScriptTargetMapping input) { String fileName; Collection<? extends VmResource> vmResources = input.getVmResources(); String text; if (vmResources.size() == 1) { VmResource resource = vmResources.iterator().next(); text = resource.getId().getVisibleName(); IFile vprojectFile = resource.getVProjectFile(); fileName = ChromiumJavascriptDecorator.getDecoratedText(vprojectFile.getName(), vprojectFile); } else { // TODO: provide better UI for this case. text = Messages.ScriptFilePage_MULTIPLE_AUTODETECT_MATCH; fileName = Messages.ScriptFilePage_MULTIPLE_AUTODETECT_MATCH; } properties.getLocalFileName().setText(fileName); properties.getScriptName().setText(text); } private interface ScriptProperties { Text getScriptName(); Text getLocalFileName(); } private ScriptProperties buildScriptProperties(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout topLayout = new GridLayout(); topLayout.numColumns = 2; composite.setLayout(topLayout); composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); final Text scriptName = createTextField(composite, Messages.ScriptFilePage_SCRIPT_NAME); final Text scriptFile = createTextField(composite, Messages.ScriptFilePage_NAME_IN_VPROJECT); return new ScriptProperties() { public Text getScriptName() { return scriptName; } public Text getLocalFileName() { return scriptFile; } }; } static Text createTextField(Composite parent, String title) { Label label = new Label(parent, SWT.NONE); label.setText(title); GridData gd; gd = new GridData(); gd.verticalAlignment = SWT.TOP; label.setLayoutData(gd); Text valueText = new Text(parent, SWT.WRAP | SWT.READ_ONLY); gd = new GridData(); gd.grabExcessHorizontalSpace = true; gd.horizontalAlignment = GridData.FILL; valueText.setLayoutData(gd); Display display = parent.getDisplay(); valueText.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); return valueText; } }