blob: 86e63b137867d62eb409fffe39d4a1b361bee5c1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems, Inc. 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:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextDoubleClickStrategy;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant;
/**
* Double click strategy aware of string and character syntax rules.
*
* @since 4.0
*/
public class CStringDoubleClickSelector extends CDoubleClickSelector {
private String fPartitioning;
private ITextDoubleClickStrategy fFallbackStrategy;
/**
* Creates a new string double click selector for the given document partitioning.
*
* @param partitioning the document partitioning
*/
public CStringDoubleClickSelector(String partitioning) {
this(partitioning, null);
}
/**
* Creates a new string double click selector for the given document partitioning.
*
* @param partitioning the document partitioning
* @param doubleClickStrategy the fallback double click strategy
*/
public CStringDoubleClickSelector(String partitioning,
ITextDoubleClickStrategy doubleClickStrategy) {
fPartitioning= partitioning;
fFallbackStrategy= doubleClickStrategy;
}
/*
* @see ITextDoubleClickStrategy#doubleClicked(ITextViewer)
*/
@Override
public void doubleClicked(ITextViewer textViewer) {
int offset= textViewer.getSelectedRange().x;
if (offset < 0)
return;
IDocument document= textViewer.getDocument();
IRegion region= matchString(document, offset);
if (region != null) {
if (region.getLength() >= 2) {
textViewer.setSelectedRange(region.getOffset() + 1, region.getLength() - 2);
}
} else if (fFallbackStrategy != null) {
fFallbackStrategy.doubleClicked(textViewer);
} else {
region= selectWord(document, offset);
if (region != null) {
textViewer.setSelectedRange(region.getOffset(), region.getLength());
}
}
}
private IRegion matchString(IDocument document, int offset) {
try {
if ((document.getChar(offset) == '"') || (document.getChar(offset) == '\'') ||
(document.getChar(offset - 1) == '"') || (document.getChar(offset - 1) == '\''))
{
ITypedRegion region= TextUtilities.getPartition(document, fPartitioning, offset, true);
// little hack: in case this strategy is used in preprocessor partitions, the string
// partition inside the preprocessor partition must be computed in an extra step
if (ICPartitions.C_PREPROCESSOR.equals(region.getType())) {
String ppDirective= document.get(region.getOffset(), region.getLength());
int hashIdx= ppDirective.indexOf('#');
document= new Document(ppDirective.substring(hashIdx+1));
new CDocumentSetupParticipant().setup(document);
int delta= region.getOffset() + hashIdx + 1;
region= TextUtilities.getPartition(document, fPartitioning, offset - delta, true);
return new Region(region.getOffset() + delta, region.getLength());
}
return region;
}
} catch (BadLocationException e) {
}
return null;
}
}