/*
* This file is part of the OpenSCADA project
* Copyright (C) 2006-2012 TH4 SYSTEMS GmbH (http://th4-systems.com)
*
* OpenSCADA is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenSCADA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenSCADA. If not, see
* <http://opensource.org/licenses/lgpl-3.0.html> for a copy of the LGPLv3 License.
*/
package org.openscada.ae.ui.views.views;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.databinding.observable.set.ISetChangeListener;
import org.eclipse.core.databinding.observable.set.SetChangeEvent;
import org.eclipse.core.databinding.observable.set.WritableSet;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.databinding.viewers.ObservableSetContentProvider;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.openscada.ae.ui.views.Settings;
import org.openscada.ae.ui.views.config.ColumnLabelProviderInformation;
import org.openscada.ae.ui.views.dialog.SearchType;
import org.openscada.ae.ui.views.filter.EventViewerFilter;
import org.openscada.ae.ui.views.model.DecoratedEvent;
import org.openscada.utils.lang.Pair;
public class EventViewTable extends Composite
{
private static final String COLUMN_KEY = "org.openscada.ae.ui.views.views.EventViewTable" + ".column.key"; //$NON-NLS-1$ //$NON-NLS-2$
private final WritableSet events;
private volatile boolean scrollLock = false;
private static class SortListener extends SelectionAdapter
{
private final TableViewer tableViewer;
public SortListener ( final TableViewer tableViewer )
{
this.tableViewer = tableViewer;
}
@Override
public void widgetSelected ( final SelectionEvent e )
{
final Table table = this.tableViewer.getTable ();
final TableColumn newColumn = (TableColumn)e.widget;
final TableColumn currentColumn = table.getSortColumn ();
final EventTableColumn column = (EventTableColumn)newColumn.getData ( COLUMN_KEY );
if ( column == EventTableColumn.reservedColumnSourceTimestamp || column == EventTableColumn.reservedColumnEntryTimestamp )
{
final int currentDir = table.getSortDirection ();
int newDir = SWT.UP;
if ( newColumn == currentColumn )
{
newDir = currentDir == SWT.UP ? SWT.DOWN : SWT.UP;
}
else
{
table.setSortColumn ( newColumn );
}
table.setSortDirection ( newDir );
this.tableViewer.setSorter ( new EventTableSorter ( column, newDir ) );
}
}
}
private Pair<SearchType, String> filter;
private final TableViewer tableViewer;
// private final ArrayList<EventTableColumn> localColumns;
private final LabelProviderSupport labelProviderSupport;
private final List<ColumnLabelProviderInformation> columnInformations;
/*
private static final List<EventTableColumn> columns = new ArrayList<EventTableColumn> ();
static
{
columns.add ( EventTableColumn.reservedColumnId );
columns.add ( EventTableColumn.reservedColumnSourceTimestamp );
columns.add ( new EventTableColumn ( Fields.EVENT_TYPE.getName () ) );
columns.add ( new EventTableColumn ( Fields.VALUE.getName () ) );
columns.add ( new EventTableColumn ( Fields.MONITOR_TYPE.getName () ) );
columns.add ( new EventTableColumn ( Fields.ITEM.getName () ) );
columns.add ( new EventTableColumn ( Fields.MESSAGE.getName () ) );
columns.add ( new EventTableColumn ( Fields.ACTOR_NAME.getName () ) );
columns.add ( new EventTableColumn ( Fields.ACTOR_TYPE.getName () ) );
for ( final Fields field : Fields.values () )
{
final EventTableColumn column = new EventTableColumn ( field.getName () );
if ( !columns.contains ( column ) )
{
columns.add ( column );
}
}
columns.add ( EventTableColumn.reservedColumnEntryTimestamp );
}
*/
public EventViewTable ( final Composite parent, final IViewSite viewSite, final int style, final WritableSet events, final List<ColumnProperties> columnSettings )
{
this ( parent, viewSite, style, events, columnSettings, null );
}
public EventViewTable ( final Composite parent, final IViewSite viewSite, final int style, final WritableSet events, final List<ColumnProperties> columnSettings, final List<ColumnLabelProviderInformation> columnInformations )
{
super ( parent, style );
this.events = events;
this.columnInformations = columnInformations;
this.labelProviderSupport = new LabelProviderSupport ( Settings.getTimeZone () );
final FillLayout layout = new FillLayout ();
setLayout ( layout );
this.tableViewer = new TableViewer ( this, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI );
createColumns ( this.tableViewer );
applyColumSettings ( columnSettings );
this.tableViewer.getTable ().setHeaderVisible ( true );
this.tableViewer.getTable ().setLinesVisible ( true );
this.tableViewer.setUseHashlookup ( true );
this.tableViewer.setSorter ( new EventTableSorter ( EventTableColumn.reservedColumnSourceTimestamp, SWT.DOWN ) );
this.tableViewer.getTable ().setSortDirection ( SWT.DOWN );
hookContextMenu ( this.tableViewer.getControl (), this.tableViewer, viewSite );
viewSite.setSelectionProvider ( this.tableViewer );
final ObservableSetContentProvider contentProvider = new ObservableSetContentProvider ();
this.tableViewer.setContentProvider ( contentProvider );
// this.tableViewer.setLabelProvider ( new EventLabelProvider ( Properties.observeEach ( contentProvider.getKnownElements (), BeanProperties.values ( new String[] { "id", "monitor" } ) ), this.localColumns, Settings.getTimeZone () ) ); //$NON-NLS-1$ //$NON-NLS-2$
this.tableViewer.setInput ( this.events );
contentProvider.getRealizedElements ().addSetChangeListener ( new ISetChangeListener () {
@Override
public void handleSetChange ( final SetChangeEvent event )
{
if ( !EventViewTable.this.scrollLock )
{
EventViewTable.this.tableViewer.getTable ().setTopIndex ( 0 );
}
}
} );
}
@Override
public void dispose ()
{
super.dispose ();
this.labelProviderSupport.dispose ();
}
protected void hookContextMenu ( final Control control, final ISelectionProvider selectionProvider, final IViewSite viewSite )
{
final MenuManager menuMgr = new MenuManager ( "#PopupMenu" ); //$NON-NLS-1$
menuMgr.setRemoveAllWhenShown ( true );
menuMgr.addMenuListener ( new IMenuListener () {
@Override
public void menuAboutToShow ( final IMenuManager manager )
{
fillContextMenu ( manager );
}
} );
final Menu menu = menuMgr.createContextMenu ( control );
control.setMenu ( menu );
viewSite.registerContextMenu ( menuMgr, selectionProvider );
}
protected void fillContextMenu ( final IMenuManager manager )
{
manager.add ( new Separator ( IWorkbenchActionConstants.MB_ADDITIONS ) );
}
public TableViewer getTableViewer ()
{
return this.tableViewer;
}
private void applyColumSettings ( final List<ColumnProperties> columnSettings )
{
if ( columnSettings == null )
{
return;
}
final int[] colOrder = this.tableViewer.getTable ().getColumnOrder ();
int i = 0;
for ( final ColumnProperties p : columnSettings )
{
if ( i >= colOrder.length )
{
break;
}
colOrder[i] = p.getNo ();
i += 1;
}
this.tableViewer.getTable ().setColumnOrder ( colOrder );
i = 0;
for ( final ColumnProperties p : columnSettings )
{
if ( i >= this.tableViewer.getTable ().getColumnCount () )
{
break;
}
final TableColumn col = this.tableViewer.getTable ().getColumn ( i );
col.setWidth ( p.getWidth () );
i += 1;
}
}
public void clear ()
{
this.events.clear ();
}
private void createColumns ( final TableViewer table )
{
final SortListener sortListener = new SortListener ( table );
for ( final ColumnLabelProviderInformation columnInformation : this.columnInformations )
{
final TableViewerColumn fieldColumn = new TableViewerColumn ( table, SWT.NONE );
fieldColumn.getColumn ().setText ( columnInformation.getLabel () );
fieldColumn.getColumn ().setWidth ( columnInformation.getInitialSize () );
fieldColumn.getColumn ().setResizable ( true );
fieldColumn.getColumn ().setMoveable ( true );
if ( columnInformation.isSortable () )
{
fieldColumn.getColumn ().addSelectionListener ( sortListener );
}
final CellLabelProvider labelProvider = columnInformation.createLabelProvider ( this.labelProviderSupport );
if ( labelProvider != null )
{
fieldColumn.setLabelProvider ( labelProvider );
}
else
{
fieldColumn.setLabelProvider ( new StyledCellLabelProvider () {} );
}
}
}
public List<DecoratedEvent> selectedEvents ()
{
if ( this.tableViewer.getTable ().getSelectionCount () == 0 )
{
return new ArrayList<DecoratedEvent> ();
}
final ArrayList<DecoratedEvent> result = new ArrayList<DecoratedEvent> ();
for ( final TableItem row : this.tableViewer.getTable ().getSelection () )
{
if ( row.getData () instanceof DecoratedEvent )
{
result.add ( (DecoratedEvent)row.getData () );
}
}
return result;
}
public void removeFilter ()
{
this.filter = null;
this.tableViewer.resetFilters ();
}
public void setFilter ( final Pair<SearchType, String> filter )
{
// filter hasn't changed
if ( filter == null )
{
return;
}
if ( filter.equals ( this.filter ) )
{
return;
}
this.tableViewer.resetFilters ();
this.filter = filter;
this.tableViewer.addFilter ( new EventViewerFilter ( filter.second ) );
}
public Pair<SearchType, String> getFilter ()
{
return this.filter;
}
public List<ColumnProperties> getColumnSettings ()
{
final List<ColumnProperties> result = new ArrayList<ColumnProperties> ();
int i = 0;
final int[] order = this.tableViewer.getTable ().getColumnOrder ();
for ( final TableColumn col : this.tableViewer.getTable ().getColumns () )
{
result.add ( new ColumnProperties ( order[i], col.getWidth () ) );
i += 1;
}
return result;
}
public void setScrollLock ( final boolean scrollLock )
{
this.scrollLock = scrollLock;
}
public boolean isScrollLock ()
{
return this.scrollLock;
}
}