/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2013 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.wizards; import java.util.Hashtable; import java.util.StringTokenizer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.DragSourceEvent; import org.eclipse.swt.dnd.DragSourceListener; import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.DropTargetListener; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Shell; import org.pentaho.di.core.Const; import org.pentaho.di.core.database.Database; import org.pentaho.di.core.exception.KettleDatabaseException; import org.pentaho.di.ui.core.PropsUI; import org.pentaho.di.ui.core.dialog.ErrorDialog; /** * This wizard page let's you select the tables that need to be ripped. * * @author Matt * @since 17-apr-04 * */ public class RipDatabaseWizardPage2 extends WizardPage { private PropsUI props; private String[] input; private Hashtable<Integer, String> selection; private Shell shell; private List wListSource, wListDest; private Label wlListSource, wlListDest; private Button wAddOne, wAddAll, wRemoveAll, wRemoveOne; public RipDatabaseWizardPage2( String arg ) { super( arg ); this.props = PropsUI.getInstance(); selection = new Hashtable<Integer, String>(); setTitle( "Select the tables" ); setDescription( "Select the tables to rip from the source database" ); } public void createControl( Composite parent ) { shell = parent.getShell(); int margin = Const.MARGIN; // create the composite to hold the widgets Composite composite = new Composite( parent, SWT.NONE ); props.setLook( composite ); FormLayout compLayout = new FormLayout(); compLayout.marginHeight = Const.FORM_MARGIN; compLayout.marginWidth = Const.FORM_MARGIN; composite.setLayout( compLayout ); // Put it all on the composite! // ////////////////////////////////////////////////// // Top & Bottom regions. // ////////////////////////////////////////////////// Composite top = new Composite( composite, SWT.NONE ); FormLayout topLayout = new FormLayout(); topLayout.marginHeight = margin; topLayout.marginWidth = margin; top.setLayout( topLayout ); FormData fdTop = new FormData(); fdTop.left = new FormAttachment( 0, 0 ); fdTop.top = new FormAttachment( 0, 0 ); fdTop.right = new FormAttachment( 100, 0 ); fdTop.bottom = new FormAttachment( 100, -50 ); top.setLayoutData( fdTop ); props.setLook( top ); Composite bottom = new Composite( composite, SWT.NONE ); bottom.setLayout( new FormLayout() ); FormData fdBottom = new FormData(); fdBottom.left = new FormAttachment( 0, 0 ); fdBottom.top = new FormAttachment( top, 0 ); fdBottom.right = new FormAttachment( 100, 0 ); fdBottom.bottom = new FormAttachment( 100, 0 ); bottom.setLayoutData( fdBottom ); props.setLook( bottom ); // ////////////////////////////////////////////////// // Sashform // ////////////////////////////////////////////////// SashForm sashform = new SashForm( top, SWT.HORIZONTAL ); sashform.setLayout( new FormLayout() ); FormData fdSashform = new FormData(); fdSashform.left = new FormAttachment( 0, 0 ); fdSashform.top = new FormAttachment( 0, 0 ); fdSashform.right = new FormAttachment( 100, 0 ); fdSashform.bottom = new FormAttachment( 100, 0 ); sashform.setLayoutData( fdSashform ); // //////////////////////// // / LEFT // //////////////////////// Composite leftsplit = new Composite( sashform, SWT.NONE ); leftsplit.setLayout( new FormLayout() ); FormData fdLeftsplit = new FormData(); fdLeftsplit.left = new FormAttachment( 0, 0 ); fdLeftsplit.top = new FormAttachment( 0, 0 ); fdLeftsplit.right = new FormAttachment( 100, 0 ); fdLeftsplit.bottom = new FormAttachment( 100, 0 ); leftsplit.setLayoutData( fdLeftsplit ); props.setLook( leftsplit ); // Source list to the left... wlListSource = new Label( leftsplit, SWT.NONE ); wlListSource.setText( "Available items:" ); props.setLook( wlListSource ); FormData fdlListSource = new FormData(); fdlListSource.left = new FormAttachment( 0, 0 ); fdlListSource.top = new FormAttachment( 0, 0 ); wlListSource.setLayoutData( fdlListSource ); wListSource = new List( leftsplit, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL ); props.setLook( wListSource ); FormData fdListSource = new FormData(); fdListSource.left = new FormAttachment( 0, 0 ); fdListSource.top = new FormAttachment( wlListSource, 0 ); fdListSource.right = new FormAttachment( 100, 0 ); fdListSource.bottom = new FormAttachment( 100, 0 ); wListSource.setLayoutData( fdListSource ); // ///////////////////////// // MIDDLE // ///////////////////////// Composite compmiddle = new Composite( sashform, SWT.NONE ); compmiddle.setLayout( new FormLayout() ); FormData fdCompMiddle = new FormData(); fdCompMiddle.left = new FormAttachment( 0, 0 ); fdCompMiddle.top = new FormAttachment( 0, 0 ); fdCompMiddle.right = new FormAttachment( 100, 0 ); fdCompMiddle.bottom = new FormAttachment( 100, 0 ); compmiddle.setLayoutData( fdCompMiddle ); props.setLook( compmiddle ); wAddOne = new Button( compmiddle, SWT.PUSH ); wAddOne.setText( " > " ); wAddOne.setToolTipText( "Add the selected items on the left." ); wAddAll = new Button( compmiddle, SWT.PUSH ); wAddAll.setText( " >> " ); wAddAll.setToolTipText( "Add all items on the left." ); wRemoveOne = new Button( compmiddle, SWT.PUSH ); wRemoveOne.setText( " < " ); wRemoveOne.setToolTipText( "Remove the selected items on the right." ); wRemoveAll = new Button( compmiddle, SWT.PUSH ); wRemoveAll.setText( " << " ); wRemoveAll.setToolTipText( "Add all items on the right." ); FormData fdAddOne = new FormData(); fdAddOne.left = new FormAttachment( compmiddle, 0, SWT.CENTER ); fdAddOne.top = new FormAttachment( 30, 0 ); wAddOne.setLayoutData( fdAddOne ); FormData fdAddAll = new FormData(); fdAddAll.left = new FormAttachment( compmiddle, 0, SWT.CENTER ); fdAddAll.top = new FormAttachment( wAddOne, margin ); wAddAll.setLayoutData( fdAddAll ); FormData fdRemoveAll = new FormData(); fdRemoveAll.left = new FormAttachment( compmiddle, 0, SWT.CENTER ); fdRemoveAll.top = new FormAttachment( wAddAll, margin ); wRemoveAll.setLayoutData( fdRemoveAll ); FormData fdRemoveOne = new FormData(); fdRemoveOne.left = new FormAttachment( compmiddle, 0, SWT.CENTER ); fdRemoveOne.top = new FormAttachment( wRemoveAll, margin ); wRemoveOne.setLayoutData( fdRemoveOne ); // /////////////////////////////// // RIGHT // /////////////////////////////// Composite rightsplit = new Composite( sashform, SWT.NONE ); rightsplit.setLayout( new FormLayout() ); FormData fdRightsplit = new FormData(); fdRightsplit.left = new FormAttachment( 0, 0 ); fdRightsplit.top = new FormAttachment( 0, 0 ); fdRightsplit.right = new FormAttachment( 100, 0 ); fdRightsplit.bottom = new FormAttachment( 100, 0 ); rightsplit.setLayoutData( fdRightsplit ); props.setLook( rightsplit ); wlListDest = new Label( rightsplit, SWT.NONE ); wlListDest.setText( "Your selection:" ); props.setLook( wlListDest ); FormData fdlListDest = new FormData(); fdlListDest.left = new FormAttachment( 0, 0 ); fdlListDest.top = new FormAttachment( 0, 0 ); wlListDest.setLayoutData( fdlListDest ); wListDest = new List( rightsplit, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL ); props.setLook( wListDest ); FormData fdListDest = new FormData(); fdListDest.left = new FormAttachment( 0, 0 ); fdListDest.top = new FormAttachment( wlListDest, 0 ); fdListDest.right = new FormAttachment( 100, 0 ); fdListDest.bottom = new FormAttachment( 100, 0 ); wListDest.setLayoutData( fdListDest ); sashform.setWeights( new int[] { 45, 10, 45 } ); // Drag & Drop for steps Transfer[] ttypes = new Transfer[] { TextTransfer.getInstance() }; DragSource ddSource = new DragSource( wListSource, DND.DROP_MOVE | DND.DROP_COPY ); ddSource.setTransfer( ttypes ); ddSource.addDragListener( new DragSourceListener() { public void dragStart( DragSourceEvent event ) { } public void dragSetData( DragSourceEvent event ) { String[] ti = wListSource.getSelection(); String data = new String(); for ( int i = 0; i < ti.length; i++ ) { data += ti[i] + Const.CR; } event.data = data; } public void dragFinished( DragSourceEvent event ) { } } ); DropTarget ddTarget = new DropTarget( wListDest, DND.DROP_MOVE | DND.DROP_COPY ); ddTarget.setTransfer( ttypes ); ddTarget.addDropListener( new DropTargetListener() { public void dragEnter( DropTargetEvent event ) { } public void dragLeave( DropTargetEvent event ) { } public void dragOperationChanged( DropTargetEvent event ) { } public void dragOver( DropTargetEvent event ) { } public void drop( DropTargetEvent event ) { if ( event.data == null ) { // no data to copy, indicate failure in event.detail event.detail = DND.DROP_NONE; return; } StringTokenizer strtok = new StringTokenizer( (String) event.data, Const.CR ); while ( strtok.hasMoreTokens() ) { String source = strtok.nextToken(); addToDestination( source ); } } public void dropAccept( DropTargetEvent event ) { } } ); wListSource.addKeyListener( new KeyAdapter() { public void keyPressed( KeyEvent e ) { if ( e.character == SWT.CR ) { addToSelection( wListSource.getSelection() ); } } } ); wListDest.addKeyListener( new KeyAdapter() { public void keyPressed( KeyEvent e ) { if ( e.character == SWT.CR ) { delFromSelection( wListDest.getSelection() ); } } } ); // Double click adds to destination. wListSource.addSelectionListener( new SelectionAdapter() { public void widgetDefaultSelected( SelectionEvent e ) { addToSelection( wListSource.getSelection() ); } } ); // Double click adds to source wListDest.addSelectionListener( new SelectionAdapter() { public void widgetDefaultSelected( SelectionEvent e ) { String[] sel = wListDest.getSelection(); delFromSelection( sel ); } } ); wAddOne.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { addToSelection( wListSource.getSelection() ); } } ); wRemoveOne.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { delFromSelection( wListDest.getSelection() ); } } ); wAddAll.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { addAllToSelection(); } } ); wRemoveAll.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { removeAllFromSelection(); } } ); // set the composite as the control for this page setControl( composite ); } public boolean getInputData() { // Get some data... RipDatabaseWizardPage1 page1 = (RipDatabaseWizardPage1) getPreviousPage(); Database sourceDb = new Database( RipDatabaseWizard.loggingObject, page1.getSourceDatabase() ); try { sourceDb.connect(); input = sourceDb.getTablenames( false ); // Don't include the schema since it can cause invalid syntax } catch ( KettleDatabaseException dbe ) { new ErrorDialog( shell, "Error getting tables", "Error obtaining table list from database!", dbe ); input = null; return false; } finally { sourceDb.disconnect(); } return true; } public void getData() { wListSource.removeAll(); wListDest.removeAll(); if ( input != null ) { for ( int i = 0; i < input.length; i++ ) { Integer idx = Integer.valueOf( i ); String str = selection.get( idx ); if ( str == null ) { // Not selected: show in source! wListSource.add( input[i] ); } else { // Selected, show in destination! wListDest.add( input[i] ); } } } setPageComplete( canFlipToNextPage() ); } public void addAllToSelection() { // Just remove it all from both lists // Then add input[] to the destination list... // This is much faster. wListSource.removeAll(); wListDest.removeAll(); selection.clear(); for ( int i = 0; i < input.length; i++ ) { wListDest.add( input[i] ); selection.put( Integer.valueOf( i ), input[i] ); } setPageComplete( canFlipToNextPage() ); } public void removeAllFromSelection() { // Just remove it all from both lists // Then add input[] to the source list... // This is much faster. wListSource.removeAll(); wListDest.removeAll(); selection.clear(); for ( int i = 0; i < input.length; i++ ) { wListSource.add( input[i] ); } setPageComplete( canFlipToNextPage() ); } public void addToSelection( String[] string ) { for ( int i = 0; i < string.length; i++ ) { addToDestination( string[i] ); } setPageComplete( canFlipToNextPage() ); } public void delFromSelection( String[] string ) { for ( int i = 0; i < string.length; i++ ) { delFromDestination( string[i] ); } setPageComplete( canFlipToNextPage() ); } public void addToDestination( String string ) { int idxInput = Const.indexOfString( string, input ); selection.put( Integer.valueOf( idxInput ), string ); getData(); } public void delFromDestination( String string ) { int idxInput = Const.indexOfString( string, input ); selection.remove( Integer.valueOf( idxInput ) ); getData(); } public boolean canFlipToNextPage() { boolean canFlip = wListDest.getItemCount() > 0; // System.out.println("canflip = "+canFlip); return canFlip; } public String[] getSelection() { return wListDest.getItems(); } }