/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.ui.keys;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.whole.lang.model.IEntity;
import org.whole.lang.reflect.EntityDescriptor;
import org.whole.lang.ui.editparts.ITextualEntityPart;
import org.whole.lang.ui.tools.EditPoint;
import org.whole.lang.ui.tools.IWholeSelection;
import org.whole.lang.ui.tools.SelectionRange;
/**
* @author Enrico Persiani
*/
public class TextualKeyHandler extends DefaultKeyHandler {
public static final TextualKeyHandler instance = new TextualKeyHandler();
public static DefaultKeyHandler instance() {
return instance;
}
protected Set<EntityDescriptor<?>> edSet;
protected Pattern RIGHT_PATTERN = Pattern.compile("(\\A[^\\p{Alnum}])|(\\A[\\p{Alnum}]+)"); // matches always
protected Pattern LEFT_PATTERN = Pattern.compile("([^\\p{Alnum}]\\z)|([\\p{Alnum}]+\\z)"); // matches always
public TextualKeyHandler() {
this.edSet = Collections.emptySet();
}
public TextualKeyHandler(EntityDescriptor<?>... eds) {
this.edSet = new HashSet<>(Arrays.asList(eds));
}
protected boolean enableSmartSelection(IEntity e) {
return edSet.isEmpty() || edSet.contains(e.wGetEntityDescriptor());
}
public IWholeSelection calculateDoubleClickSelection(EditPoint editPoint) {
ITextualEntityPart targetPart = (ITextualEntityPart) editPoint.focus;
IEntity targetEntity = targetPart.getModelEntity();
int endPosition = -1, startPosition = -1;
if (enableSmartSelection(targetEntity)) {
String text = targetEntity.wStringValue();
int position = targetPart.getCaretPosition();
int positions = targetPart.getCaretPositions();
Matcher matcher;
if (position == 0) {
matcher = RIGHT_PATTERN.matcher(text);
if (matcher.find()) {
startPosition = 0;
endPosition = matcher.end();
}
} else if (position == positions) {
matcher = LEFT_PATTERN.matcher(text);
if (matcher.find()) {
startPosition = matcher.start();
endPosition = positions;
}
} else {
if (Character.isLetterOrDigit(text.charAt(position))) {
if (Character.isLetterOrDigit(text.charAt(position-1))) {
// XX
String substring = text.substring(0, position);
matcher = LEFT_PATTERN.matcher(substring);
if (matcher.find())
startPosition = matcher.start();
matcher = RIGHT_PATTERN.matcher(text.substring(position));
if (matcher.find())
endPosition = position+matcher.end();
} else {
// .X
matcher = RIGHT_PATTERN.matcher(text.substring(position));
if (matcher.find()) {
startPosition = position+matcher.start();
endPosition = position+matcher.end();
}
}
} else {
if (Character.isLetterOrDigit(text.charAt(position-1))) {
// X.
matcher = LEFT_PATTERN.matcher(text.substring(0, position));
if (matcher.find()) {
startPosition = matcher.start();
endPosition = position;
}
} else {
// ..
startPosition = position -1;
endPosition = position;
}
}
}
}
if (endPosition >= 0 && startPosition >= 0)
return new SelectionRange(editPoint.focus, startPosition, endPosition);
else
return super.calculateDoubleClickSelection(editPoint);
}
public IWholeSelection calculateTripleClickSelection(EditPoint editPoint) {
return super.calculateDoubleClickSelection(editPoint);
}
}