/*******************************************************************************
* Copyright (c) 2011 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.example.ece2011.ui.admin;
import java.util.List;
import org.eclipse.rwt.lifecycle.IEntryPoint;
import org.eclipse.rwt.lifecycle.UICallBack;
import org.eclipse.rwt.lifecycle.WidgetUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
@SuppressWarnings( "serial" )
public class AdminUI implements IEntryPoint {
private static final String UICALLBACK_ID = AdminUI.class.getName();
private Shell shell;
private TabFolder portsTabFolder;
private Tree contributionsTree;
private Images images;
private ChangeTracker changeTracker;
public int createUI() {
final Display display = new Display();
shell = new Shell( display, SWT.NO_TRIM );
shell.setMaximized( true );
createContent( shell );
shell.layout();
shell.open();
UICallBack.activate( UICALLBACK_ID );
return 0;
}
public void createContent( Composite parent ) {
updateShell( parent );
createImages( parent.getDisplay() );
parent.setLayout( createMainLayout() );
Control upperPart = createUpperPart( parent );
upperPart.setLayoutData( new GridData( SWT.FILL, SWT.TOP, true, false ) );
Control lowerPart = createLowerPart( parent );
lowerPart.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
changeTracker = new UiChangeTracker();
changeTracker.start();
}
private void updateShell( Composite parent ) {
if( shell == null ) {
shell = parent.getShell();
}
shell.addDisposeListener( new DisposeListener() {
public void widgetDisposed( DisposeEvent event ) {
dispose();
}
} );
}
public void dispose() {
changeTracker.stop();
UICallBack.deactivate( UICALLBACK_ID );
}
private void createImages( Display display ) {
images = new Images( display );
}
private Control createUpperPart( Composite parent ) {
Composite frame = new Composite( parent, SWT.NONE );
frame.setLayout( createGridLayout() );
Label headerLabel = new Label( frame, SWT.NONE );
headerLabel.setText( "Deployed UI Contributions" );
headerLabel.setData( WidgetUtil.CUSTOM_VARIANT, "header" );
portsTabFolder = new TabFolder( frame, SWT.TOP );
portsTabFolder.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
createTabItemsForPorts();
return frame;
}
private Control createLowerPart( Composite parent ) {
Composite frame = new Composite( parent, SWT.NONE );
frame.setLayout( createGridLayout() );
Label headerLabel = new Label( frame, SWT.NONE );
headerLabel.setText( "Available UI Contributions" );
headerLabel.setData( WidgetUtil.CUSTOM_VARIANT, "header" );
contributionsTree = createTree( frame, SWT.BORDER );
contributionsTree.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
return frame;
}
private Tree createTree( Composite parent, int style ) {
Tree tree = new Tree( parent, style | SWT.SINGLE | SWT.FULL_SELECTION );
tree.setLinesVisible( true );
TreeColumn column1 = new TreeColumn( tree, SWT.NONE );
column1.setWidth( 64 );
TreeColumn column2 = new TreeColumn( tree, SWT.NONE );
column2.setWidth( 200 );
TreeColumn column3 = new TreeColumn( tree, SWT.NONE );
column3.setWidth( 500 );
tree.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetDefaultSelected( SelectionEvent e ) {
TreeItem item = ( TreeItem )e.item;
if( item != null ) {
UiComponent component = ( UiComponent )item.getData();
if( component != null ) {
handleSelection( component );
}
}
}
} );
return tree;
}
protected void handleSelection( UiComponent component ) {
UiComponentDialog dialog = new UiComponentDialog( shell, component );
String port = getSelectedPort();
if( port != null ) {
dialog.selectPort( port );
}
dialog.open();
}
protected void update() {
createTabItemsForPorts();
createTreeItemsForActiveComponents();
createTreeItemsForAvailableComponents( contributionsTree );
shell.layout( true );
}
private void createTreeItemsForActiveComponents() {
if( !portsTabFolder.isDisposed() ) { // TODO [fappel]: check dispose problem
TabItem[] tabItems = portsTabFolder.getItems();
for( TabItem tabItem : tabItems ) {
String port = ( String )tabItem.getData();
Tree tree = ( Tree )tabItem.getControl();
createTreeItemsForActiveComponents( tree, port );
}
}
}
private void createTreeItemsForActiveComponents( Tree tree, String port ) {
clearTreeItems( tree );
List<UiComponent> components = UiComponents.getActiveComponents( port );
for( UiComponent component : components ) {
if( component.isApplication() ) {
createContributionItem( tree, component );
}
}
TreeItem[] parentItems = tree.getItems();
for( TreeItem parentItem : parentItems ) {
UiComponent parentComponent = (UiComponent)parentItem.getData();
String parentName = parentComponent.getName();
for( UiComponent component : components ) {
if( component.isUiContribution() && parentName.equals( component.getApplication() ) ) {
createContributionItem( parentItem, component );
}
}
parentItem.setExpanded( true );
}
fillEmptyItems( tree, 4 );
}
private void createTreeItemsForAvailableComponents( Tree tree ) {
List<UiComponent> components = UiComponents.getAvailableComponents();
clearTreeItems( tree );
for( UiComponent component : components ) {
if( component.isApplication() ) {
createContributionItem( tree, component );
}
}
for( UiComponent component : components ) {
if( component.isUiContribution() ) {
createContributionItem( tree, component );
}
}
fillEmptyItems( tree, 7 );
}
private void createTabItemsForPorts() {
List<String> ports = UiComponents.getAvailablePorts();
String selectedPort = getSelectedPort();
if( !portsTabFolder.isDisposed() ) { // TODO [fappel]: check disposed problem
TabItem[] items = portsTabFolder.getItems();
for( TabItem item : items ) {
if( !ports.contains( item.getData() ) ) {
item.getControl().dispose();
item.dispose();
}
}
for( String port : ports ) {
int insertIndex = getTabInsertPosition( port );
if( insertIndex != -1 ) {
createPortTabItem( port, insertIndex );
}
}
selectTabForPort( selectedPort );
}
}
private String getSelectedPort() {
String result = null;
TabItem selectedItem = getSelectedItem( portsTabFolder );
if( selectedItem != null ) {
result = (String)selectedItem.getData();
}
return result;
}
private void selectTabForPort( String port ) {
TabItem item = findTabItemWithData( portsTabFolder, port );
if( item != null ) {
selectTabItem( item );
}
}
private int getTabInsertPosition( String port ) {
int insertIndex = 0;
int count = portsTabFolder.getItemCount();
for( int i = 0; i < count; i++ ) {
TabItem item = portsTabFolder.getItem( i );
String itemPort = (String)item.getData();
if( port.equals( itemPort ) ) {
insertIndex = -1;
break;
} else if( port.compareTo( itemPort ) > 0 ) {
insertIndex = i + 1;
}
}
return insertIndex;
}
private TabItem createPortTabItem( String port, int index ) {
TabItem tabItem = new TabItem( portsTabFolder, SWT.NONE, index );
tabItem.setText( "Port " + port );
tabItem.setData( port );
Tree tree = createTree( portsTabFolder, SWT.NONE );
tree.setLayoutData( new GridData( SWT.FILL, SWT.TOP, true, false ) );
tabItem.setControl( tree );
createTreeItemsForActiveComponents( tree, port );
return tabItem;
}
private void createContributionItem( Tree parent, UiComponent component ) {
if( !parent.isDisposed() ) { // TODO [fappel]: check dispose problem
TreeItem item = new TreeItem( parent, SWT.NONE );
item.setData( component );
item.setImage( 0, getTypeImage( component ) );
item.setText( 1, component.getName() );
item.setText( 2, component.getBundleName() );
}
}
private void createContributionItem( TreeItem parent, UiComponent component ) {
TreeItem item = new TreeItem( parent, SWT.NONE );
item.setData( component );
item.setImage( 0, getTypeImage( component ) );
item.setText( 1, component.getName() );
item.setText( 2, component.getBundleName() );
}
private Image getTypeImage( UiComponent component ) {
Image result;
if( component.isApplication() ) {
result = images.applicationImage;
} else {
result = images.contributionImage;
}
return result;
}
private static TabItem getSelectedItem( TabFolder folder ) {
TabItem selectedItem = null;
if( !folder.isDisposed() ) { // TODO [fappel]: check dispose problem
int selectionIndex = folder.getSelectionIndex();
if( selectionIndex != -1 ) {
selectedItem = folder.getItem( selectionIndex );
}
}
return selectedItem;
}
private static TabItem findTabItemWithData( TabFolder folder, Object data ) {
TabItem[] items = folder.getItems();
if( data != null ) {
for( TabItem item : items ) {
if( data.equals( item.getData() ) ) {
return item;
}
}
}
return null;
}
private static void selectTabItem( TabItem item ) {
if( !item.isDisposed() ) {
TabFolder folder = item.getParent();
folder.setSelection( item );
}
}
private static void clearTreeItems( Tree tree ) {
if( !tree.isDisposed() ) { // TODO [fappel]: check dispose problem
TreeItem[] items = tree.getItems();
for( TreeItem item : items ) {
item.dispose();
}
}
}
private static void fillEmptyItems( Tree tree, int minItemCount ) {
int itemCount = getFullItemCount( tree );
if( !tree.isDisposed() ) { // TODO [fappel]: check dispose problem
for( int i = itemCount; i < minItemCount; i++ ) {
new TreeItem( tree, SWT.NONE );
}
}
}
private static int getFullItemCount( Tree tree ) {
int result = 0;
if( !tree.isDisposed() ) { // TODO [fappel]: check dispose problem
TreeItem[] items = tree.getItems();
for( TreeItem item : items ) {
result++;
result += item.getItemCount();
}
}
return result;
}
private static GridLayout createGridLayout() {
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
return layout;
}
private static GridLayout createMainLayout() {
GridLayout layout = new GridLayout();
layout.marginTop = 15;
layout.marginWidth = 40;
layout.marginBottom = 20;
layout.verticalSpacing = 20;
return layout;
}
private final class UiChangeTracker extends ChangeTracker {
@Override
protected void changeDetected() {
if( !shell.isDisposed() ) {
shell.getDisplay().asyncExec( new Runnable() {
public void run() {
update();
}
} );
}
}
}
}