/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.pms.ui.concept.editor; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; 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.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.pentaho.pms.schema.concept.DefaultPropertyID; import org.pentaho.pms.schema.concept.types.ConceptPropertyType; public class AddPropertyDialog extends TitleAreaDialog { // ~ Static fields/initializers ====================================================================================== private static final Log logger = LogFactory.getLog(PropertyTreeWidget.class); // ~ Instance fields =================================================================================================== private IConceptModel conceptModel; private PropertyTreeWidget propertyTree; private Button predefinedButton; private Button customButton; private Text idField; private Combo typeField; private ComboViewer comboViewer; // ~ Constructors ====================================================================================================== public AddPropertyDialog(Shell parentShell, IConceptModel conceptModel) { super(parentShell); this.conceptModel = conceptModel; } // ~ Methods =========================================================================================================== protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText("Add New Property"); } protected void setShellStyle(int newShellStyle) { super.setShellStyle(newShellStyle | SWT.RESIZE); } protected Control createDialogArea(final Composite parent) { Composite c0 = (Composite) super.createDialogArea(parent); Composite c1 = new Composite(c0, SWT.NONE); c1.setLayoutData(new GridData(GridData.FILL_BOTH)); c1.setLayout(new FormLayout()); setTitle("Properties"); setMessage("Add a property to the current concept."); predefinedButton = new Button(c1, SWT.RADIO); FormData fdPreDefButton = new FormData(); fdPreDefButton.left = new FormAttachment(0, 10); fdPreDefButton.top = new FormAttachment(0, 10); predefinedButton.setLayoutData(fdPreDefButton); predefinedButton.setText("Add a pre-defined property"); predefinedButton.addSelectionListener(new DisableFieldsListener()); propertyTree = new PropertyTreeWidget(c1, PropertyTreeWidget.SHOW_UNUSED, false); propertyTree.setConceptModel(conceptModel); propertyTree.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(final SelectionChangedEvent e) { validatePredefined(); } }); customButton = new Button(c1, SWT.RADIO); FormData fdTree = new FormData(); fdTree.left = new FormAttachment(0, 10); fdTree.top = new FormAttachment(predefinedButton, 10); fdTree.right = new FormAttachment(100, -10); fdTree.bottom = new FormAttachment(65, 0); propertyTree.getTree().setLayoutData(fdTree); FormData fdCustomButton = new FormData(); fdCustomButton.left = new FormAttachment(0, 10); fdCustomButton.top = new FormAttachment(propertyTree.getTree(), 10); customButton.setLayoutData(fdCustomButton); customButton.setText("Add a custom property"); customButton.addSelectionListener(new DisableFieldsListener()); Composite c2 = new Composite(c1, SWT.NONE); FormData fdC2 = new FormData(); fdC2.left = new FormAttachment(0, 0); fdC2.top = new FormAttachment(customButton, 10); fdC2.right = new FormAttachment(100, 0); c2.setLayoutData(fdC2); c2.setLayout(new FormLayout()); Label lab1 = new Label(c2, SWT.RIGHT); idField = new Text(c2, SWT.BORDER); Label lab2 = new Label(c2, SWT.RIGHT); typeField = new Combo(c2, SWT.NONE | SWT.READ_ONLY); lab1.setText("ID:"); FormData fdLab1 = new FormData(); fdLab1.left = new FormAttachment(0, 10); fdLab1.top = new FormAttachment(idField, 0, SWT.CENTER); lab1.setLayoutData(fdLab1); // default to predefined property (the other radio group) idField.setEnabled(false); idField.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { validateCustom(); } }); FormData fdIdField = new FormData(); fdIdField.left = new FormAttachment(lab1, 10); fdIdField.right = new FormAttachment(100, -10); idField.setLayoutData(fdIdField); lab2.setText("Type:"); FormData fdLab2 = new FormData(); fdLab2.left = new FormAttachment(0, 10); fdLab2.top = new FormAttachment(typeField, 0, SWT.CENTER); lab2.setLayoutData(fdLab2); // default to predefined property (the other radio group) typeField.setEnabled(false); FormData fdTypeField = new FormData(); fdTypeField.left = new FormAttachment(lab2, 10); fdTypeField.right = new FormAttachment(100, -10); fdTypeField.top = new FormAttachment(idField, 10); typeField.setLayoutData(fdTypeField); comboViewer = new ComboViewer(typeField); comboViewer.setContentProvider(new IStructuredContentProvider() { public Object[] getElements(final Object inputElement) { List ul = (List) inputElement; return ul.toArray(); } public void dispose() { if (logger.isDebugEnabled()) { logger.debug("Disposing ..."); } } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { if (logger.isDebugEnabled()) { logger.debug("Input changed: old=" + oldInput + ", new=" + newInput); } } }); List<Object> list2 = new ArrayList<Object>(); list2.add(""); list2.addAll(Arrays.asList(ConceptPropertyType.propertyTypes)); comboViewer.setInput(list2); comboViewer.setLabelProvider(new LabelProvider() { public Image getImage(Object element) { return null; } public String getText(Object element) { if (element instanceof ConceptPropertyType) { ConceptPropertyType type = (ConceptPropertyType) element; if (logger.isDebugEnabled()) { logger.debug("desc: " + type.getDescription()); } return type.getDescription(); } else { if (logger.isDebugEnabled()) { logger.debug("obj class: " + element.getClass()); } return ""; } } }); comboViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent e) { validateCustom(); } }); predefinedButton.setSelection(true); return c0; } private void validatePredefined() { IStructuredSelection structuredSelection = (StructuredSelection)propertyTree.getSelection(); Object objectSelected = structuredSelection.getFirstElement(); if (!(objectSelected instanceof PropertyTreeWidget.GroupNode)) { setErrorMessage(null); getButton(IDialogConstants.OK_ID).setEnabled(true); } else { setErrorMessage("Please select a property within a group."); getButton(IDialogConstants.OK_ID).setEnabled(false); } } private void validateCustom() { if (StringUtils.isBlank(idField.getText())) { setErrorMessage("Please enter an ID."); getButton(IDialogConstants.OK_ID).setEnabled(false); return; } else if (isPredefinedPropertyId(idField.getText())) { setErrorMessage("The ID entered cannot be a pre-defined property ID. Please enter a different ID."); getButton(IDialogConstants.OK_ID).setEnabled(false); return; } else { setErrorMessage(null); getButton(IDialogConstants.OK_ID).setEnabled(true); } IStructuredSelection selection = (IStructuredSelection) comboViewer.getSelection(); if (selection.getFirstElement() instanceof ConceptPropertyType) { setErrorMessage(null); getButton(IDialogConstants.OK_ID).setEnabled(true); } else { setErrorMessage("Please select a type."); getButton(IDialogConstants.OK_ID).setEnabled(false); } } /** * Returns true if the given id is a pre-defined property id. */ private boolean isPredefinedPropertyId(final String propertyId) { String[] propertyIds = DefaultPropertyID.getDefaultPropertyIDs(); for (int i = 0; i < propertyIds.length; i++) { if (propertyIds[i].equals(propertyId)) { return true; } } return false; } protected Control createContents(Composite parent) { // start with the OK button disabled Control c = super.createContents(parent); getButton(IDialogConstants.OK_ID).setEnabled(false); return c; } protected Point getInitialSize() { return new Point(500, 500); } protected void okPressed() { String propertyId = null; ConceptPropertyType type = null; if (predefinedButton.getSelection()) { // might be null Object selectedObject = ((StructuredSelection)propertyTree.getSelection()).getFirstElement(); if (selectedObject instanceof PropertyTreeWidget.PropertyNode) { propertyId = ((PropertyTreeWidget.PropertyNode)selectedObject).getId(); } else if (selectedObject instanceof PropertyTreeWidget.GroupNode) { propertyId = ((PropertyTreeWidget.GroupNode)selectedObject).getGroupName(); } else { if (logger.isWarnEnabled()) { logger.warn("unknown node selected in property tree"); } return; } } else { IStructuredSelection selection = (IStructuredSelection) comboViewer.getSelection(); if (selection.getFirstElement() instanceof ConceptPropertyType) { propertyId = idField.getText(); type = (ConceptPropertyType) selection.getFirstElement(); } else { if (logger.isWarnEnabled()) { logger.warn("unknown item selected in concept property type combo"); } return; } } conceptModel.setProperty(PredefinedVsCustomPropertyHelper.createEmptyProperty(propertyId, type)); super.okPressed(); } private class DisableFieldsListener implements SelectionListener { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { if (predefinedButton.getSelection()) { propertyTree.getTree().setEnabled(true); idField.setEnabled(false); typeField.setEnabled(false); validatePredefined(); } else { propertyTree.getTree().setEnabled(false); idField.setEnabled(true); typeField.setEnabled(true); validateCustom(); } } } }