Krishnaveni
Krishnaveni

Reputation: 809

apply shift_right or shift_left on multiple lines

i have a source viewer. In this, i need to shift multiple lines to right, when tab is pressed and remove tab, on these lines, when Shift+Tab is pressed. Below is my code. I m not sure how to proceed further. Can you please suggest how this can be done.

public class MyViewer extends SourceViewer {
 public MyViewer(final Composite parent, final int styles) {
 super(parent, null, styles);

 final Font font = JFaceResources.getFont(MyConstants.EDITOR_TEXT_FONT);
 getTextWidget().setFont(font);

 getTextWidget().addTraverseListener(new TraverseListener() {

    public void keyTraversed(final TraverseEvent e) {
     if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
        if (areMultipleLinesSelected()) {
            e.doit = true;
            final ITextSelection textSelection = (ITextSelection) FastCodeTemplateViewer.this.getSelection();
         //what to do after this, to apply, SHIFT_LEFT or SHIFT_RIGHT, on the selected content
        }


}); 

@Override
   public void setDocument(final IDocument document) {
    ...
}

@Override
  public void setHyperlinkPresenter(final IHyperlinkPresenter hyperlinkPresenter) throws    IllegalStateException {
   ...
 }

}

Upvotes: 0

Views: 81

Answers (1)

Rüdiger Herrmann
Rüdiger Herrmann

Reputation: 20985

The SourceViewer already defines an operation to shift text left and right. There is no need to extend the SourceViewer. The operations can be invoked from the traverse listener just like this:

sourceViewer.getTextWidget().addTraverseListener( new TraverseListener() {
  @Override
  public void keyTraversed( TraverseEvent event ) {
    if( event.detail == SWT.TRAVERSE_TAB_NEXT ) {
      if( sourceViewer.canDoOperation( ITextOperationTarget.SHIFT_RIGHT ) ) {
        sourceViewer.doOperation( ITextOperationTarget.SHIFT_RIGHT );
      }
      event.doit = false;
    } else if( event.detail == SWT.TRAVERSE_TAB_PREVIOUS ) {
      if( sourceViewer.canDoOperation( ITextOperationTarget.SHIFT_LEFT ) ) {
        sourceViewer.doOperation( ITextOperationTarget.SHIFT_LEFT );
      }
      event.doit = false;
    }
  }
} );

Setting the doit flag to false prevents the traveral from taking place, i.e. transferring the focus to the previous/next control.

This has the side effect that the selection is replaced by a tab character after it was shifted. To prevent this, a VerifyKeyListener can help if it suppresses the tab key if anything is selected.

textViewer.prependVerifyKeyListener( new VerifyKeyListener() {
  @Override
  public void verifyKey( VerifyEvent verifyEvent ) {
    if( verifyEvent.keyCode == SWT.TAB && sourceViewer.getSelectedRange().y > 0 ) {
      verifyEvent.doit = false;
    }
  }
} );

You may figure out a less 'hacky' solution if you study the code of the Eclipse Text Editor which also offers this feature. In particualr the interaction between ShiftAction and TextEditor.

Upvotes: 1

Related Questions