blob: 939bf58d35d0108bc509cc659434d2e2ef9a0b60 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.compare.internal;
import java.util.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.graphics.Font;
import org.eclipse.jface.action.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.text.*;
import org.eclipse.jface.text.source.*;
import org.eclipse.jface.viewers.SelectionChangedEvent;
/**
* Extends the JFace SourceViewer with some convenience methods.
*/
public class MergeSourceViewer extends SourceViewer
implements ISelectionChangedListener, ITextListener, IMenuListener {
public static final String UNDO_ID= "undo"; //$NON-NLS-1$
public static final String REDO_ID= "redo"; //$NON-NLS-1$
public static final String CUT_ID= "cut"; //$NON-NLS-1$
public static final String COPY_ID= "copy"; //$NON-NLS-1$
public static final String PASTE_ID= "paste"; //$NON-NLS-1$
public static final String DELETE_ID= "delete"; //$NON-NLS-1$
public static final String SELECT_ALL_ID= "selectAll"; //$NON-NLS-1$
public static final String SAVE_ID= "save"; //$NON-NLS-1$
class TextOperationAction extends MergeViewerAction {
private int fOperationCode;
TextOperationAction(int operationCode, boolean mutable, boolean selection, boolean content) {
super(mutable, selection, content);
fOperationCode= operationCode;
update();
}
public void run() {
if (isEnabled())
doOperation(fOperationCode);
}
public boolean isEnabled() {
return fOperationCode != -1 && canDoOperation(fOperationCode);
}
public void update() {
this.setEnabled(isEnabled());
}
}
private ResourceBundle fResourceBundle;
private Position fRegion;
private boolean fEnabled= true;
private HashMap fActions= new HashMap();
private boolean fAddSaveAction= true;
public MergeSourceViewer(Composite parent, ResourceBundle bundle) {
super(parent, null, SWT.H_SCROLL + SWT.V_SCROLL);
fResourceBundle= bundle;
MenuManager menu= new MenuManager();
menu.setRemoveAllWhenShown(true);
menu.addMenuListener(this);
StyledText te= getTextWidget();
te.setMenu(menu.createContextMenu(te));
}
public void hideSaveAction() {
fAddSaveAction= false;
}
public void setFont(Font font) {
StyledText te= getTextWidget();
if (te != null)
te.setFont(font);
}
public void setBackgroundColor(Color color) {
StyledText te= getTextWidget();
if (te != null)
te.setBackground(color);
}
public void setEnabled(boolean enabled) {
if (enabled != fEnabled) {
fEnabled= enabled;
StyledText c= getTextWidget();
if (c != null) {
c.setEnabled(enabled);
Display d= c.getDisplay();
c.setBackground(enabled ? d.getSystemColor(SWT.COLOR_LIST_BACKGROUND) : null);
}
}
}
public boolean getEnabled() {
return fEnabled;
}
public void setRegion(Position region) {
fRegion= region;
}
public Position getRegion() {
return fRegion;
}
public boolean isControlOkToUse() {
StyledText t= getTextWidget();
return t != null && !t.isDisposed();
}
public void setSelection(Position position) {
if (position != null)
setSelectedRange(position.getOffset(), position.getLength());
}
public void setLineBackground(Position position, Color c) {
StyledText t= getTextWidget();
if (t != null && !t.isDisposed()) {
Point region= new Point(0, 0);
getLineRange(position, region);
region.x-= getDocumentRegionOffset();
try {
t.setLineBackground(region.x, region.y, c);
} catch (IllegalArgumentException ex) {
}
}
}
public void resetLineBackground() {
StyledText t= getTextWidget();
if (t != null && !t.isDisposed()) {
int lines= getLineCount();
t.setLineBackground(0, lines, null);
}
}
/**
* Returns number of lines in document region.
*/
public int getLineCount() {
IRegion region= getVisibleRegion();
int length= region.getLength();
if (length == 0)
return 0;
IDocument doc= getDocument();
int startLine= 0;
int endLine= 0;
int start= region.getOffset();
try {
startLine= doc.getLineOfOffset(start);
} catch(BadLocationException ex) {
}
try {
endLine= doc.getLineOfOffset(start+length);
} catch(BadLocationException ex) {
}
return endLine-startLine+1;
}
public int getViewportLines() {
StyledText te= getTextWidget();
Rectangle clArea= te.getClientArea();
if (!clArea.isEmpty())
return clArea.height / te.getLineHeight();
return 0;
}
public int getViewportHeight() {
StyledText te= getTextWidget();
Rectangle clArea= te.getClientArea();
if (!clArea.isEmpty())
return clArea.height;
return 0;
}
/**
* Returns lines
*/
public int getDocumentRegionOffset() {
int start= getVisibleRegion().getOffset();
IDocument doc= getDocument();
if (doc != null) {
try {
return doc.getLineOfOffset(start);
} catch(BadLocationException ex) {
}
}
return 0;
}
public int getVerticalScrollOffset() {
StyledText st= getTextWidget();
int lineHeight= st.getLineHeight();
return getTopInset() - ((getDocumentRegionOffset()*lineHeight) + st.getTopPixel());
}
/**
* Returns the start line and the number of lines which correspond to the given position.
* Starting line number is 0 based.
*/
public Point getLineRange(Position p, Point region) {
IDocument doc= getDocument();
if (p == null || doc == null) {
region.x= 0;
region.y= 0;
return region;
}
int start= p.getOffset();
int length= p.getLength();
int startLine= 0;
try {
startLine= doc.getLineOfOffset(start);
} catch (BadLocationException e) {
}
int lineCount= 0;
if (length == 0) {
// // if range length is 0 and if range starts a new line
// try {
// if (start == doc.getLineStartOffset(startLine)) {
// lines--;
// }
// } catch (BadLocationException e) {
// lines--;
// }
} else {
int endLine= 0;
try {
endLine= doc.getLineOfOffset(start + length - 1); // why -1?
} catch (BadLocationException e) {
}
lineCount= endLine-startLine+1;
}
region.x= startLine;
region.y= lineCount;
return region;
}
/**
* Scroll TextPart to the given line.
*/
public void vscroll(int line) {
int srcViewSize= getLineCount();
int srcExtentSize= getViewportLines();
if (srcViewSize > srcExtentSize) {
if (line < 0)
line= 0;
int cp= getTopIndex();
if (cp != line)
setTopIndex(line + getDocumentRegionOffset());
}
}
public void addAction(String actionId, MergeViewerAction action) {
fActions.put(actionId, action);
}
public MergeViewerAction getAction(String actionId) {
MergeViewerAction action= (MergeViewerAction) fActions.get(actionId);
if (action == null) {
action= createAction(actionId);
if (action == null)
return null;
if (action.isContentDependent())
addTextListener(this);
if (action.isSelectionDependent())
addSelectionChangedListener(this);
Utilities.initAction(action, fResourceBundle, "action." + actionId + "."); //$NON-NLS-1$ //$NON-NLS-2$
fActions.put(actionId, action);
}
if (action.isEditableDependent() && !isEditable())
return null;
return action;
}
protected MergeViewerAction createAction(String actionId) {
if (UNDO_ID.equals(actionId))
return new TextOperationAction(UNDO, true, false, true);
if (REDO_ID.equals(actionId))
return new TextOperationAction(REDO, true, false, true);
if (CUT_ID.equals(actionId))
return new TextOperationAction(CUT, true, true, false);
if (COPY_ID.equals(actionId))
return new TextOperationAction(COPY, false, true, false);
if (PASTE_ID.equals(actionId))
return new TextOperationAction(PASTE, true, false, false);
if (DELETE_ID.equals(actionId))
return new TextOperationAction(DELETE, true, false, false);
if (SELECT_ALL_ID.equals(actionId))
return new TextOperationAction(SELECT_ALL, false, false, false);
return null;
}
public void selectionChanged(SelectionChangedEvent event) {
Iterator e= fActions.values().iterator();
while (e.hasNext()) {
MergeViewerAction action= (MergeViewerAction) e.next();
if (action.isSelectionDependent())
action.update();
}
}
public void textChanged(TextEvent event) {
Iterator e= fActions.values().iterator();
while (e.hasNext()) {
MergeViewerAction action= (MergeViewerAction) e.next();
if (action.isContentDependent())
action.update();
}
}
/**
* Allows the viewer to add menus and/or tools to the context menu.
*/
public void menuAboutToShow(IMenuManager menu) {
menu.add(new Separator("undo")); //$NON-NLS-1$
addMenu(menu, UNDO_ID);
addMenu(menu, REDO_ID);
menu.add(new Separator("ccp")); //$NON-NLS-1$
addMenu(menu, CUT_ID);
addMenu(menu, COPY_ID);
addMenu(menu, PASTE_ID);
addMenu(menu, DELETE_ID);
addMenu(menu, SELECT_ALL_ID);
menu.add(new Separator("edit")); //$NON-NLS-1$
menu.add(new Separator("find")); //$NON-NLS-1$
//addMenu(menu, FIND_ID);
menu.add(new Separator("save")); //$NON-NLS-1$
if (fAddSaveAction)
addMenu(menu, SAVE_ID);
menu.add(new Separator("rest")); //$NON-NLS-1$
}
private void addMenu(IMenuManager menu, String actionId) {
IAction action= getAction(actionId);
if (action != null)
menu.add(action);
}
protected void handleDispose() {
removeTextListener(this);
removeSelectionChangedListener(this);
super.handleDispose();
}
}