/* ***************************************************************************** * JFire - it's hot - Free ERP System - http://jfire.org * * Copyright (C) 2004-2005 NightLabs - http://NightLabs.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library 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 for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin St, Fifth Floor, * * Boston, MA 02110-1301 USA * * * * Or get it online : * * http://opensource.org/licenses/lgpl-license.php * * * * * ******************************************************************************/ package org.nightlabs.jfire.trade.admin.ui.gridpriceconfig; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableCursor; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.MouseMoveListener; 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.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.nightlabs.base.ui.composite.XComposite; import org.nightlabs.jfire.accounting.Currency; import org.nightlabs.jfire.accounting.PriceFragmentType; import org.nightlabs.jfire.accounting.gridpriceconfig.IFormulaPriceConfig; import org.nightlabs.jfire.accounting.gridpriceconfig.IPriceCoordinate; import org.nightlabs.jfire.accounting.gridpriceconfig.IResultPriceConfig; import org.nightlabs.jfire.accounting.gridpriceconfig.PriceCalculationException; import org.nightlabs.jfire.accounting.gridpriceconfig.PriceCalculator; import org.nightlabs.jfire.accounting.gridpriceconfig.PriceCell; import org.nightlabs.jfire.accounting.gridpriceconfig.PriceCoordinate; import org.nightlabs.jfire.store.NestedProductTypeLocal; import org.nightlabs.jfire.store.ProductType; import org.nightlabs.l10n.NumberFormatter; /** * @author Marco Schulze - marco at nightlabs dot de */ public class PriceConfigGrid extends XComposite implements ISelectionProvider { private PriceCalculator priceCalculator; private TableViewer gridTableViewer; private Table gridTable; private TableCursor gridTableCursor; private ProductTypeSelector productTypeSelector; private DimensionValueSelector dimensionValueSelector; private DimensionXYSelector dimensionXYSelector; private PriceConfigGridCell[][] cells = null; private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); public PriceConfigGrid( Composite parent, ProductTypeSelector productInfoSelector, DimensionValueSelector dimensionValueSelector, DimensionXYSelector dimensionXYSelector) { super(parent, SWT.NONE, LayoutMode.TIGHT_WRAPPER); this.productTypeSelector = productInfoSelector; this.dimensionValueSelector = dimensionValueSelector; this.dimensionXYSelector = dimensionXYSelector; productInfoSelector.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updateTableData(); } }); dimensionValueSelector.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updateTableData(); } }); dimensionXYSelector.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updateTableData(); } }); gridTableViewer = new TableViewer(this, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); // | SWT.FULL_SELECTION | SWT.MULTI); gridTable = gridTableViewer.getTable(); gridTable.setLayoutData(new GridData(GridData.FILL_BOTH)); gridTable.setLayout(new PriceConfigTableLayout()); gridTable.setLinesVisible(true); gridTable.addMouseListener(gridTableMouseListener); gridTableCursor = new TableCursor(gridTable, SWT.NONE); gridTableCursor.addKeyListener(gridTableCursorKeyListener); gridTableCursor.addSelectionListener(gridTableCursorSelectionListener); } private KeyListener gridTableCursorKeyListener = new KeyListener() { public void keyPressed(KeyEvent event) { } public void keyReleased(KeyEvent event) { if (event.character == ' ') { toggleSelection(gridTableCursor.getColumn(), gridTable.indexOf(gridTableCursor.getRow())); } updateTableDisplay(); } }; private MouseMoveListener gridTableMouseMoveListener = new MouseMoveListener() { public void mouseMove(MouseEvent event) { } }; private MouseListener gridTableMouseListener = new MouseAdapter() { private Point gridTableSelectionStart = null; private Point gridTableSelectionStop = null; protected Point getCellCoordinate(MouseEvent event) { Point pt = new Point(event.x, event.y); TableItem tableItem = gridTable.getItem(pt); if (tableItem != null) { int colCount = gridTable.getColumnCount(); for (int i = 0; i < colCount; ++i) { Rectangle rect = tableItem.getBounds(i); if (rect.contains (pt)) { return new Point(i, gridTable.indexOf(tableItem)); } } } return null; } @Override public void mouseDown(MouseEvent event) { gridTable.setSelection(-1); // deactivate the tables own selection shit gridTableSelectionStart = getCellCoordinate(event); } @Override public void mouseUp(MouseEvent event) { gridTableSelectionStop = getCellCoordinate(event); if (gridTableSelectionStart != null && gridTableSelectionStop != null) { selectedCellCoordinates.clear(); toggleSelection( gridTableSelectionStart.x, gridTableSelectionStart.y, gridTableSelectionStop.x, gridTableSelectionStop.y); } updateTableDisplay(); } }; private static final int DEFAULT_DATALEFT = 1; private static final int DEFAULT_DATATOP = 1; private static final Point DEFAULT_DATALEFTTOP = new Point(1, 1); /** * @return Returns the column index, where data is starting. * @see #getDataLeftTop() */ public int getDataLeft() { return DEFAULT_DATALEFT; } /** * @return Returns the row index, where data is starting. * @see #getDataLeftTop() */ public int getDataTop() { return DEFAULT_DATATOP; } /** * @return Returns the coordinate where the data is starting. Because there is usually * a horizontal and a vertical header, this method usually returns <tt>Point(1, 1)</tt>, * but there might be none or multiple header rows/columns. * @see #getDataLeft() * @see #getDataTop() */ public Point getDataLeftTop() { return DEFAULT_DATALEFTTOP; } private PriceConfigGridCell cursorCell = null; private Point cursorCellCoordinate = null; public PriceConfigGridCell getCursorCell() { if (cursorCell == null) { Point cursorCoordinate = getCursorCellCoordinate(); if (cursorCoordinate.x >= getDataLeft() && cursorCoordinate.y >= getDataTop()) cursorCell = cells[cursorCoordinate.y - getDataTop()][cursorCoordinate.x - getDataLeft()]; } return cursorCell; } /** * @return Returns the coordinate of the table's cursor where y is the row and x is the * column. Note, that the data does usually start at x = 1 and y = 1, because there * is a horizontal and a vertical header. * * @see #getDataLeftTop() * @see #getSelectedCellCoordinates() */ public Point getCursorCellCoordinate() { if (cursorCellCoordinate == null) { int cursorX = -1; int cursorY = -1; if (gridTableCursor.getRow() != null) { cursorX = gridTableCursor.getColumn(); cursorY = gridTable.indexOf(gridTableCursor.getRow()); } if (cursorX > gridTable.getColumnCount() - 1) cursorX = gridTable.getColumnCount() - 1; if (cursorY > gridTable.getItemCount() - 1) cursorY = gridTable.getItemCount() - 1; cursorCellCoordinate = new Point(cursorX, cursorY); } return cursorCellCoordinate; } private SelectionListener gridTableCursorSelectionListener = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { cursorCellCoordinate = null; cursorCell = null; fireSelectionChangedEvent(); } }; /** * Stores instances of Point where x and y specify the coordinates as columnIndex and * rowIndex. */ private HashSet selectedCellCoordinates = new HashSet(); private Collection selectedCells = null; protected void resetSelectedCells() { selectedCells = null; cursorCell = null; } /** * @return Returns a <tt>Collection</tt> of <tt>PriceConfigGridCell</tt>. */ public Collection getSelectedCells() { if (selectedCells == null) { selectedCells = new HashSet(); int dataLeft = getDataLeft(); int dataTop = getDataTop(); for (Iterator it = selectedCellCoordinates.iterator(); it.hasNext(); ) { Point coordinate = (Point)it.next(); if (coordinate.x >= dataLeft && coordinate.y >= dataTop) selectedCells.add(cells[coordinate.y - dataTop][coordinate.x - dataLeft]); } } return selectedCells; } /** * @return Returns instances of <tt>Point</tt> where x and y specify the column and the row * index of the selected cells. Note, that the cursor coordinate might be missing in * this <tt>Collection</tt>. Additionally, you should be aware that header cells might be * selected. * * @see #getCursorCellCoordinate() * @see #getDataLeftTop() */ public Collection getSelectedCellCoordinates() { return selectedCellCoordinates; } protected void toggleSelection(int col, int row) { toggleSelection(col, row, col, row); } /** * Automatically switches if left > right or top > bottom, thus the order doesn't matter. */ protected void toggleSelection(int left, int top, int right, int bottom) { if (left > right) { int i = left; left = right; right = i; } if (top > bottom) { int i = top; top = bottom; bottom = i; } int colCount = gridTable.getColumnCount(); int rowCount = gridTable.getItemCount(); if (left < getDataLeft()) { if (top < getDataTop()) bottom = rowCount - 1; boolean addMode = true; for (int col = left; col < colCount; ++col) { for (int row = top; row <= bottom; ++row) { Point cellCoordinate = new Point(col, row); if (col == 0 && selectedCellCoordinates.contains(cellCoordinate)) addMode = false; if (addMode) selectedCellCoordinates.add(cellCoordinate); else selectedCellCoordinates.remove(cellCoordinate); } } } else if (top < getDataTop()) { boolean addMode = true; for (int col = left; col <= right; ++col) { for (int row = top; row < rowCount; ++row) { Point cellCoordinate = new Point(col, row); if (row == 0 && selectedCellCoordinates.contains(cellCoordinate)) addMode = false; if (addMode) selectedCellCoordinates.add(cellCoordinate); else selectedCellCoordinates.remove(cellCoordinate); } } } else { for (int col = left; col <= right; ++col) { for (int row = top; row <= bottom; ++row) { Point cellCoordinate = new Point(col, row); if (selectedCellCoordinates.contains(cellCoordinate)) selectedCellCoordinates.remove(cellCoordinate); else selectedCellCoordinates.add(cellCoordinate); } } } resetSelectedCells(); fireSelectionChangedEvent(); } // private EventPackageProductInfo assemblyPackageProductInfo = null; // // public void setEventPackageProductInfo(EventPackageProductInfo assemblyPackageProductInfo) // throws ModuleException // { // this.assemblyPackageProductInfo = assemblyPackageProductInfo; // } // private MappingDimension gridDimensionX; // private MappingDimension gridDimensionY; // // public void setGridDimensions(MappingDimension gridDimensionX, MappingDimension gridDimensionY) // { // this.gridDimensionX = gridDimensionX; // this.gridDimensionY = gridDimensionY; // } protected void updateTableDisplay() { // TODO Global JFire Colors Color gray = Display.getDefault().getSystemColor(SWT.COLOR_GRAY); Color black = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); Color darkGray = Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY); Color white = Display.getDefault().getSystemColor(SWT.COLOR_WHITE); // Color blue = Display.getDefault().getSystemColor(SWT.COLOR_BLUE); Color darkBlue = Display.getDefault().getSystemColor(SWT.COLOR_DARK_BLUE); int cursorY = gridTableCursor.getRow() == null ? -1 : gridTable.indexOf(gridTableCursor.getRow()); int cursorX = gridTableCursor.getColumn(); Point cursor = new Point(cursorX, cursorY); if (selectedCellCoordinates.contains(cursor)) { gridTableCursor.setBackground(darkBlue); gridTableCursor.setForeground(white); } else { gridTableCursor.setBackground(white); gridTableCursor.setForeground(black); } int colCount = gridTable.getColumnCount(); TableItem[] rows = gridTable.getItems(); for (int r = 0; r < rows.length; ++r) { TableItem row = rows[r]; for (int c = 0; c < colCount; ++c) { Point cellCoordinate = new Point(c, r); if (selectedCellCoordinates.contains(cellCoordinate)) { // SELECTED // if (c == cursorX && r == cursorY) { // row.setBackground(c, darkBlue); // row.setForeground(c, white); // } // else { row.setBackground(c, darkGray); row.setForeground(c, white); // } } else { // NOT SELECTED // if (c == cursorX && r == cursorY) { // row.setBackground(c, blue); // row.setForeground(c, black); // } // else { row.setForeground(c, black); if (r == 0 && c == 0) row.setBackground(c, white); else if (r == 0 || c == 0) row.setBackground(c, gray); else row.setBackground(c, white); // } } } // for (int c = 0; c < colCount; ++c) { } // for (int r = 0; r < rows.length; ++r) { } public PriceFragmentType getSelectedPriceFragmentType(boolean throwExceptionIfNothingSelected) { DimensionValue dv = dimensionValueSelector.getSelectedDimensionValue( dimensionValueSelector.getDimensionIdxPriceFragmentType(), throwExceptionIfNothingSelected); if (dv == null) return null; return (PriceFragmentType) dv.getObject(); } protected void updateTableData() { boolean doResetSelectedCells = false; // does not mean that the selection will ge lost, // but the list of selected cell instances gets // cleared and a new selection event fired. int oldRowCount = gridTable.getItemCount(); int oldColCount = gridTable.getColumnCount(); gridTable.removeAll(); TableColumn[] cols = gridTable.getColumns(); for (int i = 0; i < cols.length; ++i) cols[i].dispose(); if (productTypeSelector.getSelectedProductTypeItem(false) == null) doResetSelectedCells = true; else { NestedProductTypeLocal nestedProductTypeLocal = null; ProductType selectedProductType = productTypeSelector.getSelectedProductTypeItem(true).getProductType(); if (!productTypeSelector.getPackageProductType().getPrimaryKey().equals(selectedProductType.getPrimaryKey())) { nestedProductTypeLocal = productTypeSelector.getPackageProductType().getProductTypeLocal().getNestedProductTypeLocal( selectedProductType.getOrganisationID(), selectedProductType.getProductTypeID(), true); } IFormulaPriceConfig formulaPriceConfig = productTypeSelector.getSelectedProductType_FormulaPriceConfig(false); // IResultPriceConfig resultPriceConfig = productTypeSelector.getSelectedProductType_ResultPriceConfig(true); IResultPriceConfig resultPriceConfig = productTypeSelector.getSelectedProductType_ResultPriceConfig(false); if (resultPriceConfig == null) doResetSelectedCells = true; else { // gridTable.removeAll(); // TableColumn[] cols = gridTable.getColumns(); // for (int i = 0; i < cols.length; ++i) // cols[i].dispose(); new TableColumn(gridTable, SWT.LEFT); Dimension gridDimensionX = dimensionXYSelector.getDimensionX(); Dimension gridDimensionY = dimensionXYSelector.getDimensionY(); int x = 1; TableItem headerX = new TableItem(gridTable, SWT.NONE); for (Iterator it = gridDimensionX.getValues().iterator(); it.hasNext(); ) { DimensionValue dvX = (DimensionValue)it.next(); new TableColumn(gridTable, SWT.RIGHT); headerX.setText(x, dvX.getName()); ++x; } IPriceCoordinate priceCoordinate = dimensionValueSelector.preparePriceCoordinate(); if (priceCoordinate == null) // we have no dimensionvalues in at least one dimension return; PriceFragmentType priceFragmentType = getSelectedPriceFragmentType(true); if (cells != null) { if (cells.length != gridDimensionY.getValues().size()) cells = null; else if (cells.length < 1) cells = null; else if (cells[0].length != gridDimensionX.getValues().size()) cells = null; } if (cells == null) { cells = new PriceConfigGridCell[gridDimensionY.getValues().size()][gridDimensionX.getValues().size()]; doResetSelectedCells = true; } int cellsY = 0; for (Iterator itY = gridDimensionY.getValues().iterator(); itY.hasNext(); ) { DimensionValue dvY = (DimensionValue)itY.next(); TableItem row = new TableItem(gridTable, SWT.NONE); row.setText(0, dvY.getName()); if (dvY instanceof DimensionValue.PriceFragmentTypeDimensionValue) priceFragmentType = (PriceFragmentType) dvY.getObject(); else dvY.adjustPriceCoordinate(priceCoordinate); int tableX = 1; int cellsX = 0; for (Iterator it = gridDimensionX.getValues().iterator(); it.hasNext(); ) { DimensionValue dvX = (DimensionValue)it.next(); if (dvX instanceof DimensionValue.PriceFragmentTypeDimensionValue) priceFragmentType = (PriceFragmentType) dvX.getObject(); else dvX.adjustPriceCoordinate(priceCoordinate); if (nestedProductTypeLocal != null) priceCoordinate = priceCalculator.createMappedLocalPriceCoordinate(nestedProductTypeLocal, priceFragmentType, priceCoordinate); PriceCell priceCell = resultPriceConfig.getPriceCell(priceCoordinate, false); if (priceCell != null) { long amount = priceCell.getPrice().getAmount(priceFragmentType); Currency currency = priceCell.getPrice().getCurrency(); // row.setText(tableX, Long.toString(amount)); row.setText(tableX, NumberFormatter.formatCurrency(amount, currency, false)); } PriceConfigGridCell cell = cells[cellsY][cellsX]; if (cell == null || formulaPriceConfig != cell.getFormulaPriceConfig() || !priceCoordinate.equals(cell.getPriceCoordinate()) || priceFragmentType != cell.getPriceFragmentType()) { cells[cellsY][cellsX] = new PriceConfigGridCell( formulaPriceConfig, resultPriceConfig, createPriceCoordinate(priceCoordinate), priceFragmentType); cells[cellsY][cellsX].addPropertyChangeListener(cellChangedListener); doResetSelectedCells = true; } cellsX = tableX++; } ++cellsY; } // Make sure we never have illegal selected cells (out of range) // but keep the selection if possible. if (oldRowCount != gridTable.getItemCount() || oldColCount != gridTable.getColumnCount()) { selectedCellCoordinates.clear(); cursorCellCoordinate = null; // Point coordinate = getCursorCellCoordinate(); // // if (coordinate.y > gridTable.getItemCount() - 1) // coordinate.y = gridTable.getItemCount() - 1; // // if (coordinate.x > gridTable.getColumnCount() - 1) // coordinate.x = gridTable.getColumnCount() - 1; // gridTableCursor. // .setSelection(null, 0); // coordinate.x, coordinate.y); doResetSelectedCells = true; } } // if (formulaPriceConfig != null) } // if (productTypeSelector.getSelectedProductTypeItem(false) != null) if (doResetSelectedCells) { resetSelectedCells(); fireSelectionChangedEvent(); } gridTable.layout(); updateTableDisplay(); } protected PriceCoordinate createPriceCoordinate(IPriceCoordinate priceCoordinate) { return new PriceCoordinate(priceCoordinate); } private PropertyChangeListener cellChangedListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { try { if (priceCalculator != null) priceCalculator.calculatePrices(); // <-- Note the PLURAL term. } catch (PriceCalculationException e) { // This is where the (formula) "error" originates. // Full error message is contained in the exception caught from priceCalculator.calculatePrices(). // But we try to display the error in a more user-friendly way. propertyChangeSupport.firePropertyChange(PriceConfigComposite.PROPERTY_CHANGE_KEY_PRICE_CONFIG_ERROR, null, e); return; } updateTableData(); propertyChangeSupport.firePropertyChange(PriceConfigComposite.PROPERTY_CHANGE_KEY_PRICE_CONFIG_CHANGED, null, null); } }; /** * This method takes a <tt>PriceCoordinate</tt> (e.g. created by <tt>DimensionValueSelector.preparePriceCoordinate()</tt>) * and adjusts it to match the given cell (defined by gridX & gridY). * <p> * Note, that the <tt>PriceFragmentType</tt> is not part of the <tt>PriceCoordinate</tt>, * because price fragments are - as the name says - fragments within a price cell. The * visualisation in the table is "virtual" and works in conjunction with * <tt>getPriceFragmentType(int gridX, int gridY)</tt>. * * @param priceCoordinate The <tt>PriceCoordinate</tt> to manipulate. * @param gridX The column index. Must be >= than <tt>dataLeft</tt>. * @param gridY The row index. Must be >= than <tt>dataTop</tt>. * * @see #getPriceFragmentType(int, int) */ public void adjustPriceCoordinate(PriceCoordinate priceCoordinate, int gridX, int gridY) { int dimensionXIndex = gridX - getDataLeft(); // because of header int dimensionYIndex = gridY - getDataTop(); if (dimensionXIndex < 0) throw new IllegalArgumentException("gridX < dataLeft!"); //$NON-NLS-1$ if (dimensionYIndex < 0) throw new IllegalArgumentException("gridY < dataTop!"); //$NON-NLS-1$ if (!(dimensionXYSelector.getDimensionX() instanceof Dimension.PriceFragmentTypeDimension)) ((DimensionValue)dimensionXYSelector.getDimensionX().getValues() .get(dimensionXIndex)).adjustPriceCoordinate(priceCoordinate); if (!(dimensionXYSelector.getDimensionY() instanceof Dimension.PriceFragmentTypeDimension)) ((DimensionValue)dimensionXYSelector.getDimensionY().getValues() .get(dimensionYIndex)).adjustPriceCoordinate(priceCoordinate); } /** * @param gridX The column index. Must be >= than <tt>dataLeft</tt>. * @param gridY The row index. Must be >= than <tt>dataTop</tt>. * @return If either the X or the Y axis is spanning <tt>PriceFragmentType</tt> s, * it returns the <tt>PriceFragmentType</tt> defined by <tt>gridX</tt> or * <tt>gridY</tt>; otherwise the one coming from the <tt>DimensionValueSelector</tt>. * Never returns <tt>null</tt>. */ public PriceFragmentType getPriceFragmentType(int gridX, int gridY) { int dimensionXIndex = gridX - getDataLeft(); // because of header int dimensionYIndex = gridY - getDataTop(); if (dimensionXIndex < 0) throw new IllegalArgumentException("gridX < dataLeft!"); //$NON-NLS-1$ if (dimensionYIndex < 0) throw new IllegalArgumentException("gridY < dataTop!"); //$NON-NLS-1$ PriceFragmentType priceFragmentType = null; if (dimensionXYSelector.getDimensionX() instanceof Dimension.PriceFragmentTypeDimension) priceFragmentType = (PriceFragmentType)((DimensionValue)dimensionXYSelector.getDimensionX() .getValues().get(dimensionXIndex)).getObject(); if (dimensionXYSelector.getDimensionY() instanceof Dimension.PriceFragmentTypeDimension) priceFragmentType = (PriceFragmentType)((DimensionValue)dimensionXYSelector.getDimensionY() .getValues().get(dimensionYIndex)).getObject(); if (priceFragmentType == null) priceFragmentType = getSelectedPriceFragmentType(true); return priceFragmentType; } private List selectionChangedListeners = new LinkedList(); protected void fireSelectionChangedEvent() { SelectionChangedEvent e = new SelectionChangedEvent(this, getSelection()); for (Iterator it = selectionChangedListeners.iterator(); it.hasNext(); ) { ISelectionChangedListener l = (ISelectionChangedListener)it.next(); l.selectionChanged(e); } } /** * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) */ public void addSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedListeners.add(listener); } /** * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection() */ public ISelection getSelection() { return new PriceConfigGridSelection( getCursorCellCoordinate(), getCursorCell(), getSelectedCellCoordinates(), getSelectedCells()); } /** * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) */ public void removeSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedListeners.remove(listener); } /** * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection) */ public void setSelection(ISelection selection) { throw new UnsupportedOperationException("NYI"); //$NON-NLS-1$ } /** * @return Returns the productTypeSelector. */ public ProductTypeSelector getProductTypeSelector() { return productTypeSelector; } /** * @return Returns the priceCalculator. */ public PriceCalculator getPriceCalculator() { return priceCalculator; } /** * @param priceCalculator The priceCalculator to set. */ public void setPriceCalculator(PriceCalculator priceCalculator) { this.priceCalculator = priceCalculator; } public void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(listener); } public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); } }