org.d3s.alricg.editor.editors.composits.AbstractAuswahlPart.java Source code

Java tutorial

Introduction

Here is the source code for org.d3s.alricg.editor.editors.composits.AbstractAuswahlPart.java

Source

/*
 * Created 17.08.2007
 *
 * This file is part of the project Alricg. The file is copyright
 * protected and under the GNU General Public License.
 * For more information see "http://www.alricg.de/".
 */
package org.d3s.alricg.editor.editors.composits;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.d3s.alricg.common.icons.ControlIconsLibrary;
import org.d3s.alricg.editor.common.CustomColumnLabelProvider;
import org.d3s.alricg.editor.common.CustomColumnViewerSorter;
import org.d3s.alricg.editor.common.CustomColumnEditors.LinkTextEditingSupport;
import org.d3s.alricg.editor.common.CustomColumnEditors.LinkWertEditingSupport;
import org.d3s.alricg.editor.common.DragAndDropSupport.AuswahlDrag;
import org.d3s.alricg.editor.common.DragAndDropSupport.AuswahlDrop;
import org.d3s.alricg.editor.common.ViewUtils.TreeObject;
import org.d3s.alricg.editor.common.ViewUtils.ViewerSelectionListener;
import org.d3s.alricg.editor.editors.EditorMessages;
import org.d3s.alricg.editor.editors.dialoge.CreateAuswahlDialog;
import org.d3s.alricg.editor.utils.CustomActions.InfoCharElementAction;
import org.d3s.alricg.store.charElemente.CharElement;
import org.d3s.alricg.store.charElemente.links.IdLink;
import org.d3s.alricg.store.charElemente.links.Link;
import org.d3s.alricg.store.charElemente.links.Option;
import org.d3s.alricg.store.charElemente.links.OptionAnzahl;
import org.d3s.alricg.store.charElemente.links.OptionListe;
import org.d3s.alricg.store.charElemente.links.OptionVerteilung;
import org.d3s.alricg.store.charElemente.links.OptionVoraussetzung;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPartSite;

/**
 * Superklasse fr alle Auswahlen
 * @author Vincent
 */
public abstract class AbstractAuswahlPart<C extends CharElement> extends AbstractElementPart<C> {
    protected TreeViewer treeViewer;
    protected Composite parentComp;
    protected AuswahlDrop auswahlDrop;

    protected Action showInfos;
    protected Action buildNewAlternative;
    protected Action buildNewAuswahl;
    protected Action deleteSelected;
    protected Action editSelected;
    protected Action clearZweitZiel;

    /**
     * Erstellt die TreeTable
     * @param top Parent Composite
     * @param partSite 
     */
    public AbstractAuswahlPart(Composite top, IWorkbenchPartSite partSite) {
        parentComp = top;

        treeViewer = new TreeViewer(parentComp, SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
        treeViewer.getTree().setLinesVisible(true);
        treeViewer.getTree().setHeaderVisible(true);
        ColumnViewerToolTipSupport.enableFor(treeViewer, ToolTip.NO_RECREATE);

        TreeViewerColumn tc = new TreeViewerColumn(treeViewer, SWT.LEFT, 0);
        tc.getColumn().setText(EditorMessages.AbstractAuswahlPart_Name);
        treeViewer.getTree().setSortColumn(tc.getColumn());
        tc.setLabelProvider(new CustomColumnLabelProvider.OptionNameProvider());
        tc.getColumn().setWidth(250);
        tc.getColumn().addSelectionListener(
                new ViewerSelectionListener(new CustomColumnViewerSorter.OptionNameSorter(), treeViewer));

        tc = new TreeViewerColumn(treeViewer, SWT.LEFT, 1);
        tc.getColumn().setText(EditorMessages.AbstractAuswahlPart_Klasse);
        tc.getColumn().setWidth(100);
        tc.setLabelProvider(new CustomColumnLabelProvider.CharElementKlassenProvider());
        tc.getColumn().addSelectionListener(
                new ViewerSelectionListener(new CustomColumnViewerSorter.CharElementKlasseSorter(), treeViewer));

        tc = new TreeViewerColumn(treeViewer, SWT.LEFT, 2);
        tc.getColumn().setText(EditorMessages.AbstractAuswahlPart_Stufe);
        tc.setLabelProvider(new CustomColumnLabelProvider.LinkWertProvider());
        tc.getColumn().setWidth(100);
        tc.getColumn().setMoveable(true);
        tc.setEditingSupport(new LinkWertEditingSupport(treeViewer, treeViewer.getTree(), -10, 20, true) {

            @Override
            protected boolean canEdit(Object element) {
                if (!super.canEdit(element))
                    return false;

                // Nur die Modi "Anzahl" und "Voraussetzung" bentigen Stufe fr Links
                final Option tmpOpt = (Option) ((TreeObject) element).getParent().getValue();
                if (tmpOpt instanceof OptionListe || tmpOpt instanceof OptionVerteilung) {
                    return false;
                }
                return true;
            }
        });

        tc = new TreeViewerColumn(treeViewer, SWT.LEFT, 3);
        tc.getColumn().setText(EditorMessages.AbstractAuswahlPart_Text);
        tc.setLabelProvider(new CustomColumnLabelProvider.LinkTextProvider());
        tc.getColumn().setWidth(100);
        tc.getColumn().setMoveable(true);
        tc.setEditingSupport(new LinkTextEditingSupport(treeViewer, treeViewer.getTree()));

        tc = new TreeViewerColumn(treeViewer, SWT.LEFT, 4);
        tc.getColumn().setText(EditorMessages.AbstractAuswahlPart_ZweitZiel);
        tc.setLabelProvider(new CustomColumnLabelProvider.LinkZweitZielProvider());
        tc.getColumn().setWidth(100);
        tc.getColumn().setMoveable(true);
        auswahlDrop = new AuswahlDrop(treeViewer, tc.getColumn(), this.getOptionClass());
        treeViewer.getTree().addMouseMoveListener(auswahlDrop); // wichtig fr Drag & Drop

        // Sortierung setzen
        treeViewer.setSorter(new CustomColumnViewerSorter.NameSorter());

        // Actions erstellen
        makeActions();
        hookContextMenu(partSite);

        // Untersttzung fr DRAG
        treeViewer.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE,
                new Transfer[] { LocalSelectionTransfer.getTransfer() }, new AuswahlDrag(treeViewer));

        // Untersttzung fr DROP
        int ops = DND.DROP_COPY | DND.DROP_MOVE;
        Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
        treeViewer.addDropSupport(ops, transfers, auswahlDrop);
        // Funzt nur zusammen mit "auswahlDrop" als MouseMoveLister auf dem treeViewer
    }

    public Tree getTree() {
        return treeViewer.getTree();
    }

    // Das Context Menu beim Rechts-klick
    private void fillContextMenu(IMenuManager manager) {
        manager.add(this.showInfos);
        manager.add(new Separator());
        manager.add(this.buildNewAuswahl);
        manager.add(this.buildNewAlternative);
        manager.add(this.editSelected);
        manager.add(this.deleteSelected);
        manager.add(this.clearZweitZiel);
        /* Um die Warnung
         * Context menu missing standard group 'org.eclipse.ui.IWorkbenchActionConstants.MB_ADDITIONS'
         * im Log zu verhindern */
        manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    /**
     * Setzt das Context-menu
     */
    private void hookContextMenu(IWorkbenchPartSite partSite) {

        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                AbstractAuswahlPart.this.fillContextMenu(manager);
            }
        });

        menuMgr.addMenuListener(new IMenuListener() {

            @Override
            public void menuAboutToShow(IMenuManager manager) {

                if (getTree().getSelection().length == 0)
                    return;
                final TreeObject treeObj = (TreeObject) getTree().getSelection()[0].getData();

                if (treeObj.getValue() instanceof Link) {
                    buildNewAlternative.setEnabled(true);
                    buildNewAuswahl.setEnabled(false);
                    deleteSelected.setEnabled(true);
                    editSelected.setEnabled(false);
                    clearZweitZiel.setEnabled(((Link) treeObj.getValue()).getZweitZiel() != null);
                } else if (treeObj.getValue() instanceof Option) {
                    buildNewAlternative.setEnabled(true);
                    buildNewAuswahl.setEnabled(true);
                    deleteSelected.setEnabled(true);
                    editSelected.setEnabled(true);
                    clearZweitZiel.setEnabled(false);
                } else {
                    buildNewAlternative.setEnabled(false);
                    buildNewAuswahl.setEnabled(true);
                    deleteSelected.setEnabled(false);
                    editSelected.setEnabled(false);
                    clearZweitZiel.setEnabled(false);
                }
            }
        });

        // For Tree
        Menu menu = menuMgr.createContextMenu(treeViewer.getTree());
        treeViewer.getTree().setMenu(menu);
        partSite.registerContextMenu(menuMgr, treeViewer);
    }

    protected void makeActions() {

        // Information anzeigen Action
        showInfos = new InfoCharElementAction() {
            @Override
            public void run() {
                MessageDialog.openInformation(parentComp.getShell(), "TODO", "Noch zu implementieren"); //$NON-NLS-1$ //$NON-NLS-2$
            }
        };
        showInfos.setText(EditorMessages.AbstractAuswahlPart_Infos);

        showInfos.setToolTipText(EditorMessages.AbstractAuswahlPart_Infos_TT);
        showInfos.setImageDescriptor(ControlIconsLibrary.info.getImageDescriptor());

        // Neues Element Action 
        buildNewAlternative = new Action() {
            @Override
            public void run() {
                if (treeViewer.getTree().getSelection().length == 0)
                    return;
                TreeObject treeObj = (TreeObject) treeViewer.getTree().getSelection()[0].getData();
                TreeObject parentTreeObj = null;

                if (treeObj.getValue() instanceof Link) {
                    treeObj = treeObj.getParent();
                }
                if (treeObj.getValue() instanceof Option) {
                    parentTreeObj = treeObj;
                    if (parentTreeObj.getParent().getValue() instanceof Option) {
                        parentTreeObj = parentTreeObj.getParent();
                    }
                }

                CreateAuswahlDialog vdce = new CreateAuswahlDialog(parentComp.getShell(),
                        getOptionClass().equals(OptionVoraussetzung.class), createOption(getOptionClass()));

                if (vdce.open() == Dialog.OK) {
                    parentTreeObj.addChildren(new TreeObject(vdce.getOption(), parentTreeObj));
                    treeViewer.refresh();
                }
            }
        };
        buildNewAlternative.setText(EditorMessages.AbstractAuswahlPart_NewAlternative);
        buildNewAlternative.setToolTipText(EditorMessages.AbstractAuswahlPart_NewAlternative_TT);
        buildNewAlternative.setImageDescriptor(ControlIconsLibrary.addFolder.getImageDescriptor());

        editSelected = new Action() {
            @Override
            public void run() {
                if (getTree().getSelection().length == 0)
                    return;
                final TreeObject treeObj = (TreeObject) getTree().getSelection()[0].getData();

                CreateAuswahlDialog vdce = new CreateAuswahlDialog(parentComp.getShell(),
                        treeObj.getValue() instanceof OptionVoraussetzung, (Option) treeObj.getValue());

                if (vdce.open() == Dialog.OK) {
                    treeObj.setValue(vdce.getOption());
                    treeViewer.refresh();
                }
            }
        };
        editSelected.setText(EditorMessages.AbstractAuswahlPart_EditAuswahk);
        editSelected.setToolTipText(EditorMessages.AbstractAuswahlPart_EditAuswahl_TT);
        editSelected.setImageDescriptor(ControlIconsLibrary.edit.getImageDescriptor());

        // Neues Element Action 
        buildNewAuswahl = new Action() {
            @Override
            public void run() {
                if (treeViewer.getTree().getSelection().length == 0)
                    return;
                final TreeObject treeObj = (TreeObject) treeViewer.getTree().getSelection()[0].getData();
                final TreeObject parentTreeObj = findNodeToAdd(treeObj);

                final CreateAuswahlDialog vdce = new CreateAuswahlDialog(parentComp.getShell(),
                        getOptionClass().equals(OptionVoraussetzung.class), createOption(getOptionClass()));

                if (vdce.open() == Dialog.OK) {
                    parentTreeObj.addChildren(new TreeObject(vdce.getOption(), parentTreeObj));
                    treeViewer.refresh();
                }
            }

            private TreeObject findNodeToAdd(TreeObject treeObj) {

                if (treeObj.getParent() == null) {
                    return treeObj;
                }

                while (!(treeObj.getParent().getParent() == null)) {
                    treeObj = treeObj.getParent();
                }

                return treeObj;
            }

        };
        buildNewAuswahl.setText(EditorMessages.AbstractAuswahlPart_NewAuswahl);
        buildNewAuswahl.setToolTipText(EditorMessages.AbstractAuswahlPart_NewAuswahl_TT);
        buildNewAuswahl.setImageDescriptor(ControlIconsLibrary.add.getImageDescriptor());

        // Element lschen Action
        deleteSelected = new Action() {
            @Override
            public void run() {
                if (getTree().getSelection().length == 0)
                    return;
                final TreeObject treeObj = (TreeObject) getTree().getSelection()[0].getData();

                treeObj.getParent().removeChildren(treeObj);
                treeViewer.refresh();
            }
        };
        deleteSelected.setText(EditorMessages.AbstractAuswahlPart_Delete);
        deleteSelected.setToolTipText(EditorMessages.AbstractAuswahlPart_Delete_TT);
        ;
        deleteSelected.setImageDescriptor(ControlIconsLibrary.delete.getImageDescriptor());

        clearZweitZiel = new Action() {
            @Override
            public void run() {
                if (getTree().getSelection().length == 0)
                    return;
                final TreeObject treeObj = (TreeObject) getTree().getSelection()[0].getData();

                if (treeObj.getValue() instanceof Link) {
                    ((Link) treeObj.getValue()).setZweitZiel(null);
                }
                treeViewer.refresh();
            }
        };
        clearZweitZiel.setText(EditorMessages.AbstractAuswahlPart_DeleteZweitZiel);
        clearZweitZiel.setToolTipText(EditorMessages.AbstractAuswahlPart_DeleteZweitZiel_TT);
        clearZweitZiel.setImageDescriptor(ControlIconsLibrary.tableDelete.getImageDescriptor());

    }

    /* (non-Javadoc)
     * @see org.d3s.alricg.editor.editors.composits.AbstarctElementPart#dispose()
     */
    @Override
    public void dispose() {
        // TODO Auto-generated method stub

    }

    /**
     * Erzeugt eine neue Option der Klasse "clazz"
     * @param clazz Klasse der zu erzeugenden Option
     * @return Neu erzeugte Option
     */
    public static Option createOption(Class clazz) {
        Option option;

        if (clazz.equals(OptionVoraussetzung.class)) {
            option = new OptionVoraussetzung();
            ((OptionVoraussetzung) option).setWert(0);
            option.setAnzahl(0);
        } else if (clazz.equals(OptionAnzahl.class)) {
            option = new OptionAnzahl();
            option.setAnzahl(0);
        } else if (clazz.equals(OptionListe.class)) {
            option = new OptionListe();
            option.setWerteListe(new int[0]);
        } else if (clazz.equals(OptionVerteilung.class)) {
            option = new OptionListe();
            option.setWert(1);
            option.setMax(0);
            option.setAnzahl(0);
        } else {
            throw new IllegalArgumentException("Parameter " + clazz + " konnte nicht gefunden werden!"); //$NON-NLS-1$ //$NON-NLS-2$
        }

        return option;
    }

    /**
     * Erzeugt aus dem Tree eine neue Auswahl (Option)
     * @param root Der Knoten, ab dem eine Option erzeugt werden soll
     * @return Die Option fr den Knoten "root"
     */
    protected Option buildAuswahl(TreeObject root) {
        final Option option = ((Option) root.getValue()).copyOption();
        option.setLinkList(new ArrayList());

        if (root.getChildren() == null) {
            return validOption(option);
        }

        for (int i = 0; i < root.getChildren().length; i++) {
            // Links hinzufgen
            if (root.getChildren()[i].getValue() instanceof Link) {
                option.getLinkList().add((Link) root.getChildren()[i].getValue());

                // Alternative Optionen hinzufgen
            } else if (root.getChildren()[i].getValue() instanceof Option) {
                // Um die Option richtig hinzuzufgen
                Option optToAdd = option;
                while (optToAdd.getAlternativOption() != null) {
                    optToAdd = optToAdd.getAlternativOption();
                }
                // Um die CharElement hinzuzufgen
                optToAdd.setAlternativOption(buildAuswahl(root.getChildren()[i]));
            }
        }

        return validOption(option);
    }

    /**
     * Ld eine Liste zu Optionen in die Ansicht
     * @param auswahlList
     * @param root
     */
    protected void loadAuswahlList(List<? extends Option> auswahlList, TreeObject root) {
        for (int i1 = 0; i1 < auswahlList.size(); i1++) {
            loadOption(auswahlList.get(i1), root);
        }
    }

    /**
     * Ld eine Option "originalOption" zum TreeObject "root"
     * @param originalOption Die Option, die geladen wird
     * @param root Das TreeObject, zu dem die Option als Kind hinzugefhgt wird
     */
    private void loadOption(Option originalOption, TreeObject root) {
        if (originalOption == null)
            return;

        // Option erstellen
        Option currentOpt = null;
        if (originalOption instanceof OptionVoraussetzung) {
            currentOpt = new OptionVoraussetzung();
            currentOpt.setAnzahl(originalOption.getAnzahl());
            currentOpt.setWert(originalOption.getWert());

        } else if (originalOption instanceof OptionAnzahl) {
            currentOpt = new OptionAnzahl();
            currentOpt.setAnzahl(originalOption.getAnzahl());

        } else if (originalOption instanceof OptionListe) {
            currentOpt = new OptionListe();
            currentOpt.setWerteListe(originalOption.getWerteListe());

        } else if (originalOption instanceof OptionVerteilung) {
            currentOpt = new OptionVerteilung();
            currentOpt.setAnzahl(originalOption.getAnzahl());
            currentOpt.setWert(originalOption.getWert());
            currentOpt.setMax(originalOption.getMax());
        }
        TreeObject treeObj = new TreeObject(currentOpt, root);
        root.addChildren(treeObj);

        // Link setzen
        for (int i2 = 0; i2 < originalOption.getLinkList().size(); i2++) {
            TreeObject linkTreeObj = new TreeObject(((IdLink) originalOption.getLinkList().get(i2)).copyLink(),
                    treeObj);
            treeObj.addChildren(linkTreeObj);
        }

        if (originalOption.getAlternativOption() != null) {
            if (root.getValue() instanceof Option)
                treeObj = root;
            loadOption(originalOption.getAlternativOption(), treeObj);
        }
    }

    /**
     * Vergleicht zwei Listen von Optionen ob diese den werten nach gleich sind. 
     * @param optListOrg
     * @param optListNew
     * @return true - Die Listen sind den Werten nach gleich, ansonsten false.
     */
    protected boolean compareOptionList(List<? extends Option> optListOrg, List<? extends Option> optListNew) {
        if (optListOrg == null && optListNew == null) {
            return true;
        } else if (optListOrg != null && optListNew != null) {
            // NOOP
        } else {
            return false;
        }

        if (optListOrg.size() != optListNew.size()) {
            return false;
        }

        boolean isEqual = true;
        for (int i = 0; i < optListOrg.size(); i++) {
            isEqual &= compareOption(optListOrg.get(i), optListNew.get(i));
        }

        return isEqual;
    }

    /**
     * Vergleicht ob zwei Optionen den Werten nach gleich sind
     * @param option1
     * @param option2
     * @return true - option1 und option2 sind den Werten nach gleich, ansonsten false
     */
    private boolean compareOption(Option option1, Option option2) {
        boolean isEqual = true;

        // Generelle Eigenschaften prfen
        if (option1.getClass() != option2.getClass()) {
            return false;
        }
        if (option1.getLinkList() != null && option2.getLinkList() != null) {
            if (option1.getLinkList().size() != option2.getLinkList().size()) {
                return false;
            }
        } else if (option1.getLinkList() == null && option2.getLinkList() == null) {
            //  Noop
        } else {
            return false;
        }

        // Option Eigenschaften prfen
        if (option1 instanceof OptionVoraussetzung) {
            isEqual &= option1.getAnzahl() == option2.getAnzahl();
            isEqual &= option1.getWert() == option2.getWert();

        } else if (option1 instanceof OptionAnzahl) {
            isEqual &= option1.getAnzahl() == option2.getAnzahl();

        } else if (option1 instanceof OptionListe) {
            isEqual &= Arrays.equals(option1.getWerteListe(), option2.getWerteListe());

        } else if (option1 instanceof OptionVerteilung) {
            isEqual &= option1.getAnzahl() == option2.getAnzahl();
            isEqual &= option1.getWert() == option2.getWert();
            isEqual &= option1.getMax() == option2.getMax();
        }

        // Links prfen 
        if (option1.getLinkList() != null) {
            for (int i = 0; i < option1.getLinkList().size(); i++) {
                isEqual &= ((Link) option1.getLinkList().get(i)).isEqualLink((Link) option2.getLinkList().get(i));
            }
        }

        // Falls schon falsch, knnen die alternativen optionen gespart werden!
        if (!isEqual)
            return isEqual;

        // Alternative Optionen prfen
        if (option1.getAlternativOption() != null && option2.getAlternativOption() != null) {
            isEqual &= compareOption(option1.getAlternativOption(), option2.getAlternativOption());
        } else if (option1.getAlternativOption() == null && option2.getAlternativOption() == null) {
            // Noop
        } else {
            return false;
        }

        return isEqual;
    }

    /**
     * Prft und optimiert ggf. eine Option. berflssige Werde und Optionen
     * ohne Links werden "weg-optimiert"
     * @param option Zu optimierende Option
     * @return Die Optimierte Option oder null, falls diese berflssig ist!
     */
    private Option validOption(Option option) {

        if (option.getLinkList() == null || option.getLinkList().size() == 0) {
            if (option.getAlternativOption() != null) {
                return validOption(option.getAlternativOption());
            } else {
                return null;
            }
        }

        // Setze die Werte auf korrekte Werte
        if (option.getClass() == OptionVoraussetzung.class) {
            if (option.getLinkList().size() <= option.getAnzahl()) {
                option.setAnzahl(0);
            }

        } else if (option.getClass() == OptionAnzahl.class) {
            if (option.getLinkList().size() <= option.getAnzahl()) {
                option.setAnzahl(0);
            }

        } else if (option.getClass() == OptionListe.class) {
            if (option.getWerteListe() == null || option.getWerteListe().length == 0) {
                // TODO den User auf den Fehler Hinweisen?
            }

        } else if (option.getClass() == OptionVerteilung.class) {
            if (option.getLinkList().size() <= option.getAnzahl()) {
                option.setAnzahl(0);
            }
            if (option.getWert() <= option.getMax()) {
                option.setMax(0);
            }
        }

        return option;
    }

    /**
     * Definiert den Typ der Option, der standartmig vorgeschlagen wird
     * @return Classe der Default Option
     */
    protected Class getOptionClass() {
        return OptionAnzahl.class;
    }

}