| /* |
| * 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.Arrays; |
| import java.util.Collection; |
| |
| import org.apache.directory.api.ldap.model.message.SearchScope; |
| import org.apache.directory.api.ldap.model.schema.AttributeType; |
| import org.apache.directory.studio.common.ui.HistoryUtils; |
| import org.apache.directory.studio.common.ui.widgets.BaseWidgetUtils; |
| import org.apache.directory.studio.connection.ui.widgets.ExtendedContentAssistCommandAdapter; |
| import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator; |
| import org.apache.directory.studio.ldapbrowser.common.BrowserCommonConstants; |
| import org.apache.directory.studio.ldapbrowser.common.actions.BrowserSelectionUtils; |
| import org.apache.directory.studio.ldapbrowser.common.widgets.ListContentProposalProvider; |
| import org.apache.directory.studio.ldapbrowser.core.jobs.SearchRunnable; |
| import org.apache.directory.studio.ldapbrowser.core.jobs.StudioBrowserJob; |
| 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.IQuickSearch; |
| import org.apache.directory.studio.ldapbrowser.core.model.ISearch; |
| import org.apache.directory.studio.ldapbrowser.core.model.impl.QuickSearch; |
| import org.apache.directory.studio.ldapbrowser.core.model.schema.SchemaUtils; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.fieldassist.ComboContentAdapter; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| 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.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Combo; |
| import org.eclipse.swt.widgets.Composite; |
| |
| |
| /** |
| * The BrowserQuickSearchWidget implements an instant search |
| * for the browser widget. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| public class BrowserQuickSearchWidget |
| { |
| |
| /** The Constant VALUE_HISTORY_DIALOGSETTING_KEY. */ |
| public static final String VALUE_HISTORY_DIALOGSETTING_KEY = BrowserQuickSearchWidget.class.getName() |
| + ".valueHistory"; //$NON-NLS-1$ |
| |
| /** The Constant ATTRIBUTE_HISTORY_DIALOGSETTING_KEY. */ |
| public static final String ATTRIBUTE_HISTORY_DIALOGSETTING_KEY = BrowserQuickSearchWidget.class.getName() |
| + ".attributeHistory"; //$NON-NLS-1$ |
| |
| /** An empty string array */ |
| private static final String[] EMPTY = new String[0]; |
| |
| /** The browser widget. */ |
| private BrowserWidget browserWidget; |
| |
| /** The parent, used to create the composite. */ |
| private Composite parent; |
| |
| /** The outer composite. */ |
| private Composite composite; |
| |
| /** The inner composite, it is created/destroyed when showing/hiding the quick search. */ |
| private Composite innerComposite; |
| |
| /** The quick search attribute combo. */ |
| private Combo quickSearchAttributeCombo; |
| |
| /** The quick search attribute proposal provider. */ |
| private ListContentProposalProvider quickSearchAttributePP; |
| |
| /** The quick search operator combo. */ |
| private Combo quickSearchOperatorCombo; |
| |
| /** The quick search value combo. */ |
| private Combo quickSearchValueCombo; |
| |
| /** The quick search value proposal provider. */ |
| private ListContentProposalProvider quickSearchValuePP; |
| |
| /** The quick search scope button. */ |
| private Button quickSearchScopeButton; |
| |
| /** The quick search run button. */ |
| private Button quickSearchRunButton; |
| |
| /** Listener that listens for selections of connections */ |
| private ISelectionChangedListener selectionListener = new ISelectionChangedListener() |
| { |
| /** |
| * {@inheritDoc} |
| * |
| * This implementation sets the input when another connection was selected. |
| */ |
| public void selectionChanged( SelectionChangedEvent event ) |
| { |
| setEnabled( getSelectedEntry() != null ); |
| } |
| }; |
| |
| |
| /** |
| * Creates a new instance of BrowserQuickSearchWidget. |
| * |
| * @param browserWidget the browser widget |
| */ |
| public BrowserQuickSearchWidget( BrowserWidget browserWidget ) |
| { |
| this.browserWidget = browserWidget; |
| |
| if ( HistoryUtils.load( BrowserCommonActivator.getDefault().getDialogSettings(), |
| ATTRIBUTE_HISTORY_DIALOGSETTING_KEY ).length == 0 ) |
| { |
| BrowserCommonActivator.getDefault().getDialogSettings().put( ATTRIBUTE_HISTORY_DIALOGSETTING_KEY, |
| new String[] |
| { "cn", //$NON-NLS-1$ |
| "sn", //$NON-NLS-1$ |
| "givenName", //$NON-NLS-1$ |
| "mail", //$NON-NLS-1$ |
| "uid", //$NON-NLS-1$ |
| "description", //$NON-NLS-1$ |
| "o", //$NON-NLS-1$ |
| "ou", //$NON-NLS-1$ |
| "member" //$NON-NLS-1$ |
| } ); |
| } |
| } |
| |
| |
| /** |
| * Creates the outer composite. |
| * |
| * @param parent the parent |
| */ |
| public void createComposite( Composite parent ) |
| { |
| this.parent = parent; |
| |
| composite = BaseWidgetUtils.createColumnContainer( parent, 1, 1 ); |
| GridLayout gl = new GridLayout(); |
| gl.marginHeight = 2; |
| gl.marginWidth = 2; |
| composite.setLayout( gl ); |
| // Setting the default width and height of the composite to 0 |
| GridData compositeGridData = new GridData( SWT.NONE, SWT.NONE, false, false ); |
| compositeGridData.heightHint = 0; |
| compositeGridData.widthHint = 0; |
| composite.setLayoutData( compositeGridData ); |
| |
| innerComposite = null; |
| } |
| |
| |
| /** |
| * Creates the inner composite with its input fields. |
| */ |
| private void create() |
| { |
| this.browserWidget.getViewer().addPostSelectionChangedListener( selectionListener ); |
| |
| IDialogSettings dialogSettings = BrowserCommonActivator.getDefault().getDialogSettings(); |
| |
| // Reseting the layout of the composite to be displayed correctly |
| GridData compositeGridData = new GridData( SWT.FILL, SWT.NONE, true, false ); |
| composite.setLayoutData( compositeGridData ); |
| |
| innerComposite = BaseWidgetUtils.createColumnContainer( composite, 5, 1 ); |
| |
| String[] attributes = HistoryUtils.load( dialogSettings, ATTRIBUTE_HISTORY_DIALOGSETTING_KEY ); |
| quickSearchAttributeCombo = BaseWidgetUtils.createCombo( innerComposite, attributes, -1, 1 ); |
| quickSearchAttributePP = new ListContentProposalProvider( attributes ); |
| new ExtendedContentAssistCommandAdapter( quickSearchAttributeCombo, new ComboContentAdapter(), |
| quickSearchAttributePP, null, null, true ); |
| quickSearchAttributeCombo.addModifyListener( new ModifyListener() |
| { |
| public void modifyText( ModifyEvent e ) |
| { |
| quickSearchRunButton.setEnabled( !"".equals( quickSearchAttributeCombo.getText() ) ); //$NON-NLS-1$ |
| } |
| } ); |
| quickSearchAttributeCombo.addSelectionListener( new SelectionAdapter() |
| { |
| public void widgetDefaultSelected( SelectionEvent e ) |
| { |
| performSearch(); |
| } |
| } ); |
| GridData gd = new GridData( GridData.FILL_HORIZONTAL ); |
| gd.widthHint = 50; |
| quickSearchAttributeCombo.setLayoutData( gd ); |
| |
| String[] operators = new String[] |
| { "=", "!=", "<=", ">=", "~=" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ |
| quickSearchOperatorCombo = BaseWidgetUtils.createReadonlyCombo( innerComposite, operators, 0, 1 ); |
| GridData data = new GridData(); |
| quickSearchOperatorCombo.setLayoutData( data ); |
| |
| String[] values = HistoryUtils.load( dialogSettings, VALUE_HISTORY_DIALOGSETTING_KEY ); |
| quickSearchValueCombo = BaseWidgetUtils.createCombo( innerComposite, values, -1, 1 ); |
| quickSearchValuePP = new ListContentProposalProvider( values ); |
| new ExtendedContentAssistCommandAdapter( quickSearchValueCombo, new ComboContentAdapter(), quickSearchValuePP, |
| null, null, true ); |
| quickSearchValueCombo.addSelectionListener( new SelectionAdapter() |
| { |
| public void widgetDefaultSelected( SelectionEvent e ) |
| { |
| performSearch(); |
| } |
| } ); |
| gd = new GridData( GridData.FILL_HORIZONTAL ); |
| gd.widthHint = 50; |
| quickSearchValueCombo.setLayoutData( gd ); |
| |
| quickSearchScopeButton = new Button( innerComposite, SWT.TOGGLE ); |
| quickSearchScopeButton.setToolTipText( Messages.getString( "BrowserQuickSearchWidget.ScopeOneLevelToolTip" ) ); //$NON-NLS-1$ |
| quickSearchScopeButton.setImage( BrowserCommonActivator.getDefault().getImage( |
| BrowserCommonConstants.IMG_SUBTREE ) ); |
| quickSearchScopeButton.setSelection( BrowserCommonActivator.getDefault().getPreferenceStore() |
| .getBoolean( BrowserCommonConstants.PREFERENCE_BROWSER_QUICK_SEARCH_SUBTREE_SCOPE ) ); |
| quickSearchScopeButton.addSelectionListener( new SelectionAdapter() |
| { |
| public void widgetSelected( SelectionEvent e ) |
| { |
| String one = Messages.getString( "BrowserQuickSearchWidget.ScopeOneLevelToolTip" ); //$NON-NLS-1$ |
| String sub = Messages.getString( "BrowserQuickSearchWidget.ScopeSubtreeToolTip" ); //$NON-NLS-1$ |
| boolean selected = quickSearchScopeButton.getSelection(); |
| quickSearchScopeButton.setToolTipText( selected ? sub : one ); |
| BrowserCommonActivator.getDefault().getPreferenceStore() |
| .setValue( BrowserCommonConstants.PREFERENCE_BROWSER_QUICK_SEARCH_SUBTREE_SCOPE, selected ); |
| } |
| } ); |
| |
| quickSearchRunButton = new Button( innerComposite, SWT.PUSH ); |
| quickSearchRunButton.setToolTipText( Messages.getString( "BrowserQuickSearchWidget.RunQuickSearch" ) ); //$NON-NLS-1$ |
| quickSearchRunButton.setImage( BrowserCommonActivator.getDefault().getImage( |
| BrowserCommonConstants.IMG_QUICKSEARCH ) ); |
| quickSearchRunButton.addSelectionListener( new SelectionAdapter() |
| { |
| public void widgetSelected( SelectionEvent e ) |
| { |
| performSearch(); |
| } |
| } ); |
| |
| setEnabled( getSelectedEntry() != null ); |
| |
| composite.layout( true, true ); |
| parent.layout( true, true ); |
| } |
| |
| |
| private void performSearch() |
| { |
| if ( !quickSearchRunButton.isEnabled() ) |
| { |
| return; |
| } |
| |
| IEntry entry = getSelectedEntry(); |
| if ( entry == null ) |
| { |
| return; |
| } |
| |
| IDialogSettings dialogSettings = BrowserCommonActivator.getDefault().getDialogSettings(); |
| |
| HistoryUtils.save( dialogSettings, ATTRIBUTE_HISTORY_DIALOGSETTING_KEY, quickSearchAttributeCombo.getText() ); |
| String[] attributes = HistoryUtils.load( dialogSettings, ATTRIBUTE_HISTORY_DIALOGSETTING_KEY ); |
| quickSearchAttributeCombo.setItems( attributes ); |
| quickSearchAttributeCombo.select( 0 ); |
| HistoryUtils.save( dialogSettings, VALUE_HISTORY_DIALOGSETTING_KEY, quickSearchValueCombo.getText() ); |
| String[] values = HistoryUtils.load( dialogSettings, VALUE_HISTORY_DIALOGSETTING_KEY ); |
| quickSearchValueCombo.setItems( values ); |
| quickSearchValueCombo.select( 0 ); |
| quickSearchValuePP.setProposals( Arrays.asList( values ) ); |
| |
| IBrowserConnection conn = entry.getBrowserConnection(); |
| |
| QuickSearch quickSearch = new QuickSearch( entry, conn ); |
| quickSearch.getSearchParameter().setScope( |
| quickSearchScopeButton.getSelection() ? SearchScope.SUBTREE : SearchScope.ONELEVEL ); |
| |
| StringBuffer filter = new StringBuffer(); |
| filter.append( "(" ); //$NON-NLS-1$ |
| if ( "!=".equals( quickSearchOperatorCombo.getText() ) ) //$NON-NLS-1$ |
| { |
| filter.append( "!(" ); //$NON-NLS-1$ |
| } |
| filter.append( quickSearchAttributeCombo.getText() ); |
| filter |
| .append( Messages.getString( "BrowserQuickSearchWidget.9" ).equals( quickSearchOperatorCombo.getText() ) ? "=" : quickSearchOperatorCombo.getText() ); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| // only escape '\', '(', ')', and '\u0000' |
| // don't escape '*' to allow substring search |
| String value = quickSearchValueCombo.getText(); |
| value = value.replaceAll( "\\\\", "\\\\5c" ); //$NON-NLS-1$ //$NON-NLS-2$ |
| value = value.replaceAll( "\u0000", "\\\\00" ); //$NON-NLS-1$ //$NON-NLS-2$ |
| value = value.replaceAll( "\\(", "\\\\28" ); //$NON-NLS-1$ //$NON-NLS-2$ |
| value = value.replaceAll( "\\)", "\\\\29" ); //$NON-NLS-1$ //$NON-NLS-2$ |
| filter.append( value ); |
| if ( "!=".equals( quickSearchOperatorCombo.getText() ) ) //$NON-NLS-1$ |
| { |
| filter.append( ")" ); //$NON-NLS-1$ |
| } |
| filter.append( ")" ); //$NON-NLS-1$ |
| quickSearch.getSearchParameter().setFilter( filter.toString() ); |
| |
| // set new quick search |
| conn.setQuickSearch( quickSearch ); |
| |
| // execute quick search |
| new StudioBrowserJob( new SearchRunnable( new ISearch[] |
| { quickSearch } ) ).execute(); |
| } |
| |
| |
| private IEntry getSelectedEntry() |
| { |
| ISelection selection = browserWidget.getViewer().getSelection(); |
| IEntry[] entries = BrowserSelectionUtils.getEntries( selection ); |
| ISearch[] searches = BrowserSelectionUtils.getSearches( selection ); |
| if ( entries != null && entries.length == 1 ) |
| { |
| IEntry entry = entries[0]; |
| return entry; |
| } |
| else if ( searches != null && searches.length == 1 && ( searches[0] instanceof IQuickSearch ) ) |
| { |
| IQuickSearch quickSearch = ( IQuickSearch ) searches[0]; |
| IEntry entry = quickSearch.getSearchBaseEntry(); |
| return entry; |
| } |
| else |
| { |
| return null; |
| } |
| } |
| |
| |
| /** |
| * Destroys the inner widget. |
| */ |
| private void destroy() |
| { |
| browserWidget.getViewer().removePostSelectionChangedListener( selectionListener ); |
| |
| // Reseting the layout of the composite with a width and height set to 0 |
| GridData compositeGridData = new GridData( SWT.NONE, SWT.NONE, false, false ); |
| compositeGridData.heightHint = 0; |
| compositeGridData.widthHint = 0; |
| composite.setLayoutData( compositeGridData ); |
| |
| innerComposite.dispose(); |
| innerComposite = null; |
| |
| composite.layout( true, true ); |
| parent.layout( true, true ); |
| } |
| |
| |
| /** |
| * Disposes this widget. |
| */ |
| public void dispose() |
| { |
| if ( browserWidget != null ) |
| { |
| quickSearchAttributeCombo = null; |
| quickSearchOperatorCombo = null; |
| quickSearchValueCombo = null; |
| quickSearchRunButton = null; |
| innerComposite = null; |
| composite.dispose(); |
| composite = null; |
| parent = null; |
| browserWidget = null; |
| } |
| } |
| |
| |
| /** |
| * Enables or disables this quick search widget. |
| * |
| * @param enabled true to enable this quick search widget, false to disable it |
| */ |
| private void setEnabled( boolean enabled ) |
| { |
| if ( composite != null && !composite.isDisposed() ) |
| { |
| composite.setEnabled( enabled ); |
| } |
| if ( innerComposite != null && !innerComposite.isDisposed() ) |
| { |
| innerComposite.setEnabled( enabled ); |
| quickSearchAttributeCombo.setEnabled( enabled ); |
| quickSearchOperatorCombo.setEnabled( enabled ); |
| quickSearchValueCombo.setEnabled( enabled ); |
| quickSearchScopeButton.setEnabled( enabled ); |
| quickSearchRunButton.setEnabled( enabled && !"".equals( quickSearchAttributeCombo.getText() ) ); //$NON-NLS-1$ |
| |
| if ( !enabled ) |
| { |
| quickSearchAttributeCombo.setToolTipText( null ); |
| quickSearchOperatorCombo.setToolTipText( null ); |
| quickSearchValueCombo.setToolTipText( null ); |
| parent.setToolTipText( Messages.getString( "BrowserQuickSearchWidget.DisabledToolTipText" ) ); //$NON-NLS-1$ |
| } |
| else |
| { |
| quickSearchAttributeCombo.setToolTipText( Messages |
| .getString( "BrowserQuickSearchWidget.SearchAttribute" ) ); //$NON-NLS-1$ |
| quickSearchOperatorCombo |
| .setToolTipText( Messages.getString( "BrowserQuickSearchWidget.SearchOperator" ) ); //$NON-NLS-1$ |
| quickSearchValueCombo.setToolTipText( Messages.getString( "BrowserQuickSearchWidget.SearchValue" ) ); //$NON-NLS-1$ |
| parent.setToolTipText( null ); |
| } |
| } |
| } |
| |
| |
| /** |
| * Activates or deactivates this quick search widget. |
| * |
| * @param visible true to create this quick search widget, false to destroy it |
| */ |
| public void setActive( boolean visible ) |
| { |
| if ( visible && innerComposite == null && composite != null ) |
| { |
| create(); |
| Object input = browserWidget.getViewer().getInput(); |
| if ( input instanceof IBrowserConnection ) |
| { |
| setInput( ( IBrowserConnection ) input ); |
| } |
| else if ( input instanceof IEntry[] ) |
| { |
| setInput( ( ( IEntry[] ) input )[0].getBrowserConnection() ); |
| } |
| quickSearchAttributeCombo.setFocus(); |
| } |
| else if ( !visible && innerComposite != null && composite != null ) |
| { |
| destroy(); |
| browserWidget.getViewer().getTree().setFocus(); |
| } |
| } |
| |
| |
| /** |
| * Sets the input. |
| * |
| * @param connection the new input |
| */ |
| public void setInput( IBrowserConnection connection ) |
| { |
| if ( innerComposite != null && !innerComposite.isDisposed() ) |
| { |
| String[] atdNames; |
| if ( connection != null ) |
| { |
| Collection<AttributeType> atds = connection.getSchema().getAttributeTypeDescriptions(); |
| atdNames = SchemaUtils.getNames( atds ).toArray( EMPTY ); |
| } |
| else |
| { |
| atdNames = EMPTY; |
| setEnabled( false ); |
| } |
| quickSearchAttributePP.setProposals( Arrays.asList( atdNames ) ); |
| } |
| } |
| |
| } |