001: /*****************************************************************************************
002: * Copyright (c) 2004 Andrei Loskutov. All rights reserved. This program and the
003: * accompanying materials are made available under the terms of the BSD License which
004: * accompanies this distribution, and is available at
005: * http://www.opensource.org/licenses/bsd-license.php Contributor: Andrei Loskutov -
006: * initial API and implementation
007: ****************************************************************************************/package de.loskutov.bco.compare;
008:
009: import java.lang.reflect.Field;
010:
011: import org.eclipse.compare.CompareConfiguration;
012: import org.eclipse.compare.CompareEditorInput;
013: import org.eclipse.compare.CompareUI;
014: import org.eclipse.compare.CompareViewerPane;
015: import org.eclipse.compare.CompareViewerSwitchingPane;
016: import org.eclipse.compare.structuremergeviewer.Differencer;
017: import org.eclipse.core.runtime.IProgressMonitor;
018: import org.eclipse.core.runtime.OperationCanceledException;
019: import org.eclipse.core.runtime.SubProgressMonitor;
020: import org.eclipse.jface.action.Action;
021: import org.eclipse.jface.action.Separator;
022: import org.eclipse.jface.action.ToolBarManager;
023: import org.eclipse.swt.widgets.Composite;
024: import org.eclipse.swt.widgets.Control;
025: import org.eclipse.ui.IReusableEditor;
026:
027: import de.loskutov.bco.preferences.BCOConstants;
028: import de.loskutov.bco.ui.actions.DefaultToggleAction;
029:
030: /**
031: */
032: public class BytecodeCompare extends CompareEditorInput {
033:
034: /** Stores reference to the element displayed on the left side of the viewer. */
035: protected TypedElement left;
036: /** Stores reference to the element displayed on the right side of the viewer. */
037: protected TypedElement right;
038: /** Action used in compare view/bytecode view to toggle asmifier mode on/off */
039: protected Action toggleAsmifierModeAction;
040: /** Action used in compare view/bytecode view to hide/show line info. */
041: protected Action hideLineInfoAction;
042: /** Action used in compare view/bytecode view to hide/show local variables. */
043: protected Action hideLocalsAction;
044: protected Action hideStackMapAction;
045: protected Action expandStackMapAction;
046:
047: protected IReusableEditor myEditor;
048:
049: /**
050: * Constructor for PerforceCompareEditorInput.
051: * @param left element displayed on the left.
052: * @param right element displayed on the right.
053: */
054: public BytecodeCompare(TypedElement left, TypedElement right) {
055: super (new CompareConfiguration());
056: this .left = left;
057: this .right = right;
058: toggleAsmifierModeAction = new DefaultToggleAction(
059: BCOConstants.DIFF_SHOW_ASMIFIER_CODE) {
060:
061: public void run(boolean newState) {
062: toggleMode(BCOConstants.F_SHOW_ASMIFIER_CODE, newState,
063: newState);
064: }
065: };
066:
067: hideLineInfoAction = new DefaultToggleAction(
068: BCOConstants.DIFF_SHOW_LINE_INFO) {
069:
070: public void run(boolean newState) {
071: toggleMode(BCOConstants.F_SHOW_LINE_INFO, newState,
072: toggleAsmifierModeAction.isChecked());
073: }
074: };
075:
076: hideLocalsAction = new DefaultToggleAction(
077: BCOConstants.DIFF_SHOW_VARIABLES) {
078:
079: public void run(boolean newState) {
080: toggleMode(BCOConstants.F_SHOW_VARIABLES, newState,
081: toggleAsmifierModeAction.isChecked());
082: }
083: };
084:
085: hideStackMapAction = new DefaultToggleAction(
086: BCOConstants.DIFF_SHOW_STACKMAP) {
087:
088: public void run(boolean newState) {
089: toggleMode(BCOConstants.F_SHOW_STACKMAP, newState,
090: toggleAsmifierModeAction.isChecked());
091: }
092: };
093:
094: expandStackMapAction = new DefaultToggleAction(
095: BCOConstants.DIFF_EXPAND_STACKMAP) {
096:
097: public void run(boolean newState) {
098: toggleMode(BCOConstants.F_EXPAND_STACKMAP, newState,
099: toggleAsmifierModeAction.isChecked());
100: }
101: };
102: }
103:
104: /** @see CompareEditorInput#prepareInput(IProgressMonitor) */
105: protected Object prepareInput(IProgressMonitor monitor)
106: throws InterruptedException {
107: if (right == null || left == null) {
108: return null;
109: }
110:
111: try {
112: initLabels();
113: Differencer differencer = new Differencer();
114: monitor.beginTask("Bytecode Outline: comparing...", 30); //$NON-NLS-1$
115: IProgressMonitor sub = new SubProgressMonitor(monitor, 10);
116: try {
117: sub.beginTask("Bytecode Outline: comparing...", 100); //$NON-NLS-1$
118:
119: return differencer.findDifferences(false, sub, null,
120: null, left, right);
121: } finally {
122: sub.done();
123: }
124: } catch (OperationCanceledException e) {
125: throw new InterruptedException(e.getMessage());
126: } finally {
127: monitor.done();
128: }
129: }
130:
131: /**
132: * Sets up the title and pane labels for the comparison view.
133: */
134: private void initLabels() {
135: CompareConfiguration cc = getCompareConfiguration();
136:
137: cc.setLeftLabel(left.getName());
138: cc.setLeftImage(left.getImage());
139:
140: cc.setRightLabel(right.getName());
141: cc.setRightImage(right.getImage());
142:
143: setTitle("Bytecode compare: " //$NON-NLS-1$
144: + left.getElementName()
145: + " - " + right.getElementName()); //$NON-NLS-1$
146: }
147:
148: public CompareViewerSwitchingPane getInputPane() {
149: try {
150: Field field = CompareEditorInput.class
151: .getDeclaredField("fContentInputPane");
152: field.setAccessible(true);
153: Object object = field.get(this );
154: if (object instanceof CompareViewerSwitchingPane) {
155: return (CompareViewerSwitchingPane) object;
156: }
157: } catch (Exception e) {
158: // ignore
159: }
160:
161: // does not work after changing content: this is a bug in CompareEditorInput, because
162: // navigator instance holds old (not up to date) instance of the input pane
163: // ICompareNavigator navigator = getNavigator();
164: // if(navigator instanceof CompareNavigator) {
165: // CompareNavigator compareNavigator = (CompareNavigator) navigator;
166: // try {
167: // Method method = compareNavigator.getClass().getDeclaredMethod(
168: // "getPanes", null);
169: // method.setAccessible(true);
170: // Object object = method.invoke(compareNavigator, null);
171: // if(object instanceof Object[]) {
172: // Object[] panes = (Object[]) object;
173: // if(panes.length == 4 && panes[3] instanceof CompareViewerSwitchingPane) {
174: // // there are 4 panels, last one is the input pane that we search for
175: // // see org.eclipse.compare.CompareEditorInput.getNavigator()
176: // return (CompareViewerSwitchingPane) panes[3];
177: // }
178: // }
179: // } catch (Exception e) {
180: // // ignore.
181: // }
182: // }
183: return null;
184: }
185:
186: /**
187: * @see org.eclipse.compare.CompareEditorInput#createContents(org.eclipse.swt.widgets.Composite)
188: */
189: public Control createContents(Composite parent) {
190: Object obj = parent.getData();
191: if (obj == null) {
192: obj = parent.getParent().getData();
193: }
194: // dirty hook on this place to get reference to editor
195: // CompareEditor extends EditorPart implements IReusableEditor
196: if (obj instanceof IReusableEditor) {
197: myEditor = (IReusableEditor) obj;
198: }
199:
200: Control control = super .createContents(parent);
201:
202: CompareViewerSwitchingPane inputPane = getInputPane();
203: if (inputPane != null) {
204: ToolBarManager toolBarManager2 = CompareViewerPane
205: .getToolBarManager(inputPane);
206: if (toolBarManager2 == null) {
207: return control;
208: }
209: boolean separatorExist = false;
210: if (toolBarManager2.find(hideLineInfoAction.getId()) == null) {
211: if (!separatorExist) {
212: separatorExist = true;
213: toolBarManager2.insert(0, new Separator("bco")); //$NON-NLS-1$
214: }
215: toolBarManager2.insertBefore("bco", hideLineInfoAction); //$NON-NLS-1$
216: // toolBarManager2.update(true);
217: }
218: if (toolBarManager2.find(hideLocalsAction.getId()) == null) {
219: if (!separatorExist) {
220: separatorExist = true;
221: toolBarManager2.insert(0, new Separator("bco")); //$NON-NLS-1$
222: }
223: toolBarManager2.insertBefore("bco", hideLocalsAction); //$NON-NLS-1$
224: // toolBarManager2.update(true);
225: }
226:
227: if (toolBarManager2.find(hideStackMapAction.getId()) == null) {
228: if (!separatorExist) {
229: separatorExist = true;
230: toolBarManager2.insert(0, new Separator("bco")); //$NON-NLS-1$
231: }
232: toolBarManager2.insertBefore("bco", hideStackMapAction); //$NON-NLS-1$
233: // toolBarManager2.update(true);
234: }
235: if (toolBarManager2.find(expandStackMapAction.getId()) == null) {
236: if (!separatorExist) {
237: separatorExist = true;
238: toolBarManager2.insert(0, new Separator("bco")); //$NON-NLS-1$
239: }
240: toolBarManager2.insertBefore(
241: "bco", expandStackMapAction); //$NON-NLS-1$
242: // toolBarManager2.update(true);
243: }
244:
245: if (toolBarManager2.find(toggleAsmifierModeAction.getId()) == null) {
246: if (!separatorExist) {
247: toolBarManager2.insert(0, new Separator("bco")); //$NON-NLS-1$
248: separatorExist = true;
249: }
250: toolBarManager2.insertBefore(
251: "bco", toggleAsmifierModeAction); //$NON-NLS-1$
252: // toolBarManager2.update(true);
253: }
254: try {
255: toolBarManager2.update(true);
256: toolBarManager2.getControl().getParent().layout(true);
257: toolBarManager2.getControl().getParent().update();
258: } catch (NullPointerException e) {
259: // ignore, i'm just curios why we need this code in 3.2 and expect
260: // some unwanted side effects...
261: }
262: }
263: return control;
264: }
265:
266: protected void toggleMode(int mode, boolean value,
267: boolean isASMifierMode) {
268: String contentType = isASMifierMode ? TypedElement.TYPE_ASM_IFIER
269: : TypedElement.TYPE_BYTECODE;
270:
271: left.setMode(mode, value);
272: left.setMode(BCOConstants.F_SHOW_ASMIFIER_CODE, isASMifierMode);
273: left.setType(contentType);
274:
275: right.setMode(mode, value);
276: right
277: .setMode(BCOConstants.F_SHOW_ASMIFIER_CODE,
278: isASMifierMode);
279: right.setType(contentType);
280:
281: // createDiffViewer.refresh();
282: // myEditor.setInput(this);
283: CompareUI.reuseCompareEditor(new BytecodeCompare(left, right),
284: myEditor);
285: // CompareUI.reuseCompareEditor(this, myEditor);
286: }
287: }
|