diff --git a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/dialogs/DnDialog.java b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/dialogs/DnDialog.java index d3ce8ff8d3..1dd09bb478 100644 --- a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/dialogs/DnDialog.java +++ b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/dialogs/DnDialog.java @@ -41,6 +41,9 @@ /** * The DnDialog is used from the Dn value editor to edit and select a Dn. * + * In multi-select mode it allows the user to manage a list of DNs at once, + * which is useful e.g. when adding multiple members to a group. + * * @author Apache Directory Project */ @@ -59,13 +62,18 @@ public class DnDialog extends Dialog /** The connection. */ private IBrowserConnection connection; - /** The dn */ - private Dn dn; + /** One dn (single-select mode) or multiple DNs (multi-select mode). */ + private Dn[] dns; + + /** True when the dialog operates in multi-select mode. */ + private boolean multiSelect; /** - * Creates a new instance of DnDialog. + * Creates a new instance of DnDialog in single-select mode. * + * Use {@link #getDn()} to retrieve the result after the dialog is closed. + * * @param parentShell the parent shell * @param title the title of the dialog * @param description the description of the dialog @@ -79,7 +87,31 @@ public DnDialog( Shell parentShell, String title, String description, IBrowserCo this.title = title; this.description = description; this.connection = connection; - this.dn = dn; + this.dns = dn != null ? new Dn[]{ dn } : new Dn[0]; + this.multiSelect = false; + } + + + /** + * Creates a new instance of DnDialog in multi-select mode. + * + * Use {@link #getDns()} to retrieve the result after the dialog is closed. + * + * @param parentShell the parent shell + * @param title the title of the dialog + * @param description the description of the dialog + * @param connection the connection used to browse the directory + * @param dns the initial list of DNs, may be null or empty + */ + public DnDialog( Shell parentShell, String title, String description, IBrowserConnection connection, Dn[] dns ) + { + super( parentShell ); + super.setShellStyle( super.getShellStyle() | SWT.RESIZE ); + this.title = title; + this.description = description; + this.connection = connection; + this.dns = dns != null ? dns : new Dn[0]; + this.multiSelect = true; } @@ -99,8 +131,11 @@ protected void configureShell( Shell shell ) */ protected void okPressed() { - dn = entryWidget.getDn(); - entryWidget.saveDialogSettings(); + dns = entryWidget.getDns(); + if ( !multiSelect ) + { + entryWidget.saveDialogSettings(); + } super.okPressed(); } @@ -124,6 +159,10 @@ protected Control createDialogArea( Composite parent ) Composite composite = ( Composite ) super.createDialogArea( parent ); GridData gd = new GridData( GridData.FILL_BOTH ); gd.widthHint = convertHorizontalDLUsToPixels( IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH ) * 3 / 2; + if ( multiSelect ) + { + gd.heightHint = convertHorizontalDLUsToPixels( IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH ); + } composite.setLayoutData( gd ); if ( description != null ) @@ -132,7 +171,17 @@ protected Control createDialogArea( Composite parent ) } Composite innerComposite = BaseWidgetUtils.createColumnContainer( composite, 2, 1 ); - entryWidget = new EntryWidget( connection, dn ); + + if ( multiSelect ) + { + entryWidget = new EntryWidget( connection, dns ); + innerComposite.setLayoutData( new GridData( GridData.FILL_BOTH ) ); + } + else + { + entryWidget = new EntryWidget( connection, dns.length == 0 ? null : dns[0] ); + } + entryWidget.addWidgetModifyListener( new WidgetModifyListener() { public void widgetModified( WidgetModifyEvent event ) @@ -154,20 +203,39 @@ private void updateWidgets() { if ( getButton( IDialogConstants.OK_ID ) != null ) { - getButton( IDialogConstants.OK_ID ).setEnabled( - entryWidget.getDn() != null && !"".equals( entryWidget.getDn().toString() ) ); //$NON-NLS-1$ + if ( multiSelect ) + { + // Always allow confirming in multi-select mode (empty list is valid) + getButton( IDialogConstants.OK_ID ).setEnabled( true ); + } + else + { + getButton( IDialogConstants.OK_ID ).setEnabled( + entryWidget.getDn() != null && !"".equals( entryWidget.getDn().toString() ) ); //$NON-NLS-1$ + } } } /** - * Gets the dn. - * + * Gets the dn (single-select mode). + * * @return the dn */ public Dn getDn() { - return dn; + return dns.length == 0 ? null : dns[0]; + } + + + /** + * Gets the list of DNs (multi-select mode). + * + * @return the array of selected DNs, never null + */ + public Dn[] getDns() + { + return dns; } } diff --git a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/dialogs/SelectEntryDialog.java b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/dialogs/SelectEntryDialog.java index d74798767e..499190aa0f 100644 --- a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/dialogs/SelectEntryDialog.java +++ b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/dialogs/SelectEntryDialog.java @@ -21,6 +21,9 @@ package org.apache.directory.studio.ldapbrowser.common.dialogs; +import java.util.ArrayList; +import java.util.List; + import org.apache.directory.studio.ldapbrowser.common.widgets.browser.BrowserActionGroup; import org.apache.directory.studio.ldapbrowser.common.widgets.browser.BrowserConfiguration; import org.apache.directory.studio.ldapbrowser.common.widgets.browser.BrowserUniversalListener; @@ -60,6 +63,9 @@ public class SelectEntryDialog extends Dialog /** The selected entry. */ private IEntry selectedEntry; + /** All selected entries (supports multi-selection). */ + private List selectedEntries; + /** The browser configuration. */ private BrowserConfiguration browserConfiguration; @@ -89,6 +95,7 @@ public SelectEntryDialog( Shell parentShell, String title, IEntry rootEntry, IEn this.rootEntry = rootEntry; this.initialEntry = initialEntry; this.selectedEntry = null; + this.selectedEntries = new ArrayList<>(); } @@ -128,7 +135,23 @@ public boolean close() */ protected void okPressed() { - selectedEntry = initialEntry; + selectedEntries = new ArrayList<>(); + if ( browserWidget != null ) + { + IStructuredSelection sel = ( IStructuredSelection ) browserWidget.getViewer().getSelection(); + for ( Object o : sel.toList() ) + { + if ( o instanceof IEntry ) + { + selectedEntries.add( ( IEntry ) o ); + } + else if ( o instanceof ISearchResult ) + { + selectedEntries.add( ( ( ISearchResult ) o ).getEntry() ); + } + } + } + selectedEntry = selectedEntries.isEmpty() ? initialEntry : selectedEntries.get( 0 ); super.okPressed(); } @@ -189,14 +212,22 @@ public void selectionChanged( SelectionChangedEvent event ) { if ( !event.getSelection().isEmpty() ) { - Object o = ( ( IStructuredSelection ) event.getSelection() ).getFirstElement(); - if ( o instanceof IEntry ) + IStructuredSelection sel = ( IStructuredSelection ) event.getSelection(); + selectedEntries = new ArrayList<>(); + for ( Object o : sel.toList() ) { - initialEntry = ( IEntry ) o; + if ( o instanceof IEntry ) + { + selectedEntries.add( ( IEntry ) o ); + } + else if ( o instanceof ISearchResult ) + { + selectedEntries.add( ( ( ISearchResult ) o ).getEntry() ); + } } - else if ( o instanceof ISearchResult ) + if ( !selectedEntries.isEmpty() ) { - initialEntry = ( ( ISearchResult ) o ).getEntry(); + initialEntry = selectedEntries.get( 0 ); } } } @@ -222,12 +253,23 @@ else if ( o instanceof ISearchResult ) /** * Gets the selected entry. - * - * @return the selected entry + * + * @return the selected entry, or null if none */ public IEntry getSelectedEntry() { return selectedEntry; } + + /** + * Gets all selected entries (supports multi-selection via Ctrl/Shift+click). + * + * @return the list of selected entries, never null + */ + public List getSelectedEntries() + { + return selectedEntries; + } + } diff --git a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/EntryWidget.java b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/EntryWidget.java index f92ab2f4c5..921807b2f9 100644 --- a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/EntryWidget.java +++ b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/EntryWidget.java @@ -21,6 +21,10 @@ package org.apache.directory.studio.ldapbrowser.common.widgets.search; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; import org.apache.directory.api.ldap.model.name.Dn; import org.apache.directory.studio.common.ui.HistoryUtils; @@ -54,10 +58,16 @@ *
  • a browse button to open a {@link SelectEntryDialog} * * + * In multi-select mode the widget shows a list of DNs together with + * Add and Remove buttons so the user can manage several entries at once + * (e.g. when adding multiple members to a group). + * * @author Apache Directory Project */ public class EntryWidget extends AbstractWidget { + // ---- single-select fields ---- + /** The Dn combo. */ private Combo dnCombo; @@ -67,9 +77,6 @@ public class EntryWidget extends AbstractWidget /** The entry browse button. */ private Button entryBrowseButton; - /** The connection. */ - private IBrowserConnection browserConnection; - /** The selected Dn. */ private Dn dn; @@ -79,6 +86,28 @@ public class EntryWidget extends AbstractWidget /** Flag indicating if using local name for the dn */ boolean useLocalName; + // ---- multi-select fields ---- + + /** True when the widget operates in multi-select mode. */ + private boolean multiSelect; + + /** SWT list showing the selected DNs (multi-select mode). */ + private org.eclipse.swt.widgets.List dnListControl; + + /** Ordered list of DNs managed in multi-select mode. */ + private List dns; + + /** Button to open the entry browser and add entries (multi-select mode). */ + private Button addButton; + + /** Button to remove the currently highlighted entries (multi-select mode). */ + private Button removeButton; + + // ---- shared fields ---- + + /** The connection. */ + private IBrowserConnection browserConnection; + /** * Creates a new instance of EntryWidget. @@ -87,11 +116,12 @@ public EntryWidget() { browserConnection = null; dn = null; + multiSelect = false; } /** - * Creates a new instance of EntryWidget. + * Creates a new instance of EntryWidget (single-select mode). * * @param browserConnection the connection * @param dn the initial Dn @@ -103,7 +133,7 @@ public EntryWidget( IBrowserConnection browserConnection, Dn dn ) /** - * Creates a new instance of EntryWidget. + * Creates a new instance of EntryWidget (single-select mode). * * @param browserConnection the connection * @param dn the initial Dn @@ -116,6 +146,21 @@ public EntryWidget( IBrowserConnection browserConnection, Dn dn, Dn suffix, bool this.dn = dn; this.suffix = suffix; this.useLocalName = useLocalName; + this.multiSelect = false; + } + + + /** + * Creates a new instance of EntryWidget in multi-select mode. + * + * @param browserConnection the connection + * @param initialDns the initial list of DNs, may be null or empty + */ + public EntryWidget( IBrowserConnection browserConnection, Dn[] initialDns ) + { + this.browserConnection = browserConnection; + this.dns = new ArrayList<>( initialDns != null ? Arrays.asList( initialDns ) : new ArrayList() ); + this.multiSelect = true; } @@ -126,7 +171,22 @@ public EntryWidget( IBrowserConnection browserConnection, Dn dn, Dn suffix, bool */ public void createWidget( final Composite parent ) { + if ( multiSelect ) + { + createMultiSelectWidget( parent ); + } + else + { + createSingleSelectWidget( parent ); + } + } + + /** + * Creates the single-select widget (original behaviour). + */ + private void createSingleSelectWidget( final Composite parent ) + { // Dn combo Composite textAndUpComposite = BaseWidgetUtils.createColumnContainer( parent, 2, 1 ); dnCombo = BaseWidgetUtils.createCombo( textAndUpComposite, new String[0], -1, 1 ); @@ -213,7 +273,7 @@ public void widgetSelected( SelectionEvent e ) } catch ( LdapInvalidDnException lide ) { - // Do nothing + // Do nothing } } } @@ -263,7 +323,87 @@ public void widgetSelected( SelectionEvent e ) /** - * Notifies that the Dn has been changed. + * Creates the multi-select widget (list + Add/Remove buttons). + */ + private void createMultiSelectWidget( final Composite parent ) + { + // DN list + dnListControl = new org.eclipse.swt.widgets.List( parent, + SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL ); + GridData listGd = new GridData( GridData.FILL_BOTH ); + listGd.heightHint = 100; + listGd.widthHint = 200; + dnListControl.setLayoutData( listGd ); + + for ( Dn d : dns ) + { + dnListControl.add( d.getName() ); + } + + dnListControl.addSelectionListener( new SelectionAdapter() + { + public void widgetSelected( SelectionEvent e ) + { + internalSetEnabled(); + } + } ); + + // Buttons composite (stacked vertically in the second column) + Composite buttonsComposite = BaseWidgetUtils.createColumnContainer( parent, 1, 1 ); + GridData bgd = new GridData( SWT.FILL, SWT.TOP, false, false ); + buttonsComposite.setLayoutData( bgd ); + + addButton = BaseWidgetUtils.createButton( buttonsComposite, + Messages.getString( "EntryWidget.AddButton" ), 1 ); //$NON-NLS-1$ + addButton.addSelectionListener( new SelectionAdapter() + { + public void widgetSelected( SelectionEvent e ) + { + if ( browserConnection != null ) + { + IEntry rootEntry = browserConnection.getRootDSE(); + SelectEntryDialog dialog = new SelectEntryDialog( parent.getShell(), + Messages.getString( "EntryWidget.SelectDN" ), rootEntry, null ); //$NON-NLS-1$ + dialog.open(); + for ( IEntry entry : dialog.getSelectedEntries() ) + { + Dn entryDn = entry.getDn(); + if ( !dns.contains( entryDn ) ) + { + dns.add( entryDn ); + dnListControl.add( entryDn.getName() ); + } + } + internalSetEnabled(); + notifyListeners(); + } + } + } ); + + removeButton = BaseWidgetUtils.createButton( buttonsComposite, + Messages.getString( "EntryWidget.RemoveButton" ), 1 ); //$NON-NLS-1$ + removeButton.addSelectionListener( new SelectionAdapter() + { + public void widgetSelected( SelectionEvent e ) + { + int[] indices = dnListControl.getSelectionIndices(); + // remove in reverse order so earlier indices stay valid + for ( int i = indices.length - 1; i >= 0; i-- ) + { + dns.remove( indices[i] ); + dnListControl.remove( indices[i] ); + } + internalSetEnabled(); + notifyListeners(); + } + } ); + + internalSetEnabled(); + } + + + /** + * Notifies that the Dn has been changed (single-select mode). */ private void dnChanged() { @@ -281,14 +421,25 @@ private void dnChanged() */ public void setEnabled( boolean enabled ) { - dnCombo.setEnabled( enabled ); - - if ( enabled ) + if ( multiSelect ) { - this.dnChanged(); + if ( dnListControl != null ) + { + dnListControl.setEnabled( enabled ); + } + internalSetEnabled(); } + else + { + dnCombo.setEnabled( enabled ); - internalSetEnabled(); + if ( enabled ) + { + this.dnChanged(); + } + + internalSetEnabled(); + } } @@ -297,18 +448,38 @@ public void setEnabled( boolean enabled ) */ private void internalSetEnabled() { - upButton.setEnabled( !Dn.isNullOrEmpty( dn ) && dnCombo.isEnabled() ); - entryBrowseButton.setEnabled( browserConnection != null && dnCombo.isEnabled() ); + if ( multiSelect ) + { + if ( addButton != null ) + { + addButton.setEnabled( browserConnection != null + && ( dnListControl == null || dnListControl.isEnabled() ) ); + } + if ( removeButton != null ) + { + removeButton.setEnabled( dnListControl != null + && dnListControl.isEnabled() + && dnListControl.getSelectionCount() > 0 ); + } + } + else + { + upButton.setEnabled( !Dn.isNullOrEmpty( dn ) && dnCombo.isEnabled() ); + entryBrowseButton.setEnabled( browserConnection != null && dnCombo.isEnabled() ); + } } /** - * Saves dialog settings. + * Saves dialog settings (single-select mode only). */ public void saveDialogSettings() { - HistoryUtils.save( BrowserCommonActivator.getDefault().getDialogSettings(), - BrowserCommonConstants.DIALOGSETTING_KEY_DN_HISTORY, this.dnCombo.getText() ); + if ( !multiSelect && dnCombo != null ) + { + HistoryUtils.save( BrowserCommonActivator.getDefault().getDialogSettings(), + BrowserCommonConstants.DIALOGSETTING_KEY_DN_HISTORY, this.dnCombo.getText() ); + } } @@ -324,7 +495,7 @@ public Dn getSuffix() /** - * Gets the Dn or null if the Dn isn't valid. + * Gets the Dn or null if the Dn isn't valid (single-select mode). * * @return the Dn or null if the Dn isn't valid */ @@ -334,6 +505,25 @@ public Dn getDn() } + /** + * Gets all selected DNs (multi-select mode). + * In single-select mode returns an array with the single Dn, or an empty array. + * + * @return the array of selected DNs, never null + */ + public Dn[] getDns() + { + if ( multiSelect ) + { + return dns.toArray( new Dn[0] ); + } + else + { + return dn != null ? new Dn[]{ dn } : new Dn[0]; + } + } + + /** * Gets the browser connection. * diff --git a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/messages.properties b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/messages.properties index 23be55c93b..daface90ab 100644 --- a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/messages.properties +++ b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/messages.properties @@ -22,6 +22,8 @@ BrowserConnectionWidget.SelectConnection=Select Connection EntryWidget.BrowseButton=Br&owse... EntryWidget.Parent=Parent EntryWidget.SelectDN=Select DN +EntryWidget.AddButton=&Add... +EntryWidget.RemoveButton=&Remove FilterWidget.FilterEditor=Filter Editor FilterWidget.FilterEditorButton=F&ilter Editor... LimitWidget.CountLimit=&Count Limit: diff --git a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/messages_de.properties b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/messages_de.properties index 7b47d604f4..c4e83850e3 100644 --- a/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/messages_de.properties +++ b/plugins/ldapbrowser.common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/search/messages_de.properties @@ -22,6 +22,8 @@ BrowserConnectionWidget.SelectConnection=Verbindung ausw\u00E4hlen EntryWidget.BrowseButton=Br&owsen... EntryWidget.Parent=Übergeordneter Eintrag EntryWidget.SelectDN=DN ausw\u00E4hlen +EntryWidget.AddButton=&Hinzufügen... +EntryWidget.RemoveButton=&Entfernen FilterWidget.FilterEditor=Filtereditor FilterWidget.FilterEditorButton=F&iltereditor... LimitWidget.CountLimit=&Max. Anzahl: diff --git a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/dn/DnValueEditor.java b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/dn/DnValueEditor.java index e6a238643b..9e7db3d4b1 100644 --- a/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/dn/DnValueEditor.java +++ b/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/dn/DnValueEditor.java @@ -26,8 +26,11 @@ import org.apache.directory.studio.ldapbrowser.common.dialogs.DnDialog; import org.apache.directory.studio.ldapbrowser.common.dialogs.TextDialog; 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.IBrowserConnection; +import org.apache.directory.studio.ldapbrowser.core.model.IEntry; import org.apache.directory.studio.ldapbrowser.core.model.IValue; +import org.apache.directory.studio.ldapbrowser.core.utils.CompoundModification; import org.apache.directory.studio.valueeditors.AbstractDialogStringValueEditor; import org.eclipse.swt.widgets.Shell; @@ -44,15 +47,68 @@ public class DnValueEditor extends AbstractDialogStringValueEditor /** * {@inheritDoc} * - * This implementation opens the DnDialog. + * When the value being edited is an empty placeholder (a newly added value), + * the dialog opens in multi-select mode so the user can pick several DNs at + * once (e.g. to add multiple members to a group). If more than one DN is + * chosen, the additional values are written directly via + * {@link CompoundModification} and the cell-editor path is bypassed. + * + * For existing (non-empty) values the dialog opens in the original + * single-select mode. */ protected boolean openDialog( Shell shell ) { Object value = getValue(); - + if ( value instanceof DnValueEditorRawValueWrapper ) { DnValueEditorRawValueWrapper wrapper = ( DnValueEditorRawValueWrapper ) value; + + // --- Multi-select mode for new (empty) values --- + if ( wrapper.ivalue != null && wrapper.ivalue.isEmpty() ) + { + DnDialog dialog = new DnDialog( shell, + Messages.getString( "DnValueEditor.DNEditor" ), null, wrapper.connection, new Dn[0] ); //$NON-NLS-1$ + + if ( dialog.open() != TextDialog.OK ) + { + return false; + } + + Dn[] selectedDns = dialog.getDns(); + if ( selectedDns.length == 0 ) + { + return false; + } + + if ( selectedDns.length == 1 ) + { + // Single selection – use the normal cell-editor path + setValue( selectedDns[0].getName() ); + return true; + } + + // Multiple selections: commit everything directly so that each DN + // becomes its own attribute value. + IValue original = wrapper.ivalue; + IAttribute attribute = original.getAttribute(); + IEntry entry = attribute.getEntry(); + String attrDesc = attribute.getDescription(); + + CompoundModification modification = new CompoundModification(); + // Replace the empty placeholder with the first selected DN. + modification.modifyValue( original, selectedDns[0].getName() ); + // Append the remaining DNs as additional values. + for ( int i = 1; i < selectedDns.length; i++ ) + { + modification.createValue( entry, attrDesc, selectedDns[i].getName() ); + } + // We have already committed the changes; tell the cell editor to cancel + // so it does not try to set a value a second time. + return false; + } + + // --- Single-select mode for existing values (original behaviour) --- Dn dn; try { @@ -112,7 +168,9 @@ else if ( attributeHierarchy.size() == 1 && attributeHierarchy.getAttribute().ge * {@inheritDoc} * * Returns a DnValueEditorRawValueWrapper with the connection of - * the value and a Dn build from the given value. + * the value and a Dn built from the given value. The IValue itself is + * stored in the wrapper so that {@link #openDialog} can detect whether + * the value is an empty placeholder and act accordingly. */ public Object getRawValue( IValue value ) { @@ -120,7 +178,7 @@ public Object getRawValue( IValue value ) if ( o instanceof String ) { IBrowserConnection connection = value.getAttribute().getEntry().getBrowserConnection(); - return new DnValueEditorRawValueWrapper( connection, ( String ) o ); + return new DnValueEditorRawValueWrapper( connection, ( String ) o, value ); } return null; @@ -140,17 +198,38 @@ private class DnValueEditorRawValueWrapper /** The Dn, used as initial value in DnDialog */ private String dn; + /** + * The IValue being edited. Set when the wrapper originates from the + * cell-editor path ({@link #getRawValue(IValue)}); null when it comes + * from the read-only display path ({@link #getRawValue(AttributeHierarchy)}). + */ + private IValue ivalue; + /** - * Creates a new instance of DnValueEditorRawValueWrapper. + * Creates a new instance of DnValueEditorRawValueWrapper (display path). * * @param connection the connection * @param dn the Dn */ private DnValueEditorRawValueWrapper( IBrowserConnection connection, String dn ) + { + this( connection, dn, null ); + } + + + /** + * Creates a new instance of DnValueEditorRawValueWrapper (cell-editor path). + * + * @param connection the connection + * @param dn the Dn + * @param ivalue the IValue being edited + */ + private DnValueEditorRawValueWrapper( IBrowserConnection connection, String dn, IValue ivalue ) { this.connection = connection; this.dn = dn; + this.ivalue = ivalue; }