/* ====================================================================
*
* The ObjectStyle Group Software License, Version 1.0
*
* Copyright (c) 2005 The ObjectStyle Group,
* and individual authors of the software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* ObjectStyle Group (http://objectstyle.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "ObjectStyle Group" and "Cayenne"
* must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact andrus@objectstyle.org.
*
* 5. Products derived from this software may not be called "ObjectStyle"
* nor may "ObjectStyle" appear in their names without prior written
* permission of the ObjectStyle Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the ObjectStyle Group. For more
* information on the ObjectStyle Group, please see
* <http://objectstyle.org/>.
*
*/
package org.objectstyle.wolips.wooeditor.editor;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.IDetailsPage;
import org.eclipse.ui.forms.IFormPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import org.objectstyle.wolips.wodclipse.core.woo.DisplayGroup;
import org.objectstyle.wolips.wooeditor.databinding.observable.CustomSWTObservables;
import org.objectstyle.wolips.wooeditor.widgets.RadioGroup;
public class DisplayGroupDetailsPage implements IDetailsPage {
private IManagedForm myManagedForm;
private DisplayGroup myDisplayGroup;
private Group myMasterDetailGroup;
private Text myNameText;
private Combo myClassNameCombo;
private Spinner myEntriesPerBatchSpinner;
private Combo myEntityCombo;
private Text myEditingContextText;
private Combo myMasterEntityCombo;
private Combo mySortAttributeCombo;
private Combo myFetchSpecCombo;
private Combo myDetailKeyCombo;
private Combo myQualificationCombo;
private Button myHasDetailButton;
private Button myFetchOnLoadButton;
private Button mySelectsFirstObjectButton;
private RadioGroup mySortRadioGroup;
private DataBindingContext myBindingContext;
private PropertyChangeListener myDirtyStateListener = new PropertyChangeListener() {
public void propertyChange(final PropertyChangeEvent evt) {
myManagedForm.dirtyStateChanged();
}
};
private final ModifyListener myEntityModifyListener = new ModifyListener() {
public void modifyText(final ModifyEvent e) {
Object selection = mySortRadioGroup.getSelection();
if (!DisplayGroup.NOT_SORTED.equals(selection)) {
mySortRadioGroup.setSelection(DisplayGroup.NOT_SORTED);
}
if (!myHasDetailButton.getSelection()) {
myDetailKeyCombo.setText("");
}
}
};
private final ModifyListener myMasterEntityListener = new ModifyListener() {
public void modifyText(final ModifyEvent e) {
myDetailKeyCombo.setText("");
}
};
private final SelectionListener mySortEntityListener = new SelectionListener() {
public void widgetDefaultSelected(final SelectionEvent e) {
widgetSelected(e);
}
public void widgetSelected(final SelectionEvent e) {
Object selection = mySortRadioGroup.getSelection();
if (DisplayGroup.NOT_SORTED.equals(selection)) {
mySortRadioGroup.setSelection(DisplayGroup.ASCENDING);
}
}
};
public DisplayGroupDetailsPage() {
super();
}
private void bind() {
// XXX This method is too long
if (myDisplayGroup == null) {
return;
}
myBindingContext = new DataBindingContext();
myBindingContext
.bindValue(SWTObservables.observeText(myNameText, SWT.Modify), BeansObservables.observeValue(myDisplayGroup, DisplayGroup.NAME), null, null);
myBindingContext.bindList(SWTObservables.observeItems(myClassNameCombo), BeansObservables.observeList(Realm.getDefault(), myDisplayGroup,
DisplayGroup.CLASS_NAME_LIST), null, null);
myBindingContext.bindValue(SWTObservables.observeSingleSelectionIndex(myClassNameCombo), BeansObservables.observeValue(myDisplayGroup,
DisplayGroup.CLASS_NAME_INDEX), null, null);
myBindingContext.bindList(SWTObservables.observeItems(myEntityCombo), BeansObservables.observeList(Realm.getDefault(), myDisplayGroup,
DisplayGroup.ENTITY_LIST), null, null);
myBindingContext.bindValue(SWTObservables.observeEnabled(myMasterDetailGroup), BeansObservables
.observeValue(myDisplayGroup, DisplayGroup.HAS_MASTER_DETAIL), new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), null);
UpdateValueStrategy booleanInverse = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE) {
@Override
protected IStatus doSet(final IObservableValue observableValue, final Object value) {
Boolean newValue = !(Boolean) value;
return super.doSet(observableValue, newValue);
}
};
myBindingContext.bindValue(SWTObservables.observeEnabled(myEntityCombo), BeansObservables.observeValue(myDisplayGroup, DisplayGroup.HAS_MASTER_DETAIL),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), booleanInverse);
myBindingContext.bindValue(CustomSWTObservables.observeText(myEntityCombo), BeansObservables.observeValue(myDisplayGroup, DisplayGroup.ENTITY_NAME), null,
null);
myBindingContext.bindValue(SWTObservables.observeEnabled(myEditingContextText), BeansObservables.observeValue(myDisplayGroup,
DisplayGroup.HAS_MASTER_DETAIL), new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), booleanInverse);
myBindingContext.bindValue(SWTObservables.observeText(myEditingContextText, SWT.Modify), BeansObservables.observeValue(myDisplayGroup,
DisplayGroup.EDITING_CONTEXT), null, null);
myBindingContext.bindValue(SWTObservables.observeSelection(myHasDetailButton), BeansObservables
.observeValue(myDisplayGroup, DisplayGroup.HAS_MASTER_DETAIL), null, null);
myBindingContext.bindList(SWTObservables.observeItems(myMasterEntityCombo), BeansObservables.observeList(Realm.getDefault(), myDisplayGroup,
DisplayGroup.ENTITY_LIST), null, null);
myBindingContext.bindValue(CustomSWTObservables.observeText(myMasterEntityCombo), BeansObservables.observeValue(myDisplayGroup,
DisplayGroup.MASTER_ENTITY_NAME), null, null);
myBindingContext.bindList(SWTObservables.observeItems(myDetailKeyCombo), BeansObservables.observeList(Realm.getDefault(), myDisplayGroup,
DisplayGroup.DETAIL_KEY_LIST), null, null);
myBindingContext.bindValue(CustomSWTObservables.observeText(myDetailKeyCombo), BeansObservables.observeValue(myDisplayGroup, DisplayGroup.DETAIL_KEY_NAME),
null, null);
myBindingContext.bindValue(SWTObservables.observeSelection(myEntriesPerBatchSpinner), BeansObservables.observeValue(myDisplayGroup,
DisplayGroup.ENTRIES_PER_BATCH), null, null);
myBindingContext.bindValue(SWTObservables.observeSelection(mySelectsFirstObjectButton), BeansObservables.observeValue(myDisplayGroup,
DisplayGroup.SELECTS_FIRST_OBJECT), null, null);
myBindingContext.bindList(SWTObservables.observeItems(myQualificationCombo), BeansObservables.observeList(Realm.getDefault(), myDisplayGroup,
DisplayGroup.QUALIFICATION_LIST), null, null);
myBindingContext.bindValue(SWTObservables.observeSingleSelectionIndex(myQualificationCombo), BeansObservables.observeValue(myDisplayGroup,
DisplayGroup.QUALIFICATION_INDEX), null, null);
myBindingContext.bindValue(SWTObservables.observeSelection(myFetchOnLoadButton), BeansObservables
.observeValue(myDisplayGroup, DisplayGroup.FETCHES_ON_LOAD), null, null);
myBindingContext.bindList(SWTObservables.observeItems(mySortAttributeCombo), BeansObservables.observeList(Realm.getDefault(), myDisplayGroup,
DisplayGroup.SORT_LIST), null, null);
myBindingContext.bindValue(CustomSWTObservables.observeSelection(mySortAttributeCombo), BeansObservables.observeValue(myDisplayGroup,
DisplayGroup.SORT_ORDER_KEY), null, null);
myBindingContext.bindValue(CustomSWTObservables.observeSelection(mySortRadioGroup), BeansObservables.observeValue(myDisplayGroup, DisplayGroup.SORT_ORDER),
null, null);
UpdateValueStrategy fetchSpecEmpty = new UpdateValueStrategy();
fetchSpecEmpty.setConverter(new IConverter() {
public Object convert(final Object fromObject) {
boolean result = fromObject != null && ((List<?>) fromObject).size() > 0;
if (!myHasDetailButton.getSelection()) {
return result;
}
return false;
}
public Object getFromType() {
return new ArrayList<String>();
}
public Object getToType() {
return true;
}
});
UpdateValueStrategy fetchSpecEnabled = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE) {
@Override
protected IStatus doSet(final IObservableValue observableValue, final Object value) {
Boolean newValue = false;
if (myFetchSpecCombo.getItemCount() > 0) {
newValue = !(Boolean) value;
}
return super.doSet(observableValue, newValue);
}
};
myBindingContext.bindValue(SWTObservables.observeEnabled(myFetchSpecCombo), BeansObservables.observeValue(myDisplayGroup, DisplayGroup.HAS_MASTER_DETAIL),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), fetchSpecEnabled);
myBindingContext.bindValue(SWTObservables.observeEnabled(myFetchSpecCombo), BeansObservables.observeValue(myDisplayGroup, DisplayGroup.FETCH_SPEC_LIST),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER), fetchSpecEmpty);
myBindingContext.bindList(SWTObservables.observeItems(myFetchSpecCombo), BeansObservables.observeList(Realm.getDefault(), myDisplayGroup,
DisplayGroup.FETCH_SPEC_LIST), null, null);
UpdateValueStrategy fetchSpecSelection = new UpdateValueStrategy() {
@Override
protected IStatus doSet(IObservableValue observableValue, Object value) {
if (value == null || value.equals("")) {
value = DisplayGroup.FETCH_SPEC_NONE;
}
return super.doSet(observableValue, value);
}
};
myBindingContext.bindValue(CustomSWTObservables.observeSelection(myFetchSpecCombo), BeansObservables.observeValue(myDisplayGroup,
DisplayGroup.FETCH_SPEC_NAME), null, fetchSpecSelection);
myEntityCombo.addModifyListener(myEntityModifyListener);
myMasterEntityCombo.addModifyListener(myMasterEntityListener);
mySortAttributeCombo.addSelectionListener(mySortEntityListener);
}
public void commit(final boolean onSave) {
// nothing to do
}
public void createContents(final Composite parent) {
// XXX: Q - This method is too long
TableWrapLayout pageLayout = new TableWrapLayout();
pageLayout.topMargin = 5;
pageLayout.leftMargin = 5;
pageLayout.rightMargin = 2;
pageLayout.bottomMargin = 2;
parent.setLayout(pageLayout);
// Create form for layout
FormToolkit form = myManagedForm.getToolkit();
Section displayGroupSection = form.createSection(parent, Section.TITLE_BAR);
displayGroupSection.marginWidth = 10;
displayGroupSection.setText("Display Group Details");
displayGroupSection.setDescription("Set the properties of the " + "selected display group.");
TableWrapData tableWrapData = new TableWrapData(TableWrapData.FILL, TableWrapData.TOP);
tableWrapData.grabHorizontal = true;
displayGroupSection.setLayoutData(tableWrapData);
// form.createCompositeSeparator(displayGroupSection);
Composite displayGroupComposite = form.createComposite(displayGroupSection);
GridLayout displayGroupLayout = new GridLayout();
displayGroupLayout.marginWidth = 0;
displayGroupLayout.marginHeight = 0;
displayGroupLayout.numColumns = 2;
displayGroupComposite.setLayout(displayGroupLayout);
// Name
form.createLabel(displayGroupComposite, "Name:");
myNameText = form.createText(displayGroupComposite, "", SWT.SINGLE);
GridData nameFieldLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
myNameText.setLayoutData(nameFieldLayoutData);
// Class Name
form.createLabel(displayGroupComposite, "Class Type:");
myClassNameCombo = new Combo(displayGroupComposite, SWT.POP_UP);
GridData classNameFieldLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
myNameText.setLayoutData(classNameFieldLayoutData);
// Entity
form.createLabel(displayGroupComposite, "Entity:");
myEntityCombo = new Combo(displayGroupComposite, SWT.DROP_DOWN);
GridData entityFieldLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
myEntityCombo.setLayoutData(entityFieldLayoutData);
// Editing Context
form.createLabel(displayGroupComposite, "Editing Context:");
myEditingContextText = form.createText(displayGroupComposite, "", SWT.SINGLE);
GridData editingContextFieldLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
myEditingContextText.setLayoutData(editingContextFieldLayoutData);
// HasDetail
createSpacer(form, displayGroupComposite, 1);
myHasDetailButton = form.createButton(displayGroupComposite, "Has detail data source", SWT.CHECK);
GridData hasDetailLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
hasDetailLayoutData.horizontalIndent = 5;
myHasDetailButton.setLayoutData(hasDetailLayoutData);
// Master/Detail Group
myMasterDetailGroup = new Group(displayGroupComposite, SWT.NONE);
myMasterDetailGroup.setBackground(displayGroupComposite.getBackground());
myMasterDetailGroup.setText("Master / Detail");
GridLayout masterDetailLayout = new GridLayout();
masterDetailLayout.numColumns = 2;
myMasterDetailGroup.setEnabled(false);
myMasterDetailGroup.setLayout(masterDetailLayout);
GridData masterDetailLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
masterDetailLayoutData.horizontalSpan = 2;
myMasterDetailGroup.setLayoutData(masterDetailLayoutData);
// Master Entity
form.createLabel(myMasterDetailGroup, "Master Entity:");
myMasterEntityCombo = new Combo(myMasterDetailGroup, SWT.DROP_DOWN);
GridData masterEntityFieldLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
myMasterEntityCombo.setLayoutData(masterEntityFieldLayoutData);
// XXX For debugging
myMasterEntityCombo.setData("myMasterEntityCombo");
// Detail Key
Label label = form.createLabel(myMasterDetailGroup, "Detail Key:");
label.setAlignment(SWT.RIGHT);
myDetailKeyCombo = new Combo(myMasterDetailGroup, SWT.DROP_DOWN);
GridData detailKeyFieldLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
myDetailKeyCombo.setLayoutData(detailKeyFieldLayoutData);
// Entries per batch group (fixes layout of label and control)
Composite batchGroupComposite = new Composite(displayGroupComposite, SWT.NONE);
batchGroupComposite.setBackground(displayGroupComposite.getBackground());
GridLayout batchLayout = new GridLayout();
batchLayout.numColumns = 2;
batchGroupComposite.setLayout(batchLayout);
GridData batchGroupLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
batchGroupLayoutData.horizontalSpan = 2;
batchGroupComposite.setLayoutData(batchGroupLayoutData);
// Entries per batch
form.createLabel(batchGroupComposite, "Entities per batch:");
myEntriesPerBatchSpinner = new Spinner(batchGroupComposite, SWT.NULL);
myEntriesPerBatchSpinner.setIncrement(5);
GridData entriesPerBatchLayoutData = new GridData(SWT.FILL, SWT.FILL, false, false);
myEntriesPerBatchSpinner.setLayoutData(entriesPerBatchLayoutData);
// Selects first object
createSpacer(form, displayGroupComposite, 1);
mySelectsFirstObjectButton = form.createButton(displayGroupComposite, "Selects first object on load", SWT.CHECK);
GridData selectsFirstObjectLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
selectsFirstObjectLayoutData.horizontalIndent = 5;
mySelectsFirstObjectButton.setLayoutData(selectsFirstObjectLayoutData);
// Fetches on load
createSpacer(form, displayGroupComposite, 1);
myFetchOnLoadButton = form.createButton(displayGroupComposite, "Fetches on load", SWT.CHECK);
GridData fetchOnLoadLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
fetchOnLoadLayoutData.horizontalIndent = 5;
myFetchOnLoadButton.setLayoutData(fetchOnLoadLayoutData);
// Qualification type
form.createLabel(displayGroupComposite, "Qualification:");
myQualificationCombo = new Combo(displayGroupComposite, SWT.POP_UP);
GridData qualificationFieldLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
myQualificationCombo.setLayoutData(qualificationFieldLayoutData);
// Sorting attribute
form.createLabel(displayGroupComposite, "Sorting:");
mySortAttributeCombo = new Combo(displayGroupComposite, SWT.POP_UP);
GridData sortingFieldLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
mySortAttributeCombo.setLayoutData(sortingFieldLayoutData);
// Sort order radio group
createSpacer(form, displayGroupComposite, 1);
Composite radioGroupComposite = new Composite(displayGroupComposite, SWT.NO_BACKGROUND);
radioGroupComposite.setLayout(new GridLayout());
// Sort order radio buttons
mySortRadioGroup = new RadioGroup();
for (String s : DisplayGroup.SORT_OPTIONS) {
Button sortButton = form.createButton(radioGroupComposite, s, SWT.RADIO);
GridData sortButtonLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
sortButton.setLayoutData(sortButtonLayoutData);
mySortRadioGroup.add(sortButton);
}
// Fetch spec
form.createLabel(displayGroupComposite, "Fetch Spec:");
myFetchSpecCombo = new Combo(displayGroupComposite, SWT.POP_UP);
GridData fetchSpecFieldLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
myFetchSpecCombo.setLayoutData(fetchSpecFieldLayoutData);
form.paintBordersFor(displayGroupSection);
displayGroupSection.setClient(displayGroupComposite);
}
private void createSpacer(final FormToolkit toolkit, final Composite parent, final int span) {
Label spacer = toolkit.createLabel(parent, "");
GridData gd = new GridData();
gd.horizontalSpan = span;
spacer.setLayoutData(gd);
}
public void dispose() {
disposeBindings();
}
protected void disposeBindings() {
if (myBindingContext != null) {
myBindingContext.dispose();
}
if (myEntityCombo != null && !myEntityCombo.isDisposed()) {
myEntityCombo.removeModifyListener(myEntityModifyListener);
}
if (myMasterEntityCombo != null && !myMasterEntityCombo.isDisposed()) {
myMasterEntityCombo.removeModifyListener(myMasterEntityListener);
}
if (mySortAttributeCombo != null && !mySortAttributeCombo.isDisposed()) {
mySortAttributeCombo.removeSelectionListener(mySortEntityListener);
}
}
public void initialize(final IManagedForm form) {
this.myManagedForm = form;
}
public boolean isDirty() {
if (myDisplayGroup == null) {
return false;
}
return myDisplayGroup.getWooModel().isDirty();
}
public boolean isStale() {
return false;
}
public void refresh() {
}
public void selectionChanged(final IFormPart part, final ISelection selection) {
disposeBindings();
IStructuredSelection ssel = (IStructuredSelection) selection;
if (ssel.size() > 0) {
setDisplayGroup((DisplayGroup) ssel.getFirstElement());
} else {
setDisplayGroup(null);
}
bind();
}
public void setDisplayGroup(final DisplayGroup displayGroup) {
if (myDisplayGroup != null) {
myDisplayGroup.removePropertyChangeListener(myDirtyStateListener);
}
myDisplayGroup = displayGroup;
if (myDisplayGroup != null) {
myDisplayGroup.addPropertyChangeListener(myDirtyStateListener);
}
}
public void setFocus() {
myNameText.setFocus();
}
public boolean setFormInput(final Object input) {
return false;
}
}