/**
* Copyright (c) 2009, 2010 Mark Feber, MulgaSoft
*
* 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
*/
package com.mulgasoft.emacsplus.commands;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.texteditor.ITextEditor;
import com.mulgasoft.emacsplus.EmacsPlusUtils;
/**
* Sort lines in region alphabetically; argument means descending order.
* The variable `SortFoldCase' determines whether alphabetic case affects
* the sort order.
*
* In Emacs, partial selection on a line is included in the sort from point or mark
*
* @author Mark Feber - initial API and implementation
*/
public class SortLinesHandler extends LineHandler {
/**
* @see com.mulgasoft.emacsplus.commands.EmacsPlusCmdHandler#transform(ITextEditor, IDocument, ITextSelection, ExecutionEvent)
*/
@Override
protected int transform(ITextEditor editor, IDocument document, ITextSelection currentSelection, ExecutionEvent event)
throws BadLocationException {
int result = getCursorOffset(editor,currentSelection);
// get the selection encompassing the appropriate set of lines
ITextSelection selection = getLineSelection(editor,document,currentSelection);
if (selection != null) {
int offset = selection.getOffset();
int endOffset = offset+selection.getLength();
int begin = document.getLineOfOffset(offset);
int end = document.getLineOfOffset(endOffset);
if (begin != end && begin < end) {
ArrayList<String> alst = new ArrayList<String>();
IRegion region = document.getLineInformation(begin);
// get text from point or mark
alst.add(document.get(offset,region.getLength()-(offset-region.getOffset())));
for (int i = begin+1; i < end; i++) {
region = document.getLineInformation(i);
// get full line of text
alst.add(document.get(region.getOffset(),region.getLength()));
}
region = document.getLineInformation(end);
// get text to point or mark
alst.add(document.get(region.getOffset(),endOffset - region.getOffset()));
Collections.sort(alst,(getComparator(isUniversalPresent())));
updateLines(document,selection,alst.toArray(new String[0]));
} else {
EmacsPlusUtils.showMessage(editor, NO_REGION, true);
}
} else {
EmacsPlusUtils.showMessage(editor, NO_REGION, true);
}
return result;
}
private Comparator<String> getComparator(boolean reverse) {
return (SortFoldCase ? new SortInsensitiveComparator(reverse) : new SortComparator(reverse));
}
private class SortComparator implements Comparator<String> {
private boolean reverse = false;
SortComparator(boolean reverse) {
this.reverse = reverse;
}
/**
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(String o1, String o2) {
int result = o1.trim().compareTo(o2.trim());
return (reverse ? -result : result);
}
}
private class SortInsensitiveComparator implements Comparator<String> {
private boolean reverse = false;
SortInsensitiveComparator(boolean reverse) {
this.reverse = reverse;
}
/**
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(String o1, String o2) {
int result = String.CASE_INSENSITIVE_ORDER.compare(o1.trim(),o2.trim());
return (reverse ? -result : result);
}
}
/**
* @see com.mulgasoft.emacsplus.commands.EmacsPlusCmdHandler#isLooping()
*/
protected boolean isLooping() {
return false;
}
}