de.jwic.controls.tableviewer.TableModel Maven / Gradle / Ivy
/*******************************************************************************
* Copyright 2015 xWic group (http://www.xwic.de)
*
* Licensed under the Apache License, Version 2.0 (the "License").
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
package de.jwic.controls.tableviewer;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import de.jwic.data.IContentProvider;
import de.jwic.data.Range;
import de.jwic.events.ElementSelectedEvent;
import de.jwic.events.ElementSelectedListener;
/**
* Acts as a model for all TableViewer controls that maintains the state of the
* list, columns, paging etc.
*
* @author Florian Lippisch
*/
/**
* @author vedad
*
*/
public class TableModel implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Selection is disabled.
*/
public static final int SELECTION_NONE = 0;
/**
* The user can selected one line. If he selects another line the previous
* selected line is deselected.
*/
public static final int SELECTION_SINGLE = 1;
/**
* Multiple lines can be selected. If a selected line is selected again, the
* line is deselected.
*/
public static final int SELECTION_MULTI = 2;
protected static final int EVENT_RANGE_UPDATE = 1;
protected static final int EVENT_COLUMN_SELECTED = 2;
protected static final int EVENT_EXPANDED = 3;
protected static final int EVENT_COLLAPSED = 4;
protected static final int EVENT_COLUMN_RESIZED = 5;
protected static final int EVENT_CONTENT_CHANGED = 6;
protected List columns = new ArrayList();
protected Range range = new Range();
protected int lastRowRenderCount = 0;
protected int selectionMode = SELECTION_NONE;
protected boolean invertSelection = false;
protected boolean invertExpansion = false;
protected Set selection = new HashSet();
private Set expanded = new HashSet();
private List selectionListeners = new ArrayList();
private List modelListeners = new ArrayList();
protected IContentProvider> contentProvider = null;
protected TableViewer tableViewer = null;
protected int lastRenderedPageSize = -1;
private boolean fitToParent = true;
/**
* Mobile TableViewer behaviors
*/
private boolean defaults = false;
private boolean disabled = false;
private String columnBtnText = "Columns...";
/**
* Default constructor.
*/
public TableModel() {
super();
}
public TableModel(TableViewer tableViewer) {
this.tableViewer = tableViewer;
}
/**
* Add a column to the list.
*
* @param column
*/
public void addColumn(TableColumn column) {
addColumn(column, columns.size());
}
/**
* Add a column to the list at given index.
*
* @param column
* @param index
*/
public void addColumn(TableColumn column, int index) {
columns.add(index, column);
column.setIndex(index);
// RPF: This IF causes trouble, when adding columns to the model after
// others with indexes before the end
// Then the tableviewer column resize does not work properly. a
// reindexcolumns is always necessary!
// if (index == columns.size() - 1) {
reindexColumns();
// }
}
/**
* Removes a column.
*
* @param column
*/
public void removeColumn(TableColumn column) {
if (columns.remove(column)) {
reindexColumns();
}
}
/**
* Removes all columns.
*/
public void removeAllColumns() {
columns.clear();
}
/**
* Reindex all columns.
*/
protected void reindexColumns() {
for (int i = 0; i < columns.size(); i++) {
TableColumn col = columns.get(i);
col.setIndex(i);
}
}
/**
* Returns an iterator for the columns.
*
* @return Iterator of TableColumn objects
*/
public Iterator getColumnIterator() {
return columns.iterator();
}
/**
* Returns the columns List size.
*
* @return
*/
public int getColumnsCount() {
return columns.size();
}
/**
* Returns TableColumn at given index.
*
* @param index
* @return
*/
public TableColumn getColumn(int index) {
return columns.get(index);
}
/**
* Add a listener.
*
* @param listener
*/
public void addTableModelListener(ITableModelListener listener) {
modelListeners.add(listener);
}
/**
* Remove a listener.
*
* @param listener
*/
public void removeTableModelListener(ITableModelListener listener) {
modelListeners.remove(listener);
}
/**
* Add ElementSelectedListener
*
* @param listener
*/
public void addElementSelectedListener(ElementSelectedListener listener) {
selectionListeners.add(listener);
}
/**
* Remove ElementSelectedListener.
*
* @param listener
*/
public void removeElementSelectedListener(ElementSelectedListener listener) {
selectionListeners.remove(listener);
}
/**
* Internal fire event handler.
*
* @param eventType
*/
protected void fireTableEvent(int eventType, TableModelEvent event) {
Object[] list = modelListeners.toArray();
for (int i = 0; i < list.length; i++) {
ITableModelListener listener = (ITableModelListener) list[i];
switch (eventType) {
case EVENT_RANGE_UPDATE:
listener.rangeUpdated(event);
break;
case EVENT_COLUMN_SELECTED:
listener.columnSelected(event);
break;
case EVENT_COLUMN_RESIZED:
listener.columnResized(event);
break;
case EVENT_COLLAPSED:
listener.nodeCollapsed(event);
break;
case EVENT_EXPANDED:
listener.nodeExpanded(event);
break;
case EVENT_CONTENT_CHANGED:
listener.contentChanged(event);
break;
}
}
}
/**
* Notify ElementSelectedListeners
*
* @param selectedElement
*/
protected void fireSelectionEvent(String selectedElement, boolean dblClick) {
ElementSelectedEvent event = new ElementSelectedEvent(this, selectedElement, dblClick);
Object[] list = selectionListeners.toArray();
for (int i = 0; i < list.length; i++) {
ElementSelectedListener listener = (ElementSelectedListener) list[i];
listener.elementSelected(event);
}
}
/**
* @return the range
*/
public Range getRange() {
return range;
}
/**
* Set the maximum number of displayed lines per page. If the value is set
* to -1, all rows are displayed and the start is set to 0 (first page).
*
* @param maxLines
*/
public void setMaxLines(int maxLines) {
range.setMax(maxLines);
if (maxLines == -1) {
range.setStart(0);
}
fireTableEvent(EVENT_RANGE_UPDATE, new TableModelEvent(this));
}
/**
* Returns the maximum number of lines.
*
* @return
*/
public int getMaxLines() {
return range.getMax();
}
/**
* Goto first page.
*/
public void pageFirst() {
range.setStart(0);
fireTableEvent(EVENT_RANGE_UPDATE, new TableModelEvent(this));
}
/**
*
*/
public void pagePrev() {
int pgSize = range.getMax();
if (pgSize == 0) {
pgSize = lastRenderedPageSize;
}
if (pgSize > 0) {
int next = range.getStart() - pgSize;
if (next < 0) {
next = 0;
}
range.setStart(next);
fireTableEvent(EVENT_RANGE_UPDATE, new TableModelEvent(this));
}
}
/**
*
*/
public void pageNext() {
int pgSize = range.getMax();
if (pgSize == 0) {
pgSize = lastRenderedPageSize;
}
if (pgSize > 0) {
int total = getContentProvider().getTotalSize();
int next = range.getStart() + pgSize;
if (next < total) {
range.setStart(next);
fireTableEvent(EVENT_RANGE_UPDATE, new TableModelEvent(this));
}
}
}
/**
*
*/
public void pageLast() {
// calculate last page
int pgSize = range.getMax();
if (pgSize == 0) {
pgSize = lastRenderedPageSize;
;
}
if (pgSize > 0) {
int total = getContentProvider().getTotalSize();
int pages = total / pgSize;
if (total % pgSize == 0) {
pages -= 1;
}
range.setStart(pages * pgSize);
fireTableEvent(EVENT_RANGE_UPDATE, new TableModelEvent(this));
}
}
/**
* @return the lastRowRenderCount
*/
public int getLastRowRenderCount() {
return lastRowRenderCount;
}
/**
* @param lastRowRenderCount
* the lastRowRenderCount to set
*/
public void setLastRowRenderCount(int lastRowRenderCount) {
this.lastRowRenderCount = lastRowRenderCount;
}
/**
* @return the selectionMode
*/
public int getSelectionMode() {
return selectionMode;
}
/**
* Sets the selection mode to either
* SELECTION_NONE
* SELECTION_SINGLE
* SELECTION_MULTI
*
* Note that this method does not fire an event nor sets the TableViewer to
* requireRedraw. If this property is changed during runtime, the viewer
* must be set to redraw manually.
*
* @param selectionMode
* the selectionMode to set
*/
public void setSelectionMode(int selectionMode) {
this.selectionMode = selectionMode;
clearSelection();
}
/**
* A selection occured.
*
* @param rowKey
*/
public void selection(String rowKey) {
selection(rowKey, false);
}
/**
* Selection of a row.
*
* @param rowKey
* @param dblClick
*/
public void selection(String rowKey, boolean dblClick) {
switch (selectionMode) {
case SELECTION_SINGLE:
if (selection.contains(rowKey)) {
// selection.clear();
// no delselection
fireSelectionEvent(rowKey, dblClick);
} else {
selection.clear();
selection.add(rowKey);
fireSelectionEvent(rowKey, dblClick);
}
break;
case SELECTION_MULTI:
if (selection.contains(rowKey)) {
if (!dblClick) { // ignore de-selection on dbl-click.
selection.remove(rowKey);
fireSelectionEvent(null, dblClick); // element got removed
}
} else {
selection.add(rowKey);
fireSelectionEvent(rowKey, dblClick);
}
break;
case SELECTION_NONE:
break;
}
}
/**
* Returns true if the specified rowKey is selected.
*
* @param rowKey
* @return
*/
public boolean isSelected(String rowKey) {
boolean isSelected = selection.contains(rowKey);
return invertSelection ^ isSelected;
}
/**
* @return the invertSelection
*/
public boolean isInvertSelection() {
return invertSelection;
}
/**
* @param invertSelection
* the invertSelection to set
*/
public void setInvertSelection(boolean invertSelection) {
this.invertSelection = invertSelection;
}
/**
* @return the invertExpansion
*/
public boolean isInvertExpansion() {
return invertExpansion;
}
/**
* @param invertExpansion
* the invertExpansion to set
*/
public void setInvertExpansion(boolean invertExpansion) {
this.invertExpansion = invertExpansion;
}
/**
* Clear the selection.
*/
public void clearSelection() {
selection.clear();
invertSelection = false;
fireSelectionEvent("", false);
}
/**
* Clear the expansion.
*/
public void clearExpansion() {
expanded.clear();
invertExpansion = false;
}
/**
* Returns the first selected key or null if no key is selected.
*
* @return
*/
public String getFirstSelectedKey() {
if (selection.size() > 0) {
return selection.iterator().next();
}
return null;
}
/**
* Retruns the selected keys or deselected in invert mode.
*
* @return
*/
public Collection getSelection() {
return selection;
}
/**
* @param row
* @return
*/
public boolean isExpanded(String rowKey) {
boolean isExpanded = expanded.contains(rowKey);
return invertExpansion ^ isExpanded;
}
/**
* @param rowKey
*/
public void expand(String rowKey) {
if (!invertExpansion) {
expanded.add(rowKey);
} else {
expanded.remove(rowKey);
}
fireTableEvent(EVENT_EXPANDED, new TableModelEvent(this, rowKey));
}
/**
* @param rowKey
*/
public void collapse(String rowKey) {
if (!invertExpansion) {
expanded.remove(rowKey);
} else {
expanded.add(rowKey);
}
fireTableEvent(EVENT_COLLAPSED, new TableModelEvent(this, rowKey));
}
/**
* @param colIdx
* @param newWidth
*/
public void setColumnWidth(int colIdx, int newWidth) {
TableColumn col = columns.get(colIdx);
col.setWidth(newWidth);
TableModelEvent event = new TableModelEvent(this);
event.setTableColumn(col);
fireTableEvent(EVENT_COLUMN_RESIZED, event);
}
/**
* Notify listeners that a column header has been selected.
*
* @param colIdx
*/
public void selectColumn(int colIdx) {
TableColumn col = columns.get(colIdx);
TableModelEvent event = new TableModelEvent(this);
event.setTableColumn(col);
fireTableEvent(EVENT_COLUMN_SELECTED, event);
}
/**
* @param contentProvider
* the contentProvider to set
*/
public void setContentProvider(IContentProvider> contentProvider) {
this.contentProvider = contentProvider;
}
/**
* @return the contentProvider
*/
public IContentProvider> getContentProvider() {
return contentProvider;
}
/**
* Fire content changed event. Sets require redraw flag of TableViewer (if
* available).
*/
public void contentChanged() {
contentChanged(this);
}
/**
* Fire content changed event. Sets require redraw flag of TableViewer (if
* available).
*
* @param eventSource
* the eventSource to use
*/
public void contentChanged(Object eventSource) {
fireTableEvent(EVENT_CONTENT_CHANGED, new TableModelEvent(eventSource));
if (tableViewer != null) {
tableViewer.setRequireRedraw(true);
}
}
/**
* @return the lastRenderedPageSize
*/
public int getLastRenderedPageSize() {
return lastRenderedPageSize;
}
/**
* @param lastRenderedPageSize
* the lastRenderedPageSize to set
*/
public void setLastRenderedPageSize(int lastRenderedPageSize) {
this.lastRenderedPageSize = lastRenderedPageSize;
}
/**
* @param fitToParent
* default is true if 'true' this control disregards any other
* width settings and fills the parent container. if 'true' this
* control also takes into consideration the padding-left and
* padding-right of the parent and respects it
*/
public void setFitToParent(boolean fitToParent) {
this.fitToParent = fitToParent;
}
/**
* @return wheather or not this tableViewer is set to fit to parent
*/
public boolean isFitToParent() {
return fitToParent;
}
/**
* @return the defaults
*/
public boolean isDefaults() {
return defaults;
}
/**
* @param defaults
* the defaults to set
*/
public void setDefaults(boolean defaults) {
this.defaults = defaults;
}
/**
* @return the disabled
*/
public boolean isDisabled() {
return disabled;
}
/**
* @param disabled
* the disabled to set
*/
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
/**
* @return the columnBtnText
*/
public String getColumnBtnText() {
return columnBtnText;
}
/**
* @param columnBtnText the columnBtnText to set
*/
public void setColumnBtnText(String columnBtnText) {
this.columnBtnText = columnBtnText;
}
}