/*******************************************************************************
* Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
* This file is part of Gluster Management Console.
*
* Gluster Management Console is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Gluster Management Console 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
package org.gluster.storage.management.console.utils;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.ColumnLayout;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.progress.IProgressConstants;
import org.gluster.storage.management.console.Application;
import org.gluster.storage.management.console.ConsoleConstants;
import org.gluster.storage.management.console.GlusterDataModelManager;
import org.gluster.storage.management.console.IImageKeys;
import org.gluster.storage.management.console.views.NavigationView;
import org.gluster.storage.management.console.views.TasksView;
import org.gluster.storage.management.core.exceptions.GlusterRuntimeException;
import org.gluster.storage.management.core.model.Disk;
import org.gluster.storage.management.core.utils.JavaUtil;
public class GUIHelper {
private static final GUIHelper instance = new GUIHelper();
private static final ImageUtil imageUtil = new ImageUtil();
private static final GlusterLogger logger = GlusterLogger.getInstance();
private GUIHelper() {
}
public static GUIHelper getInstance() {
return instance;
}
public ScrolledForm setupForm(Composite parent, FormToolkit toolkit, final String formName) {
return setupForm(toolkit, formName, toolkit.createScrolledForm(parent));
}
public ScrolledForm setupForm(FormToolkit toolkit, final String formName, ScrolledForm form) {
form.setText(formName);
toolkit.decorateFormHeading(form.getForm());
ColumnLayout layout = new ColumnLayout();
// layout.topMargin = 0;
// layout.bottomMargin = 5;
// layout.leftMargin = 10;
// layout.rightMargin = 10;
// layout.horizontalSpacing = 10;
// layout.verticalSpacing = 10;
// layout.maxNumColumns = 4;
// layout.minNumColumns = 1;
form.getBody().setLayout(layout);
return form;
}
public Composite createSection(final ScrolledForm form, FormToolkit toolkit, String title, String desc,
int numColumns, boolean collapsible) {
int style = Section.TITLE_BAR | Section.EXPANDED;
if (desc != null && !desc.isEmpty()) {
style |= Section.DESCRIPTION;
}
if (collapsible) {
style |= Section.TWISTIE;
}
Section section = toolkit.createSection(form.getBody(), style);
section.setText(title);
section.setDescription(desc);
// toolkit.createCompositeSeparator(section);
Composite client = toolkit.createComposite(section);
GridLayout layout = new GridLayout();
layout.marginWidth = layout.marginHeight = 0;
layout.numColumns = numColumns;
layout.verticalSpacing = 10;
layout.marginBottom = 15;
layout.marginTop = 10;
client.setLayout(layout);
section.setClient(client);
section.addExpansionListener(new ExpansionAdapter() {
public void expansionStateChanged(ExpansionEvent e) {
form.reflow(false);
}
});
return client;
}
public Composite createTab(TabFolder tabFolder, String title, String imageKey) {
TabItem item = new TabItem(tabFolder, SWT.NONE);
item.setText(title);
item.setImage(getImage(imageKey));
Composite composite = new Composite(tabFolder, SWT.NONE);
composite.setLayout(new FillLayout());
item.setControl(composite);
return composite;
}
public ImageDescriptor getImageDescriptor(String imagePath) {
return imageUtil.getImageDescriptor(imagePath);
}
public Image getImage(String imagePath) {
return imageUtil.getImage(imagePath);
}
public Action createPullDownMenu(String menuName, String iconPath, final MenuManager menuManager) {
Action action = new Action(menuName, IAction.AS_DROP_DOWN_MENU) {
public void run() {
}
};
action.setMenuCreator(new IMenuCreator() {
@Override
public Menu getMenu(Menu menu) {
return null;
}
@Override
public Menu getMenu(Control control) {
return menuManager.createContextMenu(control);
}
@Override
public void dispose() {
}
});
action.setImageDescriptor(getImageDescriptor(iconPath));
return action;
}
public TableColumnLayout createTableColumnLayout(Table table, String[] columns) {
TableColumnLayout tableColumnLayout = new TableColumnLayout();
ColumnLayoutData defaultColumnLayoutData = new ColumnWeightData(100);
for (String columnName : columns) {
TableColumn column = new TableColumn(table, SWT.LEFT);
column.setText(columnName);
tableColumnLayout.setColumnData(column, defaultColumnLayoutData);
}
return tableColumnLayout;
}
/**
* Creates a filter for given structured viewer that will filter the contents of the viewer based on the current
* text of the text field
*
* @param viewer
* Structured viewer for which the filter is to be created
* @param filterText
* The text field whose contents are to be used for filtering
* @param caseSensitive
* Flag indicating whether the filtering should be case sensitive
* @return The newly created filter
*/
public EntityViewerFilter createFilter(final StructuredViewer viewer, final Text filterText, boolean caseSensitive) {
final String initialFilterString = filterText.getText();
final EntityViewerFilter filter = new EntityViewerFilter(initialFilterString, caseSensitive);
// On every keystroke inside the text field, update the filter string
filterText.addKeyListener(new KeyAdapter() {
private String filterString = initialFilterString;
@Override
public void keyReleased(KeyEvent e) {
String enteredString = filterText.getText();
if (enteredString.equals(filterString)) {
// Filter string has not changed. don't do anything
return;
}
// Update filter string
filterString = enteredString;
filter.setFilterString(filterString);
// Refresh viewer with newly filtered content
viewer.refresh(true);
if(viewer instanceof TreeViewer) {
((TreeViewer)viewer).expandAll();
}
}
});
viewer.addFilter(filter);
return filter;
}
public IViewPart getView(String viewId) {
IViewReference[] views = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
.getViewReferences();
for (IViewReference view : views) {
if (view.getId().equals(viewId)) {
return view.getView(false);
}
}
return null;
}
public IWorkbenchPart getActiveView() {
return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart();
}
public ControlDecoration createErrorDecoration(Control control) {
ControlDecoration passwordErrorDecoration = new ControlDecoration(control, SWT.LEFT | SWT.TOP);
passwordErrorDecoration.setImage(FieldDecorationRegistry.getDefault()
.getFieldDecoration(FieldDecorationRegistry.DEC_ERROR).getImage());
return passwordErrorDecoration;
}
public void centerShellInScreen(Shell shell) {
Rectangle monitorBounds = shell.getMonitor().getBounds();
Rectangle myBounds = shell.getBounds();
int x = monitorBounds.x + (monitorBounds.width - myBounds.width) / 2;
int y = monitorBounds.y + (monitorBounds.height - myBounds.height) / 2;
shell.setLocation(x, y);
}
public Text createFilterText(FormToolkit toolkit, Composite parent) {
final String tooltipMessage = "Start typing to filter table contents.";
final Text filterText = toolkit.createText(parent, "", SWT.FLAT);
GridData data = new GridData(SWT.RIGHT, SWT.CENTER, false, false);
data.widthHint = 300;
filterText.setLayoutData(data);
ControlDecoration searchDecoration = new ControlDecoration(filterText, SWT.LEFT);
searchDecoration.setImage(getImage(IImageKeys.SEARCH_22x22));
searchDecoration.show();
searchDecoration.setShowHover(true);
searchDecoration.setDescriptionText(tooltipMessage);
searchDecoration.setMarginWidth(5);
filterText.setToolTipText(tooltipMessage);
return filterText;
}
public Text createFilterText(Composite parent) {
final String tooltipMessage = "Start typing to filter table contents.";
final Text filterText = new Text(parent, SWT.FLAT);
GridData data = new GridData(SWT.LEFT, SWT.CENTER, false, false);
data.widthHint = 300;
filterText.setLayoutData(data);
ControlDecoration searchDecoration = new ControlDecoration(filterText, SWT.RIGHT);
searchDecoration.setImage(getImage(IImageKeys.SEARCH_22x22));
searchDecoration.show();
searchDecoration.setShowHover(true);
searchDecoration.setDescriptionText(tooltipMessage);
filterText.setToolTipText(tooltipMessage);
return filterText;
}
/**
* Sets properties for alignment and weight of given column of given table
*
* @param table
* @param columnIndex
* @param alignment
* @param weight
*/
public void setColumnProperties(Table table, int columnIndex, int alignment, int weight) {
TableColumn column = table.getColumn(columnIndex);
column.setAlignment(alignment);
TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout();
tableColumnLayout.setColumnData(column, new ColumnWeightData(weight));
}
/**
* Fetches the currently selected objects from the workbench site and returns the one of given type. If none of the
* selected objects are of given type, returns null
*
* @param site
* The workbench site
* @param expectedType
* Type of the selected object to look for
* @return The selected object of given type if found, else null
*/
public <T> T getSelectedEntity(IWorkbenchSite site, Class<T> expectedType) {
return getSelectedEntity(site.getWorkbenchWindow(), expectedType);
}
@SuppressWarnings({ "unchecked" })
public <T> T getSelectedEntity(IWorkbenchWindow window, Class<T> expectedType) {
ISelection selection = window.getSelectionService().getSelection(NavigationView.ID);
if (selection instanceof IStructuredSelection) {
Iterator<Object> iter = ((IStructuredSelection) selection).iterator();
while (iter.hasNext()) {
Object selectedObj = iter.next();
if (selectedObj.getClass() == expectedType) {
return (T)selectedObj;
}
}
}
return null;
}
/**
* Fetches the currently selected objects from the workbench site and returns those of given type. If none of the
* selected objects are of given type, returns null
*
* @param site
* The workbench site
* @param expectedType
* Type of the selected objects to look for
* @return The selected objects of given type if found, else null
*/
public <T> Set<T> getSelectedEntities(IWorkbenchSite site, Class<T> expectedType) {
return getSelectedEntities(site.getWorkbenchWindow(), expectedType);
}
@SuppressWarnings("unchecked")
public <T> Set<T> getSelectedEntities(IWorkbenchWindow window, Class<T> expectedType) {
Set<T> selectedEntities = new HashSet<T>();
ISelection selection = window.getSelectionService().getSelection();
if (selection instanceof IStructuredSelection) {
Iterator<Object> iter = ((IStructuredSelection) selection).iterator();
while (iter.hasNext()) {
Object selectedObj = iter.next();
if (selectedObj.getClass() == expectedType) {
selectedEntities.add((T) selectedObj);
}
}
}
return selectedEntities;
}
public void configureCheckboxTableViewer(final CheckboxTableViewer tableViewer) {
tableViewer.addCheckStateListener(new ICheckStateListener() {
@Override
public void checkStateChanged(CheckStateChangedEvent event) {
tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements()));
}
});
tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
List<Object> checkedElements = Arrays.asList(tableViewer.getCheckedElements());
List<Object> selectedElements = ((IStructuredSelection)event.getSelection()).toList();
if (JavaUtil.listsDiffer(checkedElements, selectedElements)) {
tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements()));
}
}
});
}
public void showView(String viewId) {
try {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(viewId);
} catch (PartInitException e) {
String errMsg = "Could not open view [" + viewId + "]";
logger.error(errMsg, e);
throw new GlusterRuntimeException(errMsg, e);
}
}
public void showTerminalView() {
showView(ConsoleConstants.TERMINAL_VIEW_ID);
}
public void showProgressView() {
showView(IProgressConstants.PROGRESS_VIEW_ID);
}
public void showTaskView() {
NavigationView navigationView = (NavigationView) getView(NavigationView.ID);
navigationView.selectEntity(GlusterDataModelManager.getInstance().getModel().getCluster());
showView(TasksView.ID);
}
public void setStatusMessage(String message) {
clearStatusMessage();
Application.getApplication().getStatusLineManager().setMessage(message);
Application.getApplication().getStatusLineManager().setMessage(message);
}
public void clearStatusMessage() {
Application.getApplication().getStatusLineManager().setMessage(null);
}
public String getDiskToolTip(Disk disk) {
return disk.getQualifiedName() + " - " + disk.getDescription();
}
public void clearSection(Composite section) {
if (section.isDisposed()) {
return;
}
for(Control control : section.getChildren()) {
if(! control.isDisposed()) {
control.dispose();
}
}
section.layout(true);
}
}