org.thanlwinsoft.doccharconvert.eclipse.editors.ClassTableEditorPart.java Source code

Java tutorial

Introduction

Here is the source code for org.thanlwinsoft.doccharconvert.eclipse.editors.ClassTableEditorPart.java

Source

/*
Copyright (C) 2007 Keith Stribley http://www.thanlwinsoft.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 Street, Fifth Floor, Boston, MA  02110-1301  USA
------------------------------------------------------------------------------*/

package org.thanlwinsoft.doccharconvert.eclipse.editors;

import java.util.Arrays;
import java.util.Iterator;
import java.util.Vector;

import org.apache.xmlbeans.XmlException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;
import org.thanlwinsoft.doccharconvert.MessageUtil;
import org.thanlwinsoft.schemas.syllableParser.C;
import org.thanlwinsoft.schemas.syllableParser.ComponentRef;
import org.thanlwinsoft.schemas.syllableParser.SyllableConverter;
import org.thanlwinsoft.util.Triple;

/**
 * Editor for SyllableConverter classes
 * @author keith
 *
 */
public class ClassTableEditorPart extends EditorPart {
    private Table table;
    private TableViewer viewer;
    private final SyllableConverterEditor parentEditor;
    private org.thanlwinsoft.schemas.syllableParser.Class classTable;
    private Clipboard clipboard;
    private MenuManager menuManager;
    protected final static int COL_OFFSET = 1;

    /**
     * @param parentEditor
     * @param clazz
     */
    public ClassTableEditorPart(SyllableConverterEditor parentEditor,
            org.thanlwinsoft.schemas.syllableParser.Class clazz) {
        this.classTable = clazz;
        this.parentEditor = parentEditor;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
     */
    @Override
    public void doSave(IProgressMonitor monitor) {
        parentEditor.doSave(monitor);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.EditorPart#doSaveAs()
     */
    @Override
    public void doSaveAs() {
        parentEditor.doSaveAs();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
     */
    @Override
    public void init(IEditorSite site, IEditorInput input) throws PartInitException {
        this.setSite(site);
        clipboard = new Clipboard(site.getShell().getDisplay());
        final IEditorPart part = this;
        menuManager = new MenuManager(parentEditor.getPartName() + ":" + classTable.getId());
        Action insertAction = new Action() {
            public void run() {
                int mapIndex = getSelectedMapIndex();
                if (mapIndex < 0)
                    mapIndex = classTable.getComponentArray(0).sizeOfCArray();
                int insertRowCount = Math.max(1, table.getSelectionCount());
                for (int i = 0; i < insertRowCount; i++) {
                    classTable.getComponentArray(0).insertNewC(mapIndex);
                    classTable.getComponentArray(1).insertNewC(mapIndex);
                }
                viewer.refresh();
                parentEditor.setDirty(true);
            }
        };
        insertAction.setId("Insert");
        insertAction.setText(MessageUtil.getString("Insert"));
        insertAction.setToolTipText(MessageUtil.getString("InsertToolTip"));
        Action deleteAction = new Action() {
            public void run() {
                int mapIndex = getSelectedMapIndex();
                Integer[] indices = getSelectedMapIndices();
                Arrays.sort(indices);
                if (mapIndex < 0)
                    return;
                // remove in reverse order so indices remain valid
                for (int i = indices.length - 1; i >= 0; i--) {
                    classTable.getComponentArray(0).removeC(mapIndex);
                    classTable.getComponentArray(1).removeC(mapIndex);
                }

                viewer.refresh();
                parentEditor.setDirty(true);
            }
        };
        deleteAction.setId("Delete");
        deleteAction.setText(MessageUtil.getString("Delete"));
        deleteAction.setToolTipText(MessageUtil.getString("DeleteToolTip"));

        Action moveUpAction = new Action() {
            @Override
            public void run() {
                int mapIndex = getSelectedMapIndex();
                if (mapIndex < 1)
                    return;
                C cA = (C) classTable.getComponentArray(0).getCArray(mapIndex).copy();
                C cB = (C) classTable.getComponentArray(1).getCArray(mapIndex).copy();
                classTable.getComponentArray(0).removeC(mapIndex);
                classTable.getComponentArray(1).removeC(mapIndex);
                C cNewA = classTable.getComponentArray(0).insertNewC(mapIndex - 1);
                C cNewB = classTable.getComponentArray(1).insertNewC(mapIndex - 1);
                if (cA.isSetHex())
                    cNewA.setHex(cA.getHex());
                else
                    cNewA.setStringValue(cA.getStringValue());
                if (cB.isSetHex())
                    cNewB.setHex(cB.getHex());
                else
                    cNewB.setStringValue(cB.getStringValue());
                assert (!cA.isSetR());
                assert (!cB.isSetR());
                viewer.refresh();
                parentEditor.setDirty(true);
            }
        };
        moveUpAction.setId("MoveUp");
        moveUpAction.setText(MessageUtil.getString("MoveUp"));
        moveUpAction.setToolTipText(MessageUtil.getString("MoveUpToolTip"));

        Action moveDownAction = new Action() {
            @Override
            public void run() {
                int mapIndex = getSelectedMapIndex();
                if (mapIndex < 0 || mapIndex + 1 >= table.getItemCount())
                    return;
                C cA = (C) classTable.getComponentArray(0).getCArray(mapIndex).copy();
                C cB = (C) classTable.getComponentArray(1).getCArray(mapIndex).copy();
                classTable.getComponentArray(0).removeC(mapIndex);
                classTable.getComponentArray(1).removeC(mapIndex);
                C cNewA = classTable.getComponentArray(0).insertNewC(mapIndex + 1);
                C cNewB = classTable.getComponentArray(1).insertNewC(mapIndex + 1);
                if (cA.isSetHex())
                    cNewA.setHex(cA.getHex());
                else
                    cNewA.setStringValue(cA.getStringValue());
                if (cB.isSetHex())
                    cNewB.setHex(cB.getHex());
                else
                    cNewB.setStringValue(cB.getStringValue());
                assert (!cA.isSetR());
                assert (!cB.isSetR());
                viewer.refresh();
                parentEditor.setDirty(true);
            }
        };
        moveDownAction.setId("MoveDown");
        moveDownAction.setText(MessageUtil.getString("MoveDown"));
        moveDownAction.setToolTipText(MessageUtil.getString("MoveDownToolTip"));

        Action deleteTableAction = new Action() {
            public void run() {
                if (MessageDialog.openConfirm(part.getSite().getShell(), part.getTitle(),
                        MessageUtil.getString("ConfirmDeleteTable")) == false) {
                    return;
                }
                int index = parentEditor.getEditorIndex(part);
                parentEditor.removePage(index);
                SyllableConverter sc = parentEditor.getDocument().getSyllableConverter();
                for (int i = 0; i < sc.getClasses().sizeOfClass1Array(); i++) {
                    if (sc.getClasses().getClass1Array(i) == classTable) {
                        sc.getClasses().removeClass1(i);
                        break;
                    }
                }
                parentEditor.setDirty(true);
            }
        };
        deleteTableAction.setId("DeleteTable");
        deleteTableAction.setText(MessageUtil.getString("DeleteTable"));
        deleteTableAction.setToolTipText(MessageUtil.getString("DeleteTableToolTip"));
        menuManager.add(deleteTableAction);
        menuManager.add(insertAction);
        menuManager.add(deleteAction);
        menuManager.add(moveUpAction);
        menuManager.add(moveDownAction);
        for (ComponentRef comp : classTable.getComponentArray()) {
            final String r = comp.getR();
            Action copyColumn = new Action() {
                @Override
                public void run() {
                    doCopy(r, false);
                }
            };
            copyColumn.setText(MessageUtil.getString("CopyCol", comp.getR()));
            menuManager.add(copyColumn);
            Action pasteColumn = new Action() {
                @Override
                public void run() {
                    doPaste(r);
                }
            };
            pasteColumn.setText(MessageUtil.getString("PasteCol", comp.getR()));
            menuManager.add(pasteColumn);
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#dispose()
     */
    @Override
    public void dispose() {
        if (clipboard != null && !clipboard.isDisposed()) {
            clipboard.clearContents();
            clipboard.dispose();
        }
        super.dispose();
    }

    /**
     * @param r
     * @param b
     */
    protected void doCopy(String r, boolean b) {
        int side = 0;
        if (!classTable.getComponentArray(side).getR().equals(r))
            side = 1;
        assert (classTable.getComponentArray(side).getR().equals(r));
        ComponentRef copyContainer = ComponentRef.Factory.newInstance();
        copyContainer.setR(r);
        if (!(viewer.getSelection() instanceof IStructuredSelection))
            return;
        IStructuredSelection ss = (IStructuredSelection) viewer.getSelection();
        Iterator<?> i = ss.iterator();
        while (i.hasNext()) {
            Object o = i.next();
            if (o instanceof Triple<?, ?, ?>) {
                Triple<?, ?, ?> pair = (Triple<?, ?, ?>) o;
                C cCopy = copyContainer.addNewC();
                C orig = null;
                // first is the row number
                if (side == 0)
                    orig = (C) pair.second;
                else
                    orig = (C) pair.third;
                if (cCopy.isSetHex())
                    cCopy.setHex(orig.getHex());
                else
                    cCopy.setStringValue(orig.getStringValue());
            }
        }
        String xmlData = copyContainer.xmlText();
        clipboard.setContents(new Object[] { xmlData }, new Transfer[] { TextTransfer.getInstance() });
    }

    /**
     * @param r
     */
    protected void doPaste(String r) {
        int side = 0;
        if (!classTable.getComponentArray(side).getR().equals(r))
            side = 1;
        assert (classTable.getComponentArray(side).getR().equals(r));

        String data = (String) clipboard.getContents(TextTransfer.getInstance());
        if (data == null)
            return;
        try {
            ComponentRef cData = ComponentRef.Factory.parse(data);
            if (!(viewer.getSelection() instanceof IStructuredSelection))
                return;
            IStructuredSelection ss = (IStructuredSelection) viewer.getSelection();
            Iterator<?> iSelection = ss.iterator();
            int i = 0;
            while (iSelection.hasNext() && i < cData.sizeOfCArray()) {
                Object o = iSelection.next();
                if (o instanceof Triple<?, ?, ?>) {
                    Triple<?, ?, ?> pair = (Triple<?, ?, ?>) o;
                    C cCopy = cData.getCArray(i++);
                    C target = null;
                    // first is the row number
                    if (side == 0)
                        target = (C) pair.second;
                    else
                        target = (C) pair.third;
                    if (cCopy.isSetHex()) {
                        target.setNil();
                        target.setHex(cCopy.getHex());
                    } else {
                        if (target.isSetHex())
                            target.unsetHex();
                        target.setStringValue(cCopy.getStringValue());
                    }
                }
            }
            parentEditor.setDirty(true);
            viewer.refresh();
        } catch (XmlException e) {
            // ignore for now
        }
    }

    /**
     * @return
     */
    protected int getSelectedMapIndex() {
        if (!(viewer.getSelection() instanceof IStructuredSelection))
            return -1;
        IStructuredSelection s = (IStructuredSelection) viewer.getSelection();
        if (s.getFirstElement() instanceof Triple<?, ?, ?>) {
            Triple<?, ?, ?> selectedPair = (Triple<?, ?, ?>) s.getFirstElement();
            for (int i = 0; i < classTable.getComponentArray(0).sizeOfCArray(); i++) {
                if (classTable.getComponentArray(0).getCArray(i) == selectedPair.second) {
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * @return
     */
    protected Integer[] getSelectedMapIndices() {
        Vector<Integer> indices = new Vector<Integer>();
        if (!(viewer.getSelection() instanceof IStructuredSelection))
            return indices.toArray(new Integer[0]);
        IStructuredSelection s = (IStructuredSelection) viewer.getSelection();

        for (Object o : s.toArray()) {
            if (o instanceof Triple<?, ?, ?>) {
                Triple<?, ?, ?> selectedPair = (Triple<?, ?, ?>) o;
                for (int i = 0; i < classTable.getComponentArray(0).sizeOfCArray(); i++) {
                    if (classTable.getComponentArray(0).getCArray(i) == selectedPair.second) {
                        indices.add(i);
                    }
                }
            }
        }
        return indices.toArray(new Integer[indices.size()]);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.EditorPart#isDirty()
     */
    @Override
    public boolean isDirty() {
        return parentEditor.isDirty();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
     */
    @Override
    public boolean isSaveAsAllowed() {
        return parentEditor.isSaveAsAllowed();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
     */
    @Override
    public void createPartControl(Composite parent) {
        parent.setLayout(new FillLayout());
        table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
        viewer = new TableViewer(table);
        viewer.setContentProvider(new ClassTableContentProvider());
        TableColumn tcNum = new TableColumn(table, SWT.TRAIL);
        tcNum.setWidth(35);
        TableViewerColumn tvcNum = new TableViewerColumn(viewer, tcNum);
        tvcNum.setLabelProvider(new CellLabelProvider() {

            @Override
            public void update(ViewerCell cell) {
                Object o = cell.getViewerRow().getElement();
                if (o instanceof Triple<?, ?, ?>) {
                    Object cValue = ((Triple<?, ?, ?>) o).get(0);
                    if (cValue instanceof Integer) {
                        int row = ((Integer) cValue).intValue() + 1;
                        cell.setText(Integer.toString(row));
                    }
                }
            }
        });
        for (int colIndex = COL_OFFSET; colIndex < classTable.sizeOfComponentArray() + COL_OFFSET; colIndex++) {
            ComponentRef cr = classTable.getComponentArray(colIndex - COL_OFFSET);
            final String colRef = cr.getR();
            final int col = colIndex;
            TableColumn tc = new TableColumn(table, SWT.LEAD);
            tc.setText(cr.getR());
            tc.setWidth(100);
            TableViewerColumn tvc = new TableViewerColumn(viewer, tc);
            SyllableConverter sc = parentEditor.getDocument().getSyllableConverter();
            tc.setToolTipText(SyllableConverterUtils.getComponentName(sc, colRef));
            tvc.setEditingSupport(new CellEditingSupport(viewer, colRef, colIndex));
            tvc.setLabelProvider(new CellLabelProvider() {

                /* (non-Javadoc)
                 * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipFont(java.lang.Object)
                 */
                @Override
                public Font getToolTipFont(Object object) {
                    /*
                     if (object instanceof Triple<?,?,?>)
                     {
                    Object cValue = ((Triple<?,?,?>)object).get(col);
                    if (cValue instanceof C)
                    {
                        return (parentEditor.getFont(col-COL_OFFSET));
                    }
                     }*/
                    return super.getToolTipFont(object);
                }

                /* (non-Javadoc)
                 * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipText(java.lang.Object)
                 */
                @Override
                public String getToolTipText(Object element) {
                    if (element instanceof Triple<?, ?, ?>) {
                        Object cValue = ((Triple<?, ?, ?>) element).get(col);
                        if (cValue instanceof C) {
                            //cell.setText(SyllableConverterUtils.getCText((C)cValue));
                            String text = SyllableConverterUtils.getCTextWithCodes((C) cValue);
                            return text;
                        }
                    }
                    return super.getToolTipText(element);
                }

                @Override
                public void update(ViewerCell cell) {
                    Object o = cell.getViewerRow().getElement();
                    if (o instanceof Triple<?, ?, ?>) {
                        Object cValue = ((Triple<?, ?, ?>) o).get(col);
                        if (cValue instanceof C) {
                            //cell.setText(SyllableConverterUtils.getCText((C)cValue));
                            String text = SyllableConverterUtils.getCTextWithCodes((C) cValue);
                            cell.setText(text);
                            cell.setFont(parentEditor.getFont(col - COL_OFFSET));
                        } else if (cValue instanceof Integer) {
                            cell.setText(cValue.toString());
                        }
                    }
                }
            });
        }
        ColumnViewerToolTipSupport.enableFor(viewer);
        viewer.setInput(classTable);
        table.setHeaderVisible(true);
        viewer.refresh();
        menuManager.add(new Separator());
        menuManager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
        this.getEditorSite().registerContextMenu(menuManager, viewer);
        this.getEditorSite().setSelectionProvider(viewer);
        menuManager.setVisible(true);
        table.setMenu(menuManager.createContextMenu(table));
        table.setToolTipText(MessageUtil.getString("ClassTableToolTip"));
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
     */
    @Override
    public void setFocus() {
        table.setFocus();
    }

    protected class CellEditingSupport extends EditingSupport {
        final String colRef;
        final int colIndex;
        CellEditor editor;

        /**
         * @param viewer
         */
        protected CellEditingSupport(ColumnViewer viewer, String colRef, int colIndex) {
            super(viewer);
            this.colRef = colRef;
            this.colIndex = colIndex;
        }

        /* (non-Javadoc)
         * @see org.eclipse.jface.viewers.EditingSupport#canEdit(java.lang.Object)
         */
        @Override
        protected boolean canEdit(Object element) {
            if (element instanceof Triple<?, ?, ?> && this.colIndex >= COL_OFFSET) {
                return true;
            }
            return false;
        }

        /* (non-Javadoc)
         * @see org.eclipse.jface.viewers.EditingSupport#getCellEditor(java.lang.Object)
         */
        @Override
        protected CellEditor getCellEditor(Object element) {
            if (editor == null)
                editor = new TextCellEditor(table);
            Control control = editor.getControl();
            control.setFont(parentEditor.getFont(colIndex - COL_OFFSET));
            return editor;
        }

        /* (non-Javadoc)
         * @see org.eclipse.jface.viewers.EditingSupport#getValue(java.lang.Object)
         */
        @Override
        protected Object getValue(Object element) {
            if (element instanceof Triple<?, ?, ?>) {
                C c = (C) ((Triple<?, ?, ?>) element).get(colIndex);
                return SyllableConverterUtils.getCText(c);
            }
            return null;
        }

        /* (non-Javadoc)
         * @see org.eclipse.jface.viewers.EditingSupport#setValue(java.lang.Object, java.lang.Object)
         */
        @Override
        protected void setValue(Object element, Object value) {
            Object o = ((Triple<?, ?, ?>) element).get(colIndex);
            if (o instanceof C) {
                C c = (C) o;
                String oldValue = SyllableConverterUtils.getCText(c);
                if (value != null) {
                    if (!value.equals(oldValue)) {
                        String newValue = SyllableConverterUtils.parseUniInput(value.toString());
                        c.setStringValue(newValue);
                        viewer.refresh(element);
                        parentEditor.setDirty(true);
                    }
                } else {
                    c.setStringValue("");
                    viewer.refresh(element);
                    parentEditor.setDirty(true);
                }
            }
        }

    }

}