package org.kettle.beam.perspective; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Composite; import org.pentaho.di.core.Const; import org.pentaho.di.core.EngineMetaInterface; import org.pentaho.di.core.logging.LogChannel; import org.pentaho.di.core.logging.LogChannelInterface; import org.pentaho.di.core.variables.VariableSpace; import org.pentaho.di.core.variables.Variables; import org.pentaho.di.i18n.BaseMessages; import org.pentaho.di.ui.core.PropsUI; import org.pentaho.di.ui.spoon.Spoon; import org.pentaho.di.ui.spoon.SpoonPerspective; import org.pentaho.di.ui.spoon.SpoonPerspectiveImageProvider; import org.pentaho.di.ui.spoon.SpoonPerspectiveListener; import org.pentaho.di.ui.spoon.XulSpoonResourceBundle; import org.pentaho.di.ui.xul.KettleXulLoader; import org.pentaho.ui.xul.XulComponent; import org.pentaho.ui.xul.XulDomContainer; import org.pentaho.ui.xul.XulException; import org.pentaho.ui.xul.XulOverlay; import org.pentaho.ui.xul.XulRunner; import org.pentaho.ui.xul.components.XulTab; import org.pentaho.ui.xul.components.XulTabpanel; import org.pentaho.ui.xul.containers.XulTabbox; import org.pentaho.ui.xul.containers.XulTabpanels; import org.pentaho.ui.xul.containers.XulTabs; import org.pentaho.ui.xul.containers.XulVbox; import org.pentaho.ui.xul.dom.Document; import org.pentaho.ui.xul.impl.AbstractXulEventHandler; import org.pentaho.ui.xul.impl.XulEventHandler; import org.pentaho.ui.xul.swt.tags.SwtDeck; import org.pentaho.ui.xul.swt.tags.SwtTab; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; public class BeamPerspective extends AbstractXulEventHandler implements SpoonPerspective, SpoonPerspectiveImageProvider, XulEventHandler { private static Class<?> PKG = BeamPerspective.class; private ResourceBundle resourceBundle = new XulSpoonResourceBundle( PKG ); final String PERSPECTIVE_ID = "031-beam"; //$NON-NLS-1$ final String PERSPECTIVE_NAME = "beamPerspective"; //$NON-NLS-1$ private XulDomContainer container; private BeamController controller; private BeamMenuController gitSpoonMenuController; private XulVbox box; private LogChannelInterface logger = LogChannel.GENERAL; protected XulRunner runner; protected Document document; protected XulTabs tabs; protected XulTabpanels panels; protected XulTabbox tabbox; protected List<SpoonPerspectiveListener> listeners = new ArrayList<>(); BeamPerspective() throws XulException { KettleXulLoader loader = new KettleXulLoader(); loader.registerClassLoader( getClass().getClassLoader() ); container = loader.loadXul( "beam_perspective.xul", resourceBundle ); try { document = container.getDocumentRoot(); tabs = (XulTabs) document.getElementById( "tabs" ); panels = (XulTabpanels) document.getElementById( "tabpanels" ); tabbox = (XulTabbox) tabs.getParent(); container.addEventHandler( this ); // addAdminTab(); /* * To make compatible with webSpoon * Create a temporary parent for the UI and then call layout(). * A different parent will be assigned to the UI in SpoonPerspectiveManager.PerspectiveManager.performInit(). SwtDeck deck = (SwtDeck) Spoon.getInstance().getXulDomContainer().getDocumentRoot().getElementById( "canvas-deck" ); box = deck.createVBoxCard(); getUI().setParent( (Composite) box.getManagedObject() ); getUI().layout(); */ } catch ( Exception e ) { logger.logError( "Error initializing perspective", e ); } } @Override public String getName() { return "beamPerspective"; } private void addAdminTab() throws Exception { final XulTabAndPanel tabAndPanel = createTab(); tabAndPanel.tab.setLabel( "Admin" ); PropsUI props = PropsUI.getInstance(); final Composite comp = (Composite) tabAndPanel.panel.getManagedObject(); props.setLook( comp ); comp.setLayout( new FillLayout() ); ScrolledComposite scrolledComposite = new ScrolledComposite( comp, SWT.V_SCROLL | SWT.H_SCROLL ); props.setLook( scrolledComposite ); scrolledComposite.setLayout( new FillLayout() ); final Composite parentComposite = new Composite( scrolledComposite, SWT.NONE ); props.setLook( parentComposite ); FormLayout formLayout = new FormLayout(); formLayout.marginLeft = 10; formLayout.marginRight = 10; formLayout.marginTop = 10; formLayout.marginBottom = 10; formLayout.spacing = Const.MARGIN; parentComposite.setLayout( formLayout ); parentComposite.layout( true ); parentComposite.pack(); // What's the size: Rectangle bounds = parentComposite.getBounds(); scrolledComposite.setContent( parentComposite ); scrolledComposite.setExpandHorizontal( true ); scrolledComposite.setExpandVertical( true ); scrolledComposite.setMinWidth( bounds.width ); scrolledComposite.setMinHeight( bounds.height ); comp.layout(); } /** * Gets controller * * @return value of controller */ public BeamController getController() { return this.controller; } @Override public String getPerspectiveIconPath() { return null; } @Override public String getId() { return PERSPECTIVE_ID; } @Override public Composite getUI() { return (Composite) container.getDocumentRoot().getRootElement().getFirstChild().getManagedObject(); } @Override public String getDisplayName( Locale locale ) { return BaseMessages.getString( PKG, "Neo4j.Perspective.perspectiveName" ); } @Override public InputStream getPerspectiveIcon() { return null; } @Override public void setActive( boolean active ) { for ( SpoonPerspectiveListener listener : listeners ) { if ( active ) { listener.onActivation(); } else { listener.onDeactication(); } } } public class XulTabAndPanel { public XulTab tab; public XulTabpanel panel; public XulTabAndPanel( XulTab tab, XulTabpanel panel ) { this.tab = tab; this.panel = panel; } } public XulTabAndPanel createTab() { try { XulTab tab = (XulTab) document.createElement( "tab" ); XulTabpanel panel = (XulTabpanel) document.createElement( "tabpanel" ); panel.setSpacing( 0 ); panel.setPadding( 0 ); tabs.addChild( tab ); panels.addChild( panel ); tabbox.setSelectedIndex( panels.getChildNodes().indexOf( panel ) ); tab.addPropertyChangeListener( new PropertyChangeListener() { @Override public void propertyChange( PropertyChangeEvent evt ) { LogChannel.GENERAL.logBasic( "Property changed: " + evt.getPropertyName() + ", " + evt.toString() ); } } ); return new XulTabAndPanel( tab, panel ); } catch ( XulException e ) { e.printStackTrace(); } return null; } private VariableSpace getVariableSpace() { VariableSpace space = (VariableSpace) Spoon.getInstance().getActiveMeta(); if ( space == null ) { // Just use system variables // space = new Variables(); space.initializeVariablesFrom( null ); } return space; } public void setNameForTab( XulTab tab, String name ) { String tabName = name; List<String> usedNames = new ArrayList<String>(); for ( XulComponent c : tabs.getChildNodes() ) { if ( c != tab ) { usedNames.add( ( (SwtTab) c ).getLabel() ); } } if ( usedNames.contains( name ) ) { int num = 2; while ( true ) { tabName = name + " (" + num + ")"; if ( usedNames.contains( tabName ) == false ) { break; } num++; } } tab.setLabel( tabName ); } @Override public List<XulOverlay> getOverlays() { return null; } @Override public List<XulEventHandler> getEventHandlers() { return null; } @Override public void addPerspectiveListener( SpoonPerspectiveListener spoonPerspectiveListener ) { } @Override public EngineMetaInterface getActiveMeta() { return null; } public boolean onTabClose( final int pos ) throws XulException { // Never close the admin tab // if ( pos == 0 ) { return false; } return true; } }