directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fel...@apache.org
Subject svn commit: r592079 [10/17] - in /directory/sandbox/felixk/studio-ldapbrowser-common: ./ META-INF/ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/directory/ src/main/java/org/apache/directory/studio/...
Date Mon, 05 Nov 2007 16:48:54 GMT
Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ModWidget.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ModWidget.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ModWidget.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ModWidget.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,604 @@
+/*
+ *  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;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreConstants;
+import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
+import org.eclipse.jface.fieldassist.DecoratedField;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.fieldassist.IControlCreator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+
+/**
+ * The ModWidget provides input elements to define an LDAP modify 
+ * operation.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ModWidget extends BrowserWidget implements ModifyListener
+{
+
+    /** The schema with the possible attribute types */
+    private Schema schema;
+
+    /** The shell */
+    private Shell shell;
+
+    /** The composite that contains the ModSpecs */
+    private Composite modComposite;
+
+    /** The list of ModSpecs */
+    private ArrayList<ModSpec> modSpecList;
+
+    /** The resulting LDIF */
+    private String ldif;
+
+
+    /**
+     * Creates a new instance of ModWidget.
+     *
+     * @param schema the schema with the possible attribute types
+     */
+    public ModWidget( Schema schema )
+    {
+        this.schema = schema;
+        this.modSpecList = new ArrayList<ModSpec>();
+        this.ldif = null;
+    }
+
+
+    /**
+     * Disposes this widget.
+     */
+    public void dispose()
+    {
+    }
+
+
+    /**
+     * Gets the ldif.
+     * 
+     * @return the ldif
+     */
+    public String getLdif()
+    {
+        return ldif;
+    }
+
+
+    /**
+     * Creates the contents.
+     * 
+     * @param parent the parent composite
+     * 
+     * @return the created composite
+     */
+    public Composite createContents( Composite parent )
+    {
+        shell = parent.getShell();
+
+        modComposite = BaseWidgetUtils.createColumnContainer( parent, 3, 1 );
+        addModSpec( modComposite, 0 );
+
+        return modComposite;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void modifyText( ModifyEvent e )
+    {
+        validate();
+    }
+
+
+    /**
+     * Validates the input elements.
+     */
+    public void validate()
+    {
+        for ( int i = 0; i < modSpecList.size(); i++ )
+        {
+            ModSpec modSpec = ( ModSpec ) modSpecList.get( i );
+            if ( modSpecList.size() > 1 )
+            {
+                modSpec.modDeleteButton.setEnabled( true );
+            }
+            else
+            {
+                modSpec.modDeleteButton.setEnabled( false );
+            }
+            for ( int k = 0; k < modSpec.valueLineList.size(); k++ )
+            {
+                ValueLine valueLine = ( ValueLine ) modSpec.valueLineList.get( k );
+                if ( modSpec.valueLineList.size() > 1 )
+                {
+                    valueLine.valueDeleteButton.setEnabled( true );
+                }
+                else
+                {
+                    valueLine.valueDeleteButton.setEnabled( false );
+                }
+            }
+        }
+
+        notifyListeners();
+    }
+
+
+    /**
+     * Adds a modification spec at the given index.
+     * 
+     * @param modComposite the composite
+     * @param index the index
+     */
+    private void addModSpec( Composite modComposite, int index )
+    {
+
+        ModSpec[] modSpecs = ( ModSpec[] ) modSpecList.toArray( new ModSpec[modSpecList.size()] );
+
+        if ( modSpecs.length > 0 )
+        {
+            for ( int i = 0; i < modSpecs.length; i++ )
+            {
+                ModSpec oldModSpec = modSpecs[i];
+
+                // remember values
+                String oldType = oldModSpec.modType.getText();
+                String oldAttribute = oldModSpec.modAttributeCombo.getText();
+                String[] oldValues = new String[oldModSpec.valueLineList.size()];
+                for ( int k = 0; k < oldValues.length; k++ )
+                {
+                    oldValues[k] = ( ( ValueLine ) oldModSpec.valueLineList.get( k ) ).valueText.getText();
+                }
+
+                // delete old
+                oldModSpec.modGroup.dispose();
+                oldModSpec.modAddButton.dispose();
+                oldModSpec.modDeleteButton.dispose();
+                modSpecList.remove( oldModSpec );
+
+                // add new
+                ModSpec newModSpec = createModSpec( modComposite );
+                modSpecList.add( newModSpec );
+
+                // restore values
+                newModSpec.modType.setText( oldType );
+                newModSpec.modAttributeCombo.setText( oldAttribute );
+                deleteValueLine( newModSpec, 0 );
+                for ( int k = 0; k < oldValues.length; k++ )
+                {
+                    addValueLine( newModSpec, k );
+                    ValueLine newValueLine = ( ValueLine ) newModSpec.valueLineList.get( k );
+                    newValueLine.valueText.setText( oldValues[k] );
+                }
+
+                // check
+                if ( index == i + 1 )
+                {
+                    ModSpec modSpec = createModSpec( modComposite );
+                    modSpecList.add( modSpec );
+                }
+            }
+        }
+        else
+        {
+            ModSpec modSpec = createModSpec( modComposite );
+            modSpecList.add( modSpec );
+        }
+
+        shell.layout( true, true );
+    }
+
+
+    /**
+     * Creates and returns a modification spec.
+     * 
+     * @param modComposite the composite
+     * 
+     * @return the created modification spec
+     */
+    private ModSpec createModSpec( final Composite modComposite )
+    {
+        final ModSpec modSpec = new ModSpec();
+
+        modSpec.modGroup = BaseWidgetUtils.createGroup( modComposite, "", 1 );
+        Composite modSpecComposite = BaseWidgetUtils.createColumnContainer( modSpec.modGroup, 2, 1 );
+        modSpec.modType = BaseWidgetUtils.createCombo( modSpecComposite, new String[]
+            { "add", "replace", "delete" }, 0, 1 );
+        modSpec.modType.addModifyListener( this );
+        String[] attributeDescriptions = schema.getAttributeTypeDescriptionNames();
+        Arrays.sort( attributeDescriptions );
+
+        // attribute combo with field decoration
+        final FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault().getFieldDecoration(
+            FieldDecorationRegistry.DEC_CONTENT_PROPOSAL );
+        modSpec.modAttributeComboField = new DecoratedField( modSpecComposite, SWT.NONE, new IControlCreator()
+        {
+            public Control createControl( Composite parent, int style )
+            {
+                Combo combo = BaseWidgetUtils.createCombo( parent, new String[0], -1, 1 );
+                combo.setVisibleItemCount( 20 );
+                return combo;
+            }
+        } );
+        modSpec.modAttributeComboField.addFieldDecoration( fieldDecoration, SWT.TOP | SWT.LEFT, true );
+        modSpec.modAttributeComboField.getLayoutControl().setLayoutData(
+            new GridData( SWT.FILL, SWT.CENTER, true, false ) );
+        modSpec.modAttributeCombo = ( Combo ) modSpec.modAttributeComboField.getControl();
+        modSpec.modAttributeCombo.setItems( attributeDescriptions );
+        modSpec.modAttributeCombo.addModifyListener( this );
+
+        // content proposal adapter
+        modSpec.modAttributeCPA = new ContentProposalAdapter( modSpec.modAttributeCombo, new ComboContentAdapter(),
+            new ListContentProposalProvider( attributeDescriptions ), null, null );
+        modSpec.modAttributeCPA.setFilterStyle( ContentProposalAdapter.FILTER_NONE );
+        modSpec.modAttributeCPA.setProposalAcceptanceStyle( ContentProposalAdapter.PROPOSAL_REPLACE );
+
+        // add button with listener
+        modSpec.modAddButton = new Button( modComposite, SWT.PUSH );
+        modSpec.modAddButton.setText( "  +   " );
+        modSpec.modAddButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                int index = modSpecList.size();
+                for ( int i = 0; i < modSpecList.size(); i++ )
+                {
+                    ModSpec modSpec = modSpecList.get( i );
+                    if ( modSpec.modAddButton == e.widget )
+                    {
+                        index = i + 1;
+                    }
+                }
+
+                addModSpec( modComposite, index );
+
+                validate();
+            }
+        } );
+
+        // delete button with listener
+        modSpec.modDeleteButton = new Button( modComposite, SWT.PUSH );
+        modSpec.modDeleteButton.setText( "  \u2212  " ); // \u2013
+        modSpec.modDeleteButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                int index = 0;
+                for ( int i = 0; i < modSpecList.size(); i++ )
+                {
+                    ModSpec modSpec = modSpecList.get( i );
+                    if ( modSpec.modDeleteButton == e.widget )
+                    {
+                        index = i;
+                    }
+                }
+
+                deleteModSpec( modComposite, index );
+
+                validate();
+            }
+        } );
+
+        addValueLine( modSpec, 0 );
+
+        return modSpec;
+    }
+
+
+    /**
+     * Delets a modification spec.
+     *
+     * @param modComposite the composite
+     * @param index the index
+     */
+    private void deleteModSpec( Composite modComposite, int index )
+    {
+        ModSpec modSpec = modSpecList.remove( index );
+        if ( modSpec != null )
+        {
+            modSpec.modGroup.dispose();
+            modSpec.modAddButton.dispose();
+            modSpec.modDeleteButton.dispose();
+
+            if ( !modComposite.isDisposed() )
+            {
+                shell.layout( true, true );
+            }
+        }
+    }
+
+
+    /**
+     * Adds a value line to the given modification spec.
+     * 
+     * @param modSpec the modification spec
+     * @param index the index
+     */
+    private void addValueLine( ModSpec modSpec, int index )
+    {
+
+        ValueLine[] valueLines = modSpec.valueLineList.toArray( new ValueLine[modSpec.valueLineList.size()] );
+
+        if ( valueLines.length > 0 )
+        {
+            for ( int i = 0; i < valueLines.length; i++ )
+            {
+                ValueLine oldValueLine = valueLines[i];
+
+                // remember values
+                String oldValue = oldValueLine.valueText.getText();
+
+                // delete old
+                oldValueLine.valueComposite.dispose();
+                modSpec.valueLineList.remove( oldValueLine );
+
+                // add new
+                ValueLine newValueLine = createValueLine( modSpec );
+                modSpec.valueLineList.add( newValueLine );
+
+                // restore value
+                newValueLine.valueText.setText( oldValue );
+
+                // check
+                if ( index == i + 1 )
+                {
+                    ValueLine valueLine = createValueLine( modSpec );
+                    modSpec.valueLineList.add( valueLine );
+                }
+            }
+        }
+        else
+        {
+            ValueLine valueLine = createValueLine( modSpec );
+            modSpec.valueLineList.add( valueLine );
+        }
+
+        shell.layout( true, true );
+    }
+
+
+    /**
+     * Creates the value line.
+     * 
+     * @param modSpec the modification spec
+     * 
+     * @return the value line
+     */
+    private ValueLine createValueLine( final ModSpec modSpec )
+    {
+        final ValueLine valueLine = new ValueLine();
+
+        // text field
+        valueLine.valueComposite = BaseWidgetUtils.createColumnContainer( modSpec.modGroup, 3, 1 );
+        valueLine.valueText = BaseWidgetUtils.createText( valueLine.valueComposite, "", 1 );
+        valueLine.valueText.addModifyListener( this );
+
+        // add button with listener
+        valueLine.valueAddButton = new Button( valueLine.valueComposite, SWT.PUSH );
+        valueLine.valueAddButton.setText( "  +   " );
+        valueLine.valueAddButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                int index = modSpec.valueLineList.size();
+                for ( int i = 0; i < modSpec.valueLineList.size(); i++ )
+                {
+                    ValueLine valueLine = modSpec.valueLineList.get( i );
+                    if ( valueLine.valueAddButton == e.widget )
+                    {
+                        index = i + 1;
+                    }
+                }
+
+                addValueLine( modSpec, index );
+
+                validate();
+            }
+        } );
+
+        // delete button with listener
+        valueLine.valueDeleteButton = new Button( valueLine.valueComposite, SWT.PUSH );
+        valueLine.valueDeleteButton.setText( "  \u2212  " ); // \u2013
+        valueLine.valueDeleteButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                int index = 0;
+                for ( int i = 0; i < modSpec.valueLineList.size(); i++ )
+                {
+                    ValueLine valueLine = modSpec.valueLineList.get( i );
+                    if ( valueLine.valueDeleteButton == e.widget )
+                    {
+                        index = i;
+                    }
+                }
+
+                deleteValueLine( modSpec, index );
+
+                validate();
+            }
+        } );
+
+        return valueLine;
+    }
+
+
+    /**
+     * Delete value line.
+     * 
+     * @param modSpec the mod spec
+     * @param index the index
+     */
+    private void deleteValueLine( ModSpec modSpec, int index )
+    {
+        ValueLine valueLine = ( ValueLine ) modSpec.valueLineList.remove( index );
+        if ( valueLine != null )
+        {
+            valueLine.valueComposite.dispose();
+
+            if ( !modComposite.isDisposed() )
+            {
+                shell.layout( true, true );
+            }
+        }
+    }
+
+
+    /**
+     * Gets the LDIF fragment.
+     * 
+     * @return the LDIF fragment
+     */
+    public String getLdifFragment()
+    {
+
+        StringBuffer sb = new StringBuffer();
+        sb.append( "changetype: modify" ).append( BrowserCoreConstants.LINE_SEPARATOR );
+
+        ModSpec[] modSpecs = ( ModSpec[] ) modSpecList.toArray( new ModSpec[modSpecList.size()] );
+
+        if ( modSpecs.length > 0 )
+        {
+            for ( int i = 0; i < modSpecs.length; i++ )
+            {
+                ModSpec modSpec = modSpecs[i];
+
+                // get values
+                String type = modSpec.modType.getText();
+                String attribute = modSpec.modAttributeCombo.getText();
+                String[] values = new String[modSpec.valueLineList.size()];
+                for ( int k = 0; k < values.length; k++ )
+                {
+                    values[k] = ( ( ValueLine ) modSpec.valueLineList.get( k ) ).valueText.getText();
+                }
+
+                // build ldif
+                sb.append( type ).append( ": " ).append( attribute ).append( BrowserCoreConstants.LINE_SEPARATOR );
+                for ( int k = 0; k < values.length; k++ )
+                {
+                    if ( values[k].length() > 0 )
+                    {
+                        sb.append( attribute ).append( ": " ).append( values[k] ).append(
+                            BrowserCoreConstants.LINE_SEPARATOR );
+                    }
+                }
+                sb.append( "-" ).append( BrowserCoreConstants.LINE_SEPARATOR );
+                // sb.append(BrowserCoreConstants.NEWLINE);
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * The Class ModSpec is a wrapper for all input elements
+     * of an modification. It contains a combo for the modify
+     * operation, a combo for the attribute to modify, 
+     * value lines and + and - buttons to add and remove 
+     * other modifications. It looks like this:
+     * <pre>
+     * ----------------------------------
+     * | operation v | attribute type v |--------
+     * ------------------------ --------| + | - |
+     * | value                  | + | - |--------
+     * ----------------------------------
+     * </pre>
+     */
+    private class ModSpec
+    {
+
+        /** The mod group. */
+        private Group modGroup;
+
+        /** The mod type. */
+        private Combo modType;
+
+        /** The modification attribute field. */
+        private DecoratedField modAttributeComboField;
+
+        /** The modification attribute. */
+        private Combo modAttributeCombo;
+
+        /** The modification content proposal adapter */
+        private ContentProposalAdapter modAttributeCPA;
+
+        /** The mod add button. */
+        private Button modAddButton;
+
+        /** The mod delete button. */
+        private Button modDeleteButton;
+
+        /** The value line list. */
+        private ArrayList<ValueLine> valueLineList = new ArrayList<ValueLine>();;
+    }
+
+    /**
+     * The Class ValueLine is a wrapper for all input elements
+     * of an value line. It contains an input field for the value
+     * and + and - buttons to add and remove other value lines. 
+     * It looks like this:
+     * <pre>
+     * -------------------------------------
+     * | value                     | + | - |
+     * -------------------------------------
+     * </pre>
+     */
+    private class ValueLine
+    {
+
+        /** The value composite. */
+        private Composite valueComposite;
+
+        /** The value text. */
+        private Text valueText;
+
+        /** The value add button. */
+        private Button valueAddButton;
+
+        /** The value delete button. */
+        private Button valueDeleteButton;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ModWidget.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/OptionsInput.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/OptionsInput.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/OptionsInput.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/OptionsInput.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,253 @@
+/*
+ *  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;
+
+
+import java.util.Arrays;
+
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+
+/**
+ * The OptionsInput could be used to select one option out of several options.
+ * It consists of two radio buttons. With the first radio button you could 
+ * select the most likely default option. With the second radio button a combo 
+ * is activated where you could select another option from a drop-down list.
+ * <p>
+ * Both, the default option and the options in the drop-down list have a raw
+ * value that is returned by {@link #getRawValue()} and a display value
+ * that is shown to the user. 
+ * <p>
+ * If the initial raw value is equal to the default raw value then the 
+ * default radio is checked and the drop-down list is disabled. Otherwise 
+ * the second radio is checked, the drop-down list is enabled and the
+ * initial value is selected. 
+ * <p>
+ * The OptionsInput is used by {@link TextFormatsPreferencePage}.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class OptionsInput extends BrowserWidget
+{
+
+    /** The option's title */
+    private String title;
+
+    /** The group, only used when asGroup is true */
+    private Group titleGroup;
+
+    /** The default raw value */
+    private String defaultRawValue;
+
+    /** The default display value */
+    private String defaultDisplayValue;
+
+    /** The radio button to select the default value */
+    private Button defaultButton;
+
+    /** The other raw values */
+    private String[] otherRawValues;
+
+    /** The other display values */
+    private String[] otherDisplayValues;
+
+    /** The radio button to select a value from drop-down list */
+    private Button otherButton;
+
+    /** The combo with the other values */
+    private Combo otherCombo;
+
+    /** The initial raw value */
+    private String initialRawValue;
+
+    /** If true the options are aggregated in a group widget */
+    private boolean asGroup;
+
+    /** If true it is possible to enter a custom value into the combo field */
+    private boolean allowCustomInput;
+
+
+    /**
+     * Creates a new instance of OptionsInput.
+     *
+     * @param title the option's title
+     * @param defaultDisplayValue the default display value
+     * @param defaultRawValue the default raw value
+     * @param otherDisplayValues the other display values
+     * @param otherRawValues the other raw vaues
+     * @param initialRawValue the initial raw value
+     * @param asGroup a flag indicating if the options should be 
+     *                aggregated in a group widget
+     * @param allowCustomInput true to make it possible to enter a 
+     *                         custom value into the combo field
+     */
+    public OptionsInput( String title, String defaultDisplayValue, String defaultRawValue, String[] otherDisplayValues,
+        String[] otherRawValues, String initialRawValue, boolean asGroup, boolean allowCustomInput )
+    {
+        super();
+        this.title = title;
+        this.defaultDisplayValue = defaultDisplayValue;
+        this.defaultRawValue = defaultRawValue;
+        this.otherDisplayValues = otherDisplayValues;
+        this.otherRawValues = otherRawValues;
+        this.initialRawValue = initialRawValue;
+        this.asGroup = asGroup;
+        this.allowCustomInput = allowCustomInput;
+    }
+
+
+    /**
+     * Creates the widget.
+     *
+     * @param parent the parent
+     */
+    public void createWidget( Composite parent )
+    {
+
+        Composite composite;
+        if ( asGroup )
+        {
+            titleGroup = BaseWidgetUtils.createGroup( parent, title, 1 );
+            composite = BaseWidgetUtils.createColumnContainer( titleGroup, 1, 1 );
+        }
+        else
+        {
+            composite = parent;
+            Composite labelComposite = BaseWidgetUtils.createColumnContainer( composite, 1, 1 );
+            BaseWidgetUtils.createLabel( labelComposite, title + ":", 1 );
+        }
+
+        Composite defaultComposite = BaseWidgetUtils.createColumnContainer( composite, 1, 1 );
+        defaultButton = BaseWidgetUtils.createRadiobutton( defaultComposite, defaultDisplayValue, 1 );
+        defaultButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                otherButton.setSelection( false );
+                otherCombo.setEnabled( false );
+                notifyListeners();
+            }
+        } );
+
+        Composite otherComposite = BaseWidgetUtils.createColumnContainer( composite, 2, 1 );
+        otherButton = BaseWidgetUtils.createRadiobutton( otherComposite, "Other: ", 1 );
+        otherButton.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                defaultButton.setSelection( false );
+                otherCombo.setEnabled( true );
+                notifyListeners();
+            }
+        } );
+
+        if ( allowCustomInput )
+        {
+            otherCombo = BaseWidgetUtils.createCombo( otherComposite, otherDisplayValues, 0, 1 );
+        }
+        else
+        {
+            otherCombo = BaseWidgetUtils.createReadonlyCombo( otherComposite, otherDisplayValues, 0, 1 );
+        }
+        otherCombo.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                notifyListeners();
+            }
+        } );
+
+        setRawValue( initialRawValue );
+    }
+
+
+    /**
+     * Gets the raw value. Either the default value or
+     * the selected value from the combo.
+     *
+     * @return the raw value
+     */
+    public String getRawValue()
+    {
+        if ( defaultButton.getSelection() )
+        {
+            return defaultRawValue;
+        }
+        else
+        {
+            String t = otherCombo.getText();
+            for ( int i = 0; i < otherDisplayValues.length; i++ )
+            {
+                if ( t.equals( otherDisplayValues[i] ) )
+                {
+                    return otherRawValues[i];
+                }
+            }
+            return t;
+        }
+    }
+
+
+    /**
+     * Sets the raw value.
+     *
+     * @param rawValue the raw value
+     */
+    public void setRawValue( String rawValue )
+    {
+        int index = Arrays.asList( otherRawValues ).indexOf( rawValue );
+        if ( index == -1 )
+        {
+            index = Arrays.asList( otherDisplayValues ).indexOf( rawValue );
+        }
+
+        if ( defaultRawValue.equals( rawValue ) )
+        {
+            defaultButton.setSelection( true );
+            otherButton.setSelection( false );
+            otherCombo.setEnabled( false );
+            otherCombo.select( index );
+        }
+        else if ( index > -1 )
+        {
+            defaultButton.setSelection( false );
+            otherButton.setSelection( true );
+            otherCombo.setEnabled( true );
+            otherCombo.select( index );
+        }
+        else
+        {
+            defaultButton.setSelection( false );
+            otherButton.setSelection( true );
+            otherCombo.setEnabled( true );
+            otherCombo.setText( rawValue );
+        }
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/OptionsInput.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ViewFormWidget.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ViewFormWidget.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ViewFormWidget.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ViewFormWidget.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,256 @@
+/*
+ *  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;
+
+
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonConstants;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ViewForm;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+
+/**
+ * The ViewFormWidget is a widget that provides an info text,
+ * a tool bar, a menu and a main content composite including
+ * a context menu. 
+ * It looks like this:
+ * <pre>
+ * -----------------------------------
+ * | info text     | tool bar | menu |
+ * -----------------------------------
+ * |                                 |
+ * |          main content           |
+ * |                                 |
+ * -----------------------------------
+ * </pre>
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class ViewFormWidget
+{
+
+    /** The view form control */
+    protected ViewForm control;
+
+    /** The info text, positioned at the top left */
+    protected Text infoText;
+
+    /** The action tool bar */
+    protected ToolBar actionToolBar;
+
+    /** The action tool bar manager */
+    protected IToolBarManager actionToolBarManager;
+
+    /** The menu tool bar. */
+    protected ToolBar menuToolBar;
+
+    /** The menu manager. */
+    protected MenuManager menuManager;
+
+    /** The context menu manager. */
+    protected MenuManager contextMenuManager;
+
+
+    /**
+     * Creates the widget.
+     *
+     * @param parent the parent composite
+     */
+    public void createWidget( Composite parent )
+    {
+
+        control = new ViewForm( parent, SWT.NONE );
+        // control.marginWidth = 0;
+        // control.marginHeight = 0;
+        // control.horizontalSpacing = 0;
+        // control.verticalSpacing = 0;
+        control.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+
+        // infoText = BaseWidgetUtils.createLabeledText(control, "", 1);
+        Composite infoTextControl = BaseWidgetUtils.createColumnContainer( control, 1, 1 );
+        infoTextControl.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+        infoText = BaseWidgetUtils.createLabeledText( infoTextControl, "", 1 );
+        infoText.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, true ) );
+        control.setTopLeft( infoTextControl );
+
+        // tool bar
+        actionToolBar = new ToolBar( control, SWT.FLAT | SWT.RIGHT );
+        actionToolBar.setLayoutData( new GridData( SWT.END, SWT.NONE, true, false ) );
+        actionToolBarManager = new ToolBarManager( actionToolBar );
+        control.setTopCenter( actionToolBar );
+
+        // local menu
+        this.menuManager = new MenuManager();
+        menuToolBar = new ToolBar( control, SWT.FLAT | SWT.RIGHT );
+        ToolItem ti = new ToolItem( menuToolBar, SWT.PUSH, 0 );
+        ti.setImage( BrowserCommonActivator.getDefault().getImage( BrowserCommonConstants.IMG_PULLDOWN ) );
+        ti.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                showViewMenu();
+            }
+        } );
+        control.setTopRight( menuToolBar );
+
+        // content
+        Composite composite = BaseWidgetUtils.createColumnContainer( control, 1, 1 );
+        GridLayout gl = new GridLayout();
+        gl.horizontalSpacing = 0;
+        gl.verticalSpacing = 0;
+        gl.marginHeight = 0;
+        gl.marginWidth = 0;
+        composite.setLayout( gl );
+        Control childControl = this.createContent( composite );
+        control.setContent( composite );
+
+        // context menu
+        this.contextMenuManager = new MenuManager();
+        Menu menu = this.contextMenuManager.createContextMenu( childControl );
+        childControl.setMenu( menu );
+    }
+
+
+    /**
+     * Creates the content.
+     * 
+     * @param control the control
+     * 
+     * @return the control
+     */
+    protected abstract Control createContent( Composite control );
+
+
+    /**
+     * Shows the local view menu.
+     */
+    private void showViewMenu()
+    {
+        Menu aMenu = menuManager.createContextMenu( control );
+        Point topLeft = new Point( 0, 0 );
+        topLeft.y += menuToolBar.getBounds().height;
+        topLeft = menuToolBar.toDisplay( topLeft );
+        aMenu.setLocation( topLeft.x, topLeft.y );
+        aMenu.setVisible( true );
+    }
+
+
+    /**
+     * Disposes this widget.
+     */
+    public void dispose()
+    {
+        if ( control != null )
+        {
+
+            if ( contextMenuManager != null )
+            {
+                contextMenuManager.removeAll();
+                contextMenuManager.dispose();
+                contextMenuManager = null;
+            }
+            if ( menuToolBar != null )
+            {
+                menuToolBar.dispose();
+                menuToolBar = null;
+                menuManager.dispose();
+                menuManager = null;
+            }
+            if ( actionToolBar != null )
+            {
+                actionToolBar.dispose();
+                actionToolBar = null;
+                actionToolBarManager.removeAll();
+                actionToolBarManager = null;
+            }
+
+            if ( infoText != null )
+            {
+                infoText.dispose();
+                infoText = null;
+            }
+
+            control.dispose();
+            control = null;
+        }
+    }
+
+
+    /**
+     * Gets the info text.
+     * 
+     * @return the info text
+     */
+    public Text getInfoText()
+    {
+        return infoText;
+    }
+
+
+    /**
+     * Gets the tool bar manager.
+     * 
+     * @return the tool bar manager
+     */
+    public IToolBarManager getToolBarManager()
+    {
+        return this.actionToolBarManager;
+    }
+
+
+    /**
+     * Gets the menu manager.
+     * 
+     * @return the menu manager
+     */
+    public IMenuManager getMenuManager()
+    {
+        return menuManager;
+    }
+
+
+    /**
+     * Gets the context menu manager.
+     * 
+     * @return the context menu manager
+     */
+    public IMenuManager getContextMenuManager()
+    {
+        return this.contextMenuManager;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/ViewFormWidget.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyEvent.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyEvent.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyEvent.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyEvent.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,52 @@
+/*
+ *  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;
+
+
+import java.util.EventObject;
+
+
+/**
+ * A WidgetModifyEvent indicates that a {@link BrowserWidget} has
+ * been modified.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class WidgetModifyEvent extends EventObject
+{
+
+    /** The serialVersionUID */
+    private static final long serialVersionUID = 2421335730580648878L;
+
+
+    /**
+     * Creates a new instance of WidgetModifyEvent.
+     *
+     * @param source the event source
+     */
+    public WidgetModifyEvent( Object source )
+    {
+        super( source );
+
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyEvent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyListener.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyListener.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyListener.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyListener.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,41 @@
+/*
+ *  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;
+
+
+/**
+ * A WidgetModifyListener listens for modifications of a
+ * {@link BrowserWidget}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface WidgetModifyListener
+{
+
+    /**
+     * Notified about the modification of a {@link BrowserWidget}.
+     * 
+     * @param event the event
+     */
+    public void widgetModified( WidgetModifyEvent event );
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/WidgetModifyListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserActionGroup.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserActionGroup.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserActionGroup.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserActionGroup.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,312 @@
+/*
+ *  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.browser;
+
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.directory.studio.ldapbrowser.common.actions.CollapseAllAction;
+import org.apache.directory.studio.ldapbrowser.common.actions.FilterChildrenAction;
+import org.apache.directory.studio.ldapbrowser.common.actions.PropertiesAction;
+import org.apache.directory.studio.ldapbrowser.common.actions.RefreshAction;
+import org.apache.directory.studio.ldapbrowser.common.actions.UnfilterChildrenAction;
+import org.apache.directory.studio.ldapbrowser.common.actions.UpAction;
+import org.apache.directory.studio.ldapbrowser.common.actions.proxy.ActionHandlerManager;
+import org.apache.directory.studio.ldapbrowser.common.actions.proxy.BrowserViewActionProxy;
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.commands.ActionHandler;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.commands.ICommandService;
+
+
+/**
+ * This class manages all the actions of the browser widget.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class BrowserActionGroup implements ActionHandlerManager, IMenuListener
+{
+
+    /** The open sort dialog action. */
+    protected OpenSortDialogAction openSortDialogAction;
+
+    /** The collapse all action. */
+    protected CollapseAllAction collapseAllAction;
+
+    /** The Constant upAction. */
+    protected static final String upAction = "upAction";
+
+    /** The Constant refreshAction. */
+    protected static final String refreshAction = "refreshAction";
+
+    /** The Constant filterChildrenAction. */
+    protected static final String filterChildrenAction = "filterChildrenAction";
+
+    /** The Constant unfilterChildrenAction. */
+    protected static final String unfilterChildrenAction = "unfilterChildrenAction";
+
+    /** The Constant propertyDialogAction. */
+    protected static final String propertyDialogAction = "propertyDialogAction";
+
+    /** The browser action map. */
+    protected Map<String, BrowserViewActionProxy> browserActionMap;
+
+    /** The action bars. */
+    protected IActionBars actionBars;
+
+    /** The browser's main widget. */
+    protected BrowserWidget mainWidget;
+
+
+    /**
+     * Creates a new instance of BrowserActionGroup.
+     *
+     * @param mainWidget the browser's main widget
+     * @param configuration the  browser's configuration
+     */
+    public BrowserActionGroup( BrowserWidget mainWidget, BrowserConfiguration configuration )
+    {
+        this.mainWidget = mainWidget;
+        this.browserActionMap = new HashMap<String, BrowserViewActionProxy>();
+
+        TreeViewer viewer = mainWidget.getViewer();
+        openSortDialogAction = new OpenSortDialogAction( ( BrowserPreferences ) configuration.getPreferences() );
+        collapseAllAction = new CollapseAllAction( viewer );
+
+        browserActionMap.put( upAction, new BrowserViewActionProxy( viewer, this, new UpAction( viewer ) ) );
+        browserActionMap.put( refreshAction, new BrowserViewActionProxy( viewer, this, new RefreshAction() ) );
+        browserActionMap.put( filterChildrenAction, new BrowserViewActionProxy( viewer, this,
+            new FilterChildrenAction() ) );
+        browserActionMap.put( unfilterChildrenAction, new BrowserViewActionProxy( viewer, this,
+            new UnfilterChildrenAction() ) );
+        browserActionMap.put( propertyDialogAction, new BrowserViewActionProxy( viewer, this, new PropertiesAction() ) );
+    }
+
+
+    /**
+     * Disposes this action group.
+     */
+    public void dispose()
+    {
+        if ( mainWidget != null )
+        {
+
+            openSortDialogAction.dispose();
+            openSortDialogAction = null;
+            collapseAllAction.dispose();
+            collapseAllAction = null;
+
+            for ( Iterator it = browserActionMap.keySet().iterator(); it.hasNext(); )
+            {
+                String key = ( String ) it.next();
+                BrowserViewActionProxy action = ( BrowserViewActionProxy ) browserActionMap.get( key );
+                action.dispose();
+                action = null;
+                it.remove();
+            }
+            browserActionMap.clear();
+            browserActionMap = null;
+
+            actionBars = null;
+            mainWidget = null;
+        }
+    }
+
+
+    /**
+     * Enables the action handlers.
+     *
+     * @param actionBars the action bars
+     */
+    public void enableGlobalActionHandlers( IActionBars actionBars )
+    {
+        this.actionBars = actionBars;
+        activateGlobalActionHandlers();
+    }
+
+
+    /**
+     * Fills the tool bar.
+     *
+     * @param toolBarManager the tool bar manager
+     */
+    public void fillToolBar( IToolBarManager toolBarManager )
+    {
+        toolBarManager.add( ( IAction ) browserActionMap.get( upAction ) );
+        toolBarManager.add( new Separator() );
+        toolBarManager.add( collapseAllAction );
+        toolBarManager.add( ( IAction ) browserActionMap.get( refreshAction ) );
+        toolBarManager.update( true );
+    }
+
+
+    /**
+     * Fills the local menu.
+     *
+     * @param menuManager the local menu manager
+     */
+    public void fillMenu( IMenuManager menuManager )
+    {
+        menuManager.add( openSortDialogAction );
+        menuManager.add( new Separator() );
+        menuManager.update( true );
+    }
+
+
+    /**
+     * Fills the context menu.
+     *
+     * @param menuManager the context menu manager
+     */
+    public void fillContextMenu( IMenuManager menuManager )
+    {
+        menuManager.setRemoveAllWhenShown( true );
+        menuManager.addMenuListener( this );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * 
+     * This implementation fills the context menu.
+     */
+    public void menuAboutToShow( IMenuManager menuManager )
+    {
+        // up
+        menuManager.add( ( IAction ) browserActionMap.get( upAction ) );
+        menuManager.add( new Separator() );
+
+        // filter
+        menuManager.add( ( IAction ) browserActionMap.get( filterChildrenAction ) );
+        if ( ( ( IAction ) browserActionMap.get( unfilterChildrenAction ) ).isEnabled() )
+        {
+            menuManager.add( ( IAction ) browserActionMap.get( unfilterChildrenAction ) );
+        }
+        menuManager.add( new Separator() );
+
+        // refresh
+        menuManager.add( ( IAction ) browserActionMap.get( refreshAction ) );
+        menuManager.add( new Separator() );
+
+        // properties
+        menuManager.add( ( IAction ) browserActionMap.get( propertyDialogAction ) );
+    }
+
+
+    /**
+     * Activates the action handlers.
+     */
+    public void activateGlobalActionHandlers()
+    {
+        ICommandService commandService = ( ICommandService ) PlatformUI.getWorkbench().getAdapter(
+            ICommandService.class );
+
+        if ( actionBars != null )
+        {
+            actionBars.setGlobalActionHandler( ActionFactory.REFRESH.getId(), ( IAction ) browserActionMap
+                .get( refreshAction ) );
+            actionBars.setGlobalActionHandler( ActionFactory.PROPERTIES.getId(), ( IAction ) browserActionMap
+                .get( propertyDialogAction ) );
+            actionBars.updateActionBars();
+        }
+        else
+        {
+            if ( commandService != null )
+            {
+                IAction pda = ( IAction ) browserActionMap.get( propertyDialogAction );
+                pda.setActionDefinitionId( "org.apache.directory.studio.ldapbrowser.action.properties" );
+                commandService.getCommand( pda.getActionDefinitionId() ).setHandler( new ActionHandler( pda ) );
+
+                IAction ra = ( IAction ) browserActionMap.get( refreshAction );
+                commandService.getCommand( ra.getActionDefinitionId() ).setHandler( new ActionHandler( ra ) );
+            }
+        }
+
+        if ( commandService != null )
+        {
+            IAction ua = ( IAction ) browserActionMap.get( upAction );
+            commandService.getCommand( ua.getActionDefinitionId() ).setHandler( new ActionHandler( ua ) );
+        }
+    }
+
+
+    /**
+     * Deactivates the action handlers.
+     */
+    public void deactivateGlobalActionHandlers()
+    {
+
+        ICommandService commandService = ( ICommandService ) PlatformUI.getWorkbench().getAdapter(
+            ICommandService.class );
+
+        if ( actionBars != null )
+        {
+            actionBars.setGlobalActionHandler( ActionFactory.REFRESH.getId(), null );
+            actionBars.setGlobalActionHandler( ActionFactory.PROPERTIES.getId(), null );
+            actionBars.updateActionBars();
+        }
+        else
+        {
+            if ( commandService != null )
+            {
+                IAction pda = ( IAction ) browserActionMap.get( propertyDialogAction );
+                commandService.getCommand( pda.getActionDefinitionId() ).setHandler( null );
+
+                IAction ra = ( IAction ) browserActionMap.get( refreshAction );
+                commandService.getCommand( ra.getActionDefinitionId() ).setHandler( null );
+            }
+        }
+
+        if ( commandService != null )
+        {
+            IAction ua = ( IAction ) browserActionMap.get( upAction );
+            commandService.getCommand( ua.getActionDefinitionId() ).setHandler( null );
+        }
+
+    }
+
+
+    /**
+     * Sets the connection input to all actions
+     *
+     * @param connection the connection
+     */
+    public void setInput( IBrowserConnection connection )
+    {
+        for ( Iterator it = browserActionMap.values().iterator(); it.hasNext(); )
+        {
+            BrowserViewActionProxy action = ( BrowserViewActionProxy ) it.next();
+            action.inputChanged( connection );
+        }
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserActionGroup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserCategory.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserCategory.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserCategory.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserCategory.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,121 @@
+/*
+ *  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.browser;
+
+
+import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
+
+
+/**
+ * A BrowserCategory is the top-level node in the browser widget. 
+ * There are three types: DIT categories, searches categories
+ * and bookmarks categories.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class BrowserCategory
+{
+
+    /** The Constant TYPE_DIT identifies DIT categories. */
+    public static final int TYPE_DIT = 0;
+
+    /** The Constant TYPE_SEARCHES identifies searches categories. */
+    public static final int TYPE_SEARCHES = 1;
+
+    /** The Constant TYPE_BOOKMARKS identifies bookmark categories. */
+    public static final int TYPE_BOOKMARKS = 2;
+
+    /** The title for the DIT categoy */
+    public static final String TITLE_DIT = "DIT";
+
+    /** The title for the searches categoy */
+    public static final String TITLE_SEARCHES = "Searches";
+
+    /** The title for the bookmarks categoy */
+    public static final String TITLE_BOOKMARKS = "Bookmarks";
+
+    /** The category's connection */
+    private IBrowserConnection parent;
+
+    /** The category's type */
+    private int type;
+
+
+    /**
+     * Creates a new instance of BrowserCategory.
+     *
+     * @param type the category's type, one of TYPE_DIT, TYPE_SEARCHES or TYPE_BOOKMARKS
+     * @param parent the category's connection
+     */
+    public BrowserCategory( int type, IBrowserConnection parent )
+    {
+        this.parent = parent;
+        this.type = type;
+    }
+
+
+    /**
+     * Gets the category's parent, which is always a connection.
+     * 
+     * @return the parent connection
+     */
+    public IBrowserConnection getParent()
+    {
+        return parent;
+    }
+
+
+    /**
+     * Gets the category's type, one of TYPE_DIT, TYPE_SEARCHES or TYPE_BOOKMARKS.
+     *
+     * @return the category's type.
+     */
+    public int getType()
+    {
+        return type;
+    }
+
+
+    /**
+     * Gets the category's title.
+     *
+     * @return the category's title
+     */
+    public String getTitle()
+    {
+        switch ( type )
+        {
+            case TYPE_DIT:
+                return TITLE_DIT;
+
+            case TYPE_SEARCHES:
+                return TITLE_SEARCHES;
+
+            case TYPE_BOOKMARKS:
+                return TITLE_BOOKMARKS;
+
+            default:
+                return "ERROR";
+        }
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserCategory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserConfiguration.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserConfiguration.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserConfiguration.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserConfiguration.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,206 @@
+/*
+ *  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.browser;
+
+
+import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.widgets.Menu;
+
+
+/**
+ * The BrowserConfiguration contains the content provider, the
+ * label provider, the sorter, the context menu manager and the
+ * preferences for the browser widget. 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class BrowserConfiguration
+{
+
+    /** The disposed flag */
+    private boolean disposed = false;
+
+    /** The sorter. */
+    protected BrowserSorter sorter;
+
+    /** The preferences. */
+    protected BrowserPreferences preferences;
+
+    /** The content provider. */
+    protected BrowserContentProvider contentProvider;
+
+    /** The label provider. */
+    protected BrowserLabelProvider labelProvider;
+
+    /** The decorating label provider. */
+    protected DecoratingLabelProvider decoratingLabelProvider;
+
+    /** The context menu manager. */
+    protected MenuManager contextMenuManager;
+
+
+    /**
+     * Creates a new instance of BrowserConfiguration.
+     */
+    public BrowserConfiguration()
+    {
+    }
+
+
+    /**
+     * Disposes this configuration.
+     */
+    public void dispose()
+    {
+        if ( !disposed )
+        {
+            if ( sorter != null )
+            {
+                sorter.dispose();
+                sorter = null;
+            }
+
+            if ( preferences != null )
+            {
+                preferences.dispose();
+                preferences = null;
+            }
+
+            if ( contentProvider != null )
+            {
+                contentProvider.dispose();
+                contentProvider = null;
+            }
+
+            if ( labelProvider != null )
+            {
+                labelProvider.dispose();
+                labelProvider = null;
+                decoratingLabelProvider.dispose();
+                decoratingLabelProvider = null;
+            }
+
+            if ( contextMenuManager != null )
+            {
+                contextMenuManager.dispose();
+                contextMenuManager = null;
+            }
+
+            disposed = true;
+        }
+    }
+
+
+    /**
+     * Gets the context menu manager.
+     * 
+     * @param viewer the browser widget's tree viewer 
+     * 
+     * @return the context menu manager
+     */
+    public IMenuManager getContextMenuManager( TreeViewer viewer )
+    {
+        if ( contextMenuManager == null )
+        {
+            contextMenuManager = new MenuManager();
+            Menu menu = contextMenuManager.createContextMenu( viewer.getControl() );
+            viewer.getControl().setMenu( menu );
+        }
+
+        return contextMenuManager;
+    }
+
+
+    /**
+     * Gets the content provider.
+     * 
+     * @param viewer the browser widget's tree viewer 
+     * 
+     * @return the content provider
+     */
+    public BrowserContentProvider getContentProvider( TreeViewer viewer )
+    {
+        if ( contentProvider == null )
+        {
+            contentProvider = new BrowserContentProvider( getPreferences(), getSorter() );
+        }
+
+        return contentProvider;
+    }
+
+
+    /**
+     * Gets the label provider.
+     * 
+     * @param viewer the browser widget's tree viewer 
+     * 
+     * @return the label provider
+     */
+    public DecoratingLabelProvider getLabelProvider( TreeViewer viewer )
+    {
+        if ( labelProvider == null )
+        {
+            labelProvider = new BrowserLabelProvider( getPreferences() );
+            decoratingLabelProvider = new DecoratingLabelProvider( labelProvider, BrowserCommonActivator.getDefault().getWorkbench()
+                .getDecoratorManager().getLabelDecorator() );
+        }
+
+        return decoratingLabelProvider;
+    }
+
+
+    /**
+     * Gets the sorter.
+     * 
+     * @return the sorter
+     */
+    public BrowserSorter getSorter()
+    {
+        if ( sorter == null )
+        {
+            sorter = new BrowserSorter( getPreferences() );
+        }
+
+        return sorter;
+    }
+
+
+    /**
+     * Gets the preferences.
+     * 
+     * @return the preferences
+     */
+    public BrowserPreferences getPreferences()
+    {
+        if ( preferences == null )
+        {
+            preferences = new BrowserPreferences();
+        }
+
+        return preferences;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserContentProvider.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserContentProvider.java?rev=592079&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserContentProvider.java (added)
+++ directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserContentProvider.java Mon Nov  5 08:48:35 2007
@@ -0,0 +1,554 @@
+/*
+ *  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.browser;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.directory.studio.connection.core.jobs.OpenConnectionsJob;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCoreConstants;
+import org.apache.directory.studio.ldapbrowser.core.BrowserCorePlugin;
+import org.apache.directory.studio.ldapbrowser.core.jobs.InitializeChildrenJob;
+import org.apache.directory.studio.ldapbrowser.core.jobs.SearchJob;
+import org.apache.directory.studio.ldapbrowser.core.model.IBookmark;
+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.IRootDSE;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearch;
+import org.apache.directory.studio.ldapbrowser.core.model.ISearchResult;
+import org.apache.directory.studio.ldapbrowser.core.model.impl.DirectoryMetadataEntry;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+
+/**
+ * The BrowserContentProvider implements the content provider for
+ * the browser widget. It accepts an IConnection as input.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class BrowserContentProvider implements ITreeContentProvider
+{
+
+    /** The prefernces */
+    protected BrowserPreferences preferences;
+
+    /** The sorter */
+    protected BrowserSorter sorter;
+
+    /** This map contains the pages for entries with many children (if folding is activated) */
+    private Map<IEntry, BrowserEntryPage[]> entryToEntryPagesMap;
+
+    /** This map contains the pages for searches with many results (if folding is activated) */
+    private Map<ISearch, BrowserSearchResultPage[]> searchToSearchResultPagesMap;
+
+    /** This map contains the top-level categories for each connection */
+    private Map<IBrowserConnection, BrowserCategory[]> connectionToCategoriesMap;
+
+
+    /**
+     * Creates a new instance of BrowserContentProvider.
+     *
+     * @param preferences the preferences
+     * @param sorter the sorter
+     */
+    public BrowserContentProvider( BrowserPreferences preferences, BrowserSorter sorter )
+    {
+        this.preferences = preferences;
+        this.sorter = sorter;
+        this.entryToEntryPagesMap = new HashMap<IEntry, BrowserEntryPage[]>();
+        this.searchToSearchResultPagesMap = new HashMap<ISearch, BrowserSearchResultPage[]>();
+        this.connectionToCategoriesMap = new HashMap<IBrowserConnection, BrowserCategory[]>();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void inputChanged( Viewer v, Object oldInput, Object newInput )
+    {
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dispose()
+    {
+        if ( entryToEntryPagesMap != null )
+        {
+            entryToEntryPagesMap.clear();
+            entryToEntryPagesMap = null;
+        }
+        if ( searchToSearchResultPagesMap != null )
+        {
+            searchToSearchResultPagesMap.clear();
+            searchToSearchResultPagesMap = null;
+        }
+        if ( connectionToCategoriesMap != null )
+        {
+            connectionToCategoriesMap.clear();
+            connectionToCategoriesMap = null;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object[] getElements( Object parent )
+    {
+        if ( parent instanceof IBrowserConnection )
+        {
+            IBrowserConnection connection = ( IBrowserConnection ) parent;
+            if ( !connectionToCategoriesMap.containsKey( connection ) )
+            {
+                BrowserCategory[] categories = new BrowserCategory[3];
+                categories[0] = new BrowserCategory( BrowserCategory.TYPE_DIT, connection );
+                categories[1] = new BrowserCategory( BrowserCategory.TYPE_SEARCHES, connection );
+                categories[2] = new BrowserCategory( BrowserCategory.TYPE_BOOKMARKS, connection );
+                connectionToCategoriesMap.put( connection, categories );
+            }
+
+            BrowserCategory[] categories = connectionToCategoriesMap.get( connection );
+
+            List<BrowserCategory> catList = new ArrayList<BrowserCategory>( 3 );
+            if ( preferences.isShowDIT() )
+            {
+                catList.add( categories[0] );
+            }
+            if ( preferences.isShowSearches() )
+            {
+                catList.add( categories[1] );
+            }
+            if ( preferences.isShowBookmarks() )
+            {
+                catList.add( categories[2] );
+            }
+
+            return catList.toArray( new BrowserCategory[0] );
+        }
+        else if ( parent instanceof IEntry[] )
+        {
+            return ( IEntry[] ) parent;
+        }
+        else
+        {
+            return getChildren( parent );
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object getParent( final Object child )
+    {
+        if ( child instanceof BrowserCategory )
+        {
+            return ( ( BrowserCategory ) child ).getParent();
+        }
+        else if ( child instanceof BrowserEntryPage )
+        {
+            return ( ( BrowserEntryPage ) child ).getParent();
+        }
+        else if ( child instanceof IEntry )
+        {
+            IEntry parentEntry = ( ( IEntry ) child ).getParententry();
+            if ( parentEntry == null )
+            {
+                if ( connectionToCategoriesMap.get( ( ( IEntry ) child ).getBrowserConnection() ) != null )
+                {
+                    return connectionToCategoriesMap.get( ( ( IEntry ) child ).getBrowserConnection() )[0];
+                }
+                else
+                {
+                    return null;
+                }
+            }
+            else if ( entryToEntryPagesMap.containsKey( parentEntry ) )
+            {
+                BrowserEntryPage[] entryPages = entryToEntryPagesMap.get( parentEntry );
+                BrowserEntryPage ep = null;
+                for ( int i = 0; i < entryPages.length && ep == null; i++ )
+                {
+                    ep = entryPages[i].getParentOf( ( IEntry ) child );
+                }
+                return ep;
+            }
+            else
+            {
+                return parentEntry;
+            }
+        }
+        else if ( child instanceof BrowserSearchResultPage )
+        {
+            return ( ( BrowserSearchResultPage ) child ).getParent();
+        }
+        else if ( child instanceof ISearch )
+        {
+            ISearch search = ( ( ISearch ) child );
+            return connectionToCategoriesMap.get( search.getBrowserConnection() )[1];
+        }
+        else if ( child instanceof ISearchResult )
+        {
+            ISearch parentSearch = ( ( ISearchResult ) child ).getSearch();
+            if ( parentSearch != null && searchToSearchResultPagesMap.containsKey( parentSearch ) )
+            {
+                BrowserSearchResultPage[] srPages = searchToSearchResultPagesMap.get( parentSearch );
+                BrowserSearchResultPage srp = null;
+                for ( int i = 0; i < srPages.length && srp == null; i++ )
+                {
+                    srp = srPages[i].getParentOf( ( ISearchResult ) child );
+                }
+                return srp;
+            }
+            else
+            {
+                return parentSearch;
+            }
+        }
+        else if ( child instanceof IBookmark )
+        {
+            IBookmark bookmark = ( ( IBookmark ) child );
+            return connectionToCategoriesMap.get( bookmark.getBrowserConnection() )[2];
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object[] getChildren( Object parent )
+    {
+        if ( parent instanceof BrowserEntryPage )
+        {
+            BrowserEntryPage entryPage = ( BrowserEntryPage ) parent;
+            Object[] objects = entryPage.getChildren();
+            if ( objects == null )
+            {
+                return new String[]
+                    { "Fetching Entries..." };
+            }
+            else if ( objects instanceof IEntry[] )
+            {
+                IEntry[] entries = ( IEntry[] ) objects;
+                return entries;
+            }
+            else
+            {
+                return objects;
+            }
+        }
+        else if ( parent instanceof IRootDSE )
+        {
+            final IRootDSE rootDSE = ( IRootDSE ) parent;
+
+            if ( !rootDSE.isChildrenInitialized() && rootDSE.isDirectoryEntry() )
+            {
+                new InitializeChildrenJob( new IEntry[]
+                    { rootDSE } ).execute();
+                return new String[]
+                    { "Fetching Entries..." };
+            }
+
+            // get base entries
+            List<IEntry> entryList = new ArrayList<IEntry>();
+            entryList.addAll( Arrays.asList( rootDSE.getChildren() ) );
+
+            // remove non-visible entries
+            for ( Iterator<IEntry> it = entryList.iterator(); it.hasNext(); )
+            {
+                Object o = it.next();
+                if ( !preferences.isShowDirectoryMetaEntries() && ( o instanceof DirectoryMetadataEntry ) )
+                {
+                    it.remove();
+                }
+            }
+
+            return entryList.toArray();
+        }
+        else if ( parent instanceof IEntry )
+            {
+                final IEntry parentEntry = ( IEntry ) parent;
+
+            if ( !parentEntry.isChildrenInitialized() && parentEntry.isDirectoryEntry() )
+            {
+                new InitializeChildrenJob( new IEntry[]
+                    { parentEntry } ).execute();
+                return new String[]
+                    { "Fetching Entries..." };
+            }
+
+            int childrenCount = parentEntry.getChildrenCount();
+            if ( childrenCount <= preferences.getFoldingSize() || !preferences.isUseFolding() )
+            {
+                if ( entryToEntryPagesMap.containsKey( parentEntry ) )
+                {
+                    entryToEntryPagesMap.remove( parentEntry );
+                }
+
+                IEntry[] entries = parentEntry.getChildren();
+                if ( entries == null )
+                {
+                    return new String[]
+                        { "Fetching Entries..." };
+                }
+                else
+                {
+                    return entries;
+                }
+            }
+            else
+            {
+                BrowserEntryPage[] entryPages = null;
+                if ( !entryToEntryPagesMap.containsKey( parentEntry ) )
+                {
+                    entryPages = getEntryPages( parentEntry, 0, childrenCount - 1 );
+                    entryToEntryPagesMap.put( parentEntry, entryPages );
+                }
+                else
+                {
+                    entryPages = entryToEntryPagesMap.get( parentEntry );
+                    if ( childrenCount - 1 != entryPages[entryPages.length - 1].getLast() )
+                    {
+                        entryPages = getEntryPages( parentEntry, 0, childrenCount - 1 );
+                        entryToEntryPagesMap.put( parentEntry, entryPages );
+                    }
+                }
+                return entryPages;
+            }
+        }
+        else if ( parent instanceof BrowserSearchResultPage )
+        {
+            BrowserSearchResultPage srPage = ( BrowserSearchResultPage ) parent;
+            Object[] objects = srPage.getChildren();
+            if ( objects == null )
+            {
+                return new String[]
+                    { "Fetching Search Results..." };
+            }
+            else if ( objects instanceof ISearchResult[] )
+            {
+                ISearchResult[] srs = ( ISearchResult[] ) objects;
+                return srs;
+            }
+            else
+            {
+                return objects;
+            }
+        }
+        else if ( parent instanceof ISearch )
+        {
+            ISearch search = ( ISearch ) parent;
+            if ( search.getSearchResults() == null )
+            {
+                new SearchJob( new ISearch[]
+                    { search } ).execute();
+                return new String[]
+                    { "Performing Search..." };
+            }
+            else if ( search.getSearchResults().length == 0 )
+            {
+                return new String[]
+                    { "No Results" };
+            }
+            else if ( search.getSearchResults().length <= preferences.getFoldingSize() || !preferences.isUseFolding() )
+            {
+                ISearchResult[] results = search.getSearchResults();
+                return results;
+            }
+            else
+            {
+                BrowserSearchResultPage[] srPages = null;
+                if ( !searchToSearchResultPagesMap.containsKey( search ) )
+                {
+                    srPages = getSearchResultPages( search, 0, search.getSearchResults().length - 1 );
+                    searchToSearchResultPagesMap.put( search, srPages );
+                }
+                else
+                {
+                    srPages = searchToSearchResultPagesMap.get( search );
+                    if ( search.getSearchResults().length - 1 != srPages[srPages.length - 1].getLast() )
+                    {
+                        srPages = getSearchResultPages( search, 0, search.getSearchResults().length - 1 );
+                        searchToSearchResultPagesMap.put( search, srPages );
+                    }
+                }
+                return srPages;
+            }
+        }
+        else if ( parent instanceof BrowserCategory )
+        {
+            BrowserCategory category = ( BrowserCategory ) parent;
+            IBrowserConnection connection = category.getParent();
+
+            switch ( category.getType() )
+            {
+                case BrowserCategory.TYPE_DIT:
+                {
+                    // open connection when expanding DIT
+                    if ( !connection.getConnection().getJNDIConnectionWrapper().isConnected() )
+                    {
+                        new OpenConnectionsJob( connection.getConnection() ).execute();
+                        return new String[]
+                            { "Opening Connection..." };
+                    }
+
+                    return new Object[]
+                        { connection.getRootDSE() };
+                }
+
+                case BrowserCategory.TYPE_SEARCHES:
+                {
+                    return connection.getSearchManager().getSearches();
+                }
+
+                case BrowserCategory.TYPE_BOOKMARKS:
+                {
+                    return connection.getBookmarkManager().getBookmarks();
+                }
+            }
+
+            return new Object[0];
+        }
+        else
+        {
+            return new Object[0];
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasChildren( Object parent )
+    {
+        if ( parent instanceof IEntry )
+        {
+            IEntry parentEntry = ( IEntry ) parent;
+            return parentEntry.hasChildren()
+                || ( BrowserCorePlugin.getDefault().getPluginPreferences().getBoolean(
+                    BrowserCoreConstants.PREFERENCE_SHOW_ALIAS_AND_REFERRAL_OBJECTS ) && ( parentEntry.isAlias() || parentEntry
+                    .isReferral() ) );
+        }
+        else if ( parent instanceof BrowserEntryPage )
+        {
+            return true;
+        }
+        else if ( parent instanceof BrowserSearchResultPage )
+        {
+            return true;
+        }
+        else if ( parent instanceof ISearchResult )
+        {
+            return false;
+        }
+        else if ( parent instanceof ISearch )
+        {
+            return true;
+        }
+        else if ( parent instanceof BrowserCategory )
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Creates and returns the entry pages for the given entry. The number of pages
+     * depends on the number of entries and the paging size. 
+     *
+     * @param entry the parent entry
+     * @param first the index of the first child entry
+     * @param last the index of the last child entry
+     * @return the created entry pages
+     */
+    private BrowserEntryPage[] getEntryPages( IEntry entry, int first, int last )
+    {
+        int pagingSize = preferences.getFoldingSize();
+
+        int diff = last - first;
+        int factor = diff > 0 ? ( int ) ( Math.log( diff ) / Math.log( pagingSize ) ) : 0;
+
+        int groupFirst = first;
+        int groupLast = first;
+        BrowserEntryPage[] pages = new BrowserEntryPage[( int ) ( diff / Math.pow( pagingSize, factor ) ) + 1];
+        for ( int i = 0; i < pages.length; i++ )
+        {
+            groupFirst = ( int ) ( i * Math.pow( pagingSize, factor ) ) + first;
+            groupLast = ( int ) ( ( i + 1 ) * Math.pow( pagingSize, factor ) ) + first - 1;
+            groupLast = groupLast > last ? last : groupLast;
+            BrowserEntryPage[] subpages = ( factor > 1 ) ? getEntryPages( entry, groupFirst, groupLast ) : null;
+            pages[i] = new BrowserEntryPage( entry, groupFirst, groupLast, subpages, sorter );
+        }
+
+        return pages;
+    }
+
+
+    /**
+     * Creates and returns the search result pages for the given search. The number of pages
+     * depends on the number of search results and the paging size. 
+     *
+     * @param search the parent search
+     * @param first the index of the first search result
+     * @param last the index of the last child search result
+     * @return the created search result pages
+     */
+    private BrowserSearchResultPage[] getSearchResultPages( ISearch search, int first, int last )
+    {
+        int pagingSize = preferences.getFoldingSize();
+
+        int diff = last - first;
+        int factor = diff > 0 ? ( int ) ( Math.log( diff ) / Math.log( pagingSize ) ) : 0;
+
+        int groupFirst = first;
+        int groupLast = first;
+        BrowserSearchResultPage[] pages = new BrowserSearchResultPage[( int ) ( diff / Math.pow( pagingSize, factor ) ) + 1];
+        for ( int i = 0; i < pages.length; i++ )
+        {
+            groupFirst = ( int ) ( i * Math.pow( pagingSize, factor ) ) + first;
+            groupLast = ( int ) ( ( i + 1 ) * Math.pow( pagingSize, factor ) ) + first - 1;
+            groupLast = groupLast > last ? last : groupLast;
+            BrowserSearchResultPage[] subpages = ( factor > 1 ) ? getSearchResultPages( search, groupFirst, groupLast )
+                : null;
+            pages[i] = new BrowserSearchResultPage( search, groupFirst, groupLast, subpages, sorter );
+        }
+
+        return pages;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldapbrowser-common/src/main/java/org/apache/directory/studio/ldapbrowser/common/widgets/browser/BrowserContentProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message