/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ package org.apache.directory.studio.ldapbrowser.common.widgets.entryeditor; import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator; import org.apache.directory.studio.ldapbrowser.common.actions.BrowserSelectionUtils; import org.apache.directory.studio.ldapbrowser.core.events.BulkModificationEvent; import org.apache.directory.studio.ldapbrowser.core.events.EmptyValueAddedEvent; import org.apache.directory.studio.ldapbrowser.core.events.EmptyValueDeletedEvent; import org.apache.directory.studio.ldapbrowser.core.events.EntryModificationEvent; import org.apache.directory.studio.ldapbrowser.core.events.EntryUpdateListener; import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry; import org.apache.directory.studio.ldapbrowser.core.events.ValueAddedEvent; import org.apache.directory.studio.ldapbrowser.core.events.ValueDeletedEvent; import org.apache.directory.studio.ldapbrowser.core.events.ValueModifiedEvent; import org.apache.directory.studio.ldapbrowser.core.events.ValueRenamedEvent; import org.apache.directory.studio.ldapbrowser.core.model.AttributeHierarchy; import org.apache.directory.studio.ldapbrowser.core.model.IAttribute; import org.apache.directory.studio.ldapbrowser.core.model.IEntry; import org.apache.directory.studio.ldapbrowser.core.model.IValue; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; /** * The EntryEditorWidgetUniversalListener manages all events for the entry editor widget. * * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> */ public class EntryEditorWidgetUniversalListener implements EntryUpdateListener { /** The tree viewer */ protected TreeViewer viewer; /** The configuration. */ protected EntryEditorWidgetConfiguration configuration; /** The action group. */ protected EntryEditorWidgetActionGroup actionGroup; /** The action used to start the default value editor */ protected OpenDefaultEditorAction startEditAction; /** This listener starts the value editor when pressing enter */ protected SelectionListener viewerSelectionListener = new SelectionAdapter() { /** * {@inheritDoc} */ public void widgetSelected( SelectionEvent e ) { } /** * {@inheritDoc} * * This implementation starts the value editor. */ public void widgetDefaultSelected( SelectionEvent e ) { if ( startEditAction.isEnabled() ) { startEditAction.run(); } } }; /** This listener starts the value editor or expands/collapses the selected attribute */ protected MouseListener viewerMouseListener = new MouseAdapter() { /** * {@inheritDoc} * * This implementation starts the value editor or expands/collapses the selected attribute. */ public void mouseDoubleClick( MouseEvent e ) { IAttribute[] attributes = BrowserSelectionUtils.getAttributes( viewer.getSelection() ); IValue[] values = BrowserSelectionUtils.getValues( viewer.getSelection() ); if ( ( attributes.length == 1 ) && ( values.length == 0 ) ) { if ( viewer.getExpandedState( attributes[0] ) ) { viewer.collapseToLevel( attributes[0], 1 ); } else { viewer.expandToLevel( attributes[0], 1 ); } } } /** * {@inheritDoc} */ public void mouseDown( MouseEvent e ) { } /** * {@inheritDoc} */ public void mouseUp( MouseEvent e ) { } }; /** This listener updates the viewer if an property (e.g. is operational attributes visible) has been changed */ protected IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() { public void propertyChange( PropertyChangeEvent event ) { if ( viewer != null ) { viewer.refresh(); } } }; /** * Creates a new instance of EntryEditorWidgetUniversalListener. * * @param treeViewer the tree viewer * @param configuration the configuration * @param actionGroup the action group * @param startEditAction the action used to start the default value editor */ public EntryEditorWidgetUniversalListener( TreeViewer treeViewer, EntryEditorWidgetConfiguration configuration, EntryEditorWidgetActionGroup actionGroup, OpenDefaultEditorAction startEditAction ) { this.startEditAction = startEditAction; this.viewer = treeViewer; this.configuration = configuration; this.actionGroup = actionGroup; // register listeners viewer.getTree().addSelectionListener( viewerSelectionListener ); viewer.getTree().addMouseListener( viewerMouseListener ); EventRegistry.addEntryUpdateListener( this, BrowserCommonActivator.getDefault().getEventRunner() ); BrowserCommonActivator.getDefault().getPreferenceStore().addPropertyChangeListener( propertyChangeListener ); // Don't invoke Finish' or 'OK' button when pressing 'Enter' in wizard or dialog viewer.getTree().addTraverseListener( new TraverseListener() { public void keyTraversed( TraverseEvent e ) { if ( e.detail == SWT.TRAVERSE_RETURN ) { e.doit = false; } } } ); } /** * Disposes this universal listener. */ public void dispose() { if ( viewer != null ) { EventRegistry.removeEntryUpdateListener( this ); BrowserCommonActivator.getDefault().getPreferenceStore().removePropertyChangeListener( propertyChangeListener ); startEditAction = null; viewer = null; configuration = null; actionGroup = null; } } /** * {@inheritDoc} * * This implementation refreshes the viewer and selects a value depending * on the event. */ public void entryUpdated( EntryModificationEvent event ) { if ( ( viewer == null ) || ( viewer.getTree() == null ) || viewer.getTree().isDisposed() || ( viewer.getInput() == null ) || ( ( event.getModifiedEntry() != viewer.getInput() ) && !( event instanceof BulkModificationEvent ) ) ) { return; } // force closing of cell editors if ( viewer.isCellEditorActive() ) { viewer.cancelEditing(); } // refresh viewer.refresh(); // selection value if ( event instanceof ValueAddedEvent ) { // select the vadded value ValueAddedEvent vaEvent = ( ValueAddedEvent ) event; viewer.setSelection( new StructuredSelection( vaEvent.getAddedValue() ), true ); viewer.refresh(); } else if ( event instanceof ValueDeletedEvent ) { // select another value of the deleted attribute ValueDeletedEvent vdEvent = ( ValueDeletedEvent ) event; if ( viewer.getSelection().isEmpty() && vdEvent.getDeletedValue().getAttribute().getValueSize() > 0 ) { viewer.setSelection( new StructuredSelection( vdEvent.getDeletedValue().getAttribute().getValues()[0] ), true ); } } else if ( event instanceof EmptyValueAddedEvent ) { EmptyValueAddedEvent evaEvent = ( EmptyValueAddedEvent ) event; // select the added value and start editing viewer.setSelection( new StructuredSelection( evaEvent.getAddedValue() ), true ); if ( startEditAction.isEnabled() && viewer.getControl().isFocusControl() ) { startEditAction.run(); } } else if ( event instanceof EmptyValueDeletedEvent ) { // select another value of the deleted attribute EmptyValueDeletedEvent evdEvent = ( EmptyValueDeletedEvent ) event; if ( viewer.getSelection().isEmpty() && ( evdEvent.getDeletedValue().getAttribute().getValueSize() > 0 ) ) { viewer.setSelection( new StructuredSelection( evdEvent.getDeletedValue().getAttribute().getValues()[0] ), true ); } } else if ( event instanceof ValueModifiedEvent ) { // select the modified value ValueModifiedEvent vmEvent = ( ValueModifiedEvent ) event; viewer.setSelection( new StructuredSelection( vmEvent.getNewValue() ), true ); } else if ( event instanceof ValueRenamedEvent ) { // select the renamed value ValueRenamedEvent vrEvent = ( ValueRenamedEvent ) event; viewer.setSelection( new StructuredSelection( vrEvent.getNewValue() ), true ); } } /** * Sets the input to the viewer. * * @param entry the entry input */ public void setInput( IEntry entry ) { // if ( entry != viewer.getInput() ) { viewer.setInput( entry ); actionGroup.setInput( entry ); expandFoldedAttributes(); } } /** * Sets the input to the viewer. * * @param attributeHierarchy the attribute hierarchy */ public void setInput( AttributeHierarchy attributeHierarchy ) { if ( attributeHierarchy != viewer.getInput() ) { viewer.setInput( attributeHierarchy ); actionGroup.setInput( attributeHierarchy ); expandFoldedAttributes(); } } /** * Expands folded attributes if the appropriate preference is set. */ protected void expandFoldedAttributes() { if ( configuration.getPreferences().isAutoExpandFoldedAttributes() ) { viewer.expandAll(); } } }