/* * Copyright 2004-2007 IDCA. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and * the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions * and the following disclaimer in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY IDCA AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IDCA OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the authors and * should not be interpreted as representing official policies, either expressed or implied, of IDCA. */ package com.idcanet.vasc.impl.swt; import java.awt.TextField; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; 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.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import com.idcanet.fff.SwingImageHelper; import com.idcanet.vasc.core.VascDataExporter; import com.idcanet.vasc.core.VascTable; import com.idcanet.vasc.core.VascUserOption; import com.idcanet.vasc.core.VascViewRenderer; import com.idcanet.vasc.core.actions.GlobalVascAction; import com.idcanet.vasc.core.actions.RowVascAction; import com.idcanet.vasc.core.column.VascTableColumn; /** * * @author Willem Cazander * @version 1.0 Mar 21, 2007 */ public class SwtVascViewRenderer implements VascViewRenderer { private Logger logger = null; private Composite parent = null; private VascTable table = null; public SwtVascViewRenderer(Composite parent) { logger = Logger.getLogger(SwtVascViewRenderer.class.getName()); this.parent=parent; } public void initTable(VascTable table) throws Exception { if (table.getVascViewRenderer()==null) { table.setVascViewRenderer(this); } else { if (table.getVascViewRenderer()!=this) { throw new IllegalArgumentException("VascTable has already a differtent VascViewRenderer attected"); } } table.getVascTableController().finalizeVascColumns(table); table.getVascTableController().finalizeVascTable(table); table.getVascTableController().refreshData(table); this.table=table; } private static final String[] FILTER_NAMES = { "All Files (*.*)", "Comma Separated Values Files (*.csv)", "Microsoft Excel Spreadsheet Files (*.xls)", }; /** These filter extensions are used to filter which files are displayed. */ private static final String[] FILTER_EXTS = { "*.*","*.csv","*.xls" }; public void renderExport(VascDataExporter exporter) throws Exception { FileDialog dlg = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE); dlg.setFilterNames(FILTER_NAMES); dlg.setFilterExtensions(FILTER_EXTS); dlg.setFileName(table.getHeaderName()+".csv"); String fileName = dlg.open(); logger.fine("FileName: "+fileName); if (fileName == null) { return; } OutputStream out = new FileOutputStream(fileName); try { exporter.doExport(out, table); } catch (Exception e) { //MessageDialog.openError(Display.getCurrent().getActiveShell(),crudTable.i18n("crud.event.export.error.title"),crudTable.i18n("crud.event.export.error.message")); logger.log(Level.WARNING,"Error: "+e.getMessage(),e); } finally { if (out!=null) { out.close(); } } } public void renderEdit(Object object) throws Exception { logger.info("Rending Edit View"); table.getVascTableController().initEditObject(table, object); SwtVascEditDialog dialog = new SwtVascEditDialog(Display.getCurrent().getActiveShell(),table,object,"Vasc Edit","Edit"); Object result = dialog.open(); if(result==null) { return; } try { result = table.getVascDataSource().merge(object); //table.getVascTableController().fireModelUpdateListeners(result); } finally { //TODO: or merge into table == faster table.getVascTableController().refreshData(table); } } public ImageDescriptor getImageDescriptor(String path) { try { path = table.getVascTextValue().getTextValue(path); logger.info("Loading image: "+path); //System.out.println("==== 1"); ImageDescriptor result = ImageDescriptor.createFromFile(path.getClass(), path); result = ImageDescriptor.createFromFile(SwingImageHelper.class, path); if(result==null) { // try load fff //.out.println("==== 2"); //result = ImageDescriptor.createFromURL(SwingImageHelper.class.getClass().getResource(path)); } //System.out.println("==== 3"); if(result==null) { throw new NullPointerException("Can't load resource: "+path); } //System.out.println("==== 4 "+result.getImageData().height+" w:"+result.getImageData().width); return result; } catch (Exception e) { logger.warning("Could not load image from path: '"+path+"'"); try { ImageDescriptor result = null; //ImageDescriptor.createFromURL(SwingImageHelper.class.getClass().getResource("/META-INF/images/silk/png/bomb.png")); if(result==null) { throw new NullPointerException("Can't load resource: "+path); } return result; } catch (Exception e2) { return ImageDescriptor.getMissingImageDescriptor(); // default swt missing image fall back } } } public void renderDelete(Object rowBean) throws Exception { } public class SwtVascEditDialog extends Dialog { private Shell shell = null; private String headerText = null; private String title = null; private Object result = null; private Object bean = null; public SwtVascEditDialog (Shell parent,VascTable table,Object bean,String title,String headerText) { super (parent, 0); this.headerText = headerText; this.title = title; this.bean = bean; } public Object open() { shell = new Shell(getParent(), SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL); shell.setText(title); GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; shell.setLayout(layout); Composite header = new Composite(shell, SWT.NONE); GridLayout headerLayout = new GridLayout(); headerLayout.numColumns = 6; header.setLayout(headerLayout); header.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite body = new Composite(shell, SWT.NONE); GridLayout bodyLayout = new GridLayout(); bodyLayout.numColumns = 1; body.setLayout(bodyLayout); body.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite footer = new Composite(shell, SWT.NONE); GridLayout footerLayout = new GridLayout(); footerLayout.numColumns = 6; footer.setLayout(footerLayout); footer.setLayoutData(new GridData(SWT.NONE)); //createHeader(header); createBody(body); //createFooter(footer); // should be last partCreated(); shell.pack(); shell.open(); Display display = shell.getDisplay(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } //image.dispose(); //closeDialog(); return result; } public void createBody(Composite body) { body.setLayout(new GridLayout(2, true)); body.setLayoutData(new GridData(GridData.FILL_BOTH)); for(VascTableColumn c:table.getTableColumns()) { Label l = new Label(body, SWT.WRAP); l.setText(c.getName()); if(c.getToolTip()!=null) { l.setToolTipText(c.getToolTip()); } try { table.getVascTableController().initEditObjectColumn(c, bean); //if(c.getVascColumnEditor()==null) { Label valueLabel = new Label(body, SWT.WRAP); valueLabel.setText(""+c.getVascColumnValue().getValue(c, bean)); c.setColumnEditor(valueLabel); /* } else { c.setColumnEditor(c.getVascColumnEditor().createColumnEditor(c,bean,body)); } */ } catch (Exception e) { logger.log(Level.WARNING,"Error making column editor: '"+c.getVascColumnValue()+"' error: "+e.getMessage(),e); } if(c.getColumnEditor() instanceof Control) { Control editor = (Control)c.getColumnEditor(); GridData gridData = new GridData(); gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = true; gridData.horizontalAlignment = GridData.FILL; gridData.verticalAlignment = GridData.FILL; editor.setLayoutData(gridData); } } // create some spaceing , should replace by seperator new Label(body, SWT.WRAP); new Label(body, SWT.WRAP); Button saveButton = new Button(body, SWT.NONE); saveButton.setImage(getImageDescriptor("vasc.dialog.save.image").createImage()); saveButton.setText(table.getVascTextValue().getTextValue("vasc.dialog.save.name")); saveButton.setToolTipText(table.getVascTextValue().getTextValue("vasc.dialog.save.tooltip")); saveButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { //if(hasRecordError()) { // return; //} //result = bean; shell.dispose(); } }); Button cancelButton = new Button(body, SWT.NONE); cancelButton.setImage(getImageDescriptor("vasc.dialog.cancel.image").createImage()); cancelButton.setText(table.getVascTextValue().getTextValue("vasc.dialog.cancel.name")); cancelButton.setToolTipText(table.getVascTextValue().getTextValue("vasc.dialog.cancel.tooltip")); cancelButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { result = null; shell.dispose(); } }); } } public Object defaultColumnEditor(VascTableColumn column,Object bean,Object gui) throws Exception { Composite body = (Composite)gui; Text text = new Text(body,SWT.SINGLE); text.addSelectionListener(new TextListener(column,bean)); text.setText(""+column.getVascColumnValue().getValue(column, bean)); return text; } class TextListener extends SelectionAdapter { private VascTableColumn column = null; private Object bean = null; public TextListener(VascTableColumn column,Object bean) { this.column=column; this.bean=bean; } /** * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { // SHIT it works :) Object value = e.data; logger.finer("Setting value: "+value); try { column.getVascColumnValue().setValue(column, bean, value); } catch (Exception ee) { ee.printStackTrace(); } } } public Object defaultColumnRenderer(VascTableColumn column,Object gui) throws Exception { return null; } public void renderView() throws Exception { GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; parent.setLayout(layout); Composite header = new Composite(parent, SWT.NONE); GridLayout headerLayout = new GridLayout(); headerLayout.numColumns = 6; header.setLayout(headerLayout); header.setLayoutData(new GridData(SWT.NONE)); Composite body = new Composite(parent, SWT.NONE); GridLayout bodyLayout = new GridLayout(); bodyLayout.numColumns = 1; body.setLayout(bodyLayout); body.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite footer = new Composite(parent, SWT.NONE); GridLayout footerLayout = new GridLayout(); footerLayout.numColumns = 6; footer.setLayout(footerLayout); footer.setLayoutData(new GridData(SWT.NONE)); createHeader(header); createBody(body); createFooter(footer); // should be last partCreated(); } public void createHeader(Composite header) { logger.finest("Creating header"); GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; header.setLayout(layout); header.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Composite headerBar = new Composite(header, SWT.NONE); //GridLayout headerLayout = new GridLayout(); //headerLayout.numColumns = 1; headerBar.setLayout(new FillLayout()); //headerBar.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite headerName = new Composite(header, SWT.NONE); GridLayout bodyLayout = new GridLayout(); bodyLayout.numColumns = 1; headerName.setLayout(bodyLayout); headerName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); //headerName.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite headerOptions = new Composite(header, SWT.NONE); GridLayout footerLayout = new GridLayout(); footerLayout.numColumns = 1; headerOptions.setLayout(footerLayout); //headerOptions.setLayoutData(new GridData(SWT.NONE)); headerOptions.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); ToolBar toolBar = new ToolBar(headerBar, SWT.NONE); for (GlobalVascAction action:table.getGlobalActions()) { ToolItem item = new ToolItem(toolBar, SWT.PUSH); item.setText(table.getVascTextValue().getTextValue(action.getName())); item.setToolTipText(table.getVascTextValue().getTextValue(action.getToolTip())); if (action.getImage()!=null) { item.setImage(getImageDescriptor(action.getImage()).createImage()); } item.addSelectionListener(new GlobalActionListener(action)); } Color c = new Color(header.getDisplay(),255,255,255); headerName.setBackground(c); if(table.getHeaderName()!=null) { Font headerFont = new Font(header.getDisplay(), "verdana", 16, SWT.BOLD); Label l = new Label(headerName, SWT.CENTER); l.setImage(getImageDescriptor(table.getHeaderImage()).createImage()); l.setFont(headerFont); l.setText(table.getVascTextValue().getTextValue(table.getHeaderName())); l.setBackground(c); } // create options for(VascUserOption option:table.getUserOptions()) { /* if(option.getLabelText()!=null) { Label l = new Label(header,SWT.WRAP); l.setText(crudTable.i18n(cpo.getLabelText())); l.setBackground(c); } // create ValueHolder cpo.setValueHolder(new ValueHolder(null)); // create control cpo.setTempObjectPropertyControl(cpo.getPropertyEditor().createPropertyEditor(header,cpo.getValueHolder())); cpo.getValueHolder().addPropertyChangeListener(this); */ } } class GlobalActionListener extends SelectionAdapter { private GlobalVascAction action = null; public GlobalActionListener(GlobalVascAction action) { this.action=action; } /** * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent event) { logger.info("Global Action"); try { action.doGlobalAction(table); } catch (Exception e) { table.getVascTableController().handleException(e, table); } } } public void createBody(Composite body) { logger.finer("Creating body"); // Create the table viewer to display the players final TableViewer tableViewer = new TableViewer(body, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); final Table table2 = tableViewer.getTable(); table2.setLayoutData(new GridData(GridData.FILL_BOTH)); table2.setHeaderVisible(true); table2.setLinesVisible(true); table2.addSelectionListener(new SelectionListener() { /** * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetDefaultSelected(SelectionEvent e) { } /** * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { Object data = e.item.getData(); logger.info("Slecting data: "+data); table.setSelectedObject(data); } }); // Set the content and label providers tableViewer.setContentProvider(new ListConverterContentProvider()); tableViewer.setLabelProvider(new DefaultLabelProvider(table)); //TODO: add renderer support //Add sort indicator and sort data when column selected Listener sortListener = new Listener() { public void handleEvent(Event e) { // determine new sort column and direction TableColumn sortColumn = table2.getSortColumn(); TableColumn currentColumn = (TableColumn) e.widget; int dir = table2.getSortDirection(); if (sortColumn == currentColumn) { dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; } else { table2.setSortColumn(currentColumn); dir = SWT.UP; } // sort the data based on column and direction //String prop = (String)currentColumn.getData("PROP"); //List l = new ArrayList(10); /* * //columns[i].setData("PROP",table.getTableColumns().get(i)....); * for(int i=0;i<crudTable.getSelectionInList().getSize();i++) { l.add(crudTable.getSelectionInList().getElementAt(i)); } BeanPropertyComparator c = new BeanPropertyComparator(); c.setAscending(dir!=SWT.DOWN); c.setProperty(prop); Collections.sort(l,c); crudTable.getSelectionInList().setList(l); */ } }; for(VascTableColumn c:table.getTableColumns()) { TableColumn tc = new TableColumn(table2, SWT.LEFT); tc.setText(c.getName()); tc.setToolTipText(c.getToolTip()); if (c.getImage()!=null) { tc.setImage(getImageDescriptor(c.getImage()).createImage()); } tc.addListener(SWT.Selection, sortListener); tc.setMoveable(false); tc.setResizable(true); } int totalWidth = table.getVascTableController().getTotalColumnsWidth(table); logger.finer("Total size: "+totalWidth); TableColumn[] columns = table2.getColumns(); for (int i = 0; i < columns.length; i++) { Integer cWidth = table.getTableColumns().get(i).getWidth(); if (cWidth==null) { break; } //int w = (int)((double)totalSize/(double)totalSize)*cWidth; columns[i].setWidth(cWidth); columns[i].pack(); //logger.finest("Setting column width: "+w+" total: "+totalSize+" c: "+cWidth+" of column: "+i); } logger.fine("Table with columns created: "+table2.getColumnCount()); tableViewer.setInput(table); } public void createFooter(Composite footer) { logger.finest("Creating footer"); for(RowVascAction action:table.getRowActions()) { Button actionButton = new Button(footer, SWT.NONE); actionButton.setText(table.getVascTextValue().getTextValue(action.getName())); actionButton.setToolTipText(table.getVascTextValue().getTextValue(action.getToolTip())); if (action.getImage()!=null) { actionButton.setImage(getImageDescriptor(action.getImage()).createImage()); } actionButton.addSelectionListener(new ActionListener(action)); } } class ActionListener extends SelectionAdapter { private RowVascAction action = null; public ActionListener(RowVascAction action) { this.action=action; } /** * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent event) { logger.info("Row Action"); try { action.doRowAction(table, table.getSelectedObject()); } catch (Exception e) { table.getVascTableController().handleException(e, table); } } } /** * Is called when all createPartControl is done with creating Parts */ public void partCreated() { } class DefaultLabelProvider implements ITableLabelProvider { private VascTable table = null; public DefaultLabelProvider(VascTable table) { this.table=table; } /** * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int) */ public Image getColumnImage(Object arg0, int arg1) { return null; } /** * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) */ public String getColumnText(Object bean, int columnNumber) { VascTableColumn vtc = table.getTableColumns().get(columnNumber); if (vtc.getVascColumnRenderer()==null) { try { return ""+vtc.getVascColumnValue().getValue(vtc,bean); } catch (Exception e) { logger.log(Level.WARNING,"Error in get value: '"+vtc.getVascColumnValue()+"' error: "+e.getMessage(),e); return "Err"; } } // see custem column renderer, so this code will never be called return "CUSTEM_RENDER"; } /** * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener) */ public void addListener(ILabelProviderListener arg0) { } /** * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() */ public void dispose() { } /** * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String) */ public boolean isLabelProperty(Object arg0, String arg1) { return false; } /** * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener) */ public void removeListener(ILabelProviderListener arg0) { } } class ListConverterContentProvider implements IStructuredContentProvider { /** * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */ public Object[] getElements(Object obj) { return ((VascTable)obj).getTableData().toArray(); } /** * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ public void dispose() { } /** * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ public void inputChanged(Viewer arg0, Object arg1, Object arg2) { } } }