/**
*
*/
package org.nightlabs.jfire.reporting.ui.textpart;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.nightlabs.base.ui.composite.LabeledText;
import org.nightlabs.base.ui.composite.XComboComposite;
import org.nightlabs.base.ui.composite.XComposite;
import org.nightlabs.base.ui.language.I18nTextEditor;
import org.nightlabs.base.ui.language.II18nTextEditor;
import org.nightlabs.base.ui.language.LanguageChangeEvent;
import org.nightlabs.base.ui.language.LanguageChangeListener;
import org.nightlabs.base.ui.language.LanguageChooser;
import org.nightlabs.base.ui.language.LanguageChooserCombo;
import org.nightlabs.base.ui.language.I18nTextEditor.EditMode;
import org.nightlabs.base.ui.table.TableLabelProvider;
import org.nightlabs.jfire.reporting.textpart.ReportTextPart;
import org.nightlabs.jfire.reporting.ui.resource.Messages;
import org.nightlabs.language.LanguageCf;
/**
* A {@link Composite} to edit a {@link ReportTextPart}.
* This includes its {@link ReportTextPart.Type} its name as well as its content.
* <p>
* This Composite operates without changing the {@link ReportTextPart} it
* was instantiated with, to update the {@link ReportTextPart} call
* {@link #updateReportTextPart()}.
* </p>
*
* @author Alexander Bieber <!-- alex [AT] nightlabs [DOT] de -->
*/
public class ReportTextPartEditComposite extends XComposite {
private ReportTextPart reportTextPart;
private XComboComposite<ReportTextPart.Type> typeCombo;
private LanguageChooser languageChooser;
private Composite editorWrapper;
private StackLayout editorWrapperLayout;
private II18nTextEditor nameEditor;
private Map<String, IReportTextPartContentEditor> contentEditors = new HashMap<String, IReportTextPartContentEditor>();
private ListenerList changedListeners = new ListenerList();
boolean showTextPartID = false;
private ModifyListener modifyListener = new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
notifyChangedListeners();
}
};
private LanguageChangeListener languageListener = new LanguageChangeListener() {
@Override
public void languageChanged(LanguageChangeEvent event)
{
switchLanguage(event.getNewLanguage().getLanguageID());
}
};
private LabeledText reportTextPartID;
/**
* Create a new {@link ReportTextPartEditComposite}.
*
* @param parent The parent {@link Composite} to use.
* @param style The style to apply to the {@link Composite}.
*/
public ReportTextPartEditComposite(
Composite parent, int style, ReportTextPart reportTextPart,
LanguageChooser languageChooser, boolean showTextPartID) {
super(parent, style, LayoutMode.LEFT_RIGHT_WRAPPER);
this.reportTextPart = reportTextPart;
this.languageChooser = languageChooser;
this.showTextPartID = showTextPartID;
createContents();
}
/**
* Create a new {@link ReportTextPartEditComposite}.
*
* @param parent The parent {@link Composite} to use.
* @param style The style to apply to the {@link Composite}.
* @param layoutDataMode The {@link LayoutDataMode} to apply.
*/
public ReportTextPartEditComposite(Composite parent,
int style, LayoutDataMode layoutDataMode, ReportTextPart reportTextPart) {
super(parent, style, LayoutMode.LEFT_RIGHT_WRAPPER, layoutDataMode);
this.reportTextPart = reportTextPart;
createContents();
}
/**
* Creates the contents of this composite.
*/
protected void createContents() {
XComposite header = new XComposite(this, SWT.NONE, LayoutDataMode.GRID_DATA_HORIZONTAL);
GridLayout layout = new GridLayout(2, false);
XComposite.configureLayout(LayoutMode.TIGHT_WRAPPER, layout);
header.setLayout(layout);
if (showTextPartID) {
reportTextPartID = new LabeledText(header, Messages.getString("org.nightlabs.jfire.reporting.ui.textpart.ReportTextPartEditComposite.label.identifier"), SWT.READ_ONLY); //$NON-NLS-1$
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
reportTextPartID.setLayoutData(gd);
reportTextPartID.setText(reportTextPart.getReportTextPartID());
}
Composite nameParent = languageChooser != null ? header : this;
if (languageChooser == null) {
languageChooser = new LanguageChooserCombo(header);
((LanguageChooserCombo) languageChooser).setLayoutData(new GridData(GridData.VERTICAL_ALIGN_END));
}
languageChooser.addLanguageChangeListener(languageListener);
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
languageChooser.removeLanguageChangeListener(languageListener);
}
});
nameEditor = new I18nTextEditor(nameParent, languageChooser, Messages.getString("org.nightlabs.jfire.reporting.ui.textpart.ReportTextPartEditComposite.label.name")); //$NON-NLS-1$
nameEditor.setI18nText(reportTextPart.getName(), EditMode.BUFFERED);
nameEditor.addModifyListener(modifyListener);
editorWrapper = new Composite(this, SWT.NONE);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
editorWrapper.setLayoutData(gd);
editorWrapperLayout = new StackLayout();
editorWrapper.setLayout(editorWrapperLayout);
typeCombo = new XComboComposite<ReportTextPart.Type>(
header, getBorderStyle() | SWT.READ_ONLY,
Messages.getString("org.nightlabs.jfire.reporting.ui.textpart.ReportTextPartEditComposite.combo.textPartType")); //$NON-NLS-1$
typeCombo.setLabelProvider(new TableLabelProvider() {
@Override
public String getColumnText(Object element, int columnIndex) {
return ((ReportTextPart.Type) element).toString();
}
});
// typeCombo.setInput(Arrays.asList(new ReportTextPart.Type[] {ReportTextPart.Type.HTML, ReportTextPart.Type.JAVASCRIPT}));
typeCombo.setInput(Arrays.asList(new ReportTextPart.Type[] {ReportTextPart.Type.JSHTML}));
typeCombo.setSelection(reportTextPart.getType());
typeCombo.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
switchMode(typeCombo.getSelectedElement());
notifyChangedListeners();
}
});
switchMode(typeCombo.getSelectedElement());
}
private void switchMode(ReportTextPart.Type type) {
Collection<LanguageCf> languages = languageChooser.getLanguages();
for(LanguageCf language : languages) {
IReportTextPartContentEditor contentEditor = contentEditors.get(language.getLanguageID());
String content = null;
if (contentEditor != null) {
content = contentEditor.getContent();
Control c = contentEditor.getControl();
if (c != null && !c.isDisposed())
c.dispose();
}
if (type == ReportTextPart.Type.JSHTML) {
contentEditor = new ReportTextPartContentEditorDefault(editorWrapper, SWT.NONE); // TODO: integrate rich editor
// } else if (type == ReportTextPart.Type.HTML) {
// contentEditor = new ReportTextPartContentEditorDefault(editorWrapper, SWT.NONE);
}
if (content == null) {
if (reportTextPart.getContent().containsLanguageID(language.getLanguageID()))
content = reportTextPart.getContent().getText(language.getLanguageID());
else
content = ""; //$NON-NLS-1$
}
contentEditor.setContent(content);
contentEditor.addModifyListener(modifyListener);
contentEditors.put(language.getLanguageID(), contentEditor);
}
switchLanguage(languageChooser.getLanguage().getLanguageID());
}
private void switchLanguage(String languageId) {
IReportTextPartContentEditor contentEditor = contentEditors.get(languageId);
if(contentEditor == null)
throw new IllegalStateException("Editor for language "+languageId+" is unknown"); //$NON-NLS-1$ //$NON-NLS-2$
editorWrapperLayout.topControl = contentEditor.getControl();
editorWrapper.layout();
}
/**
* Updates the {@link ReportTextPart} this {@link Composite} was instantiated
* with so its attributes and content reflect the values in the ui.
*/
public void updateReportTextPart() {
reportTextPart.setType(typeCombo.getSelectedElement());
reportTextPart.getName().copyFrom(nameEditor.getI18nText());
Collection<LanguageCf> languages = languageChooser.getLanguages();
for(LanguageCf language : languages) {
IReportTextPartContentEditor contentEditor = contentEditors.get(language.getLanguageID());
if (contentEditor != null) {
String content = contentEditor.getContent();
reportTextPart.getContent().setText(language.getLanguageID(), content);
}
}
}
public void addReportTextPartChangedListener(IReportTextPartChangedListener listener) {
changedListeners.add(listener);
}
public void removeReportTextPartChangedListener(IReportTextPartChangedListener listener) {
changedListeners.remove(listener);
}
protected void notifyChangedListeners() {
Object[] listeners = changedListeners.getListeners();
if (listeners.length <= 0)
return;
ReportTextPartChangedEvent event = new ReportTextPartChangedEvent(reportTextPart);
for (Object listener : listeners) {
if (listener instanceof IReportTextPartChangedListener) {
((IReportTextPartChangedListener) listener).reportTextPartChanged(event);
}
}
}
}