/******************************************************************************* * Copyright (c) 2014 BREDEX GmbH. * 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: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.client.wiki.ui.dialogs; import org.apache.commons.lang.StringUtils; import org.eclipse.jface.dialogs.DialogSettings; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; import org.eclipse.jubula.client.core.model.INodePO; import org.eclipse.jubula.client.ui.utils.DelayableTimer; import org.eclipse.jubula.client.wiki.ui.i18n.Messages; import org.eclipse.jubula.client.wiki.ui.utils.DescriptionUtil; import org.eclipse.jubula.client.wiki.ui.utils.ProjectMarkupUtil; import org.eclipse.jubula.client.wiki.ui.Activator; import org.eclipse.mylyn.wikitext.ui.editor.MarkupSourceViewer; import org.eclipse.mylyn.wikitext.ui.editor.MarkupSourceViewerConfiguration; import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewer; import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewerConfiguration; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; 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.Shell; /** * * @author BREDEX GmbH */ public class DescriptionEditDialog extends TitleAreaDialog { /** key for dialog settings */ private static final String SASH_WEIGHTS = "sashWeights"; //$NON-NLS-1$ /** the wait time(ms) before the preview is updated */ private static final int WAIT_BEFORE_UPDATE = 400; /** the working node */ private INodePO m_workNode; /** the description text as document */ private IDocument m_description; /** the sash which is used as main container*/ private SashForm m_sash; /** * * @param parentShell the parent shell * @param workNode the node which should be worked with */ public DescriptionEditDialog(Shell parentShell, INodePO workNode) { super(parentShell); setShellStyle(getShellStyle() | SWT.RESIZE); m_workNode = workNode; String description = workNode.getDescription(); if (StringUtils.isBlank(description)) { description = DescriptionUtil.getReferenceDescription(workNode); } m_description = new Document(description); } /** * {@inheritDoc} */ protected Control createDialogArea(Composite parent) { String markupLanguage = ProjectMarkupUtil.getProjectMarkupLanguage() .getName(); setTitle(Messages.EditDescriptionDialogHeader); setMessage(NLS.bind(Messages.EditDescriptionDialogDescription, markupLanguage)); getShell().setText( NLS.bind(Messages.EditDescriptionDialogTitle, markupLanguage)); m_sash = new SashForm(parent, SWT.VERTICAL); createDialogComponents(m_sash); IDialogSettings settings = getDialogBoundsSettings(); String[] weights = settings.getArray(SASH_WEIGHTS); try { if (weights != null) { int[] sashWeigths = new int[weights.length]; for (int i = 0; i < weights.length; i++) { sashWeigths[i] = Integer.parseInt(weights[i]); } m_sash.setWeights(sashWeigths); } } catch (NumberFormatException nfe) { // ignore } final GridData sashGridData = createGridData(); sashGridData.widthHint = 500; sashGridData.heightHint = 500; m_sash.setLayoutData(sashGridData); return m_sash; } /** * @param sashForm the parent sash */ private void createDialogComponents(SashForm sashForm) { // styles for the viewer and sourceViewer int styles = SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | SWT.WRAP | SWT.V_SCROLL; // creating group and source viewer Group sourceGroup = new Group(sashForm, SWT.SHADOW_ETCHED_IN); sourceGroup.setText(Messages.EditDescriptionDialogSourceViewer); sourceGroup.setLayout(new GridLayout()); MarkupSourceViewer sourceViewer = createsMarkupSourceViewer( sourceGroup, styles); // creating group and preview Group previewGroup = new Group(sashForm, SWT.SHADOW_ETCHED_IN); previewGroup.setText(Messages.EditDescriptionDialogPreview); previewGroup.setLayout(new GridLayout()); MarkupViewer viewer = createMarkupViewer(previewGroup, styles); addDocumentListenerViewer(sourceViewer, viewer); } /** * @param sourceViewer the {@link MarkupSourceViewer} which is the source * of the description * @param viewer the {@link MarkupViewer} which should get the new data */ private void addDocumentListenerViewer( final MarkupSourceViewer sourceViewer, final MarkupViewer viewer) { final DelayableTimer delayedPreviewTimer = new DelayableTimer( WAIT_BEFORE_UPDATE, new Runnable() { public void run() { Display.getDefault().syncExec(new Runnable() { public void run() { int test = viewer.getTopIndex(); viewer.setDocument(new Document(m_description .get())); viewer.setTopIndex(test); } }); } }); m_description.addDocumentListener(new IDocumentListener() { public void documentChanged(DocumentEvent event) { delayedPreviewTimer.cancel(); delayedPreviewTimer.schedule(); } public void documentAboutToBeChanged(DocumentEvent event) { // Nothing before changed } }); } /** * creates the {@link MarkupSourceViewera} for the description. * @param parent the parent * @param styles styles that should be used for the {@link MarkupSourceViewera} * @return the created {@link MarkupSourceViewera} */ private MarkupSourceViewer createsMarkupSourceViewer(Composite parent, int styles) { final MarkupSourceViewer sourceViewer = new MarkupSourceViewer(parent, null, styles, ProjectMarkupUtil.getProjectMarkupLanguage()); sourceViewer.setDocument(m_description); MarkupSourceViewerConfiguration sourceViewerConfig = new MarkupSourceViewerConfiguration(null); sourceViewer.configure(sourceViewerConfig); sourceViewer.getControl().setLayoutData(createGridData()); return sourceViewer; } /** * creates the {@link MarkupViewer} for the rendered description * @param parent the parent * @param styles styles thaht should be used for the {@link MarkupViewer} * @return the created {@link MarkupViewer} */ private MarkupViewer createMarkupViewer(Composite parent, int styles) { final MarkupViewer viewer = new MarkupViewer(parent, null, null, true, styles); MarkupViewerConfiguration viewerConfiguration = new MarkupViewerConfiguration(viewer); viewerConfiguration.setEnableSelfContainedIncrementalFind(true); viewerConfiguration.setDisableHyperlinkModifiers(false); viewer.configure(viewerConfiguration); viewer.setMarkupLanguage(ProjectMarkupUtil.getProjectMarkupLanguage()); viewer.getControl().setLayoutData(createGridData()); viewer.setDocument(new Document(m_workNode.getDescription())); return viewer; } /** * * @return a {@link GridData} with full grabbing of space */ private GridData createGridData() { final GridData areaGridData = new GridData(); areaGridData.grabExcessVerticalSpace = true; areaGridData.grabExcessHorizontalSpace = true; areaGridData.horizontalAlignment = GridData.FILL; areaGridData.verticalAlignment = GridData.FILL; return areaGridData; } /** * get the description * @return the description */ public String getDescription() { return m_description.get(); } /** {@inheritDoc} */ protected IDialogSettings getDialogBoundsSettings() { IDialogSettings bundleDialogSettings = Activator.getActivator() .getDialogSettings(); return DialogSettings.getOrCreateSection(bundleDialogSettings, this.getClass().getName()); } /** * {@inheritDoc} */ public boolean close() { int[] sashWeights = (m_sash.getWeights()); String[] weights = new String[sashWeights.length]; for (int i = 0; i < sashWeights.length; i++) { weights[i] = Integer.toString(sashWeights[i]); } getDialogBoundsSettings().put(SASH_WEIGHTS, weights); return super.close(); } }