package com.log4jviewer.ui.preferences.filters;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.log4jviewer.Activator;
import com.log4jviewer.filters.FilterConstants;
import com.log4jviewer.filters.FilterItemModel;
/**
* Class represents a part of filters preferences page. It is responsible for building a table, where filter's rules are
* displayed, and control buttons: Add and Remove to add/remove filter's rules.
*
* @authors <a href="mailto:rd.ryly@gmail.com">Ruslan Diachenko</a></br> <a
* href="mailto:Daniil.Yaroslavtsev@gmail.com">Daniil Yaroslavtsev</a>
*/
public class FilterRuleSettings extends AbstractFilterSettings {
public static final int ENABLE_COLUMN_INDEX = 4;
public static final int COLUMN_NUMBER = 5;
private static final Image CHECKED = Activator.getImageDescriptor(
"icons/checkbox_checked.gif").createImage();
private static final Image UNCHECKED = Activator.getImageDescriptor(
"icons/checkbox_unchecked.gif").createImage();
private final Logger logger = LoggerFactory.getLogger(getClass());
private FilterContentProvider filterContentProvider;
private FilterController filterController;
private TableViewer tableViewer;
private Button addNewFilterItemButton;
private Button removeFilterItemButton;
private Table filterRuleTable;
public FilterRuleSettings(final FilterContentProvider filterContentProvider,
final FilterController filterController) {
this.filterContentProvider = filterContentProvider;
this.filterController = filterController;
}
@Override
public TableViewer getTableViewer() {
return tableViewer;
}
@Override
protected void createTableViewer(final Composite composite) {
tableViewer = new TableViewer(composite, SWT.SINGLE
| SWT.H_SCROLL
| SWT.V_SCROLL
| SWT.BORDER
| SWT.FULL_SELECTION);
tableViewer.setUseHashlookup(true);
tableViewer.setContentProvider(new ArrayContentProvider());
filterRuleTable = tableViewer.getTable();
filterRuleTable.setHeaderVisible(true);
filterRuleTable.setLinesVisible(true);
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 17);
filterRuleTable.setLayoutData(gridData);
createColumns();
filterController.setCellEditingStrategy(tableViewer);
filterRuleTable.addKeyListener(new KeyListener() {
@Override
public void keyReleased(final KeyEvent e) {
}
@Override
public void keyPressed(final KeyEvent e) {
switch (e.keyCode) {
case SWT.INSERT:
doAddNewFilterItemButtonAction();
break;
case SWT.DEL:
doRemoveFilterItemButtonAction();
break;
default:
break;
}
}
});
Listener paintListener = new Listener() {
@Override
public void handleEvent(final Event event) {
if ((event.type == SWT.PaintItem) && (event.index == ENABLE_COLUMN_INDEX)) {
TableItem item = (TableItem) event.item;
Image checkBoxImage = getImage(item.getData());
Rectangle imageBounds = checkBoxImage.getBounds();
int xOffset = (filterRuleTable.getColumn(ENABLE_COLUMN_INDEX).getWidth()
- imageBounds.width) / 2;
int yOffset = (item.getBounds().height - imageBounds.height) / 2;
event.gc.drawImage(checkBoxImage, event.x + xOffset, event.y + yOffset);
}
}
};
filterRuleTable.addListener(SWT.PaintItem, paintListener);
tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(final SelectionChangedEvent arg0) {
removeFilterItemButton.setEnabled(true);
}
});
// Selects a full row even when any it`s cell is editing
filterRuleTable.addListener(SWT.EraseItem, new Listener() {
@Override
public void handleEvent(final Event evt) {
ISelection selection = tableViewer.getSelection();
if (!selection.isEmpty()) {
TableItem eventItem = (TableItem) evt.item;
FilterItemModel evtFilterItemModel = (FilterItemModel) eventItem.getData();
int selectedItemIndex = filterRuleTable.getSelectionIndex();
FilterItemModel selectedFilterItemModel = (FilterItemModel) tableViewer
.getElementAt(selectedItemIndex);
if (selectedFilterItemModel.equals(evtFilterItemModel)) {
evt.detail |= SWT.SELECTED;
}
}
}
});
filterRuleTable.addTraverseListener(new TraverseListener() {
@Override
public void keyTraversed(final TraverseEvent e) {
if (e.detail == SWT.TRAVERSE_TAB_NEXT) {
e.doit = false;
}
}
});
}
public void setRemoveButtonEnabled(final boolean value) {
removeFilterItemButton.setEnabled(value);
}
@Override
protected void createColumns() {
// 'Logic operand' filter's rule column
final String logicOperandColumnTitle = "Logic operand";
final int logicOperandColumnWidth = 100;
TableViewerColumn logicOperandColumn = createSingleColumn(tableViewer,
logicOperandColumnTitle,
logicOperandColumnWidth);
logicOperandColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
FilterItemModel filterItemModel = (FilterItemModel) element;
FilterItemModel firstItem = (FilterItemModel) tableViewer.getElementAt(0);
String logicOperand = "";
if (!filterItemModel.equals(firstItem)) {
logicOperand = filterItemModel.getLogicOperand().getValue();
logger.debug("Filter's rule logic operand: {}", logicOperand);
}
return logicOperand;
}
});
logicOperandColumn.setEditingSupport(new RulesLogicCellEditor(tableViewer));
// 'Field type' filter's rule column
final String fieldTypeColumnTitle = "Field type";
final int fieldTypeColumnWidth = 85;
TableViewerColumn fieldTypeColumn = createSingleColumn(tableViewer,
fieldTypeColumnTitle,
fieldTypeColumnWidth);
fieldTypeColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
FilterItemModel filterItemModel = (FilterItemModel) element;
String fieldType = filterItemModel.getFieldType().getValue();
logger.debug("Filter's rule field type: {}", fieldType);
return fieldType;
}
});
fieldTypeColumn.setEditingSupport(new RulesFieldTypeCellEditor(tableViewer));
// 'Include' filter's rule column
final String includeColumnTitle = "Include";
final int includeColumnWidth = 60;
TableViewerColumn includeColumn = createSingleColumn(tableViewer, includeColumnTitle,
includeColumnWidth);
includeColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
FilterItemModel filterItemModel = (FilterItemModel) element;
String filterItemInclude = FilterConstants.EXCLUDE;
if (filterItemModel.isInclude()) {
filterItemInclude = FilterConstants.INCLUDE;
}
logger.debug("Filter's rule include: {}", filterItemInclude);
return filterItemInclude;
}
});
includeColumn.setEditingSupport(new RulesIncludeCellEditor(tableViewer));
// 'Match pattern' filter's rule column
final String patternColumnTitle = "Match pattern";
final int patternColumnWidth = 250;
TableViewerColumn matchPatternColumn = createSingleColumn(tableViewer,
patternColumnTitle,
patternColumnWidth);
matchPatternColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
FilterItemModel filterItemModel = (FilterItemModel) element;
String matchPattern = filterItemModel.getPattern();
logger.debug("Filter's rule match pattern: {}", matchPattern);
return matchPattern;
}
});
matchPatternColumn.setEditingSupport(new RulesMatchPatternCellEditor(tableViewer));
final String enableColumnTitle = "Enable";
final int enableColumnWidth = 40;
TableViewerColumn enableColumn = createSingleColumn(tableViewer, enableColumnTitle,
enableColumnWidth);
enableColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(final Object element) {
return null;
}
});
enableColumn.setEditingSupport(new RulesEnableCellEditor(tableViewer));
}
@Override
protected void createButtons(final Composite composite) {
addNewFilterItemButton = createSingleButton(composite, ADD_BUTTON_NAME);
removeFilterItemButton = createSingleButton(composite, REMOVE_BUTTON_NAME);
checkAndSetAddButtonState();
removeFilterItemButton.setEnabled(false);
addNewFilterItemButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
doAddNewFilterItemButtonAction();
}
});
removeFilterItemButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
doRemoveFilterItemButtonAction();
}
});
}
public Image getImage(final Object element) {
Image currentImage;
if (((FilterItemModel) element).isEnabled()) {
currentImage = CHECKED;
} else {
currentImage = UNCHECKED;
}
return currentImage;
}
private void doAddNewFilterItemButtonAction() {
if (filterContentProvider.isSelectedFilterIndexValid()) {
FilterItemModel filterItemModel = filterContentProvider.createFilterItem();
tableViewer.add(filterItemModel);
}
checkAndSetAddButtonState();
}
private void doRemoveFilterItemButtonAction() {
int selectedFilterItemIndex = filterRuleTable.getSelectionIndex();
if (selectedFilterItemIndex >= 0) {
filterContentProvider.removeFilterItem(selectedFilterItemIndex);
filterRuleTable.remove(selectedFilterItemIndex);
}
removeFilterItemButton.setEnabled(false);
}
public void checkAndSetAddButtonState() {
if (filterContentProvider.isFilterListEmpty()) {
addNewFilterItemButton.setEnabled(false);
} else {
addNewFilterItemButton.setEnabled(true);
}
}
}