de.marw.cdt.cmake.core.ui.DefinesViewer.java Source code

Java tutorial

Introduction

Here is the source code for de.marw.cdt.cmake.core.ui.DefinesViewer.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Martin Weber.
 * 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:
 *      Martin Weber - Initial implementation
 *******************************************************************************/
package de.marw.cdt.cmake.core.ui;

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

import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.BaseLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

import de.marw.cdt.cmake.core.internal.settings.CmakeDefine;

/**
 * Displays a table for the Cmake defines. The created table will be displayed
 * in a group, together with buttons to add, edit and delete table entries.
 *
 * @author Martin Weber
 */
/* package */class DefinesViewer {
    /** table column names */
    private static final String[] tableColumnNames = { "Name", "Type", "Value" };
    /** table column widths */
    private static final int[] tableColumnWidths = { 120, 80, 250 };

    private TableViewer tableViewer;
    private MyViewerComparator comparator;

    /**
     * @param parent
     */
    public DefinesViewer(Composite parent) {
        createEditor(parent);
        // Set the sorter for the table
        comparator = new MyViewerComparator();
        tableViewer.setComparator(comparator);
    }

    /**
     * Gets the TableViewer for the Cmake-defines
     */
    public TableViewer getTableViewer() {
        return tableViewer;
    }

    /**
     * Sets the list of cmake defines that are displayed by the viewer.
     */
    public void setInput(List<CmakeDefine> defines) {
        // Get the content for the viewer, setInput will call getElements in the
        // contentProvider
        tableViewer.setInput(defines);
    }

    private TableViewer createViewer(Composite parent) {
        TableViewer viewer = new TableViewer(parent,
                SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);

        createColumns(parent, viewer);

        final Table table = viewer.getTable();
        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        viewer.setContentProvider(new CmakeDefineTableContentProvider());
        viewer.setLabelProvider(new CmakeVariableLabelProvider());

        // Layout the viewer
        GridData gridData = new GridData();
        gridData.verticalAlignment = GridData.FILL;
        //    gridData.horizontalSpan = 2;
        gridData.grabExcessHorizontalSpace = true;
        gridData.grabExcessVerticalSpace = true;
        gridData.horizontalAlignment = GridData.FILL;
        viewer.getControl().setLayoutData(gridData);
        return viewer;
    }

    /**
     * Creates the columns for the table.
     *
     * @param parent
     * @param viewer
     */
    private void createColumns(final Composite parent, final TableViewer viewer) {
        for (int i = 0; i < tableColumnNames.length; i++) {
            createTableViewerColumn(viewer, tableColumnNames[i], tableColumnWidths[i], i);
        }
    }

    /**
     * Creates a table viewer column for the table.
     */
    private TableViewerColumn createTableViewerColumn(final TableViewer viewer, String title, int colWidth,
            final int colNumber) {
        final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
        final TableColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setWidth(colWidth);
        column.setResizable(true);
        column.setMoveable(true);
        column.addSelectionListener(createSelectionAdapter(column, colNumber));
        return viewerColumn;
    }

    /**
     * Creates a selection adapter that changes the sorting order and sorting
     * column of the table.
     */
    private SelectionAdapter createSelectionAdapter(final TableColumn column, final int index) {
        SelectionAdapter selectionAdapter = new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                comparator.setSortColumn(index);
                int dir = comparator.getSortDirection();
                tableViewer.getTable().setSortDirection(dir);
                tableViewer.getTable().setSortColumn(column);
                tableViewer.refresh();
            }
        };
        return selectionAdapter;
    }

    /**
     * Creates the control to add/delete/edit cmake-variables to define.
     */
    private void createEditor(Composite parent) {
        final Group gr = WidgetHelper.createGroup(parent, SWT.FILL, 2, "CMake cache entries to define (-D)", 2);

        tableViewer = createViewer(gr);

        // let double click trigger the edit dialog
        tableViewer.addDoubleClickListener(new IDoubleClickListener() {
            @Override
            public void doubleClick(DoubleClickEvent event) {
                handleDefineEditButton(tableViewer);
            }
        });
        // let DEL key trigger the delete dialog
        tableViewer.getTable().addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.keyCode == SWT.DEL) {
                    handleDefineDelButton(tableViewer);
                } else if (e.keyCode == SWT.INSERT) {
                    handleDefineAddButton(tableViewer);
                }
            }
        });

        // Buttons, vertically stacked
        Composite editButtons = new Composite(gr, SWT.NONE);
        editButtons.setLayoutData(new GridData(SWT.CENTER, SWT.BEGINNING, false, false));
        editButtons.setLayout(new GridLayout(1, false));
        //    editButtons.setBackground(BACKGROUND_FOR_USER_VAR);

        Button buttonDefineAdd = WidgetHelper.createButton(editButtons, AbstractCPropertyTab.ADD_STR, true);
        final Button buttonDefineEdit = WidgetHelper.createButton(editButtons, AbstractCPropertyTab.EDIT_STR,
                false);
        final Button buttonDefineDel = WidgetHelper.createButton(editButtons, AbstractCPropertyTab.DEL_STR, false);

        // wire button actions...
        buttonDefineAdd.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent event) {
                handleDefineAddButton(tableViewer);
            }
        });
        buttonDefineEdit.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent event) {
                handleDefineEditButton(tableViewer);
            }
        });
        buttonDefineDel.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent event) {
                handleDefineDelButton(tableViewer);
            }
        });

        // enable button sensitivity based on table selection
        tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                // update button sensitivity..
                int sels = ((IStructuredSelection) event.getSelection()).size();
                boolean canEdit = (sels == 1);
                boolean canDel = (sels >= 1);
                buttonDefineEdit.setEnabled(canEdit);
                buttonDefineDel.setEnabled(canDel);
            }
        });

    }

    private void handleDefineAddButton(TableViewer tableViewer) {
        final Shell shell = tableViewer.getControl().getShell();
        AddCmakeDefineDialog dlg = new AddCmakeDefineDialog(shell, null);
        if (dlg.open() == Dialog.OK) {
            CmakeDefine cmakeDefine = dlg.getCmakeDefine();
            @SuppressWarnings("unchecked")
            ArrayList<CmakeDefine> defines = (ArrayList<CmakeDefine>) tableViewer.getInput();
            defines.add(cmakeDefine);
            tableViewer.add(cmakeDefine); // updates the display
        }
    }

    private void handleDefineEditButton(TableViewer tableViewer) {
        final IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
        if (selection.size() == 1) {
            Object cmakeDefine = selection.getFirstElement();
            // edit the selected variable in-place..
            final Shell shell = tableViewer.getControl().getShell();
            AddCmakeDefineDialog dlg = new AddCmakeDefineDialog(shell, (CmakeDefine) cmakeDefine);
            if (dlg.open() == Dialog.OK) {
                tableViewer.update(cmakeDefine, null); // updates the display
            }
        }
    }

    private void handleDefineDelButton(TableViewer tableViewer) {
        final IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
        final Shell shell = tableViewer.getControl().getShell();
        if (MessageDialog.openQuestion(shell, "CMake-Define deletion confirmation",
                "Are you sure to delete the selected CMake-defines?")) {
            @SuppressWarnings("unchecked")
            ArrayList<CmakeDefine> defines = (ArrayList<CmakeDefine>) tableViewer.getInput();
            defines.removeAll(selection.toList());
            tableViewer.remove(selection.toArray());// updates the display
        }
    }

    ////////////////////////////////////////////////////////////////////
    // inner classes
    ////////////////////////////////////////////////////////////////////

    /**
     * Converts the list of CmakeDefine object.
     *
     * @author Martin Weber
     */
    private static class CmakeDefineTableContentProvider implements IStructuredContentProvider {
        @Override
        public Object[] getElements(Object inputElement) {
            @SuppressWarnings("unchecked")
            final List<CmakeDefine> elems = (List<CmakeDefine>) inputElement;
            return elems.toArray();
        }

        @Override
        public void dispose() {
        }

        @Override
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }
    } // CmakeDefineTableContentProvider

    private static class CmakeVariableLabelProvider extends BaseLabelProvider implements ITableLabelProvider {

        //    // LabelProvider
        //    @Override
        //    public String getText(Object element) {
        //      return getColumnText(element, 0);
        //    }

        // interface ITableLabelProvider
        @Override
        public Image getColumnImage(Object element, int columnIndex) {
            return null;
        }

        // interface ITableLabelProvider
        @Override
        public String getColumnText(Object element, int columnIndex) {
            final CmakeDefine var = (CmakeDefine) element;
            switch (columnIndex) {
            case 0:
                return var.getName();
            case 1:
                return var.getType().name();
            case 2:
                return var.getValue();
            }
            return "";
        }
    } // CmakeVariableLabelProvider

    private static class MyViewerComparator extends ViewerComparator {
        private int sortColumn;
        private boolean ascending;

        public MyViewerComparator() {
            this.sortColumn = 0;
            ascending = true;
        }

        public int getSortDirection() {
            return ascending ? SWT.UP : SWT.DOWN;
        }

        public void setSortColumn(int column) {
            if (column == this.sortColumn) {
                // Same column as last sort; toggle the direction
                ascending ^= true;
            } else {
                // New column; do an ascending sort
                this.sortColumn = column;
                ascending = true;
            }
        }

        @Override
        public int compare(Viewer viewer, Object e1, Object e2) {
            CmakeDefine v1 = (CmakeDefine) e1;
            CmakeDefine v2 = (CmakeDefine) e2;
            int rc = 0;
            switch (sortColumn) {
            case 0:
                rc = v1.getName().compareTo(v2.getName());
                break;
            case 1:
                rc = v1.getType().name().compareTo(v2.getType().name());
                break;
            case 2:
                rc = v1.getValue().compareTo(v2.getValue());
                break;
            default:
                rc = 0;
            }
            // If descending order, flip the direction
            if (!ascending) {
                rc = -rc;
            }
            return rc;
        }
    } // MyViewerComparator
}