/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2017 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package org.pentaho.di.ui.spoon;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Control;
import org.pentaho.di.core.Const;
import org.pentaho.di.ui.spoon.trans.TransGraph;
import java.util.function.Consumer;
import java.util.function.Supplier;
public final class ExpandedContentManager {
static Supplier<Spoon> spoonSupplier = Spoon::getInstance;
/**
* The value of the most recent URL navigated to.
* Storing this value is useful because in some Operating Systems the internal browser implementations used via the
* SWT browser widget seem to always return the same URL when a new value is set that only contains changes in its
* hash section.
*/
static String lastNavigateURL;
/**
* isBrowserVisible
*
* @return a boolean that represents that the web browser is the topmost control of the active TransGraph. If browser
* hasn't been created it will return false.
*/
public static boolean isVisible() {
return isVisible( spoonInstance().getActiveTransGraph() );
}
/**
* isBrowserVisible( TransGraph graph )
*
* @param graph
* a TransGraph object that is being interrogated to see if the web browser is the topmost control
* @return true if the web browser is the topmost control of the graph
*/
public static boolean isVisible( TransGraph graph ) {
if ( graph != null ) {
if ( graph.getChildren().length > 0 ) {
return graph.getChildren()[0] instanceof Browser;
}
}
return false;
}
/**
* createExpandedContent
*
* creates a web browser for the current TransGraph
*/
public static void createExpandedContent( String url ) {
createExpandedContent( spoonInstance().getActiveTransGraph(), url );
}
/**
* createExpandedContent( TransGraph parent )
*
* Create a web browser for the TransGraph argument.
*
* @param parent
* a TransGraph that will be the parent of the web browser.
* @param url
* The content to open and expand
*/
public static void createExpandedContent( TransGraph parent, String url ) {
if ( parent == null ) {
return;
}
Browser browser = getExpandedContentForTransGraph( parent );
if ( browser == null ) {
browser = new Browser( parent, SWT.NONE );
browser.addKeyListener( new KeyListener() {
@Override public void keyPressed( KeyEvent keyEvent ) {
int state = keyEvent.stateMask, key = keyEvent.keyCode;
boolean copyContent = state == SWT.CTRL && key == SWT.F6,
arrowNavigation = ( state == SWT.COMMAND || state == SWT.ALT )
&& ( key == SWT.ARROW_LEFT || key == SWT.ARROW_RIGHT ),
backslashNavigation = ( state == SWT.SHIFT && key == SWT.BS ),
reloadContent = state == SWT.CTRL && ( key == SWT.F5 || key == 114 /* r key */ ) || key == SWT.F5,
zoomContent = state == SWT.CTRL && ( key == SWT.KEYPAD_ADD || key == SWT.KEYPAD_SUBTRACT
|| key == 61 /* + key */ || key == 45 /* - key */ );
if ( copyContent ) {
Browser thisBrowser = (Browser) keyEvent.getSource();
Clipboard clipboard = new Clipboard( thisBrowser.getDisplay() );
clipboard.setContents( new String[] { lastNavigateURL }, new Transfer[] { TextTransfer.getInstance() } );
clipboard.dispose();
} else if ( arrowNavigation || backslashNavigation || reloadContent || zoomContent ) {
keyEvent.doit = false;
}
}
@Override public void keyReleased( KeyEvent keyEvent ) {
}
} );
}
browser.setUrl( url );
lastNavigateURL = url;
}
/**
* showTransformationBrowser
*
* Creates and shows the web browser for the active TransGraph
*/
public static void showExpandedContent() {
showExpandedContent( spoonInstance().getActiveTransGraph() );
}
/**
* showExpandedContent( TransGraph graph )
*
* @param graph
* TransGraph to create the web browser for. If the wev browser hasn't been created this will create one.
* Else it will just bring the web browser associated to this TransGraph to the top.
*/
public static void showExpandedContent( TransGraph graph ) {
if ( graph == null ) {
return;
}
Browser browser = getExpandedContentForTransGraph( graph );
if ( browser == null ) {
return;
}
if ( !isVisible( graph ) ) {
maximizeExpandedContent( browser );
}
if ( Const.isOSX() && graph.isExecutionResultsPaneVisible() ) {
graph.extraViewComposite.setVisible( false );
}
browser.moveAbove( null );
browser.getParent().layout( true );
browser.getParent().redraw();
}
/**
* getExpandedContentForTransGraph
*
* @param graph
* a TransGraph object that will be interrogated for a web browser
* @return a web browser that is associated with the TransGraph or null if it has yet to be created.
*/
public static Browser getExpandedContentForTransGraph( TransGraph graph ) {
for ( Control control : graph.getChildren() ) {
if ( control instanceof Browser ) {
return (Browser) control;
}
}
return null;
}
/**
* hideExpandedContent
*
* hides the web browser associated with the active TransGraph
*/
public static void hideExpandedContent() {
hideExpandedContent( spoonInstance().getActiveTransGraph() );
}
/**
* closeExpandedContent
*
* closes the web browser associated with the active TransGraph
*/
public static void closeExpandedContent() {
closeExpandedContent( spoonInstance().getActiveTransGraph() );
}
/**
* hideExpandedContent( TransGraph graph )
*
* @param graph
* the TransGraph whose web browser will be hidden
*/
public static void hideExpandedContent( TransGraph graph ) {
doToExpandedContent( graph, browser -> {
if ( Const.isOSX() && graph.isExecutionResultsPaneVisible() ) {
graph.extraViewComposite.setVisible( true );
}
browser.moveBelow( null );
browser.getParent().layout( true, true );
browser.getParent().redraw();
} );
}
/**
* closeExpandedContent( TransGraph graph )
*
* @param graph
* the TransGraph whose web browser will be closed
*/
public static void closeExpandedContent( TransGraph graph ) {
doToExpandedContent( graph, Browser::close );
}
/**
* doToExpandedContent( TransGraph graph )
*
* @param graph
* the TransGraph whose web browser will be hidden
* @param browserAction Consumer for acting on the browser
*/
private static void doToExpandedContent( TransGraph graph, Consumer<Browser> browserAction ) {
Browser browser = getExpandedContentForTransGraph( graph );
if ( browser == null ) {
return;
}
SashForm sash = (SashForm) spoonInstance().getDesignParent();
sash.setWeights( spoonInstance().getTabSet().getSelected().getSashWeights() );
browserAction.accept( browser );
}
private static Spoon spoonInstance() {
return spoonSupplier.get();
}
/**
* maximizeBrowser
*
* @param browser
* the browser object to maximize. We try to take up as much of the Spoon window as possible.
*/
private static void maximizeExpandedContent( Browser browser ) {
SashForm sash = (SashForm) spoonInstance().getDesignParent();
int[] weights = sash.getWeights();
int[] savedSashWeights = new int[weights.length];
System.arraycopy( weights, 0, savedSashWeights, 0, weights.length );
spoonInstance().getTabSet().getSelected().setSashWeights( savedSashWeights );
weights[0] = 0;
weights[1] = 1000;
sash.setWeights( weights );
FormData formData = new FormData();
formData.top = new FormAttachment( 0, 0 );
formData.left = new FormAttachment( 0, 0 );
formData.bottom = new FormAttachment( 100, 0 );
formData.right = new FormAttachment( 100, 0 );
browser.setLayoutData( formData );
browser.getParent().layout( true );
browser.getParent().redraw();
}
}