/******************************************************************************* * Copyright (c) 2009, 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.tabris.demos.enron; import static com.eclipsesource.tabris.widgets.enhancement.Widgets.onToolItem; import static com.eclipsesource.tabris.widgets.enhancement.Widgets.onTree; import java.io.File; import java.io.IOException; import java.io.InputStream; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.ILazyTreeContentProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import com.eclipsesource.tabris.demos.enron.EnronDataset.Folder; import com.eclipsesource.tabris.demos.enron.EnronDataset.Node; import com.eclipsesource.tabris.device.ClientDevice; import com.eclipsesource.tabris.device.ClientDevice.Platform; import com.eclipsesource.tabris.widgets.enhancement.Widgets; public class EnronExample { // Change this path to your Enron maildir private static final String DEFAULT_DATASET_DIR = "/var/lib/tomcat5.5/shared/data/enron_mail_20110402/maildir"; private static final String DATASET_DIR_PROP = "org.eclipse.rap.demo.enronDatasetDirectory"; private TreeViewer viewer; private Composite parent; public void createMainArea( Composite parent ) { this.parent = parent; createTreeArea( parent ); } private void createTreeArea( Composite parent ) { Composite composite = new Composite( parent, SWT.NONE ); GridLayout layout = ExampleUtil.createGridLayout(); composite.setLayout( layout ); viewer = new TreeViewer( composite, SWT.SINGLE | SWT.VIRTUAL ); viewer.setUseHashlookup( true ); onTree( viewer.getTree() ).setBackButtonNavigationEnabled( true ); TreeColumn treeColumn = new TreeColumn( viewer.getTree(), SWT.NONE ); treeColumn.setWidth( 200 ); TreeColumn treeColumn2 = new TreeColumn( viewer.getTree(), SWT.NONE ); treeColumn2.setWidth( 200 ); Tree tree = viewer.getTree(); tree.setLinesVisible( true ); tree.setToolTipText( "Enron Mailbox" ); viewer.getControl().setLayoutData( ExampleUtil.createFillData() ); viewer.setLabelProvider( new EnronLabelProvider( parent.getDisplay() ) ); viewer.setContentProvider( new EnronLazyContentProvider( viewer ) ); viewer.setInput( getDataSet() ); viewer.addSelectionChangedListener( new ISelectionChangedListener() { @Override public void selectionChanged( SelectionChangedEvent event ) { IStructuredSelection selection = ( IStructuredSelection )event.getSelection(); Object firstElement = selection.getFirstElement(); if( firstElement instanceof Node ) { nodeSelected( ( Node )firstElement ); } } } ); } private void nodeSelected( Node selectedNode ) { if( selectedNode != null ) { if( selectedNode.getFile().isFile() ) { try { Mail mail = new Mail( selectedNode.readContents() ); Shell mailShell = new Shell( parent.getDisplay(), SWT.NO_TRIM ); mailShell.setBackground( mailShell.getDisplay().getSystemColor( SWT.COLOR_DARK_GRAY ) ); mailShell.setMaximized( true ); mailShell.setLayout( new FillLayout() ); Widgets.onShell( mailShell ).useAnimation(); createContentArea( mailShell, mail ); mailShell.open(); } catch( IOException exception ) { throw new RuntimeException( "Failed to read contents from node", exception ); } } } } private void createContentArea( Composite parent, Mail mail ) { final Composite composite = new Composite( parent, SWT.NONE ); GridLayout layout = ExampleUtil.createGridLayout(); composite.setLayout( layout ); ClientDevice clientDevice = RWT.getClient().getService( ClientDevice.class ); if( clientDevice.getPlatform() != Platform.ANDROID ) { createCloseButtonToolbar( composite ); } createMailHeaderArea( composite, mail ); createMailContentArea( composite, mail ); } private void createCloseButtonToolbar( final Composite parent ) { final ToolBar toolBar = new ToolBar( parent, SWT.NONE ); GridDataFactory.fillDefaults() .align( SWT.FILL, SWT.BEGINNING ) .grab( true, false ) .applyTo( toolBar ); ToolItem titleItem = new ToolItem( toolBar, SWT.NONE ); onToolItem( titleItem ).useAsTitle(); ToolItem closeToolItem = new ToolItem( toolBar, SWT.PUSH ); closeToolItem.setText( "Close" ); closeToolItem.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent e ) { parent.getShell().close(); } } ); } private void createMailHeaderArea( Composite parent, Mail mail ) { Composite header = new Composite( parent, SWT.NONE ); header.setLayoutData( ExampleUtil.createHorzFillData() ); GridLayout headerLayout = new GridLayout( 2, false ); headerLayout.horizontalSpacing = 5; headerLayout.verticalSpacing = 5; header.setLayout( headerLayout ); Color foreground = parent.getDisplay().getSystemColor( SWT.COLOR_WHITE ); Label senderLabel = new Label( header, SWT.NONE ); senderLabel.setForeground( foreground ); senderLabel.setText( "From:" ); senderLabel.setLayoutData( new GridData( SWT.BEGINNING, SWT.CENTER, false, false ) ); Label senderText = new Label( header, SWT.SINGLE | SWT.READ_ONLY ); senderText.setText( mail.sender ); senderText.setForeground( foreground ); GridData senderTextData = ExampleUtil.createHorzFillData(); senderTextData.horizontalIndent = 2; senderText.setLayoutData( senderTextData ); Label subjectLabel = new Label( header, SWT.NONE ); subjectLabel.setForeground( foreground ); subjectLabel.setText( "Subject:" ); subjectLabel.setLayoutData( new GridData( SWT.BEGINNING, SWT.CENTER, false, false ) ); Label subjectText = new Label( header, SWT.SINGLE | SWT.READ_ONLY ); subjectText.setText( mail.subject ); subjectText.setForeground( foreground ); subjectText.setLayoutData( senderTextData ); } private void createMailContentArea( Composite parent, Mail mail ) { Composite bodyComp = new Composite( parent, SWT.NONE ); bodyComp.setBackground( Display.getDefault().getSystemColor( SWT.COLOR_WHITE ) ); bodyComp.setLayoutData( ExampleUtil.createFillData() ); GridLayout bodyLayout = new GridLayout( 1, false ); bodyComp.setLayout( bodyLayout ); Text messageText = new Text( bodyComp, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.READ_ONLY ); GridData messageTextData = ExampleUtil.createFillData(); messageText.setLayoutData( messageTextData ); messageText.setText( mail.content ); } private static Node getDataSet() { try { File root = getRootDirectory(); return new EnronDataset( root ).getRootNode(); } catch( IOException exception ) { throw new IllegalStateException( "Could not access data model", exception ); } } private static File getRootDirectory() { String path = getRootDirectoryPath(); File root = new File( path ); if( !root.isDirectory() ) { throw new RuntimeException( "Enron dataset directory missing: " + root ); } return root; } private static String getRootDirectoryPath() { String path = System.getProperty( DATASET_DIR_PROP ); if( path == null ) { path = DEFAULT_DATASET_DIR; } return path; } private static class Mail { private String sender; private String subject; private final String content; public Mail( String text ) { String[] lines = text.split( "\n" ); StringBuilder buffer = new StringBuilder(); boolean headerFinished = false; for( String line : lines ) { if( headerFinished ) { buffer.append( line ); buffer.append( "\n" ); } else if( line.startsWith( "From:" ) ) { sender = line.substring( "From:".length() ).trim(); } else if( line.startsWith( "Subject:" ) ) { subject = line.substring( "Subject:".length() ).trim(); } else if( "".equals( line.trim() ) ) { headerFinished = true; } } content = buffer.toString(); } } private static final class EnronLabelProvider extends CellLabelProvider { private static final String ICON_FILE = "/envelope.png"; private static final String ICON_FOLDER = "/inbox.png"; private static final int COLUMN_TITLE = 0; private static final int COLUMN_SUB_TITLE = 1; private final Image fileImage; private final Image folderImage; private final Device device; EnronLabelProvider( final Device device ) { this.device = device; fileImage = createImage( device, ICON_FILE ); folderImage = createImage( device, ICON_FOLDER ); } @Override public void update( final ViewerCell cell ) { Object element = cell.getElement(); if( element instanceof Node ) { Node node = ( Node )element; int columnIndex = cell.getColumnIndex(); switch( columnIndex ) { case COLUMN_TITLE: updateTitle( cell, node ); break; case COLUMN_SUB_TITLE: cell.setForeground( device.getSystemColor( SWT.COLOR_DARK_GRAY ) ); updateSubTitle( cell, node ); break; } } } @Override public String getToolTipText( final Object element ) { String result = ""; if( element instanceof File ) { File file = ( File )element; result = file.getName(); } return result; } private void updateTitle( ViewerCell cell, Node node ) { if( node instanceof Folder ) { cell.setText( node.getTitle() ); cell.setImage( folderImage ); } else { cell.setText( node.getFrom() ); cell.setImage( fileImage ); } } private void updateSubTitle( ViewerCell cell, Node node ) { if( !( node instanceof Folder ) ) { cell.setText( node.getTitle() ); } } private static Image createImage( Device device, String name ) { ClassLoader classLoader = EnronLabelProvider.class.getClassLoader(); InputStream inputStream = classLoader.getResourceAsStream( name ); Image result = null; if( inputStream != null ) { result = new Image( device, inputStream ); } return result; } } private static class EnronLazyContentProvider implements ILazyTreeContentProvider { private final TreeViewer viewer; public EnronLazyContentProvider( TreeViewer viewer ) { this.viewer = viewer; } @Override public Object getParent( Object element ) { Object result = null; if( element instanceof Node ) { result = ( ( Node )element ).getParent(); } return result; } @Override public void updateElement( Object parent, int index ) { if( parent instanceof Folder ) { Folder folder = ( Folder )parent; Node node = folder.getChild( index ); if( node != null ) { viewer.replace( parent, index, node ); viewer.setChildCount( node, node.getChildCount() ); } } } @Override public void updateChildCount( Object element, int currentChildCount ) { if( element instanceof Node ) { Node node = ( Node )element; int childCount = node.getChildCount(); if( childCount != currentChildCount ) { viewer.setChildCount( element, childCount ); } } } @Override public void inputChanged( Viewer viewer, Object oldInput, Object newInput ) { // nothing } @Override public void dispose() { // nothing } } }