/*=============================================================================# # Copyright (c) 2015-2016 Stephan Wahlbrink (WalWare.de) 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: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.docmlet.base.internal.ui.viewer; import java.util.HashMap; import java.util.Map; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.UpdateValueStrategy; import org.eclipse.core.databinding.observable.Realm; import org.eclipse.core.databinding.observable.value.WritableValue; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.variables.IStringVariable; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.ILaunchConfigurationDialog; import org.eclipse.jface.databinding.swt.WidgetProperties; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import de.walware.jcommons.collections.ImCollections; import de.walware.jcommons.collections.ImList; import de.walware.ecommons.databinding.core.conversion.StringTrimConverter; import de.walware.ecommons.databinding.core.util.UpdateableErrorValidator; import de.walware.ecommons.debug.core.variables.ResourceVariableResolver; import de.walware.ecommons.debug.core.variables.ResourceVariables; import de.walware.ecommons.debug.ui.config.InputArgumentsComposite; import de.walware.ecommons.debug.ui.config.LaunchConfigPresets; import de.walware.ecommons.debug.ui.config.LaunchConfigTabWithPresets; import de.walware.ecommons.io.win.DDE; import de.walware.ecommons.ui.SharedMessages; import de.walware.ecommons.ui.SharedUIResources; import de.walware.ecommons.ui.util.DialogUtil; import de.walware.ecommons.ui.util.LayoutUtil; import de.walware.ecommons.ui.workbench.ResourceInputComposite; import de.walware.ecommons.ui.workbench.ResourceVariableUtil; import de.walware.ecommons.variables.core.VariableText2; import de.walware.ecommons.variables.core.VariableTextValidator; import de.walware.ecommons.variables.core.VariableUtils; import de.walware.docmlet.base.ui.processing.DocProcessingConfig; import de.walware.docmlet.base.ui.viewer.DocViewerConfig; public class DocViewerMainTab extends LaunchConfigTabWithPresets { private static class DDETask { final String attrQualifier; final String title; final String label; final WritableValue commandValue; final WritableValue applicationValue; final WritableValue topicValue; InputArgumentsComposite commandControl; Text applicationControl; Text topicControl; public DDETask(final String attrQualifier, final Realm realm, final String title, final String label) { this.attrQualifier= attrQualifier; this.title= title; this.label= label; this.commandValue= new WritableValue(realm, null, String.class); this.applicationValue= new WritableValue(realm, null, String.class); this.topicValue= new WritableValue(realm, null, String.class); } } private final ResourceVariableUtil resolvedSourceFileVariableUtil; private final Map<String, IStringVariable> resolvedSourceFileVariables= new HashMap<>(); private final WritableValue programFileValue; private final WritableValue programArgumentsValue; private ResourceInputComposite programFileControl; private InputArgumentsComposite programArgumentsControl; private final ImList<DDETask> ddeTasks; public DocViewerMainTab(final LaunchConfigPresets presets) { final Realm realm= getRealm(); this.programFileValue= new WritableValue(realm, null, String.class); this.programArgumentsValue= new WritableValue(realm, null, String.class); setPresets(presets); this.resolvedSourceFileVariableUtil= new ResourceVariableUtil() { @Override protected IResource fetchResource() { final IResource resource= super.fetchResource(); return (resource instanceof IFile) ? resource : null; } }; if (DDE.isSupported()) { this.ddeTasks= ImCollections.newList( new DDETask(DocViewerConfig.TASK_VIEW_OUTPUT_ATTR_QUALIFIER, realm, Messages.MainTab_DDE_ViewOutput_label, Messages.DDE_ViewOutput_label ), new DDETask(DocViewerConfig.TASK_PRE_PRODUCE_OUTPUT_ATTR_QUALIFIER, realm, Messages.MainTab_DDE_PreProduceOutput_label, Messages.DDE_PreProduceOutput_label )); } else { this.ddeTasks= ImCollections.emptyList(); } } @Override public Image getImage() { return SharedUIResources.getImages().get(SharedUIResources.OBJ_MAIN_TAB_ID); } @Override public String getName() { return Messages.MainTab_name; } @Override public void setLaunchConfigurationDialog(final ILaunchConfigurationDialog dialog) { super.setLaunchConfigurationDialog(dialog); initVariables(this.resolvedSourceFileVariables); } protected void initVariables(final Map<String, IStringVariable> variables) { VariableUtils.add(variables, ResourceVariables.getSingleResourceVariables(), new ResourceVariableResolver(this.resolvedSourceFileVariableUtil) ); VariableUtils.add(variables, VariableUtils.toStaticVariable(DocProcessingConfig.SOURCE_FILE_PATH_VAR, variables.get(ResourceVariables.RESOURCE_PATH_VAR_NAME) ) ); } public Map<String, IStringVariable> getSourceFileVariables() { return this.resolvedSourceFileVariables; } @Override public void createControl(final Composite parent) { final Composite mainComposite= new Composite(parent, SWT.NONE); setControl(mainComposite); mainComposite.setLayout(LayoutUtil.createTabGrid(1)); addPresetsButton(mainComposite); { final Composite composite= createProgramGroup(mainComposite); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); } LayoutUtil.addSmallFiller(mainComposite, false); for (final DDETask ddeTask : this.ddeTasks) { final Composite composite= createDDEGroup(mainComposite, ddeTask); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); } LayoutUtil.addSmallFiller(mainComposite, true); { final Label note= new Label(mainComposite, SWT.WRAP); note.setText(SharedMessages.Note_label + ": " + this.programArgumentsControl.getNoteText()); //$NON-NLS-1$ note.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, true)); } Dialog.applyDialogFont(parent); initBindings(); } protected Composite createProgramGroup(final Composite parent) { final Group group= new Group(parent, SWT.NONE); group.setLayout(LayoutUtil.createGroupGrid(1)); group.setText(Messages.MainTab_Program_label + ':'); final ResourceInputComposite pathInput= new ResourceInputComposite(group, ResourceInputComposite.STYLE_TEXT, ResourceInputComposite.MODE_FILE | ResourceInputComposite.MODE_OPEN, Messages.MainTab_ProgramPath_label ); pathInput.getValidator().setResourceLabel(Messages.MainTab_ProgramPath_name); pathInput.getValidator().setVariableResolver(new VariableText2(getSourceFileVariables())); pathInput.setShowInsertVariable(true, DialogUtil.DEFAULT_INTERACTIVE_FILTERS, null); pathInput.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); this.programFileControl= pathInput; LayoutUtil.addSmallFiller(group, false); final InputArgumentsComposite argsInput= new InputArgumentsComposite(group, Messages.MainTab_ProgramArgs_label + ':' ); argsInput.setVariableResolver(new VariableText2(getSourceFileVariables())); argsInput.setVariableFilter(DialogUtil.DEFAULT_INTERACTIVE_FILTERS); argsInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); this.programArgumentsControl= argsInput; return group; } protected Composite createDDEGroup(final Composite parent, final DDETask task) { final Group group= new Group(parent, SWT.NONE); group.setLayout(LayoutUtil.createGroupGrid(4)); group.setText(task.title + ':'); { final Label label= new Label(group, SWT.NONE); label.setText(Messages.MainTab_DDECommand_label + ':'); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); } { final InputArgumentsComposite input= new InputArgumentsComposite(group, InputArgumentsComposite.STYLE_SINGLE, null ); input.setVariableResolver(new VariableText2(getSourceFileVariables())); input.setVariableFilter(DialogUtil.DEFAULT_INTERACTIVE_FILTERS); input.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); task.commandControl= input; } { final Label label= new Label(group, SWT.NONE); label.setText(Messages.MainTab_DDEApplication_label + ':'); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); } { final Text text= new Text(group, SWT.BORDER); final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false); gd.widthHint= LayoutUtil.hintWidth(text, 40); text.setLayoutData(gd); task.applicationControl= text; } { final Label label= new Label(group, SWT.NONE); label.setText(Messages.MainTab_DDETopic_label + ':'); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); } { final Text text= new Text(group, SWT.BORDER); final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false); gd.widthHint= LayoutUtil.hintWidth(text, 40); text.setLayoutData(gd); task.topicControl= text; } return group; } @Override protected void addBindings(final DataBindingContext dbc) { dbc.bindValue(this.programFileControl.getObservable(), this.programFileValue, new UpdateValueStrategy().setAfterGetValidator( new UpdateableErrorValidator(this.programFileControl.getValidator()) ), null); dbc.bindValue(WidgetProperties.text(SWT.Modify).observe( this.programArgumentsControl.getTextControl() ), this.programArgumentsValue, new UpdateValueStrategy().setAfterGetValidator( new UpdateableErrorValidator(new VariableTextValidator( this.programArgumentsControl.getVariableResolver(), Messages.ProgramArgs_error_Other_message ))), null); for (final DDETask ddeTask : this.ddeTasks) { dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(ddeTask.commandControl.getTextControl()), ddeTask.commandValue, new UpdateValueStrategy().setAfterGetValidator( new UpdateableErrorValidator(new VariableTextValidator( ddeTask.commandControl.getVariableResolver(), NLS.bind(Messages.DDECommand_error_Other_message, ddeTask.label, "{0}" )))), //$NON-NLS-1$ null); dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(ddeTask.applicationControl), ddeTask.applicationValue, new UpdateValueStrategy() .setConverter(StringTrimConverter.INSTANCE) .setAfterConvertValidator( new UpdateableErrorValidator(new VariableTextValidator( ddeTask.commandControl.getVariableResolver(), NLS.bind(Messages.DDEApplication_error_Other_message, ddeTask.label, "{0}" )))), //$NON-NLS-1$ null ); dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(ddeTask.topicControl), ddeTask.topicValue, new UpdateValueStrategy() .setConverter(StringTrimConverter.INSTANCE) .setAfterConvertValidator( new UpdateableErrorValidator(new VariableTextValidator( ddeTask.commandControl.getVariableResolver(), NLS.bind(Messages.DDETopic_error_Other_message, ddeTask.label, "{0}" )))), //$NON-NLS-1$ null ); } } @Override public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) { } @Override public void initializeFrom(final ILaunchConfiguration configuration) { super.initializeFrom(configuration); if (((String) this.programFileValue.getValue()).isEmpty()) { setErrorMessage(null); } } @Override protected void doInitialize(final ILaunchConfiguration configuration) { { String path= ""; //$NON-NLS-1$ try { path= configuration.getAttribute(DocViewerConfig.PROGRAM_FILE_ATTR_NAME, path); } catch (final CoreException e) { logReadingError(e); } this.programFileValue.setValue(path); } { String s= ""; //$NON-NLS-1$ try { s= configuration.getAttribute(DocViewerConfig.PROGRAM_ARGUMENTS_ATTR_NAME, s); } catch (final CoreException e) { logReadingError(e); } this.programArgumentsValue.setValue(s); } for (final DDETask ddeTask : this.ddeTasks) { { String message= ""; //$NON-NLS-1$ try { message= configuration.getAttribute(ddeTask.attrQualifier + '/' + DocViewerConfig.DDE_COMMAND_ATTR_KEY, message ); } catch (final CoreException e) { logReadingError(e); } ddeTask.commandValue.setValue(message); } { String id= ""; //$NON-NLS-1$ try { id= configuration.getAttribute(ddeTask.attrQualifier + '/' + DocViewerConfig.DDE_APPLICATION_ATTR_KEY, id ); } catch (final CoreException e) { logReadingError(e); } ddeTask.applicationValue.setValue(id); } { String id= ""; //$NON-NLS-1$ try { id= configuration.getAttribute(ddeTask.attrQualifier + '/' + DocViewerConfig.DDE_TOPIC_ATTR_KEY, id ); } catch (final CoreException e) { logReadingError(e); } ddeTask.topicValue.setValue(id); } } } @Override protected void doSave(final ILaunchConfigurationWorkingCopy configuration) { { final String path= (String) this.programFileValue.getValue(); configuration.setAttribute(DocViewerConfig.PROGRAM_FILE_ATTR_NAME, path); } { final String s= (String) this.programArgumentsValue.getValue(); configuration.setAttribute(DocViewerConfig.PROGRAM_ARGUMENTS_ATTR_NAME, s); } for (final DDETask ddeTask : this.ddeTasks) { String message; { message= (String) ddeTask.commandValue.getValue(); if (message.isEmpty()) { message= null; } configuration.setAttribute(ddeTask.attrQualifier + '/' + DocViewerConfig.DDE_COMMAND_ATTR_KEY, message ); } { String name= (String) ddeTask.applicationValue.getValue(); if (message == null && name.isEmpty()) { name= null; } configuration.setAttribute(ddeTask.attrQualifier + '/' + DocViewerConfig.DDE_APPLICATION_ATTR_KEY, name ); } { String name= (String) ddeTask.topicValue.getValue(); if (message == null && name.isEmpty()) { name= null; } configuration.setAttribute(ddeTask.attrQualifier + '/' + DocViewerConfig.DDE_TOPIC_ATTR_KEY, name ); } } } }