1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-14 20:45:22 +02:00

Sort Lines command.

This commit is contained in:
Sergey Prigogin 2010-05-03 04:53:27 +00:00
parent 0ae94097b3
commit d6c48415c3
13 changed files with 614 additions and 15 deletions

View file

@ -0,0 +1,190 @@
/*******************************************************************************
* Copyright (c) 2010 Google, 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text;
import java.util.ListResourceBundle;
import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.ui.testplugin.EditorTestHelper;
import org.eclipse.cdt.ui.testplugin.ResourceTestHelper;
import org.eclipse.cdt.ui.tests.BaseUITestCase;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.editor.SortLinesAction;
/**
* Tests for the SortLinesAction.
*
* @since 5.2
*/
public class SortLinesTest extends BaseUITestCase {
private static final String PROJECT = "SortLinesTest";
private static final String FILE = "test.cpp";
private static final class EmptyBundle extends ListResourceBundle {
@Override
protected Object[][] getContents() {
return new Object[0][];
}
}
protected static class SortLinesTestSetup extends TestSetup {
private ICProject fCProject;
public SortLinesTestSetup(Test test) {
super(test);
}
@Override
protected void setUp() throws Exception {
super.setUp();
fCProject= CProjectHelper.createCProject(PROJECT, null);
fCProject.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, DefaultCodeFormatterConstants.MIXED);
fCProject.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, String.valueOf(8));
fCProject.setOption(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, String.valueOf(4));
IFile file= EditorTestHelper.createFile(fCProject.getProject(), FILE, "", new NullProgressMonitor());
}
@Override
protected void tearDown () throws Exception {
EditorTestHelper.closeAllEditors();
if (fCProject != null) {
CProjectHelper.delete(fCProject);
}
super.tearDown();
}
}
private static final Class<?> THIS= SortLinesTest.class;
public static Test suite() {
return new SortLinesTestSetup(new TestSuite(THIS));
}
private CEditor fEditor;
private SourceViewer fSourceViewer;
private IDocument fDocument;
private SortLinesTestSetup fProjectSetup;
/*
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception {
if (!ResourcesPlugin.getWorkspace().getRoot().exists(new Path(PROJECT))) {
fProjectSetup= new SortLinesTestSetup(this);
fProjectSetup.setUp();
}
fEditor= (CEditor) EditorTestHelper.openInEditor(ResourceTestHelper.findFile(PROJECT + '/' + FILE), true);
fSourceViewer= EditorTestHelper.getSourceViewer(fEditor);
fDocument= fSourceViewer.getDocument();
super.setUp();
}
/*
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
if (fProjectSetup != null) {
fProjectSetup.tearDown();
}
super.tearDown();
}
private void sortLines() throws Exception {
new SortLinesAction(fEditor).run();
}
/**
* Selects part of the document.
*
* @param startLine First line of the selection. Zero based.
* @param startPosition Start position of the selection in startLine. Zero based.
* @param endLine Last line of the selection. Zero based.
* @param endPosition Position after the end of the selection in endLine. Zero based.
*/
private void select(int startLine, int startPosition, int endLine, int endPosition)
throws BadLocationException {
int offset = fDocument.getLineOffset(startLine) + startPosition;
fSourceViewer.setSelectedRange(offset, fDocument.getLineOffset(endLine) + endPosition - offset);
}
/**
* Selects the whole document.
*/
private void selectAll() {
fSourceViewer.setSelectedRange(0, fDocument.getLength());
}
// // e.h
// #include "e.h"
// #include "bbb.h"
// #include "dd.h"
// /*
// * ccccc.h
// */
// #include "ccccc.h"
// #include "aaaa.h"
// #include "aaaa.h"
// #include "bbb.h"
// /*
// * ccccc.h
// */
// #include "ccccc.h"
// #include "dd.h"
// // e.h
// #include "e.h"
public void testSortLinesMixed() throws Exception {
StringBuffer[] contents= getContentsForTest(2);
String before= contents[0].toString();
String after= contents[1].toString();
fDocument.set(before);
selectAll();
sortLines();
assertEquals(after, fDocument.get());
}
// /*
// * Ganymede
// * Europa
// * Callisto
// */
// /*
// * Europa
// * Ganymede
// * Callisto
// */
public void testSortLinesCommentsOnly() throws Exception {
StringBuffer[] contents= getContentsForTest(2);
String before= contents[0].toString();
String after= contents[1].toString();
fDocument.set(before);
select(1, 0, 3, 0);
sortLines();
assertEquals(after, fDocument.get());
}
}

View file

@ -72,10 +72,11 @@ public class TextTestSuite extends TestSuite {
// compare tests // compare tests
addTest(CStructureCreatorTest.suite()); addTest(CStructureCreatorTest.suite());
// block comment tests // source manipulation tests
addTest(AddBlockCommentTest.suite()); addTest(AddBlockCommentTest.suite());
addTest(RemoveBlockCommentTest.suite()); addTest(RemoveBlockCommentTest.suite());
addTest(SortLinesTest.suite());
// add include // add include
addTest(AddIncludeTest.suite()); addTest(AddIncludeTest.suite());
} }

View file

@ -170,7 +170,7 @@ Refactoring.extractLocalVariable.label=Extract &Local Variable
Refactoring.extractFunction.label=Extract &Function... Refactoring.extractFunction.label=Extract &Function...
Refactoring.hideMethod.label=Hide Method... Refactoring.hideMethod.label=Hide Method...
Refactoring.implementMethod.label=Impl&ement Method... Refactoring.implementMethod.label=Impl&ement Method...
Refactoring.gettersAndSetters.label=Generate Getters and Setters... Refactoring.gettersAndSetters.label=Gene&rate Getters and Setters...
Source.menu.label = &Source Source.menu.label = &Source
@ -253,10 +253,14 @@ OpenTypeAction.tooltip= Open Element
ActionDefinition.openType.name= Open Element ActionDefinition.openType.name= Open Element
ActionDefinition.openType.description= Open an element in an Editor ActionDefinition.openType.description= Open an element in an Editor
#Add include #Add Include
ActionDefinition.addInclude.name= Add Include ActionDefinition.addInclude.name= Add Include
ActionDefinition.addInclude.description= Create include statement on selection ActionDefinition.addInclude.description= Create include statement on selection
#Sort Lines
ActionDefinition.sortLines.name= Sort Lines
ActionDefinition.sortLines.description= Sort selected lines alphabetically
#Show outline dialog #Show outline dialog
ActionDefinition.showOutline.name= Show outline ActionDefinition.showOutline.name= Show outline
ActionDefinition.showOutline.description= Shows outline ActionDefinition.showOutline.description= Shows outline
@ -555,6 +559,7 @@ renameParticipant.name = Source Folder Rename
FormatAction.label= &Format FormatAction.label= &Format
IndentAction.label= Correct &Indentation IndentAction.label= Correct &Indentation
AddIncludeAction.label= A&dd Include AddIncludeAction.label= A&dd Include
SortLinesAction.label= Sor&t Lines
CommentAction.label= Co&mment CommentAction.label= Co&mment
UncommentAction.label= &Uncomment UncommentAction.label= &Uncomment
ToggleCommentAction.label= Togg&le Comment ToggleCommentAction.label= Togg&le Comment

View file

@ -1334,6 +1334,13 @@
retarget="true"> retarget="true">
</action> </action>
<!-- Import Group --> <!-- Import Group -->
<action
definitionId="org.eclipse.cdt.ui.edit.text.c.sort.lines"
label="%SortLinesAction.label"
retarget="true"
menubarPath="org.eclipse.jdt.ui.source.menu/importGroup"
id="org.eclipse.cdt.ui.actions.SortLines">
</action>
<action <action
definitionId="org.eclipse.cdt.ui.edit.text.c.add.include" definitionId="org.eclipse.cdt.ui.edit.text.c.add.include"
label="%AddIncludeAction.label" label="%AddIncludeAction.label"
@ -1805,6 +1812,11 @@
contextId="org.eclipse.cdt.ui.cEditorScope" contextId="org.eclipse.cdt.ui.cEditorScope"
commandId="org.eclipse.cdt.ui.edit.text.c.add.include" commandId="org.eclipse.cdt.ui.edit.text.c.add.include"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/> schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
<key
sequence="M1+M2+S"
contextId="org.eclipse.cdt.ui.cEditorScope"
commandId="org.eclipse.cdt.ui.edit.text.c.sort.lines"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
<key <key
sequence="M1+O" sequence="M1+O"
contextId="org.eclipse.cdt.ui.cEditorScope" contextId="org.eclipse.cdt.ui.cEditorScope"
@ -2253,6 +2265,12 @@
categoryId="org.eclipse.cdt.ui.category.source" categoryId="org.eclipse.cdt.ui.category.source"
id="org.eclipse.cdt.ui.edit.text.c.add.include"> id="org.eclipse.cdt.ui.edit.text.c.add.include">
</command> </command>
<command
name="%ActionDefinition.sortLines.name"
description="%ActionDefinition.sortLines.description"
categoryId="org.eclipse.cdt.ui.category.source"
id="org.eclipse.cdt.ui.edit.text.c.sort.lines">
</command>
<command <command
name="%ActionDefinition.showOutline.name" name="%ActionDefinition.showOutline.name"
description="%ActionDefinition.showOutline.description" description="%ActionDefinition.showOutline.description"

View file

@ -378,7 +378,6 @@ public class Strings {
} }
} }
/** /**
* Concatenate the given strings into one strings using the passed line delimiter as a * Concatenate the given strings into one strings using the passed line delimiter as a
* delimiter. No delimiter is added to the last line. * delimiter. No delimiter is added to the last line.
@ -397,9 +396,10 @@ public class Strings {
if (s.length() != c.length) if (s.length() != c.length)
return false; return false;
for (int i = c.length; --i >= 0;) for (int i = c.length; --i >= 0;) {
if (s.charAt(i) != c[i]) if (s.charAt(i) != c[i])
return false; return false;
}
return true; return true;
} }
@ -421,7 +421,32 @@ public class Strings {
else else
return text.substring(0, end); return text.substring(0, end);
} }
/**
* Converts tabs to spaces in a line of text.
* @param line The line of text.
* @param tabWidth Tabulation size.
* @return The line with tab characters replaced by spaces.
*/
public static String convertTabsToSpaces(String line, int tabWidth) {
StringBuilder buf = null;
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
if (c == '\t') {
if (buf == null) {
buf = new StringBuilder(line.length() * tabWidth);
buf.append(line.subSequence(0, i));
}
for (int k = tabWidth - i % tabWidth; --k >= 0;) {
buf.append(' ');
}
} else if (buf != null) {
buf.append(c);
}
}
return buf != null ? buf.toString() : line;
}
public static String removeMnemonicIndicator(String string) { public static String removeMnemonicIndicator(String string) {
return LegacyActionTools.removeMnemonics(string); return LegacyActionTools.removeMnemonics(string);
} }

View file

@ -2191,6 +2191,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
setAction("Format", action); //$NON-NLS-1$ setAction("Format", action); //$NON-NLS-1$
markAsStateDependentAction("Format", true); //$NON-NLS-1$ markAsStateDependentAction("Format", true); //$NON-NLS-1$
action = new SortLinesAction(this);
action.setActionDefinitionId(ICEditorActionDefinitionIds.SORT_LINES);
setAction("SortLines", action); //$NON-NLS-1$
markAsStateDependentAction("SortLines", true); //$NON-NLS-1$
markAsSelectionDependentAction("SortLines", true); //$NON-NLS-1$
action = new ContentAssistAction(bundle, "ContentAssistProposal.", this); //$NON-NLS-1$ action = new ContentAssistAction(bundle, "ContentAssistProposal.", this); //$NON-NLS-1$
action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
setAction("ContentAssistProposal", action); //$NON-NLS-1$ setAction("ContentAssistProposal", action); //$NON-NLS-1$
@ -2225,7 +2231,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
action.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_QUICK_MACRO_EXPLORER); action.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_QUICK_MACRO_EXPLORER);
setAction("OpenMacroExplorer", action); //$NON-NLS-1$*/ setAction("OpenMacroExplorer", action); //$NON-NLS-1$*/
//Assorted action groupings // Assorted action groupings
fSelectionSearchGroup = createSelectionSearchGroup(); fSelectionSearchGroup = createSelectionSearchGroup();
fTextSearchGroup= new TextSearchGroup(this); fTextSearchGroup= new TextSearchGroup(this);
fRefactoringActionGroup= new CRefactoringActionGroup(this, ITextEditorActionConstants.GROUP_EDIT); fRefactoringActionGroup= new CRefactoringActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);

View file

@ -196,6 +196,7 @@ public class CEditorActionContributor extends TextEditorActionContributor {
bars.setGlobalActionHandler(CdtActionConstants.REMOVE_BLOCK_COMMENT, getAction(textEditor, "RemoveBlockComment")); //$NON-NLS-1$ bars.setGlobalActionHandler(CdtActionConstants.REMOVE_BLOCK_COMMENT, getAction(textEditor, "RemoveBlockComment")); //$NON-NLS-1$
bars.setGlobalActionHandler(CdtActionConstants.INDENT, getAction(textEditor, "Indent")); //$NON-NLS-1$ bars.setGlobalActionHandler(CdtActionConstants.INDENT, getAction(textEditor, "Indent")); //$NON-NLS-1$
bars.setGlobalActionHandler(CdtActionConstants.ADD_INCLUDE, getAction(textEditor, "AddIncludeOnSelection")); //$NON-NLS-1$ bars.setGlobalActionHandler(CdtActionConstants.ADD_INCLUDE, getAction(textEditor, "AddIncludeOnSelection")); //$NON-NLS-1$
bars.setGlobalActionHandler(CdtActionConstants.SORT_LINES, getAction(textEditor, "SortLines")); //$NON-NLS-1$
IAction action= getAction(textEditor, ITextEditorActionConstants.REFRESH); IAction action= getAction(textEditor, ITextEditorActionConstants.REFRESH);
bars.setGlobalActionHandler(ITextEditorActionConstants.REFRESH, action); bars.setGlobalActionHandler(ITextEditorActionConstants.REFRESH, action);

View file

@ -17,6 +17,10 @@ AddIncludeOnSelection.description=Add include statement for selected name
AddIncludeOnSelection.label=Add Include AddIncludeOnSelection.label=Add Include
AddIncludeOnSelection.tooltip=Add Include Statement for Selected Name AddIncludeOnSelection.tooltip=Add Include Statement for Selected Name
SortLines.description=Sort selected lines alphabetically
SortLines.label=Sort Lines
SortLines.tooltip=Sort Selected Lines Alphabetically
OpenOutline.label= Quick Out&line OpenOutline.label= Quick Out&line
OpenOutline.tooltip= Shows the Quick Outline of Editor Input OpenOutline.tooltip= Shows the Quick Outline of Editor Input
OpenOutline.description= Shows the quick outline for the editor input OpenOutline.description= Shows the quick outline for the editor input

View file

@ -235,11 +235,17 @@ public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinition
*/ */
public static final String TOGGLE_MARK_OCCURRENCES= "org.eclipse.cdt.ui.edit.text.c.toggleMarkOccurrences"; //$NON-NLS-1$ public static final String TOGGLE_MARK_OCCURRENCES= "org.eclipse.cdt.ui.edit.text.c.toggleMarkOccurrences"; //$NON-NLS-1$
/** /**
* Action definition ID of the open macro explorer quick view action * Action definition ID of the open macro explorer quick view action
* (value <code>"org.eclipse.cdt.ui.edit.open.quick.macro.explorer"</code>). * (value <code>"org.eclipse.cdt.ui.edit.open.quick.macro.explorer"</code>).
* @since 5.0 * @since 5.0
*/ */
public static final String OPEN_QUICK_MACRO_EXPLORER = "org.eclipse.cdt.ui.edit.open.quick.macro.explorer"; //$NON-NLS-1$ public static final String OPEN_QUICK_MACRO_EXPLORER = "org.eclipse.cdt.ui.edit.open.quick.macro.explorer"; //$NON-NLS-1$
/**
* Action definition id of sort lines action.
* (value: <code>"org.eclipse.cdt.ui.edit.text.c.sort.lines"</code>).
* @since 5.2
*/
public static final String SORT_LINES = "org.eclipse.cdt.ui.edit.text.c.sort.lines"; //$NON-NLS-1$
} }

View file

@ -0,0 +1,329 @@
/*******************************************************************************
* Copyright (c) 2010 Google, 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
import java.util.Arrays;
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.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.undo.DocumentUndoManagerRegistry;
import org.eclipse.text.undo.IDocumentUndoManager;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.TextEditorAction;
import com.ibm.icu.text.Collator;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.cdt.internal.corext.util.Strings;
import org.eclipse.cdt.internal.ui.util.EditorUtility;
/**
* Sorts selected lines in alphabetical order. If both, comment and non-comment lines
* are selected, the non-comment lines are sorted, and the comments are moved together
* with the non-comment lines they precede.
*
* @since 5.2
*/
public final class SortLinesAction extends TextEditorAction {
public SortLinesAction(ITextEditor editor) {
super(CEditorMessages.getBundleForConstructedKeys(), "SortLines.", editor); //$NON-NLS-1$
}
/**
* Sorts selected lines.
*/
@Override
public void run() {
ITextEditor editor= getTextEditor();
if (editor == null)
return;
ISelection selection = editor.getSelectionProvider().getSelection();
if (!(selection instanceof ITextSelection))
return;
ITextSelection textSelection= (ITextSelection) selection;
if (textSelection.getStartLine() < 0 || textSelection.getEndLine() < 0)
return;
IEditorInput editorInput = editor.getEditorInput();
ICProject cProject = EditorUtility.getCProject(editorInput);
IDocument document= editor.getDocumentProvider().getDocument(editorInput);
try {
IRegion block= getTextBlockFromSelection(textSelection, document);
SortElement[] elements = createSortElements(block, document,
CodeFormatterUtil.getTabWidth(cProject));
if (elements.length <= 1)
return;
if (!validateEditorInputState())
return;
Arrays.sort(elements);
StringBuilder buf = new StringBuilder();
for (SortElement element : elements) {
buf.append(document.get(element.getOffset(), element.getLength()));
if (!isLastLineTerminated(element, document)) {
buf.append(TextUtilities.getDefaultLineDelimiter(document));
}
}
ReplaceEdit edit = new ReplaceEdit(block.getOffset(), block.getLength(), buf.toString());
IDocumentUndoManager manager= DocumentUndoManagerRegistry.getDocumentUndoManager(document);
manager.beginCompoundChange();
edit.apply(document);
editor.getSelectionProvider().setSelection(new TextSelection(block.getOffset(), buf.length()));
manager.endCompoundChange();
} catch (BadLocationException e) {
CUIPlugin.log(e);
}
}
/**
* Creates a region describing the text block (something that consists of full lines)
* completely containing the current selection.
*
* @param selection The selection to use
* @param document The document
* @return the region describing the text block comprising the given selection
*/
private IRegion getTextBlockFromSelection(ITextSelection selection, IDocument document) {
try {
IRegion firstLine= document.getLineInformationOfOffset(selection.getOffset());
int selectionEnd = selection.getOffset() + selection.getLength();
IRegion lastLine= document.getLineInformationOfOffset(selectionEnd);
int length = lastLine.getOffset() - firstLine.getOffset();
if (selectionEnd > lastLine.getOffset()) {
// Last line is included with the line delimiter.
length += document.getLineLength(document.getLineOfOffset(selectionEnd));
}
return new Region(firstLine.getOffset(), length);
} catch (BadLocationException e) {
CUIPlugin.log(e); // Should not happen
}
return null;
}
private SortElement[] createSortElements(IRegion block, IDocument document, int tabWidth)
throws BadLocationException {
ITypedRegion[] regions= TextUtilities.computePartitioning(document, ICPartitions.C_PARTITIONING,
block.getOffset(), block.getLength(), false);
int numLines = document.getNumberOfLines(block.getOffset(), block.getLength());
if (endOf(block) <= document.getLineInformationOfOffset(endOf(block)).getOffset()) {
numLines--; // Last line is excluded
}
LineInfo[] lineDescriptors = new LineInfo[numLines];
int numNonCommentLines = 0;
int i = 0;
int k = 0;
int line = document.getLineOfOffset(block.getOffset());
int endLine = line + numLines;
for (; line < endLine; line++) {
LineInfo lineInfo = new LineInfo(document, line);
lineDescriptors[k++] = lineInfo;
while (i < regions.length && endOf(regions[i]) <= lineInfo.getTrimmedOffset())
i++;
for (; i < regions.length && regions[i].getOffset() < lineInfo.getTrimmedEndOffset(); i++) {
ITypedRegion region = regions[i];
if (region.getType() != ICPartitions.C_MULTI_LINE_COMMENT &&
region.getType() != ICPartitions.C_MULTI_LINE_DOC_COMMENT &&
region.getType() != ICPartitions.C_SINGLE_LINE_COMMENT &&
region.getType() != ICPartitions.C_SINGLE_LINE_DOC_COMMENT) {
lineInfo.nonComment = true;
break;
}
}
if (lineInfo.nonComment) {
numNonCommentLines++;
}
}
SortElement[] elements;
if (numNonCommentLines > 1) {
elements = new SortElement[numNonCommentLines];
k = 0;
int offset = block.getOffset();
for (int j = 0; j < lineDescriptors.length; j++) {
LineInfo lineInfo = lineDescriptors[j];
if (lineInfo.nonComment) {
int endOffset = k < numNonCommentLines - 1 ?
lineInfo.getEndOffset() : block.getOffset() + block.getLength();
elements[k++] = new SortElement(new Region(offset, endOffset - offset), lineInfo,
document, tabWidth);
offset = lineInfo.getEndOffset();
}
}
} else {
elements = new SortElement[numLines];
for (int j = 0; j < lineDescriptors.length; j++) {
LineInfo lineInfo = lineDescriptors[j];
elements[j] = new SortElement(lineInfo, lineInfo, document, tabWidth);
}
}
return elements;
}
/**
* Returns end offset of a region.
*/
private int endOf(IRegion region) {
return region.getOffset() + region.getLength();
}
/**
* Returns <code>true</code> if the given region is terminated by a line delimiter.
*/
private static boolean isLastLineTerminated(IRegion region, IDocument document) throws BadLocationException {
int offset = region.getOffset() + region.getLength();
IRegion nextLine = document.getLineInformationOfOffset(offset);
return nextLine.getOffset() == offset;
}
@Override
public void update() {
if (!canModifyEditor()) {
setEnabled(false);
return;
}
// Enable if two or more lines are selected.
boolean enabled = false;
ITextEditor editor = getTextEditor();
if (editor != null) {
ISelection selection = editor.getSelectionProvider().getSelection();
if (selection instanceof ITextSelection) {
ITextSelection textSelection= (ITextSelection) selection;
int startLine = textSelection.getStartLine();
int endLine = textSelection.getEndLine();
if (startLine >= 0 && endLine > startLine) {
if (endLine == startLine + 1) {
IDocument document= editor.getDocumentProvider().getDocument(editor.getEditorInput());
try {
if (textSelection.getOffset() + textSelection.getLength() > document.getLineOffset(endLine)) {
enabled = true;
}
} catch (BadLocationException e) {
CUIPlugin.log(e);
}
} else {
enabled = true;
}
}
}
}
setEnabled(enabled);
}
/*
* @see TextEditorAction#setEditor(ITextEditor)
*/
@Override
public void setEditor(ITextEditor editor) {
super.setEditor(editor);
}
private static class SortElement implements Comparable<SortElement>, IRegion {
private static final Collator collator = Collator.getInstance();
private final IRegion region;
private final String collationKey;
public SortElement(IRegion region, IRegion collationLine, IDocument document, int tabWidth)
throws BadLocationException {
super();
this.region = region;
this.collationKey = Strings.convertTabsToSpaces(Strings.trimTrailingTabsAndSpaces(
document.get(collationLine.getOffset(), collationLine.getLength())), tabWidth);
}
public int compareTo(SortElement other) {
return collator.compare(collationKey, other.collationKey);
}
public int getOffset() {
return region.getOffset();
}
public int getLength() {
return region.getLength();
}
}
private static class LineInfo implements IRegion {
final int offset;
final int length;
final int trimmedOffset;
final int trimmedEndOffset;
boolean nonComment;
LineInfo(IDocument document, int line) throws BadLocationException {
offset = document.getLineOffset(line);
length = document.getLineLength(line);
int begin = offset;
int end = offset + length;
while (--end >= begin && Character.isWhitespace(document.getChar(end))) {
}
end++;
while (begin < end && Character.isWhitespace(document.getChar(begin))) {
begin++;
}
trimmedOffset = begin;
trimmedEndOffset = end;
}
/**
* Offset of the line in the document.
*/
public int getOffset() {
return offset;
}
/**
* Length of the line including line delimiter.
*/
public int getLength() {
return length;
}
/**
* End offset of the line including line delimiter.
*/
public int getEndOffset() {
return offset + length;
}
/**
* Document offset of the first non-whitespace character of the line.
*/
public int getTrimmedOffset() {
return trimmedOffset;
}
/**
* Document offset after the last non-whitespace character of the line.
*/
public int getTrimmedEndOffset() {
return trimmedEndOffset;
}
}
}

View file

@ -733,14 +733,14 @@ public class EditorUtility {
public static ICProject getCProject(IEditorInput input) { public static ICProject getCProject(IEditorInput input) {
ICProject cProject= null; ICProject cProject= null;
if (input instanceof IFileEditorInput) { if (input instanceof IFileEditorInput) {
IProject project= ((IFileEditorInput)input).getFile().getProject(); IProject project= ((IFileEditorInput) input).getFile().getProject();
if (project != null) { if (project != null) {
cProject= CoreModel.getDefault().create(project); cProject= CoreModel.getDefault().create(project);
if (!cProject.exists()) if (!cProject.exists())
cProject= null; cProject= null;
} }
} else if (input instanceof ITranslationUnitEditorInput) { } else if (input instanceof ITranslationUnitEditorInput) {
final ITranslationUnit tu= ((ITranslationUnitEditorInput)input).getTranslationUnit(); final ITranslationUnit tu= ((ITranslationUnitEditorInput) input).getTranslationUnit();
if (tu != null) { if (tu != null) {
cProject= tu.getCProject(); cProject= tu.getCProject();
} else if (input instanceof ExternalEditorInput) { } else if (input instanceof ExternalEditorInput) {

View file

@ -132,19 +132,26 @@ public class CdtActionConstants {
* (value <code>"org.eclipse.cdt.ui.actions.Format"</code>). * (value <code>"org.eclipse.cdt.ui.actions.Format"</code>).
*/ */
public static final String FORMAT= "org.eclipse.cdt.ui.actions.Format"; //$NON-NLS-1$ public static final String FORMAT= "org.eclipse.cdt.ui.actions.Format"; //$NON-NLS-1$
/** /**
* Source menu: name of standard Add Include global action * Source menu: name of standard Add Include global action
* (value <code>"org.eclipse.cdt.ui.actions.AddInclude"</code>). * (value <code>"org.eclipse.cdt.ui.actions.AddInclude"</code>).
*/ */
public static final String ADD_INCLUDE= "org.eclipse.cdt.ui.actions.AddInclude"; //$NON-NLS-1$ public static final String ADD_INCLUDE= "org.eclipse.cdt.ui.actions.AddInclude"; //$NON-NLS-1$
/**
* Source menu: name of standard Sort Lines global action
* (value <code>"org.eclipse.cdt.ui.actions.SortLines"</code>).
* @since 5.2
*/
public static final String SORT_LINES= "org.eclipse.cdt.ui.actions.SortLines"; //$NON-NLS-1$
/** /**
* Source menu: name of standard Sort Members global action (value * Source menu: name of standard Sort Members global action (value
* <code>"org.eclipse.cdt.ui.actions.SortMembers"</code>). * <code>"org.eclipse.cdt.ui.actions.SortMembers"</code>).
*/ */
public static final String SORT_MEMBERS= "org.eclipse.cdt.ui.actions.SortMembers"; //$NON-NLS-1$ public static final String SORT_MEMBERS= "org.eclipse.cdt.ui.actions.SortMembers"; //$NON-NLS-1$
/** /**
* Source menu: name of standard Surround with try/catch block global action * Source menu: name of standard Surround with try/catch block global action
* (value <code>"org.eclipse.cdt.ui.actions.SurroundWithTryCatch"</code>). * (value <code>"org.eclipse.cdt.ui.actions.SurroundWithTryCatch"</code>).

View file

@ -52,6 +52,7 @@ import org.eclipse.cdt.internal.ui.actions.CDTQuickMenuCreator;
import org.eclipse.cdt.internal.ui.editor.AddIncludeOnSelectionAction; import org.eclipse.cdt.internal.ui.editor.AddIncludeOnSelectionAction;
import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.editor.ICEditorActionDefinitionIds; import org.eclipse.cdt.internal.ui.editor.ICEditorActionDefinitionIds;
import org.eclipse.cdt.internal.ui.editor.SortLinesAction;
/** /**
* Action group that adds the source and generate actions to a part's context * Action group that adds the source and generate actions to a part's context
@ -129,6 +130,7 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
// //
// private OrganizeIncludesAction fOrganizeIncludes; // private OrganizeIncludesAction fOrganizeIncludes;
// private SortMembersAction fSortMembers; // private SortMembersAction fSortMembers;
private SortLinesAction fSortLines;
// private FormatAllAction fFormatAll; // private FormatAllAction fFormatAll;
// private CopyQualifiedNameAction fCopyQualifiedNameAction; // private CopyQualifiedNameAction fCopyQualifiedNameAction;
// //
@ -161,7 +163,11 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
// fSortMembers= new SortMembersAction(editor); // fSortMembers= new SortMembersAction(editor);
// fSortMembers.setActionDefinitionId(ICEditorActionDefinitionIds.SORT_MEMBERS); // fSortMembers.setActionDefinitionId(ICEditorActionDefinitionIds.SORT_MEMBERS);
// editor.setAction("SortMembers", fSortMembers); //$NON-NLS-1$ // editor.setAction("SortMembers", fSortMembers); //$NON-NLS-1$
//
fSortLines= new SortLinesAction(editor);
fSortLines.setActionDefinitionId(ICEditorActionDefinitionIds.SORT_LINES);
editor.setAction("SortLines", fSortLines); //$NON-NLS-1$
// IAction pastAction= editor.getAction(ITextEditorActionConstants.PASTE);//IWorkbenchActionDefinitionIds.PASTE); // IAction pastAction= editor.getAction(ITextEditorActionConstants.PASTE);//IWorkbenchActionDefinitionIds.PASTE);
// fCopyQualifiedNameAction= new CopyQualifiedNameAction(editor, null, pastAction); // fCopyQualifiedNameAction= new CopyQualifiedNameAction(editor, null, pastAction);
// fCopyQualifiedNameAction.setActionDefinitionId(CopyQualifiedNameAction.JAVA_EDITOR_ACTION_DEFINITIONS_ID); // fCopyQualifiedNameAction.setActionDefinitionId(CopyQualifiedNameAction.JAVA_EDITOR_ACTION_DEFINITIONS_ID);
@ -412,6 +418,7 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
added+= addAction(source, fAddInclude); added+= addAction(source, fAddInclude);
// added+= addAction(source, fOrganizeIncludes); // added+= addAction(source, fOrganizeIncludes);
// added+= addAction(source, fSortMembers); // added+= addAction(source, fSortMembers);
added+= addAction(source, fSortLines);
// added+= addAction(source, fCleanUp); // added+= addAction(source, fCleanUp);
source.add(new Separator(GROUP_GENERATE)); source.add(new Separator(GROUP_GENERATE));
// added+= addAction(source, fOverrideMethods); // added+= addAction(source, fOverrideMethods);