### Eclipse Workspace Patch 1.0 #P org.jboss.tools.vpe Index: src/org/jboss/tools/vpe/editor/VpeController.java =================================================================== --- src/org/jboss/tools/vpe/editor/VpeController.java (revision 37991) +++ src/org/jboss/tools/vpe/editor/VpeController.java (working copy) @@ -32,12 +32,14 @@ import org.eclipse.jface.bindings.keys.KeySequence; import org.eclipse.jface.bindings.keys.KeyStroke; import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; import org.eclipse.swt.custom.LineStyleEvent; import org.eclipse.swt.custom.LineStyleListener; import org.eclipse.swt.custom.StyleRange; @@ -46,6 +48,10 @@ import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.events.MenuListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; @@ -56,6 +62,8 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Scrollable; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; @@ -150,17 +158,25 @@ import org.jboss.tools.vpe.resref.core.RelativeFolderReferenceList; import org.jboss.tools.vpe.resref.core.TaglibReferenceList; import org.jboss.tools.vpe.xulrunner.editor.XulRunnerEditor; +import org.mozilla.interfaces.nsIBaseWindow; import org.mozilla.interfaces.nsIDOMDocument; import org.mozilla.interfaces.nsIDOMElement; import org.mozilla.interfaces.nsIDOMEvent; +import org.mozilla.interfaces.nsIDOMEventListener; +import org.mozilla.interfaces.nsIDOMEventTarget; import org.mozilla.interfaces.nsIDOMKeyEvent; import org.mozilla.interfaces.nsIDOMMouseEvent; import org.mozilla.interfaces.nsIDOMMutationEvent; import org.mozilla.interfaces.nsIDOMNSUIEvent; import org.mozilla.interfaces.nsIDOMNode; +import org.mozilla.interfaces.nsIDOMWindow; +import org.mozilla.interfaces.nsIDOMWindowInternal; import org.mozilla.interfaces.nsISelection; import org.mozilla.interfaces.nsISelectionDisplay; import org.mozilla.interfaces.nsISelectionListener; +import org.mozilla.interfaces.nsISupports; +import org.mozilla.interfaces.nsIWebBrowser; +import org.mozilla.xpcom.XPCOMException; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -175,6 +191,17 @@ MozillaContextMenuListener, MozillaResizeListener, MozillaAfterPaintListener, MozillaScrollListener { + /* + * https://issues.jboss.org/browse/JBIDE-8701 + * Scroll listeners staff. + */ + private SelectionListener sourceScrollSelectionListener; + private ScrollBar sourceVB; + private nsIDOMEventListener visualScrollListener; + private nsIDOMEventTarget domEventTarget; + private boolean sourceScrollEvent = false; + private boolean visualScrollEvent = false; + public static final int DEFAULT_UPDATE_DELAY_TIME = 400; private boolean visualEditorVisible = true; private boolean synced = true; @@ -335,12 +362,100 @@ // sourceEditor.getViewerSelectionManager(); // selectionManager.addNodeSelectionListener(this); // selectionManager.addTextSelectionListener(this); - StyledText textWidget = SelectionHelper - .getSourceTextWidget(sourceEditor); + final StyledText textWidget = SelectionHelper.getSourceTextWidget(sourceEditor); if (textWidget != null) { textWidget.addSelectionListener(this); } - + /* + * Add ScrollBar Listeners + */ + if ((visualEditor != null) && (sourceEditor != null)) { + sourceVB = textWidget.getVerticalBar(); + if (sourceVB != null) { + if (visualEditor.getXulRunnerEditor() != null) { + nsIWebBrowser webBrowser = visualEditor.getXulRunnerEditor().getWebBrowser(); + if (webBrowser != null) { + /* + * Initialize source and visual bars + */ + final nsIDOMWindow domWindow = webBrowser.getContentDOMWindow(); + final nsIDOMWindowInternal windowInternal = org.jboss.tools.vpe.xulrunner.util.XPCOM + .queryInterface(domWindow, nsIDOMWindowInternal.class); + /* + * Adding source listener + */ + sourceScrollSelectionListener = new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + sourceScrollEvent = true; + if (!visualScrollEvent) { // ignore my visual scroll event + removeVisualScrollListener(); + ScrollBar sb = (ScrollBar)e.widget; + int pageYOffsetSrc = sb.getSelection(); + int scrollMaxYSrc = sb.getMaximum() - sb.getThumb(); + float percentsSrc = ((float)pageYOffsetSrc/scrollMaxYSrc); + if (getVisualScrollBar() != null) { + int scrollMaxYVisual = -1; + scrollMaxYVisual = windowInternal.getScrollMaxY(); + if (scrollMaxYVisual != 0 && scrollMaxYVisual != -1) { + // there is a visual scroll bar + int posY = ((int) (scrollMaxYVisual*percentsSrc)); + domWindow.scrollTo(windowInternal.getPageXOffset(),posY); + } + } + addVisualScrollListener(); + } else { + visualScrollEvent = false; + } + } + @Override + public void widgetDefaultSelected(SelectionEvent e) { } + }; + sourceVB.addSelectionListener(sourceScrollSelectionListener); + /* + * Adding visual listener + */ + visualScrollListener = new nsIDOMEventListener() { + public nsISupports queryInterface(String interfaceId) { + return interfaceId.equals(nsIDOMEventListener.NS_IDOMEVENTLISTENER_IID) ? this : null; + } + public void handleEvent(nsIDOMEvent event) { + visualScrollEvent = true; + if (!sourceScrollEvent) { // ignore my event from source + removeSourceScrollListener(); + nsIDOMWindowInternal windowInternal = org.jboss.tools.vpe.xulrunner.util.XPCOM + .queryInterface(domWindow, nsIDOMWindowInternal.class); + int pageYOffsetVisual = windowInternal.getPageYOffset(); + int scrollMaxYVisual = windowInternal.getScrollMaxY(); + float percentsVisual = ((float)pageYOffsetVisual/scrollMaxYVisual); + ScrollBar sb = getSourceScrollBar(); + if (sb != null) { + int scrollMaxYSrc = -1; + scrollMaxYSrc = sb.getMaximum();// - sb.getThumb(); + if (scrollMaxYSrc != 1 && scrollMaxYSrc != -1) { + // there is a source scroll bar + int posY = ((int) (scrollMaxYSrc*percentsVisual)); + sb.setSelection(posY); +// textWidget.setSelection(posY); // set text position (in symbols) +// textWidget.scroll(destX, destY, x, y, width, height, all); + } + } + addSourceScrollListener(); + } else { + sourceScrollEvent = false; + } + } + }; + try { + domEventTarget = queryInterface(domWindow, nsIDOMEventTarget.class); + domEventTarget.addEventListener("scroll", visualScrollListener, false); + } catch (XPCOMException e) { + VpePlugin.getDefault().logError(e); + } + } + } + } + } registerEventTargets(); if (optionsListener == null) { @@ -378,6 +493,38 @@ refreshCommands(); } + private ScrollBar getSourceScrollBar() { + return sourceVB; + } + + private nsIDOMEventTarget getVisualScrollBar() { + return domEventTarget; + } + + private void removeSourceScrollListener() { + if (sourceVB != null && sourceScrollSelectionListener != null) { + sourceVB.removeSelectionListener(sourceScrollSelectionListener); + } + } + + private void addSourceScrollListener() { + if (sourceVB != null && sourceScrollSelectionListener != null) { + sourceVB.addSelectionListener(sourceScrollSelectionListener); + } + } + + private void removeVisualScrollListener() { + if (domEventTarget != null && visualScrollListener != null) { + domEventTarget.removeEventListener("scroll", visualScrollListener, false); + } + } + + private void addVisualScrollListener() { + if (domEventTarget != null && visualScrollListener != null) { + domEventTarget.addEventListener("scroll", visualScrollListener, false); + } + } + public void dispose() { if (job != null) { job.cancel(); @@ -958,8 +1105,8 @@ } onRefresh(); } - + public boolean isKeyBinding(Event keyboardEvent) { boolean keyBindingPressed = false; List possibleKeyStrokes = WorkbenchKeyboard @@ -1064,6 +1211,7 @@ if (uiJob != null && uiJob.getState() != Job.NONE) { return; } + if (visualRefreshJob == null || visualRefreshJob.getState() == Job.NONE) { visualRefreshJob = new UIJob(VpeUIMessages.VPE_VISUAL_REFRESH_JOB) { @Override @@ -1768,10 +1916,10 @@ public void setZoomEventManager(IZoomEventManager zoomEventManager) { this.zoomEventManager = zoomEventManager; - } + } - + public VpeDropWindow getDropWindow() { return dropWindow; }