blob: e40862a4938fdc3a8292947042f4a248fee11e70 [file] [log] [blame]
/*
* 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.wizards;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.directory.studio.common.ui.widgets.BaseWidgetUtils;
import org.eclipse.jface.wizard.WizardPage;
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;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
/**
* The AttributeOptionsWizardPageprovides input elements for various options
* and a preview field.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class AttributeOptionsWizardPage extends WizardPage
{
/** The wizard. */
private AttributeWizard wizard;
/** The shell */
private Shell shell;
/** The possible languages. */
private String[] possibleLanguages;
/** The possible language to countries map. */
private Map<String, String[]> possibleLangToCountriesMap;
/** The parsed lang list. */
private List<String> parsedLangList;
/** The parsed option list. */
private List<String> parsedOptionList;
/** The parsed binary option. */
private boolean parsedBinary;
/** The language group. */
private Group langGroup;
/** The lang line list. */
private ArrayList<LangLine> langLineList;
/** The options group. */
private Group optionsGroup;
/** The option line list. */
private ArrayList<OptionLine> optionLineList;
/** The binary option button. */
private Button binaryOptionButton;
/** The preview text. */
private Text previewText;
/**
* Creates a new instance of AttributeOptionsWizardPage.
*
* @param pageName the page name
* @param initialAttributeDescription the initial attribute description
* @param wizard the wizard
*/
public AttributeOptionsWizardPage( String pageName, String initialAttributeDescription, AttributeWizard wizard )
{
super( pageName );
super.setTitle( Messages.getString( "AttributeOptionsWizardPage.Options" ) ); //$NON-NLS-1$
super.setDescription( Messages.getString( "AttributeOptionsWizardPage.OptionsDescription" ) ); //$NON-NLS-1$
// super.setImageDescriptor(BrowserUIPlugin.getDefault().getImageDescriptor(BrowserUIConstants.IMG_ATTRIBUTE_WIZARD));
super.setPageComplete( false );
this.wizard = wizard;
// init possible languages and countries
SortedSet<String> languageSet = new TreeSet<String>();
Map<String, SortedSet<String>> languageToCountrySetMap = new HashMap<String, SortedSet<String>>();
Locale[] locales = Locale.getAvailableLocales();
for ( int i = 0; i < locales.length; i++ )
{
Locale locale = locales[i];
languageSet.add( locale.getLanguage() );
if ( !languageToCountrySetMap.containsKey( locale.getLanguage() ) )
{
languageToCountrySetMap.put( locale.getLanguage(), new TreeSet<String>() );
}
SortedSet<String> countrySet = languageToCountrySetMap.get( locale.getLanguage() );
countrySet.add( locale.getCountry() );
}
possibleLanguages = languageSet.toArray( new String[languageSet.size()] );
possibleLangToCountriesMap = new HashMap<String, String[]>();
for ( Iterator<String> it = languageToCountrySetMap.keySet().iterator(); it.hasNext(); )
{
String language = it.next();
SortedSet<String> countrySet = languageToCountrySetMap.get( language );
String[] countries = countrySet.toArray( new String[countrySet.size()] );
possibleLangToCountriesMap.put( language, countries );
}
// parse options
if ( initialAttributeDescription == null )
{
initialAttributeDescription = ""; //$NON-NLS-1$
}
String[] attributeDescriptionComponents = initialAttributeDescription.split( ";" ); //$NON-NLS-1$
parsedLangList = new ArrayList<String>();
parsedOptionList = new ArrayList<String>();
parsedBinary = false;
for ( int i = 1; i < attributeDescriptionComponents.length; i++ )
{
if ( attributeDescriptionComponents[i].startsWith( "lang-" ) ) //$NON-NLS-1$
{
parsedLangList.add( attributeDescriptionComponents[i] );
}
else if ( attributeDescriptionComponents[i].equals( "binary" ) ) //$NON-NLS-1$
{
parsedBinary = true;
}
else
{
parsedOptionList.add( attributeDescriptionComponents[i] );
}
}
}
/**
* Validates the options.
*/
private void validate()
{
previewText.setText( wizard.getAttributeDescription() );
setPageComplete( true );
}
/**
* {@inheritDoc}
*/
public void setVisible( boolean visible )
{
super.setVisible( visible );
if ( visible )
{
validate();
}
}
/**
* {@inheritDoc}
*/
public void createControl( Composite parent )
{
shell = parent.getShell();
Composite composite = new Composite( parent, SWT.NONE );
GridLayout gl = new GridLayout( 2, false );
composite.setLayout( gl );
composite.setLayoutData( new GridData( GridData.FILL_BOTH ) );
// Lang group
langGroup = BaseWidgetUtils.createGroup( composite, Messages
.getString( "AttributeOptionsWizardPage.LanguageTags" ), 2 ); //$NON-NLS-1$
GridData gd = new GridData( GridData.FILL_HORIZONTAL );
gd.horizontalSpan = 2;
langGroup.setLayoutData( gd );
Composite langComposite = BaseWidgetUtils.createColumnContainer( langGroup, 6, 1 );
langLineList = new ArrayList<LangLine>();
BaseWidgetUtils.createSpacer( composite, 2 );
// Options group with binary option
optionsGroup = BaseWidgetUtils.createGroup( composite, Messages
.getString( "AttributeOptionsWizardPage.OtherOptions" ), 2 ); //$NON-NLS-1$
gd = new GridData( GridData.FILL_HORIZONTAL );
gd.horizontalSpan = 2;
optionsGroup.setLayoutData( gd );
Composite optionsComposite = BaseWidgetUtils.createColumnContainer( optionsGroup, 3, 1 );
optionLineList = new ArrayList<OptionLine>();
Composite binaryComposite = BaseWidgetUtils.createColumnContainer( optionsGroup, 1, 1 );
binaryOptionButton = BaseWidgetUtils.createCheckbox( binaryComposite, Messages
.getString( "AttributeOptionsWizardPage.BinaryOption" ), 1 ); //$NON-NLS-1$
binaryOptionButton.setSelection( parsedBinary );
Label la = new Label( composite, SWT.NONE );
gd = new GridData( GridData.GRAB_VERTICAL );
gd.horizontalSpan = 2;
la.setLayoutData( gd );
// Preview text
BaseWidgetUtils.createLabel( composite, Messages.getString( "AttributeOptionsWizardPage.Preview" ), 1 ); //$NON-NLS-1$
previewText = BaseWidgetUtils.createReadonlyText( composite, "", 1 ); //$NON-NLS-1$
// fill lang
if ( parsedLangList.isEmpty() )
{
addLangLine( langComposite, 0 );
}
else
{
for ( int i = 0; i < parsedLangList.size(); i++ )
{
addLangLine( langComposite, i );
String l = parsedLangList.get( i );
String[] ls = l.split( "-", 3 ); //$NON-NLS-1$
if ( ls.length > 1 )
{
langLineList.get( i ).languageCombo.setText( ls[1] );
}
if ( ls.length > 2 )
{
langLineList.get( i ).countryCombo.setText( ls[2] );
}
}
}
// fill options
if ( parsedOptionList.isEmpty() )
{
addOptionLine( optionsComposite, 0 );
}
else
{
for ( int i = 0; i < parsedOptionList.size(); i++ )
{
addOptionLine( optionsComposite, i );
optionLineList.get( i ).optionText.setText( parsedOptionList.get( i ) );
}
}
// binary listener
binaryOptionButton.addSelectionListener( new SelectionAdapter()
{
public void widgetSelected( SelectionEvent e )
{
validate();
}
} );
validate();
setControl( composite );
}
/**
* Gets the attribute options.
*
* @return the attribute options
*/
String getAttributeOptions()
{
if ( binaryOptionButton == null || binaryOptionButton.isDisposed() )
{
return ""; //$NON-NLS-1$
}
// attribute type
StringBuffer sb = new StringBuffer();
// options
// sort and unique options
Comparator<String> comparator = new Comparator<String>()
{
public int compare( String s1, String s2 )
{
if ( s1 == null || s2 == null )
{
throw new ClassCastException( Messages.getString( "AttributeOptionsWizardPage.MustNotBeNull" ) ); //$NON-NLS-1$
}
return s1.compareToIgnoreCase( s2 );
}
};
SortedSet<String> options = new TreeSet<String>( comparator );
if ( binaryOptionButton.getSelection() )
{
options.add( "binary" ); //$NON-NLS-1$
}
for ( int i = 0; i < optionLineList.size(); i++ )
{
OptionLine optionLine = optionLineList.get( i );
if ( !"".equals( optionLine.optionText.getText() ) ) //$NON-NLS-1$
{
options.add( optionLine.optionText.getText() );
}
if ( optionLineList.size() > 1 )
{
optionLine.optionDeleteButton.setEnabled( true );
}
else
{
optionLine.optionDeleteButton.setEnabled( false );
}
}
for ( int i = 0; i < langLineList.size(); i++ )
{
LangLine langLine = langLineList.get( i );
String l = langLine.languageCombo.getText();
String c = langLine.countryCombo.getText();
if ( !"".equals( l ) ) //$NON-NLS-1$
{
String s = "lang-" + l; //$NON-NLS-1$
if ( !"".equals( c ) ) //$NON-NLS-1$
{
s += "-" + c; //$NON-NLS-1$
}
options.add( s );
}
if ( langLineList.size() > 1 )
{
langLine.deleteButton.setEnabled( true );
}
else
{
langLine.deleteButton.setEnabled( false );
}
}
// append options
for ( Iterator<String> it = options.iterator(); it.hasNext(); )
{
String option = it.next();
sb.append( ';' );
sb.append( option );
}
return sb.toString();
}
/**
* Adds an option line at the given index.
*
* @param optionComposite the option composite
* @param index the index
*/
private void addOptionLine( Composite optionComposite, int index )
{
OptionLine[] optionLines = optionLineList.toArray( new OptionLine[optionLineList.size()] );
if ( optionLines.length > 0 )
{
for ( int i = 0; i < optionLines.length; i++ )
{
OptionLine oldOptionLine = optionLines[i];
// remember values
String oldValue = oldOptionLine.optionText.getText();
// delete old
oldOptionLine.optionText.dispose();
oldOptionLine.optionAddButton.dispose();
oldOptionLine.optionDeleteButton.dispose();
optionLineList.remove( oldOptionLine );
// add new
OptionLine newOptionLine = createOptionLine( optionComposite );
optionLineList.add( newOptionLine );
// restore value
newOptionLine.optionText.setText( oldValue );
// check
if ( index == i + 1 )
{
OptionLine optionLine = createOptionLine( optionComposite );
optionLineList.add( optionLine );
}
}
}
else
{
OptionLine optionLine = createOptionLine( optionComposite );
optionLineList.add( optionLine );
}
shell.layout( true, true );
}
/**
* Creates the option line.
*
* @param optionComposite the option composite
*
* @return the option line
*/
private OptionLine createOptionLine( final Composite optionComposite )
{
OptionLine optionLine = new OptionLine();
optionLine.optionText = new Text( optionComposite, SWT.BORDER );
GridData gd = new GridData( GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL );
optionLine.optionText.setLayoutData( gd );
optionLine.optionAddButton = new Button( optionComposite, SWT.PUSH );
optionLine.optionAddButton.setText( " + " ); //$NON-NLS-1$
optionLine.optionAddButton.addSelectionListener( new SelectionAdapter()
{
public void widgetSelected( SelectionEvent e )
{
int index = optionLineList.size();
for ( int i = 0; i < optionLineList.size(); i++ )
{
OptionLine optionLine = optionLineList.get( i );
if ( optionLine.optionAddButton == e.widget )
{
index = i + 1;
}
}
addOptionLine( optionComposite, index );
validate();
}
} );
optionLine.optionDeleteButton = new Button( optionComposite, SWT.PUSH );
optionLine.optionDeleteButton.setText( " \u2212 " ); //$NON-NLS-1$
optionLine.optionDeleteButton.addSelectionListener( new SelectionAdapter()
{
public void widgetSelected( SelectionEvent e )
{
int index = 0;
for ( int i = 0; i < optionLineList.size(); i++ )
{
OptionLine optionLine = optionLineList.get( i );
if ( optionLine.optionDeleteButton == e.widget )
{
index = i;
}
}
deleteOptionLine( optionComposite, index );
validate();
}
} );
optionLine.optionText.addModifyListener( new ModifyListener()
{
public void modifyText( ModifyEvent e )
{
validate();
}
} );
return optionLine;
}
/**
* Deletes the option line at the given index.
*
* @param optionComposite the option composite
* @param index the index
*/
private void deleteOptionLine( Composite optionComposite, int index )
{
OptionLine optionLine = optionLineList.remove( index );
if ( optionLine != null )
{
optionLine.optionText.dispose();
optionLine.optionAddButton.dispose();
optionLine.optionDeleteButton.dispose();
if ( !optionComposite.isDisposed() )
{
shell.layout( true, true );
}
}
}
/**
* The class OptionLine is a wrapper for all input elements of an option.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class OptionLine
{
/** The option text. */
public Text optionText;
/** The option add button. */
public Button optionAddButton;
/** The option delete button. */
public Button optionDeleteButton;
}
/**
* Adds a language line at the given index.
*
* @param langComposite the language composite
* @param index the index
*/
private void addLangLine( Composite langComposite, int index )
{
LangLine[] langLines = langLineList.toArray( new LangLine[langLineList.size()] );
if ( langLines.length > 0 )
{
for ( int i = 0; i < langLines.length; i++ )
{
LangLine oldLangLine = langLines[i];
// remember values
String oldLanguage = oldLangLine.languageCombo.getText();
String oldCountry = oldLangLine.countryCombo.getText();
// delete old
oldLangLine.langLabel.dispose();
oldLangLine.languageCombo.dispose();
oldLangLine.minusLabel.dispose();
oldLangLine.countryCombo.dispose();
oldLangLine.addButton.dispose();
oldLangLine.deleteButton.dispose();
langLineList.remove( oldLangLine );
// add new
LangLine newLangLine = createLangLine( langComposite );
langLineList.add( newLangLine );
// restore value
newLangLine.languageCombo.setText( oldLanguage );
newLangLine.countryCombo.setText( oldCountry );
// check
if ( index == i + 1 )
{
LangLine langLine = createLangLine( langComposite );
langLineList.add( langLine );
}
}
}
else
{
LangLine langLine = createLangLine( langComposite );
langLineList.add( langLine );
}
shell.layout( true, true );
}
/**
* Creates a language line.
*
* @param langComposite the language composite
*
* @return the language line
*/
private LangLine createLangLine( final Composite langComposite )
{
final LangLine langLine = new LangLine();
langLine.langLabel = BaseWidgetUtils.createLabel( langComposite, "lang-", 1 ); //$NON-NLS-1$
langLine.languageCombo = BaseWidgetUtils.createCombo( langComposite, possibleLanguages, -1, 1 );
langLine.minusLabel = BaseWidgetUtils.createLabel( langComposite, "-", 1 ); //$NON-NLS-1$
langLine.countryCombo = BaseWidgetUtils.createCombo( langComposite, new String[0], -1, 1 );
langLine.countryCombo.setEnabled( false );
langLine.addButton = new Button( langComposite, SWT.PUSH );
langLine.addButton.setText( " + " ); //$NON-NLS-1$
langLine.addButton.addSelectionListener( new SelectionAdapter()
{
public void widgetSelected( SelectionEvent e )
{
int index = langLineList.size();
for ( int i = 0; i < langLineList.size(); i++ )
{
LangLine langLine = langLineList.get( i );
if ( langLine.addButton == e.widget )
{
index = i + 1;
}
}
addLangLine( langComposite, index );
validate();
}
} );
langLine.deleteButton = new Button( langComposite, SWT.PUSH );
langLine.deleteButton.setText( " \u2212 " ); //$NON-NLS-1$
langLine.deleteButton.addSelectionListener( new SelectionAdapter()
{
public void widgetSelected( SelectionEvent e )
{
int index = 0;
for ( int i = 0; i < langLineList.size(); i++ )
{
LangLine langLine = langLineList.get( i );
if ( langLine.deleteButton == e.widget )
{
index = i;
}
}
deleteLangLine( langComposite, index );
validate();
}
} );
langLine.languageCombo.addModifyListener( new ModifyListener()
{
public void modifyText( ModifyEvent e )
{
if ( "".equals( langLine.languageCombo.getText() ) ) //$NON-NLS-1$
{
langLine.countryCombo.setEnabled( false );
}
else
{
langLine.countryCombo.setEnabled( true );
String oldValue = langLine.countryCombo.getText();
if ( possibleLangToCountriesMap.containsKey( langLine.languageCombo.getText() ) )
{
langLine.countryCombo.setItems( possibleLangToCountriesMap.get( langLine.languageCombo
.getText() ) );
}
else
{
langLine.countryCombo.setItems( new String[0] );
}
langLine.countryCombo.setText( oldValue );
}
validate();
}
} );
langLine.countryCombo.addModifyListener( new ModifyListener()
{
public void modifyText( ModifyEvent e )
{
validate();
}
} );
return langLine;
}
/**
* Deletes the language line at the given index.
*
* @param langComposite the language composite
* @param index the index
*/
private void deleteLangLine( Composite langComposite, int index )
{
LangLine langLine = langLineList.remove( index );
if ( langLine != null )
{
langLine.langLabel.dispose();
langLine.languageCombo.dispose();
langLine.minusLabel.dispose();
langLine.countryCombo.dispose();
langLine.addButton.dispose();
langLine.deleteButton.dispose();
if ( !langComposite.isDisposed() )
{
shell.layout( true, true );
}
}
}
/**
* The class LangLine is a wrapper for all input elements of a language tag.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class LangLine
{
/** The lang label. */
public Label langLabel;
/** The language combo. */
public Combo languageCombo;
/** The minus label. */
public Label minusLabel;
/** The country combo. */
public Combo countryCombo;
/** The add button. */
public Button addButton;
/** The delete button. */
public Button deleteButton;
}
}