net.sf.sveditor.ui.argfile.editor.outline.SVArgFileOutlinePage.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.sveditor.ui.argfile.editor.outline.SVArgFileOutlinePage.java

Source

/****************************************************************************
 * Copyright (c) 2008-2014 Matthew Ballance and others.
 * All rights reserved. This program and the accompanying materials
 * are 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:
 *     Matthew Ballance - initial implementation
 ****************************************************************************/

package net.sf.sveditor.ui.argfile.editor.outline;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import net.sf.sveditor.core.Tuple;
import net.sf.sveditor.core.db.ISVDBChildItem;
import net.sf.sveditor.core.db.ISVDBChildParent;
import net.sf.sveditor.core.db.ISVDBItemBase;
import net.sf.sveditor.core.db.ISVDBNamedItem;
import net.sf.sveditor.core.db.SVDBFile;
import net.sf.sveditor.core.db.SVDBFileTree;
import net.sf.sveditor.core.db.SVDBItem;
import net.sf.sveditor.core.db.SVDBItemType;
import net.sf.sveditor.core.db.SVDBModIfcInst;
import net.sf.sveditor.core.db.argfile.SVDBArgFileIncFileStmt;
import net.sf.sveditor.core.db.argfile.SVDBArgFilePathStmt;
import net.sf.sveditor.core.db.index.ISVDBChangeListener;
import net.sf.sveditor.core.db.index.SVDBFilePath;
import net.sf.sveditor.core.db.stmt.SVDBVarDeclStmt;
import net.sf.sveditor.core.log.ILogHandle;
import net.sf.sveditor.core.log.ILogLevelListener;
import net.sf.sveditor.core.log.LogFactory;
import net.sf.sveditor.core.log.LogHandle;
import net.sf.sveditor.ui.SVEditorUtil;
import net.sf.sveditor.ui.SVUiPlugin;
import net.sf.sveditor.ui.argfile.editor.SVArgFileEditor;
import net.sf.sveditor.ui.svcp.SVDBDefaultContentFilter;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IElementComparer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;

public class SVArgFileOutlinePage extends ContentOutlinePage
        implements IShowInTarget, IAdaptable, Runnable, ISVDBChangeListener, ILogLevelListener {
    private SVArgFileOutlineContent fContent;
    private SVArgFileOutlineContentProvider fContentProvider;
    private SVArgFileEditor fEditor;
    private boolean fIgnoreSelectionChange = false;
    private ISVDBItemBase fLastSelection;
    private SVDBDefaultContentFilter DefaultContentFilter;
    private ViewerComparator ViewerComapartor;
    private LogHandle fLog;
    private boolean fDebugEn;
    private SortAction ToggleSort;

    public SVArgFileOutlinePage(SVArgFileEditor editor) {
        fEditor = editor;
        fContentProvider = new SVArgFileOutlineContentProvider();
        fContent = new SVArgFileOutlineContent(new SVDBFile(""), null);

        fLog = LogFactory.getLogHandle("SVArgFileOutlinePage");
        fDebugEn = fLog.isEnabled();
    }

    public void logLevelChanged(ILogHandle handle) {
        fDebugEn = handle.isEnabled();
    }

    public ITreeContentProvider getContentProvider() {
        return fContentProvider;
    }

    @Override
    public void setSelection(ISelection selection) {
        if (fDebugEn) {
            fLog.debug("setSelection: " + selection);
        }
        super.setSelection(selection);
    }

    public void createControl(Composite parent) {
        super.createControl(parent);

        fContentProvider = new SVArgFileOutlineContentProvider();
        DefaultContentFilter = new SVDBDefaultContentFilter();
        ViewerComapartor = new ViewerComparator();

        // Set up the preferences from the preference store
        getTreeViewer().setContentProvider(fContentProvider);
        getTreeViewer().addFilter(DefaultContentFilter);
        // Check whether we have sorting enabled or not
        /*
        if (SVUiPlugin.getDefault().getPreferenceStore().getBoolean(SVArgFileEditorPrefsConstants.P_OUTLINE_SORT))  {
           getTreeViewer().setComparator(ViewerComapartor);
        } else {
         */
        getTreeViewer().setComparator(null);
        //      }
        getTreeViewer().setLabelProvider(new SVArgFileOutlineLabelProvider());
        getTreeViewer().setComparer(new IElementComparer() {
            public int hashCode(Object element) {
                return element.hashCode();
            }

            public boolean equals(Object a, Object b) {
                // Just do a simple compare
                return (a == b);
            }
        });

        getTreeViewer().setInput(fContent);

        getTreeViewer().addSelectionChangedListener(fSelectionListener);
        getTreeViewer().addDoubleClickListener(fDoubleClickListener);
        getTreeViewer().setAutoExpandLevel(TreeViewer.ALL_LEVELS);

        // Get initial contents
        refresh();
    }

    public void clearIgnoreSelectionChange() {
        if (fDebugEn) {
            fLog.debug("clearIgnoreSelectionChange");
        }
        fIgnoreSelectionChange = false;
    }

    public void SVDBFileChanged(SVDBFile file, List<SVDBItem> adds, List<SVDBItem> removes,
            List<SVDBItem> changes) {
        /** TODO:
        if (file.getFilePath().equals(fEditor.getFilePath())) {
           if (getTreeViewer() != null && !getTreeViewer().getControl().isDisposed()) {
        Display.getDefault().asyncExec(this);
           }
        }
         */
    }

    public void refresh() {
        if (getTreeViewer() != null && !getTreeViewer().getControl().isDisposed()) {
            if (fDebugEn) {
                fLog.debug("refresh: schedule refresh of content");
            }
            Display.getDefault().asyncExec(this);
        }
    }

    public void run() {
        if (getTreeViewer() != null && !getTreeViewer().getControl().isDisposed()) {
            if (fDebugEn) {
                fLog.debug("run: refresh content");
            }

            SVDBFilePath file_path = null;
            List<SVDBFilePath> curr_path = fEditor.getSVDBFilePath();

            if (curr_path != null && curr_path.size() > 0) {
                file_path = curr_path.get(0);
            }

            fContent = new SVArgFileOutlineContent(fEditor.getSVDBFile(), file_path);

            List<Object> exp_path_list = getExpansionPaths();

            ISelection sel = getTreeViewer().getSelection();

            getTreeViewer().setInput(fContent);

            // Apply selection and expansions previously saved
            setExpansionPaths(exp_path_list);

            setSavedSelection(sel);
        } else {
            if (fDebugEn) {
                fLog.debug("run: ignore due to page closing");
            }
        }
    }

    private List<Object> getExpansionPaths() {
        List<Object> ret = new ArrayList<Object>();
        for (TreePath p : getTreeViewer().getExpandedTreePaths()) {
            Object last_seg_o = p.getLastSegment();

            if (last_seg_o instanceof ISVDBItemBase || last_seg_o instanceof Tuple
                    || last_seg_o instanceof SVDBFilePath) {
                ret.add(last_seg_o);
            }
        }

        return ret;
    }

    @SuppressWarnings("unchecked")
    private void setExpansionPaths(List<Object> exp_paths) {
        List<Object> path = new ArrayList<Object>();
        List<Object> target_path = new ArrayList<Object>();
        List<TreePath> exp_tree_paths = new ArrayList<TreePath>();

        for (Object item : exp_paths) {
            path.clear();
            target_path.clear();

            if (item instanceof Tuple) {
                Tuple<SVDBFileTree, ISVDBItemBase> t = (Tuple<SVDBFileTree, ISVDBItemBase>) item;
                target_path.add(fContent.getFilePath());

                for (Tuple<SVDBFileTree, ISVDBItemBase> i : fContent.getFilePath().getPath()) {
                    if (i.first().getFilePath().equals(t.first().getFilePath())) {
                        target_path.add(i);
                        break;
                    }
                }

                if (target_path.size() < 2) {
                    target_path.clear();
                }
            } else if (item instanceof SVDBFilePath) {
                target_path.add(fContent.getFilePath());
            } else if (item instanceof ISVDBItemBase) {
                // Build the path
                buildFullPath(path, (ISVDBItemBase) item);

                // Find the corresponding path
                lookupPath(fContent.getFile(), path.iterator(), target_path);
            }

            if (target_path.size() > 0) {
                exp_tree_paths.add(new TreePath(target_path.toArray()));
            }
        }

        if (exp_tree_paths.size() > 0) {
            getTreeViewer().setExpandedTreePaths(exp_tree_paths.toArray(new TreePath[exp_tree_paths.size()]));
        }
    }

    private void buildFullPath(List<Object> path, ISVDBItemBase leaf) {
        ISVDBItemBase item_tmp = leaf;
        while (item_tmp != null && item_tmp.getType() != SVDBItemType.File) {
            // Don't record the container, since there isn't an
            // identifier to use
            if (!(item_tmp instanceof SVDBVarDeclStmt) && !(item_tmp instanceof SVDBModIfcInst)) {
                path.add(0, item_tmp);
            }
            if (item_tmp instanceof ISVDBChildItem) {
                item_tmp = ((ISVDBChildItem) item_tmp).getParent();
            } else {
                item_tmp = null;
            }
        }
    }

    @SuppressWarnings("unchecked")
    private void setSavedSelection(ISelection sel) {
        if (fDebugEn) {
            fLog.debug("--> setSavedSelection: set fIgnoreSelectionChange=true");
        }
        fIgnoreSelectionChange = true;
        try {
            if (!sel.isEmpty() && sel instanceof IStructuredSelection) {
                List<Object> path = new ArrayList<Object>();
                IStructuredSelection ss = (IStructuredSelection) sel;
                List<Object> new_sel_l = new ArrayList<Object>();
                List<Object> target_path = new ArrayList<Object>();

                for (Object sel_it : ss.toList()) {
                    if (sel_it instanceof ISVDBItemBase) {
                        path.clear();
                        target_path.clear();
                        buildFullPath(path, (ISVDBItemBase) sel_it);

                        if (lookupPath(fContent.getFile(), path.iterator(), target_path)) {
                            ISVDBItemBase sel_t = (ISVDBItemBase) target_path.get(target_path.size() - 1);
                            new_sel_l.add(sel_t);
                        }
                    } else if (sel_it instanceof SVDBFilePath) {
                        new_sel_l.add(fContent.getFilePath());
                    } else if (sel_it instanceof Tuple) {
                        Tuple<SVDBFileTree, ISVDBItemBase> t = (Tuple<SVDBFileTree, ISVDBItemBase>) sel_it;

                        for (Tuple<SVDBFileTree, ISVDBItemBase> i : fContent.getFilePath().getPath()) {
                            if (i.first().getFilePath().equals(t.first().getFilePath())) {
                                new_sel_l.add(i);
                                break;
                            }
                        }
                    }
                }
                StructuredSelection new_sel = new StructuredSelection(new_sel_l);

                getTreeViewer().setSelection(new_sel);
            }
        } finally {
            fIgnoreSelectionChange = false;
        }
        if (fDebugEn) {
            fLog.debug("<-- setSavedSelection: set fIgnoreSelectionChange=true");
        }
    }

    private boolean lookupPath(ISVDBChildParent scope, Iterator<Object> path_it, List<Object> target_path) {
        ISVDBItemBase path_item = (ISVDBItemBase) path_it.next();
        ISVDBItemBase target_item = null;
        boolean ret = false;

        if (!(path_item instanceof ISVDBNamedItem)) {
            // TODO:
            return ret;
        }

        ISVDBNamedItem ni = (ISVDBNamedItem) path_item;

        for (ISVDBChildItem ci : scope.getChildren()) {
            if (ci instanceof ISVDBNamedItem) {
                ISVDBNamedItem ci_ni = (ISVDBNamedItem) ci;
                if (ni.getName().equals(ci_ni.getName()) && ni.getType() == ci_ni.getType()) {
                    target_item = ci;
                    break;
                }
            } else if (ci instanceof SVDBVarDeclStmt || ci instanceof SVDBModIfcInst) {
                // instance list
                ISVDBChildParent inst_list = (ISVDBChildParent) ci;
                for (ISVDBChildItem ci_inst : inst_list.getChildren()) {
                    ISVDBNamedItem ci_inst_ni = (ISVDBNamedItem) ci_inst;
                    if (ni.getName().equals(ci_inst_ni.getName()) && ni.getType() == ci_inst_ni.getType()) {
                        target_item = ci_inst;
                        break;
                    }
                }
                if (target_item != null) {
                    break;
                }
            } else {
                // TODO: How to match?
            }
        }

        if (target_item != null) {
            target_path.add(target_item);
        }

        if (path_it.hasNext() && target_item != null && target_item instanceof ISVDBChildParent) {
            ret = lookupPath((ISVDBChildParent) target_item, path_it, target_path);
        } else if (!path_it.hasNext() && target_item != null) {
            ret = true;
        }

        return ret;
    }

    public void dispose() {
        if (getTreeViewer() != null) {
            getTreeViewer().removeSelectionChangedListener(fSelectionListener);
        }
    }

    @SuppressWarnings("rawtypes")
    public Object getAdapter(Class adapter) {
        if (IShowInTarget.class.equals(adapter)) {
            return this;
        }
        return null;
    }

    public boolean show(ShowInContext context) {
        // TODO Auto-generated method stub
        return true;
    }

    private IDoubleClickListener fDoubleClickListener = new IDoubleClickListener() {

        @SuppressWarnings("unchecked")
        public void doubleClick(DoubleClickEvent event) {
            IStructuredSelection sel = (IStructuredSelection) getSelection();

            if (sel.getFirstElement() != null) {
                if (sel.getFirstElement() instanceof Tuple) {
                    Tuple<SVDBFileTree, ISVDBItemBase> t = (Tuple<SVDBFileTree, ISVDBItemBase>) sel
                            .getFirstElement();

                    if (t.second() != null) { // Don't mess with 'this' file
                        try {
                            SVEditorUtil.openEditor(t.second());
                        } catch (PartInitException e) {
                            fLog.error("Failed to open editor", e);
                        }
                    }
                } else if (sel.getFirstElement() instanceof ISVDBItemBase) {
                    ISVDBItemBase item = (ISVDBItemBase) sel.getFirstElement();
                    String path = null;

                    if (item.getType() == SVDBItemType.ArgFileIncFileStmt) {
                        path = ((SVDBArgFileIncFileStmt) item).getPath();
                    } else if (item.getType() == SVDBItemType.ArgFilePathStmt) {
                        path = ((SVDBArgFilePathStmt) item).getPath();
                    }

                    if (path != null) {
                        try {
                            SVEditorUtil.openEditor(path);
                        } catch (PartInitException e) {
                            fLog.error("Failed to open editor for \"" + path + "\"", e);
                        }
                    }
                }
            }
        }
    };

    private ISelectionChangedListener fSelectionListener = new ISelectionChangedListener() {

        public void selectionChanged(SelectionChangedEvent event) {
            if (fDebugEn) {
                fLog.debug("selectionChanged: " + event.getSelection() + " fIgnoreSelectionChange="
                        + fIgnoreSelectionChange);
            }

            if (fIgnoreSelectionChange) {
                if (fDebugEn) {
                    fLog.debug("  Toggle fIgnoreSelectionChange=false and return");
                }
                //               fIgnoreSelectionChange = false;
                return;
            }

            removeSelectionChangedListener(this);

            if (fDebugEn) {
                if (event.getSelection() == null) {
                    fLog.debug("  Selection is null");
                } else {
                    fLog.debug("  Selection is of type " + event.getSelection().getClass().getName());
                }
            }

            if (event.getSelection() instanceof StructuredSelection) {
                StructuredSelection sel = (StructuredSelection) event.getSelection();
                if (fDebugEn) {
                    if (sel.getFirstElement() == null) {
                        fLog.debug("  Selection target is null");
                    } else {
                        fLog.debug("  Selection target is of type " + sel.getFirstElement().getClass().getName());
                    }
                }
                if (sel.getFirstElement() instanceof ISVDBItemBase) {
                    ISVDBItemBase it = (ISVDBItemBase) sel.getFirstElement();

                    if (fLastSelection == null || !fLastSelection.equals(it, true)) {
                        if (fDebugEn) {
                            fLog.debug("Setting SVArgFileEditor selection: " + SVDBItem.getName(it) + " @ "
                                    + ((it.getLocation() != null) ? it.getLocation().getLine() : -1));
                        }
                        fEditor.setSelection(it, false);
                        fLastSelection = it;
                    }
                }
            }

            addSelectionChangedListener(this);
        }
    };

    public void createActions() {
    }

    private class SortAction extends Action {
        public SortAction() {
            super("sort", Action.AS_CHECK_BOX);
            setImageDescriptor(SVUiPlugin.getImageDescriptor("/icons/elcl16/alphab_sort_co.gif"));
        }

        public void run() {
            boolean new_value = true;
            /** TODO:
            if (SVUiPlugin.getDefault().getPreferenceStore().getBoolean(SVArgFileEditorPrefsConstants.P_OUTLINE_SORT))  {
               new_value = false;
            }
            // Update the preferences
            SVUiPlugin.getDefault().getPreferenceStore().setValue(SVArgFileEditorPrefsConstants.P_OUTLINE_SORT, new_value);
            // Update the value
            ToggleSort.setChecked(new_value);
             */

            // enable or disable the sorter
            if (new_value) {
                getTreeViewer().setComparator(ViewerComapartor);
            } else {
                getTreeViewer().setComparator(null);
            }
            refresh();
        }
    }

    @Override
    public void init(IPageSite pageSite) {
        super.init(pageSite);

        // Add button to toggle assign statements on and off
        ToggleSort = new SortAction();
        pageSite.getActionBars().getToolBarManager().add(ToggleSort);
        /** TODO:
         */

        // Set up which of the content filters are enabled
        // Now, format the new addition if auto-indent is enabled
        //      IPreferenceStore ps = SVUiPlugin.getDefault().getPreferenceStore();
    }
}