/*!
* 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 org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.pentaho.pms.messages.Messages;
import org.pentaho.pms.schema.concept.Concept;
import org.pentaho.pms.schema.concept.ConceptInterface;
import org.pentaho.pms.schema.concept.DeleteNotAllowedException;
import org.pentaho.pms.util.ObjectAlreadyExistsException;
public class ConceptTreeWidget extends Composite implements ISelectionProvider {
// ~ Static fields/initializers ======================================================================================
private static final Log logger = LogFactory.getLog(TableColumnTreeWidget.class);
// ~ Instance fields =================================================================================================
private TreeViewer treeViewer;
private boolean decorate = true;
private IConceptTreeModel conceptTreeModel;
// ~ Constructors ====================================================================================================
/**
* Shows only the properties defined in the given concept model. Refreshes itself in reaction to concept model
* changes.
*/
public ConceptTreeWidget(final Composite parent, final int style, final IConceptTreeModel conceptTreeModel,
final boolean decorate) {
super(parent, style);
this.conceptTreeModel = conceptTreeModel;
conceptTreeModel.addConceptTreeModificationListener(new IConceptTreeModificationListener() {
public void conceptTreeModified(ConceptTreeModificationEvent e) {
refreshTree();
}
});
this.decorate = decorate;
createContents();
}
// ~ Methods =========================================================================================================
protected void refreshTree() {
treeViewer.refresh(true);
treeViewer.expandAll();
}
protected void createContents() {
addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
ConceptTreeWidget.this.widgetDisposed(e);
}
});
setLayout(new FormLayout());
Label lab1 = new Label(this, SWT.NONE);
lab1.setFont(Constants.getFontRegistry(getDisplay()).get("prop-mgmt-title")); //$NON-NLS-1$
lab1.setText(Messages.getString("ConceptTreeWidget.USER_TREE_LABEL")); //$NON-NLS-1$
Tree tree2 = new Tree(this, SWT.SINGLE | SWT.BORDER); // single selection at a time
treeViewer = new TreeViewer(tree2);
ToolBar tb3 = new ToolBar(this, SWT.FLAT);
ToolItem ti4 = new ToolItem(tb3, SWT.PUSH);
ti4.setImage(Constants.getImageRegistry(Display.getCurrent()).get("concept-add-button")); //$NON-NLS-1$
ti4.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(final SelectionEvent e) {
}
public void widgetSelected(final SelectionEvent e) {
addButtonPressed();
}
});
final ToolItem delButton = new ToolItem(tb3, SWT.PUSH);
delButton.setImage(Constants.getImageRegistry(Display.getCurrent()).get("concept-del-button")); //$NON-NLS-1$
delButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(final SelectionEvent e) {
}
public void widgetSelected(final SelectionEvent e) {
deleteButtonPressed();
}
});
treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(final SelectionChangedEvent e) {
TreeSelection sel = (TreeSelection) e.getSelection();
Object selectedObject = sel.getFirstElement();
if (selectedObject instanceof ConceptInterface) {
delButton.setEnabled(true);
} else {
delButton.setEnabled(false);
}
}
});
FormData fd1 = new FormData();
fd1.bottom = new FormAttachment(tree2, -10);
fd1.left = new FormAttachment(0, 0);
lab1.setLayoutData(fd1);
FormData fd6 = new FormData();
fd6.top = new FormAttachment(0, 38);
fd6.left = new FormAttachment(0, 0);
fd6.right = new FormAttachment(100, 0);
fd6.bottom = new FormAttachment(100, 0);
tree2.setLayoutData(fd6);
FormData fd3 = new FormData();
fd3.top = new FormAttachment(0, 0);
fd3.right = new FormAttachment(100, 0);
tb3.setLayoutData(fd3);
ITreeContentProvider contentProvider = null;
contentProvider = new ConceptTreeContentProvider();
treeViewer.setContentProvider(contentProvider);
treeViewer.setLabelProvider(new ConceptTreeLabelProvider());
treeViewer.setInput("ignored"); //$NON-NLS-1$
treeViewer.expandAll();
}
protected void deleteButtonPressed() {
TreeSelection treeSelection = (TreeSelection) treeViewer.getSelection();
ConceptInterface selected = (ConceptInterface) treeSelection.getFirstElement();
boolean delete = MessageDialog.openConfirm(this.getShell(), Messages
.getString("ConceptTreeWidget.USER_CONFIRM_DELETE_TITLE"), //$NON-NLS-1$
Messages.getString("ConceptTreeWidget.USER_CONFIRM_DELETE_MESSAGE", selected.getName())); //$NON-NLS-1$ //$NON-NLS-2$
if (logger.isDebugEnabled()) {
logger.debug(Messages.getString("ConceptTreeWidget.DEBUG_DELETE") + delete); //$NON-NLS-1$
}
if (delete) {
try {
conceptTreeModel.removeConcept(selected);
} catch (DeleteNotAllowedException e) {
MessageDialog.openError(this.getShell(), Messages
.getString("ConceptTreeWidget.USER_DELETE_NOT_ALLOWED_TITLE"), //$NON-NLS-1$
Messages.getString("ConceptTreeWidget.USER_DELETE_NOT_ALLOWED", selected.getName())); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
protected void addButtonPressed() {
InputDialog dialog = new InputDialog(getShell(), Messages.getString("ConceptTreeWidget.USER_ADD_CONCEPT_TITLE"), //$NON-NLS-1$
Messages.getString("ConceptTreeWidget.USER_ADD_CONCEPT_MESSAGE"), "", null); //$NON-NLS-1$ //$NON-NLS-2$
dialog.open();
String name = dialog.getValue();
if (StringUtils.isNotBlank(name)) {
TreeSelection treeSelection = (TreeSelection) treeViewer.getSelection();
Object selectedObject = treeSelection.getFirstElement();
ConceptInterface selected = null;
if (selectedObject instanceof ConceptInterface) {
selected = (ConceptInterface) treeSelection.getFirstElement();
}
ConceptInterface newConcept = new Concept(name, selected);
try {
conceptTreeModel.addConcept(selected, newConcept);
} catch (ObjectAlreadyExistsException e) {
MessageDialog
.openError(
getShell(),
Messages.getString("ConceptTreeWidget.USER_DUPE_TITLE"), Messages.getString("ConceptTreeWidget.USER_DUPE_MESSAGE")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
protected void widgetDisposed(final DisposeEvent e) {
}
private class ConceptTreeContentProvider implements ITreeContentProvider {
protected final Object[] EMPTY_ARRAY = new Object[0];
private TreeViewer viewer;
protected TreeViewer getViewer() {
return viewer;
}
public Object getParent(final Object element) {
if (logger.isDebugEnabled()) {
logger.debug(Messages.getString("ConceptTreeWidget.DEBUG_PARENT_ARG") + element); //$NON-NLS-1$
}
if (element instanceof ConceptInterface) {
return ((ConceptInterface) element).getParentInterface();
}
return null;
}
public boolean hasChildren(final Object element) {
if (logger.isDebugEnabled()) {
logger.debug(Messages.getString("ConceptTreeWidget.DEBUG_HASCHILDREN_ARG") + element); //$NON-NLS-1$
}
if (element instanceof ConceptInterface) {
ConceptInterface[] children = conceptTreeModel.getChildren((ConceptInterface) element);
if (null != children && children.length > 0) {
return true;
}
} else if (element instanceof String) {
// this is the root
return true;
}
return false;
}
public void dispose() {
if (logger.isDebugEnabled()) {
logger.debug(Messages.getString("ConceptTreeWidget.DEBUG_DISPOSE")); //$NON-NLS-1$
}
// nothing to dispose
}
public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
if (logger.isDebugEnabled()) {
logger.debug(Messages.getString("ConceptTreeWidget.DEBUG_INPUTCHANGED")); //$NON-NLS-1$
}
this.viewer = (TreeViewer) viewer;
// no need to adjust listeners
}
public Object[] getChildren(final Object parentElement) {
if (logger.isDebugEnabled()) {
logger.debug(Messages.getString("ConceptTreeWidget.DEBUG_GETCHILDREN_ARG") + parentElement); //$NON-NLS-1$
}
if (parentElement instanceof ConceptInterface) {
return conceptTreeModel.getChildren((ConceptInterface) parentElement);
} else if (parentElement instanceof String) {
// this is the root
return conceptTreeModel.getChildren(null);
}
return null;
}
public Object[] getElements(final Object inputElement) {
if (logger.isDebugEnabled()) {
logger.debug(Messages.getString("ConceptTreeWidget.DEBUG_GETELEMENTS_ARG") + inputElement); //$NON-NLS-1$
}
return new String[] { Messages.getString("ConceptTreeWidget.USER_CONCEPTS_ROOT_NODE") }; //$NON-NLS-1$
}
}
private class ConceptTreeLabelProvider implements ILabelProvider {
public Image getImage(final Object element) {
if (logger.isDebugEnabled()) {
logger.debug(Messages.getString("ConceptTreeWidget.DEBUG_GETIMAGE_ARG") + element); //$NON-NLS-1$
}
if (decorate) {
return Constants.getImageRegistry(Display.getCurrent()).get("concept"); //$NON-NLS-1$
}
return null;
}
public String getText(final Object element) {
if (logger.isDebugEnabled()) {
logger.debug(Messages.getString("ConceptTreeWidget.DEBUG_GETTEXT_ARG") + element); //$NON-NLS-1$
}
if (element instanceof ConceptInterface) {
return ((ConceptInterface) element).getName();
} else if (element instanceof String) {
return (String) element;
}
return null;
}
public void addListener(final ILabelProviderListener listener) {
// not used
}
public void dispose() {
// not used
}
public boolean isLabelProperty(final Object element, final String property) {
// not used
return false;
}
public void removeListener(final ILabelProviderListener listener) {
// not used
}
}
public void addSelectionChangedListener(final ISelectionChangedListener listener) {
treeViewer.addSelectionChangedListener(listener);
}
public ISelection getSelection() {
return treeViewer.getSelection();
}
public void removeSelectionChangedListener(final ISelectionChangedListener listener) {
treeViewer.removeSelectionChangedListener(listener);
}
public void setSelection(final ISelection selection) {
treeViewer.setSelection(selection);
}
}