/* Copyright (c) 2009 Andrejs Jermakovics. * * 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: * Andrejs Jermakovics - initial implementation */ package it.unibz.instasearch.ui; import it.unibz.instasearch.InstaSearchPlugin; import it.unibz.instasearch.indexing.Field; import it.unibz.instasearch.indexing.Searcher; import it.unibz.instasearch.indexing.querying.ModifiedTimeConverter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import org.eclipse.jface.fieldassist.IContentProposal; import org.eclipse.jface.fieldassist.SimpleContentProposalProvider; class SearchContentProposalProvider extends SimpleContentProposalProvider { private final IContentProposal[] EMPTY_PROPOSALS = new IContentProposal[]{}; private ResultContentProvider contentProvider; public SearchContentProposalProvider(ResultContentProvider contentProvider) { super(new String[]{}); this.contentProvider = contentProvider; } @Override public IContentProposal[] getProposals(String contents, int position) { String curText = contents.substring(0, position); String rest = contents.substring(position); if( curText.endsWith(" ") ) return EMPTY_PROPOSALS; //TODO: use parser int colIdx = curText.lastIndexOf(':'); int spaceIdx = curText.lastIndexOf(' '); if( colIdx == -1 || spaceIdx > colIdx ) return getPrefixProposals(curText, Field.CONTENTS, rest); String beforeCol = curText.substring(0, colIdx); String fieldName = beforeCol; if( spaceIdx != -1 ) fieldName = beforeCol.substring(spaceIdx+1); fieldName = fieldName.toLowerCase(Locale.ENGLISH); List<String> proposalNames = null; int commaIdx = curText.lastIndexOf(','); String prevProposal = ""; if( commaIdx > colIdx && commaIdx < position ) { prevProposal = curText.substring(colIdx+1, commaIdx+1); colIdx = commaIdx; } String prefix = curText.substring(colIdx+1).toLowerCase(Locale.ENGLISH); // filtering text Field field = Field.getByName(fieldName); if( field == null ) return EMPTY_PROPOSALS; proposalNames = getFieldProposals(field, prefix); if( proposalNames.size() == 0 ) return EMPTY_PROPOSALS; ArrayList<IContentProposal> proposals = new ArrayList<IContentProposal>(); if( "".equals(prefix) && field == Field.PROJ ) addCurrentProjectProposal(rest, beforeCol, prevProposal, proposals); for(String proposalName: proposalNames) { if( proposalName.toLowerCase(Locale.ENGLISH).startsWith(prefix) ) { String label = proposalName; proposalName = prevProposal + proposalName; if( proposalName.contains(" ") && !proposalName.contains("\"") ) proposalName = "\"" + proposalName + "\""; String proposalContent = beforeCol + ':' + proposalName + rest; int pos = beforeCol.length() + 1 + proposalName.length(); proposals.add( makeContentProposal(proposalContent, label, pos) ); } } return proposals.toArray(new IContentProposal[proposals.size()]); } public List<String> getFieldProposals(Field field, String prefix) { List<String> proposalNames; switch(field) { case PROJ: proposalNames = InstaSearchPlugin.getProjectNames(); break; case WS: proposalNames = InstaSearchPlugin.getWorkingSets(); break; case MODIFIED: proposalNames = ModifiedTimeConverter.getDurationNames(); break; case FILE: return Collections.emptyList(); case DIR: return Collections.emptyList(); default: proposalNames = getIndexedProposals(prefix, field); break; } return proposalNames; } private void addCurrentProjectProposal(String rest, String beforeCol, String prevProposal, ArrayList<IContentProposal> proposals) { if( InstaSearchUI.getActiveProject() != null ) { String content = beforeCol + ":" + prevProposal + Searcher.CURRENT_PROJECT_CHAR + rest; proposals.add( makeContentProposal(content, Searcher.CURRENT_PROJECT_CHAR + " (Current Project)", beforeCol.length()+2) ); } } /** * @param rest * @param curText * @return */ private IContentProposal[] getPrefixProposals(String text, Field field, String rest) { if( "".equals(text.trim())) return EMPTY_PROPOSALS; String before, prefix; int spaceIdx = text.lastIndexOf(' '); if( spaceIdx != -1 ) { prefix = text.substring(spaceIdx+1); before = text.substring(0, spaceIdx+1); } else { // whole prefix prefix = text; before = ""; } ArrayList<IContentProposal> contentProposals = new ArrayList<IContentProposal>(); List<String> proposals = getIndexedProposals(prefix, field); if( proposals == null ) return EMPTY_PROPOSALS; for(String proposal: proposals) { if( proposal.toLowerCase(Locale.ENGLISH).startsWith(prefix) ) { String label = proposal; String proposalContent = before + proposal + rest; int pos = before.length() + proposal.length(); contentProposals.add( makeContentProposal(proposalContent, label, pos) ); } } return contentProposals.toArray(new IContentProposal[contentProposals.size()]); } private List<String> getIndexedProposals(String prefix, Field field) { List<String> proposals = null; try { proposals = contentProvider.getProposals(prefix, field); } catch (IOException e) { return null; } return proposals; } private IContentProposal makeContentProposal(final String proposalContent, final String label, final int position) { return new IContentProposal() { public String getContent() { return proposalContent; } public String getDescription() { return null; } public String getLabel() { return label; } public int getCursorPosition() { return position; } }; } }