| /******************************************************************************* |
| * Copyright (c) 2016 ALL4TEC & CEA LIST. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * ALL4TEC & CEA LIST - initial API and implementation |
| ******************************************************************************/ |
| package org.polarsys.esf.core.common.ui.view; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.viewers.ArrayContentProvider; |
| import org.eclipse.jface.viewers.ColumnLabelProvider; |
| import org.eclipse.jface.viewers.ColumnViewer; |
| import org.eclipse.jface.viewers.EditingSupport; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.ViewerColumn; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.ListSelectionDialog; |
| import org.polarsys.esf.core.common.ui.CommonUIActivator; |
| |
| /** |
| * Abstract base of all the Pages to use in a PageBookView, |
| * and which includes a tree. |
| * |
| * This implementation doesn't manage the columns in the tree, |
| * but it inherits of all the standard mechanisms like the filters, the editing domain mechanisms, etc. |
| * |
| * @author $Author: jdumont $ |
| * @version $Revision: 83 $ |
| */ |
| public abstract class AbstractColumnViewerPage |
| extends AbstractPage { |
| |
| /** |
| * Name of the required column. |
| * The required column is mandatory and can't be hidden. |
| */ |
| private String mRequiredColumnName = null; |
| |
| /** Arrays of the optional columns names, which can be displayed in the tree view. */ |
| private String[] mColumnsNamesArray = null; |
| |
| /** |
| * Default constructor, which allows to specify if the viewer must be read only or not. |
| * |
| * @param pReadOnlyMode <code>true</code> if this view is in read only mode, <code>false</code> otherwise |
| */ |
| public AbstractColumnViewerPage(final boolean pReadOnlyMode) { |
| // Call the advanced constructor with default values |
| this(StringUtils.EMPTY, new String[0], pReadOnlyMode); |
| } |
| |
| /** |
| * Advanced constructor which takes the name of the required column, an array with the optional columns name, |
| * and a boolean which specifies if the viewer must be in read only mode or not. |
| * |
| * The required column will mandatory be visible and can't be hidden. |
| * |
| * @param pRequiredColumnName The name of the required column name |
| * @param pColumnsName The array of optional columns name. This list must not contain the required column name |
| * @param pReadOnlyMode <code>true</code> if this view is in read only mode, <code>false</code> otherwise |
| */ |
| public AbstractColumnViewerPage( |
| final String pRequiredColumnName, |
| final String[] pColumnsName, |
| final boolean pReadOnlyMode) { |
| |
| // Call the parent constructor |
| super(pReadOnlyMode); |
| |
| // Remember the given columns names |
| mRequiredColumnName = pRequiredColumnName; |
| mColumnsNamesArray = pColumnsName.clone(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected void setViewerProviders() { |
| // We call the createRequiredViewerColumn() and then we associate |
| // the providers to associate the default label provider to the required column |
| createRequiredViewerColumn(); |
| super.setViewerProviders(); |
| createInitialViewerColumns(); |
| } |
| |
| /** |
| * Create the required column in the viewer. |
| * @return The created column |
| */ |
| protected abstract ViewerColumn createRequiredViewerColumn(); |
| |
| /** |
| * Create the initial viewer columns, from the optional ones, which must be initially displayed. |
| * By default, no optional columns are initially displayed. |
| */ |
| protected void createInitialViewerColumns() { |
| // Nothing to do |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected abstract ColumnViewer createViewer(final Composite pParent); |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public ColumnViewer getViewer() { |
| return (ColumnViewer) super.getViewer(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * Overridden to add the actions for the columns, the headers and the lines visibility. |
| */ |
| @Override |
| protected void addMenuBarActions() { |
| addColumnsVisibilityAction(); |
| addMenuBarSeparator(); |
| addHideHeaderAction(); |
| addHideLinesAction(); |
| super.addMenuBarActions(); |
| } |
| |
| /** |
| * Add the columns visibility action to the menu bar. |
| */ |
| protected void addColumnsVisibilityAction() { |
| addMenuBarAction(createColumnsVisibilityAction()); |
| } |
| |
| /** |
| * Add the hide header action to the menu bar. |
| */ |
| protected void addHideHeaderAction() { |
| addMenuBarAction(createHideHeaderAction(isViewerHeaderInitiallyVisible())); |
| } |
| |
| /** |
| * Add the hide lines action to the menu bar. |
| */ |
| protected void addHideLinesAction() { |
| addMenuBarAction(createHideLinesAction(isViewerLinesInitiallyVisible())); |
| } |
| |
| /** |
| * Return <code>true</code>if the header of the viewer is initially visible. |
| * @return <code>true</code>if the header of the viewer is initially visible. |
| */ |
| protected abstract boolean isViewerHeaderInitiallyVisible(); |
| |
| /** |
| * Return <code>true</code>if the lines of the viewer are initially visible. |
| * @return <code>true</code>if the lines of the viewer are initially visible. |
| */ |
| protected abstract boolean isViewerLinesInitiallyVisible(); |
| |
| /** |
| * Create and return the columns visibility action |
| * linked to the managed viewer. |
| * |
| * @return A new instance of the column visibility action |
| */ |
| protected IAction createColumnsVisibilityAction() { |
| return new ColumnsVisibilityAction(); |
| } |
| |
| /** |
| * Create and return the hide lines action. |
| * |
| * @param pVisible <code>true</code> if the lines are visible by default, <code>false</code> otherwise |
| * @return A new instance of the hide lines action |
| */ |
| protected IAction createHideLinesAction(final boolean pVisible) { |
| // Create the action, with the right label and display it as a checkbox |
| final Action vHideLinesAction = new Action( |
| CommonUIActivator.getMessages().getString("AbstractColumnViewerPage.action.showlines"), //$NON-NLS-1$ |
| IAction.AS_CHECK_BOX) { |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void run() { |
| AbstractColumnViewerPage.this.setLinesVisible(isChecked()); |
| } |
| }; |
| |
| // Set the initial state to the action |
| vHideLinesAction.setChecked(pVisible); |
| |
| return vHideLinesAction; |
| } |
| |
| /** |
| * Create and return the hide header action. |
| * |
| * @param pVisible <code>true</code> if the header is visible by default, <code>false</code> otherwise |
| * @return A new instance of the hide header action |
| */ |
| protected IAction createHideHeaderAction(final boolean pVisible) { |
| // Create the action, with the right label and display it as a checkbox |
| final Action vHideHeaderAction = new Action( |
| CommonUIActivator.getMessages().getString("AbstractColumnViewerPage.action.showheaders"), //$NON-NLS-1$ |
| IAction.AS_CHECK_BOX) { |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void run() { |
| AbstractColumnViewerPage.this.setHeaderVisible(isChecked()); |
| } |
| }; |
| |
| // Set the initial state to the action |
| vHideHeaderAction.setChecked(pVisible); |
| |
| return vHideHeaderAction; |
| } |
| |
| /** |
| * Set the visibility of the lines in the viewer. |
| * |
| * @param pVisible <code>true</code> if the lines must be visible, <code>false</code> otherwise |
| */ |
| public abstract void setLinesVisible(final boolean pVisible); |
| |
| /** |
| * Set the visibility of the header in the viewer. |
| * |
| * @param pVisible <code>true</code> if the header must be visible, <code>false</code> otherwise |
| */ |
| public abstract void setHeaderVisible(final boolean pVisible); |
| |
| /** |
| * Create a new column at the end of the viewer, with the name given in parameter. |
| * |
| * @param pColumnName The name of the column |
| * @return The created tree viewer column, or null if the concrete implementation of this page doesn't support |
| * the column viewers |
| */ |
| protected abstract ViewerColumn createViewerColumn(final String pColumnName); |
| |
| /** |
| * Create a new column in the viewer, at the specified location, with the name given in parameter. |
| * |
| * @param pColumnName The name of the column |
| * @param pIndex The location index where the column must be created in the viewer |
| * @return The created tree viewer column, or null if the concrete implementation of this page doesn't support |
| * the column viewers |
| */ |
| protected abstract ViewerColumn createViewerColumn(final String pColumnName, final int pIndex); |
| |
| /** |
| * Create a new column at the end of the viewer, with the name given in parameter, and associate to it a |
| * label provider also given in parameter. |
| * |
| * @param pColumnName The name of the column |
| * @param pColumnLabelProvider The column label provider to use in the column |
| * |
| * @return The created tree viewer column, or null if the concrete implementation of this page doesn't support |
| * the column viewers |
| */ |
| protected abstract ViewerColumn createViewerColumn( |
| final String pColumnName, |
| final ColumnLabelProvider pColumnLabelProvider); |
| |
| /** |
| * Create a new column at the end of the viewer, with the name given in parameter, and associate to it a |
| * label provider and an editing support also given in parameter. |
| * |
| * @param pColumnName The name of the column |
| * @param pColumnLabelProvider The column label provider to use in the column |
| * @param pEditingSupport The editing support to use in the column |
| * |
| * @return The created tree viewer column, or null if the concrete implementation of this page doesn't support |
| * the column viewers |
| */ |
| protected abstract ViewerColumn createViewerColumn( |
| final String pColumnName, |
| final ColumnLabelProvider pColumnLabelProvider, |
| final EditingSupport pEditingSupport); |
| |
| /** |
| * Create a new column at the end of the viewer, with the name given in parameter, and associate to it a |
| * label provider and an editing support according to the property whose ID is given in parameter. |
| * |
| * @param pColumnName The name of the column |
| * @param pPropertyID The id of the property to display in the column |
| * |
| * @return The created tree viewer column, or null if the concrete implementation of this page doesn't support |
| * the column viewers |
| */ |
| protected abstract ViewerColumn createViewerColumn(final String pColumnName, final String pPropertyID); |
| |
| /** |
| * Show a list of columns whose name is given in parameter. |
| * |
| * @param pColumnsNamesArray The array of the columns names to display. |
| */ |
| protected void showColumns(final String[] pColumnsNamesArray) { |
| boolean vRefreshNeeded = false; |
| |
| if (pColumnsNamesArray != null) { |
| // Loop on the names to find and display the corresponding column |
| for (String vColumnName : pColumnsNamesArray) { |
| // Check if the column in not already visible |
| if (!isColumnVisible(vColumnName)) { |
| // Show the column and remember that a refresh is needed on the tree |
| vRefreshNeeded = showColumn(vColumnName) || vRefreshNeeded; |
| } |
| } |
| |
| // Refresh the tree content if at least one new column is displayed |
| if (vRefreshNeeded) { |
| getViewer().refresh(); |
| } |
| } |
| } |
| |
| /** |
| * Hide a list of columns, whose name is given in parameter. |
| * |
| * @param pColumnsNamesArray The array of the columns names to hide. |
| */ |
| protected void hideColumns(final String[] pColumnsNamesArray) { |
| if (pColumnsNamesArray != null) { |
| // Loop on the names to find and hide the corresponding column |
| for (final String vColumnName : pColumnsNamesArray) { |
| // Check if the column is really visible and then hide it |
| if (isColumnVisible(vColumnName)) { |
| hideColumn(vColumnName); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Show a column, whose name is given in parameter. |
| * The column may be created if needed. |
| * |
| * @param pColumnName The column name |
| * @return <code>true</code> if a column was found and shown, <code>false</code> otherwise |
| */ |
| protected abstract boolean showColumn(final String pColumnName); |
| |
| /** |
| * Hide the column whose name is given in parameter. |
| * |
| * @param pColumnName The column name |
| * @return <code>true</code> if a column was found and hidden, <code>false</code> otherwise |
| */ |
| protected abstract boolean hideColumn(final String pColumnName); |
| |
| /** |
| * Return a map containing in key the name of the columns |
| * and in value a flag specifying if it is currently visible or not. |
| * |
| * This map will contain the name of all the optional columns which may |
| * be added in the viewer, but not the required column which is considered |
| * as always visible. |
| * |
| * @return A map containing in key the name of the columns in the viewer, |
| * and in value a flag specifying if the column is visible or not |
| */ |
| protected Map<String, Boolean> getColumnsVisibility() { |
| // Create the returned map |
| final Map<String, Boolean> vColumnsVisibilityMap = new HashMap<String, Boolean>(mColumnsNamesArray.length); |
| |
| // Loop on the names of optional columns |
| for (final String vColumnName : mColumnsNamesArray) { |
| // Add in the map the corresponding key and flag value |
| vColumnsVisibilityMap.put(vColumnName, isColumnVisible(vColumnName)); |
| } |
| |
| return vColumnsVisibilityMap; |
| } |
| |
| /** |
| * Return the names of the optional columns which can be displayed in the tree view. |
| * |
| * @return The names of the optional columns which can be displayed in the tree view. |
| */ |
| public String[] getColumnsName() { |
| return mColumnsNamesArray; |
| } |
| |
| /** |
| * Return the name of the required column for the tree view. |
| * |
| * @return The required column name |
| */ |
| public String getRequiredColumnName() { |
| return mRequiredColumnName; |
| } |
| |
| /** |
| * Return <code>true</code> if a column exists in the viewer, |
| * and <code>false</code> otherwise. |
| * |
| * @param pColumnName The name of the column to check |
| * @return <code>true</code> if the table column is visible, <code>false</code> otherwise |
| */ |
| protected abstract boolean isColumnVisible(final String pColumnName); |
| |
| /** |
| * Custom action used to manage and change the visibility of the columns of the viewer. |
| * |
| * @author $Author: jdumont $ |
| * @version $Revision: 83 $ |
| */ |
| private class ColumnsVisibilityAction |
| extends Action { |
| |
| /** |
| * Default constructor. |
| */ |
| ColumnsVisibilityAction() { |
| super(CommonUIActivator.getMessages() |
| .getString("AbstractColumnViewerPage.menu.columnsvisibility")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void run() { |
| final List<String> vColumnsNameArray = new ArrayList<String>(); |
| final List<String> vVisibleColumnsNamesArray = new ArrayList<String>(); |
| |
| // Get the map specifying the visibility of each column |
| final Map<String, Boolean> vColumnsVisibilityMap = getColumnsVisibility(); |
| |
| // Loop on all the column visibility map to build two arrays : |
| // - one for all the columns names |
| // - one with only the name of visible columns |
| for (final String vColumnName : vColumnsVisibilityMap.keySet()) { |
| // Remember the column name |
| vColumnsNameArray.add(vColumnName); |
| |
| // Remember the name of the visible column |
| if (vColumnsVisibilityMap.get(vColumnName)) { |
| vVisibleColumnsNamesArray.add(vColumnName); |
| } |
| } |
| |
| // Open a dialog to allow the user which columns must be visible |
| final Object[] vResultsArray = openColumnsSelectionDialog( |
| vColumnsNameArray, |
| vVisibleColumnsNamesArray); |
| |
| if (vResultsArray != null) { |
| |
| // Loop on the results array to build a set containing all the |
| // names of the column to show |
| Set<String> vShownColumnsNamesSet = new HashSet<String>(); |
| for (final Object vResult : vResultsArray) { |
| // NB : The result is normally already a String with the column name |
| vShownColumnsNamesSet.add(vResult.toString()); |
| } |
| |
| // Then build the list of columns to hide, by removing from the whole list |
| // of columns, those to hide |
| Set<String> vHiddenColumnsNamesSet = new HashSet<String>(vColumnsVisibilityMap.keySet()); |
| vHiddenColumnsNamesSet.removeAll(vShownColumnsNamesSet); |
| |
| // Finally, hide and show the columns according to the user choices |
| hideColumns(vHiddenColumnsNamesSet.toArray(new String[vHiddenColumnsNamesSet.size()])); |
| showColumns(vShownColumnsNamesSet.toArray(new String[vShownColumnsNamesSet.size()])); |
| } |
| } |
| |
| /** |
| * Open a dialog allowing the user to select which columns must |
| * be visible in the viewer. |
| * |
| * The array of selected columns is directly returned. |
| * |
| * @param pColumnsNamesArray The array of all the column names |
| * @param pVisibleColumnsNamesArray The array of all the columns names already currently visible |
| * @return The array of all the columns names to show |
| */ |
| private Object[] openColumnsSelectionDialog( |
| final List<String> pColumnsNamesArray, |
| final List<String> pVisibleColumnsNamesArray) { |
| |
| Object[] vResultsArray = null; |
| |
| // Build the selection dialog |
| final ListSelectionDialog vDialog = new ListSelectionDialog( |
| PlatformUI.getWorkbench().getDisplay().getActiveShell(), |
| pColumnsNamesArray, |
| new ArrayContentProvider(), |
| new LabelProvider(), |
| CommonUIActivator.getMessages() |
| .getString("AbstractColumnViewerPage.label.columnsvisibility")); //$NON-NLS-1$ |
| |
| // Set the dialog title and select by default the columns which are currently visible |
| vDialog.setTitle(CommonUIActivator.getMessages() |
| .getString("AbstractColumnViewerPage.title.columnsvisibility")); //$NON-NLS-1$ |
| vDialog.setInitialElementSelections(pVisibleColumnsNamesArray); |
| |
| // Finally open the dialog and remember of its result if the user validate its choice |
| if (vDialog.open() == Window.OK) { |
| vResultsArray = vDialog.getResult(); |
| } |
| |
| return vResultsArray; |
| } |
| } |
| } |