blob: 01b215c2c2f51a3c487bc354165bc1515510c808 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Mathias Schaeffner and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Mathias Schaeffner - initial API and implementation
*******************************************************************************/
package org.eclipse.rap.themeeditor.editor.source;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ContextInformation;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.rap.themeeditor.SupportedKeywords;
import org.eclipse.rap.themeeditor.ThemeEditorPlugin;
import org.eclipse.rap.themeeditor.editor.source.region.IRegionExt;
import org.eclipse.rwt.internal.theme.ThemeDefElementWrapper;
import org.eclipse.rwt.internal.theme.ThemeDefProperty;
import org.eclipse.rwt.internal.theme.ThemeDefinitionProvider;
public class CSSCompletionProcessor implements IContentAssistProcessor {
private CSSTokenScanner tokenScanner;
public CSSCompletionProcessor( final CSSTokenScanner tokenScanner ) {
this.tokenScanner = tokenScanner;
}
public ICompletionProposal[] computeCompletionProposals( final ITextViewer viewer,
final int offset )
{
IRegionExt regionExt = tokenScanner.getRegionExt( offset );
String currentContent = regionExt.getContent();
if( offset >= regionExt.getOffset()
&& offset <= ( regionExt.getOffset() + regionExt.getLength() )
&& ( offset - regionExt.getOffset() ) <= currentContent.length() )
{
currentContent = currentContent.substring( 0, offset
- regionExt.getOffset() );
} else {
return null;
}
String[] proposalStrings = SupportedKeywords.getKeywordsStartWith( currentContent.trim(),
regionExt.getKeywordType() );
if( proposalStrings == null ) {
return null;
}
proposalStrings = filterProposalStrings( proposalStrings, regionExt );
if( proposalStrings.length == 0 ) {
return null;
}
// just a hack to perform trimStart only, as whitespace at end must remain
currentContent = currentContent + '#';
int beginIndex = currentContent.trim().length() - 1;
ICompletionProposal[] result = new ICompletionProposal[ proposalStrings.length ];
for( int i = 0; i < proposalStrings.length; i++ ) {
String additionalInfo = ThemeDefinitionProvider.getDescription( regionExt,
proposalStrings[ i ] );
IContextInformation info = new ContextInformation( proposalStrings[ i ],
proposalStrings[ i ] );
result[ i ] = new CompletionProposal( proposalStrings[ i ],
offset - beginIndex,
beginIndex,
proposalStrings[ i ].length(),
ThemeEditorPlugin.getDefault()
.getImage( ThemeEditorPlugin.IMG_FIELD_PRIVATE ),
proposalStrings[ i ],
info,
additionalInfo );
}
return result;
}
public IContextInformation[] computeContextInformation( final ITextViewer viewer,
final int offset )
{
return null;
}
public char[] getCompletionProposalAutoActivationCharacters() {
return new char[]{
'.', ':', '['
};
}
public char[] getContextInformationAutoActivationCharacters() {
return null;
}
public IContextInformationValidator getContextInformationValidator() {
return null;
}
public String getErrorMessage() {
return null;
}
private String[] filterProposalStrings( final String[] proposalStrings,
final IRegionExt regionExt )
{
String[] result;
switch( regionExt.getKeywordType() ) {
case SupportedKeywords.STYLE_TYPE:
result = filterProposalStyles( proposalStrings, regionExt );
break;
case SupportedKeywords.STATE_TYPE:
result = filterProposalStates( proposalStrings, regionExt );
break;
case SupportedKeywords.PROPERTY_TYPE:
result = filterProposalProperties( proposalStrings, regionExt );
break;
default:
result = proposalStrings;
break;
}
return result;
}
private String[] filterProposalStyles( final String[] proposalStrings,
final IRegionExt regionExt )
{
String[] result = new String[ 0 ];
if( regionExt.getTokenType() == CSSTokenProvider.STYLE_TOKEN ) {
ThemeDefElementWrapper wrapper = ThemeDefinitionProvider.getElementWrapper( regionExt );
if( wrapper != null ) {
List resultList = new ArrayList();
for( int i = 0; i < proposalStrings.length; i++ ) {
String text = proposalStrings[ i ];
if( wrapper.element.styleMap.containsKey( text ) ) {
resultList.add( text );
}
}
result = new String[ resultList.size() ];
result = ( String[] )resultList.toArray( result );
}
}
return result;
}
private String[] filterProposalStates( final String[] proposalStrings,
final IRegionExt regionExt )
{
String[] result = new String[ 0 ];
if( regionExt.getTokenType() == CSSTokenProvider.STATE_TOKEN ) {
ThemeDefElementWrapper wrapper = ThemeDefinitionProvider.getElementWrapper( regionExt );
if( wrapper != null ) {
List resultList = new ArrayList();
for( int i = 0; i < proposalStrings.length; i++ ) {
String text = proposalStrings[ i ];
if( wrapper.element.stateMap.containsKey( text ) ) {
resultList.add( text );
}
}
result = new String[ resultList.size() ];
result = ( String[] )resultList.toArray( result );
}
}
return result;
}
private String[] filterProposalProperties( final String[] proposalStrings,
final IRegionExt regionExt )
{
String[] result = new String[ 0 ];
if( regionExt.getTokenType() == CSSTokenProvider.PROPERTY_TOKEN ) {
OutlineRegion[] regions = tokenScanner.getOutlineRegionsArray();
OutlineRegion outlineRegion = null;
for( int i = 0; i < regions.length; i++ ) {
OutlineRegion next = regions[ i ];
if( next.getOffset() <= regionExt.getOffset() ) {
outlineRegion = next;
}
}
if( outlineRegion != null ) {
List resultList = new ArrayList();
for( int i = 0; i < outlineRegion.getElements().length; i++ ) {
ThemeDefElementWrapper wrapper = ThemeDefinitionProvider.getElementWrapper( outlineRegion.getElements()[ i ] );
if( wrapper != null ) {
for( int j = 0; j < proposalStrings.length; j++ ) {
String text = proposalStrings[ j ];
for( int k = 0; k < wrapper.element.properties.length; k++ ) {
ThemeDefProperty property = wrapper.element.properties[ k ];
if( property.name.equals( text ) ) {
if( !resultList.contains( text ) ) {
resultList.add( text );
}
}
}
}
}
}
result = new String[ resultList.size() ];
result = ( String[] )resultList.toArray( result );
Arrays.sort( result );
}
}
return result;
}
}