blob: 7f98a6c3f803476e0cfdee17870b2f3709292319 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2005 Sybase, Inc. and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.datatools.sqltools.sqleditor.internal.sql;
import java.util.ArrayList;
import org.eclipse.datatools.sqltools.editor.template.GenericSQLContext;
import org.eclipse.datatools.sqltools.editor.template.GenericSQLContextType;
import org.eclipse.datatools.sqltools.editor.template.SQLTemplate;
import org.eclipse.datatools.sqltools.editor.template.TemplateConstant;
import org.eclipse.datatools.sqltools.editor.ui.core.SQLDevToolsUIConfiguration;
import org.eclipse.datatools.sqltools.editor.ui.core.SQLToolsUIFacade;
import org.eclipse.datatools.sqltools.sqleditor.SQLEditor;
import org.eclipse.datatools.sqltools.sqleditor.internal.SQLEditorPlugin;
import org.eclipse.datatools.sqltools.sqleditor.internal.SQLEditorResources;
import org.eclipse.datatools.sqltools.sqleditor.internal.templates.SQLTemplateProposal;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.templates.GlobalTemplateVariables;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
/**
*
* @author Hui Cao
*
*/
public class SQLTemplateProposalsService {
private static final String _LINE_SELECTION = "${" + GlobalTemplateVariables.LineSelection.NAME + "}"; //$NON-NLS-1$ //$NON-NLS-2$
private static final String _WORD_SELECTION = "${" + GlobalTemplateVariables.WordSelection.NAME + "}"; //$NON-NLS-1$ //$NON-NLS-2$
/**
* Inspects the context of the compilation unit around
* <code>completionPosition</code> and feeds the collector with proposals.
*
* @param viewer
* the text viewer
* @param completionPosition
* the context position in the document of the text viewer
* @param word
* the word before the proposal invocation point
* @param isStatementStart
* whether it is possible to start a new statement
* @return ArrayList of <code>TemplateProposal</code>s
*/
public ArrayList getProposals(SQLEditor editor, int completionPosition,
String word, boolean isStatementStart, Point selection) {
ArrayList proposals = new ArrayList();
IDocument document = editor.getSV().getDocument();
TemplateContextType contextType;
SQLDevToolsUIConfiguration config = SQLToolsUIFacade
.getConfigurationByVendorIdentifier(editor.getConnectionInfo()
.getDatabaseVendorDefinitionId());
if (config != null) {
contextType = config.getSQLUIService().getSQLContextType();
} else {
contextType = SQLEditorPlugin.getDefault()
.getTemplateContextTypeRegistry().getContextType(
GenericSQLContextType.SQL_CONTEXT_TYPE);
}
if (!(contextType instanceof GenericSQLContextType)) {
return proposals;
}
// remember selected text
String selectedText = null;
if (selection.y != 0) {
try {
selectedText = document.get(selection.x, selection.y);
} catch (BadLocationException e) {
}
}
GenericSQLContext context = ((GenericSQLContextType) contextType)
.createContext(document, completionPosition - word.length(),
selection.y, editor.getParsingResult());
context.setVariable("selection", selectedText); //$NON-NLS-1$
IRegion region = new Region(completionPosition, selection.y);
Template[] templates = SQLEditorPlugin.getDefault().getTemplateStore()
.getTemplates();
if (selection.y == 0) {
for (int i = 0; i != templates.length; i++) {
if (context.canEvaluate(templates[i])) {
if (word.equals("")) //$NON-NLS-1$
{
if (isStatementStart) {
proposals.add(new SQLTemplateProposal(editor, templates[i],
context, region, getTemplateImage(templates[i]),
SQLCompletionProposal.TEMPLATE));
}
} else if (SQLParserCompletionEngine.startsWithIgnoreCase(templates[i].getName(),
word)) {
proposals.add(new SQLTemplateProposal(editor, templates[i],
context, region, getTemplateImage(templates[i]),
SQLCompletionProposal.TEMPLATE));
}
}
}
} else {
boolean multipleLinesSelected = areMultipleLinesSelected(editor.getSV());
for (int i = 0; i != templates.length; i++) {
Template template = templates[i];
if (context.canEvaluate(template)
&& (!multipleLinesSelected
&& template.getPattern().indexOf(
_WORD_SELECTION) != -1 || (multipleLinesSelected && template
.getPattern().indexOf(_LINE_SELECTION) != -1))) {
proposals.add(new SQLTemplateProposal(editor, templates[i], context,
region, getTemplateImage(templates[i]),
SQLCompletionProposal.TEMPLATE));
}
}
}
return proposals;
}
private Image getTemplateImage(Template template)
{
if (template instanceof SQLTemplate)
{
SQLTemplate sqlTemplate = (SQLTemplate) template;
if (sqlTemplate.getId().startsWith(TemplateConstant.INTELLIGENT_TEMPLATE))
{
return SQLEditorResources.getImage("intelligent_template");
}
}
return SQLEditorResources.getImage("template_obj");
}
/**
* Returns <code>true</code> if one line is completely selected or if
* multiple lines are selected. Being completely selected means that all
* characters except the new line characters are selected.
*
* @return <code>true</code> if one or multiple lines are selected
* @since 2.1
*/
protected boolean areMultipleLinesSelected(ITextViewer viewer) {
if (viewer == null) {
return false;
}
Point s = viewer.getSelectedRange();
if (s.y == 0) {
return false;
}
try {
IDocument document = viewer.getDocument();
int startLine = document.getLineOfOffset(s.x);
int endLine = document.getLineOfOffset(s.x + s.y);
IRegion line = document.getLineInformation(startLine);
return startLine != endLine
|| (s.x == line.getOffset() && s.y == line.getLength());
} catch (BadLocationException x) {
return false;
}
}
}