/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.ui.objecteditor; import java.util.Properties; import java.util.Set; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Widget; import org.jboss.tools.common.editor.AbstractSelectionProvider; import org.jboss.tools.common.meta.action.XActionInvoker; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.ui.action.CommandBar; import org.jboss.tools.common.model.ui.action.CommandBarListener; import org.jboss.tools.common.model.ui.dnd.ControlDragDrop; import org.jboss.tools.common.model.ui.dnd.IControlDragDropProvider; import org.jboss.tools.common.model.ui.dnd.IControlDropListener; import org.jboss.tools.common.model.ui.swt.util.BorderLayout; import org.jboss.tools.common.model.util.AbstractTableHelper; public class XChildrenEditor implements CommandBarListener { protected static Color DEFAULT_COLOR = Display.getDefault().getSystemColor(SWT.COLOR_BLACK); protected static Color GREYED_COLOR = Display.getDefault().getSystemColor(SWT.COLOR_GRAY); protected static Color RED_COLOR = Display.getDefault().getSystemColor(SWT.COLOR_RED); public static String ADD = Messages.XChildrenEditor_Add; public static String DELETE = Messages.XChildrenEditor_Delete; public static String EDIT = Messages.XChildrenEditor_Edit; public static String UP = Messages.XChildrenEditor_Up; public static String DOWN = Messages.XChildrenEditor_Down; protected Composite control; protected AbstractTableHelper helper = createHelper(); protected XTable xtable = new XTable(); protected boolean lock = false; protected CommandBar bar = new CommandBar(); protected SelectionListener selectionListener = null; DnDProvider dndProvider = new DnDProvider(); ControlDragDrop dnd = new ControlDragDrop(); public void dispose() { if (xtable!=null) xtable.dispose(); xtable = null; if (bar!=null) bar.dispose(); bar = null; } public XChildrenEditor() { bar.addCommandBarListener(this); xtable.setTableProvider(new XTableProviderImpl()); } public void setMnemonicEnabled(boolean b) { bar.setMnemonicEnabled(b); } public void setHeaderVisible(boolean b) { xtable.setHeaderVisible(b); } public Control createControl(Composite parent) { control = new Composite(parent, SWT.NONE); BorderLayout bl = new BorderLayout(); control.setLayout(bl); xtable.createControl(control); bl.centerComposite = xtable.getControl(); createCommandBar(); enableSelectionListener(); update(); dnd.setProvider(dndProvider); dnd.enable(); xtable.getTable().addMouseListener(new DoubleClickListener()); xtable.update(); return control; } class DoubleClickListener extends MouseAdapter { public void mouseDoubleClick(MouseEvent e) { if(bar.isEnabled(EDIT)) action(EDIT); } } public Control getControl() { return control; } protected int[] getColumnWidthHints() { int l = helper.getHeader().length; int[] is = new int[l]; for (int i = 0; i < l; i++) is[i] = 10; return is; } protected void createCommandBar() { String[] commands = (areUpDounActionsEnabled()) ? new String[]{ADD, EDIT, DELETE, UP, DOWN} : new String[]{ADD, EDIT, DELETE}; bar.setCommands(commands); bar.getLayout().direction = SWT.VERTICAL; bar.getLayout().buttonWidth = convertHorizontalDLUsToPixels(control, IDialogConstants.BUTTON_WIDTH); setMargins(bar); bar.createControl(control); BorderLayout bl = (BorderLayout)control.getLayout(); bl.eastComposite = bar.getControl(); bl.eastWidth = SWT.DEFAULT; } protected void setMargins(CommandBar bar) { bar.getLayout().setMargins(0,10,0,0); } protected int convertHorizontalDLUsToPixels(Control control, int dlus) { GC gc= new GC(control); gc.setFont(control.getFont()); int averageWidth= gc.getFontMetrics().getAverageCharWidth(); gc.dispose(); double horizontalDialogUnitSize = averageWidth * 0.25; return (int)Math.round(dlus * horizontalDialogUnitSize); } protected AbstractTableHelper createHelper() { return null; } public void setObject(XModelObject object) { helper.setModelObject(object); if(xtable != null && xtable.getTable() != null && xtable.getSelectionIndex() < 0 && xtable.getTable().getItemCount() > 0) { xtable.getTable().select(0); } } protected boolean areUpDounActionsEnabled() { return false; } long updateTimeStamp = -1; public void update() { if(xtable.getControl() == null || xtable.getControl().isDisposed()) return; long ts = (helper.getModelObject() == null) ? -1 : helper.getModelObject().getTimeStamp(); if(ts != updateTimeStamp || ts == -1) { updateTimeStamp = ts; lock = true; xtable.update(); lock = false; } if(selectionListener != null) updateBar(); } protected Color getItemColor(int i) { return DEFAULT_COLOR; } protected void enableSelectionListener() { selectionListener = new TL(); xtable.getTable().addSelectionListener(selectionListener); updateBar(); } class TL implements SelectionListener { public void widgetSelected(SelectionEvent e) { onSelectionChanged(); } public void widgetDefaultSelected(SelectionEvent e) {} } protected void onSelectionChanged() { if(!lock) { updateBar(); selectionProvider.fireSelectionChanged(); } } public void action(String command) { if(ADD.equals(command)) add(); else if(DELETE.equals(command)) delete(); else if(EDIT.equals(command)) edit(); else if(UP.equals(command)) up(); else if(DOWN.equals(command)) down(); update(); if(xtable.isActive()) xtable.getTable().setFocus(); } protected void add() { if(helper.getModelObject() == null) return; Set set = getKeys(); callAction(helper.getModelObject(), getAddActionPath()); update(); int i = getAddedKey(set); if(i >= 0) { xtable.setSelection(i); onSelectionChanged(); } } protected void delete() { XModelObject o = helper.getModelObject(xtable.getSelectionIndex()); if(o != null) callAction(o, "DeleteActions.Delete"); //$NON-NLS-1$ } protected void edit() { XModelObject o = helper.getModelObject(xtable.getSelectionIndex()); if(o != null) callAction(o, "Edit"); //$NON-NLS-1$ } protected void up() { int r1 = xtable.getSelectionIndex(), r2 = r1 - 1; if(r2 < 0) return; move(r1, r2); } protected void down() { int r1 = xtable.getSelectionIndex(), r2 = r1 + 1; if(r1 < 0 || r2 >= xtable.getTable().getItemCount()) return; move(r1, r2); } private void move(int r1, int r2) { XModelObject o1 = helper.getModelObject(r1), o2 = helper.getModelObject(r2); callAction(o1, "CopyActions.Copy"); //$NON-NLS-1$ callAction(o2, "MoveActions.Move"); //$NON-NLS-1$ if(helper.getModelObject(r2) == o1) { xtable.getViewer().setSelection(new StructuredSelection(o1) , true); ((SP)getSelectionProvider()).fireSelectionChanged(); } } protected Set getKeys() { return xtable.getKeys(); } protected int getAddedKey(Set set) { return xtable.getAddedKey(set); } protected String getAddActionPath() { return "CreateActions.AddKeyPair"; //$NON-NLS-1$ } protected void updateBar() { boolean enabled = !isReadOnly(); boolean multi = xtable.getTable().getSelectionIndices().length > 1; int r = (!enabled) ? -1 : xtable.getSelectionIndex(); bar.setEnabled(ADD, enabled); bar.setEnabled(DELETE, r >= 0); bar.setEnabled(EDIT, r >= 0 && !multi); if(areUpDounActionsEnabled()) { bar.setEnabled(UP, r > 0 && !multi); bar.setEnabled(DOWN, (r >= 0 && r < helper.size() - 1) && !multi); } } protected boolean isReadOnly() { return (helper == null || helper.getModelObject() == null || !helper.getModelObject().isObjectEditable()); } public void callAction(XModelObject o, String path) { Properties p = new Properties(); p.put("shell", bar.getControl().getShell()); //$NON-NLS-1$ int i = xtable.getSelectionIndex(); p.put("insertAfter", Integer.valueOf(i)); //$NON-NLS-1$ XActionInvoker.invoke(path, o, getTargets(), p); } private XModelObject[] getTargets() { int[] is = xtable.getTable().getSelectionIndices(); if(is.length < 2) return null; XModelObject[] os = new XModelObject[is.length]; for (int i = 0; i < os.length; i++) { os[i] = helper.getModelObject(is[i]); } return os; } class XTableProviderImpl implements XTableProvider { public int getColumnCount() { return helper.getHeader().length; } public int getRowCount() { return helper.size(); } public String getColumnName(int c) { return helper.getVisibleHeader()[c]; } public String getValueAt(int r, int c) { return helper.getValueAt(r, c); } public Color getColor(int r) { return getItemColor(r); } public int getWidthHint(int c) { return getColumnWidthHints()[c]; } public Object getDataAt(int r) { return helper.getModelObject(r); } public void dispose() { } } AbstractSelectionProvider selectionProvider = new SP(); public ISelectionProvider getSelectionProvider() { return selectionProvider; } public XModelObject getSelectedObject() { return ((SP)selectionProvider).getSelectedModelObject(); } class SP extends AbstractSelectionProvider { protected XModelObject getSelectedModelObject() { if(xtable.getTable() == null || xtable.getTable().isDisposed()) return null; int r = xtable.getSelectionIndex(); return helper.getModelObject(r); } protected void setSelectedModelObject(XModelObject object) { if(xtable.getTable() == null || xtable.getTable().isDisposed()) return; if(object == null || object.getPath() == null) return; XModelObject o = helper.getModelObject(); if(o != null && !object.getPath().startsWith(o.getPath())) return; for (int i = 0; i < helper.size(); i++) { if(helper.getModelObject(i) == object) { xtable.setSelection(i); updateBar(); return; } } } } class DnDProvider implements IControlDragDropProvider, IControlDropListener { public Control getControl() { return xtable.getTable(); } public XModelObject getModelObjectForWidget(Widget widget) { if(widget == null) return null; Object o = widget.getData(); return (o instanceof XModelObject) ? (XModelObject)o : null; } public Widget[] getSelection() { return xtable.getTable().getSelection(); } public Properties getDropProperties(int x, int y) { return new Properties(); } public void drop(Properties p) { XModelObject draggedObject = (XModelObject)p.get("draggedObject"); //$NON-NLS-1$ if(draggedObject == null) return; xtable.getViewer().cancelEditing(); update(); xtable.getViewer().setSelection(new StructuredSelection(draggedObject)); } } }