/******************************************************************************* * Copyright (c) 2005, 2017 IBM Corporation 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: * xored software, Inc. - initial API and Implementation (Andrei Sobolev) * xored software, Inc. - TCL ManPageFolder management refactoring (Alex Panchenko <alex@xored.com>) *******************************************************************************/ package org.eclipse.dltk.tcl.internal.ui.documentation; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.dltk.tcl.ui.manpages.Documentation; import org.eclipse.dltk.tcl.ui.manpages.ManPageFolder; import org.eclipse.dltk.tcl.ui.manpages.ManPageLoader; import org.eclipse.dltk.tcl.ui.manpages.ManPageResource; import org.eclipse.dltk.ui.DLTKPluginImages; import org.eclipse.dltk.ui.DLTKUIPlugin; import org.eclipse.dltk.ui.dialogs.StatusInfo; import org.eclipse.dltk.ui.util.IStatusChangeListener; import org.eclipse.dltk.ui.util.PixelConverter; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.IFontProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.window.IShellProvider; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; 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.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; /** * Control used to edit the libraries associated with a Interpreter install */ public class ManPagesLocationsBlock implements ISelectionChangedListener { /** * Attribute name for the last path used to open a file/directory chooser * dialog. */ protected static final String LAST_PATH_SETTING = "LAST_PATH_SETTING"; //$NON-NLS-1$ /** * the prefix for dialog setting pertaining to this block */ protected static final String DIALOG_SETTINGS_PREFIX = "ManPagesLocationsBlock"; //$NON-NLS-1$ private TreeViewer fLocationsViewer; private Button fAddButton; private Button fEditButton; private Button fRemoveButton; private Button fDefaultButton; private final IStatusChangeListener fPage; private final boolean fEditable; public ManPagesLocationsBlock(IStatusChangeListener page, boolean editable) { fPage = page; fEditable = editable; } private static class ManPagesLabelProvider extends LabelProvider implements IFontProvider { public ManPagesLabelProvider() { } @Override public Image getImage(Object element) { if (element instanceof Documentation) { return DLTKUIPlugin.getImageDescriptorRegistry() .get(DLTKPluginImages.DESC_OBJS_JAVADOCTAG); } else if (element instanceof ManPageFolder) { return DLTKPluginImages.get(DLTKPluginImages.IMG_OBJS_LIBRARY); } else { return super.getImage(element); } } @Override public String getText(Object element) { if (element instanceof Documentation) { final Documentation doc = (Documentation) element; String text = doc.getName(); if (doc.isDefault()) { text += ManPagesMessages.ManPagesLocationsBlock_DefaultSuffix; } return text; } else if (element instanceof ManPageFolder) { return ((ManPageFolder) element).getPath(); } else { return super.getText(element); } } @Override public Font getFont(Object element) { if (element instanceof Documentation) { final Documentation doc = (Documentation) element; if (doc.isDefault()) { return JFaceResources.getFontRegistry() .getBold(JFaceResources.DIALOG_FONT); } } return null; } } private ManPageResource documentations = null; private static class ManLocationsContentProvider implements ITreeContentProvider { public ManLocationsContentProvider() { } @Override public Object[] getChildren(Object parentElement) { if (parentElement instanceof Documentation) { final EList<ManPageFolder> folders = ((Documentation) parentElement) .getFolders(); return folders.toArray(new ManPageFolder[folders.size()]); } return new Object[0]; } @Override public Object getParent(Object element) { return null; } @Override public boolean hasChildren(Object element) { if (element instanceof Documentation) return true; return false; } @Override public Object[] getElements(Object inputElement) { if (inputElement instanceof ManPageResource) { final List<Documentation> docs = ((ManPageResource) inputElement) .getDocumentations(); return docs.toArray(new Object[docs.size()]); } else { return new Object[0]; } } @Override public void dispose() { } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } }; /** * Creates and returns the source lookup control. * * @param parent * the parent widget of this control */ public Control createControl(Composite parent) { Composite comp = new Composite(parent, SWT.NONE); GridLayout topLayout = new GridLayout(); topLayout.numColumns = fEditable ? 2 : 1; topLayout.marginHeight = 0; topLayout.marginWidth = 0; comp.setLayout(topLayout); comp.setLayoutData(new GridData(GridData.FILL_BOTH)); fLocationsViewer = new TreeViewer(comp); final GridData gd = new GridData(GridData.FILL_BOTH); final PixelConverter pixConv = new PixelConverter(parent); gd.widthHint = pixConv.convertWidthInCharsToPixels(48); gd.heightHint = pixConv.convertHeightInCharsToPixels(8); fLocationsViewer.getControl().setLayoutData(gd); fLocationsViewer.setContentProvider(new ManLocationsContentProvider()); fLocationsViewer.setLabelProvider(new ManPagesLabelProvider()); fLocationsViewer.setComparator(new ViewerComparator()); fLocationsViewer.addSelectionChangedListener(this); if (fEditable) { createButtons(comp); } Dialog.applyDialogFont(comp); return comp; } private void createButtons(Composite comp) { Composite pathButtonComp = new Composite(comp, SWT.NONE); GridLayout pathButtonLayout = new GridLayout(); pathButtonLayout.marginHeight = 0; pathButtonLayout.marginWidth = 0; pathButtonComp.setLayout(pathButtonLayout); pathButtonComp .setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL)); fAddButton = createPushButton(pathButtonComp, ManPagesMessages.ManPagesLocationsBlock_AddButton); fAddButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { add(); } }); fEditButton = createPushButton(pathButtonComp, ManPagesMessages.ManPagesLocationsBlock_EditButton); fEditButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { final IStructuredSelection selection = getSelection(); if (selection.size() == 1 && selection .getFirstElement() instanceof Documentation) { edit((Documentation) selection.getFirstElement()); } } }); fRemoveButton = createPushButton(pathButtonComp, ManPagesMessages.ManPagesLocationsBlock_RemoveButton); fRemoveButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { final IStructuredSelection selection = getSelection(); if (canRemove(selection)) { remove(selection); } } }); fDefaultButton = createPushButton(pathButtonComp, ManPagesMessages.ManPagesLocationsBlock_SetDefaultButton); ((GridData) fDefaultButton.getLayoutData()).verticalIndent = 16; fDefaultButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { final IStructuredSelection selection = getSelection(); if (selection.size() == 1 && selection .getFirstElement() instanceof Documentation) { setDefault((Documentation) selection.getFirstElement()); } } }); } protected void setDefault(Documentation documentation) { documentation.setDefault(true); for (Documentation doc : documentations.getDocumentations()) { if (doc != documentation && doc.isDefault()) { doc.setDefault(false); } } fLocationsViewer.refresh(); } /** * Creates and returns a button * * @param parent * parent widget * @param label * label * @return Button */ protected Button createPushButton(Composite parent, String label) { Button button = new Button(parent, SWT.PUSH); button.setFont(parent.getFont()); button.setText(label); setButtonLayoutData(button); return button; } static void setButtonLayoutData(Button button) { GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); int widthHint = 80; Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); data.widthHint = Math.max(widthHint, minSize.x); button.setLayoutData(data); } /** * Create some empty space */ protected void createVerticalSpacer(Composite comp, int colSpan) { Label label = new Label(comp, SWT.NONE); GridData gd = new GridData(); gd.horizontalSpan = colSpan; label.setLayoutData(gd); } /** * Updates buttons and status based on current mans */ public void update() { updateButtons(); updatePageStatus(StatusInfo.OK_STATUS); } // public void setDefaults() { // String res = fStore // .getDefaultString(TclPreferenceConstants.DOC_MAN_PAGES_LOCATIONS); // fStore.setValue(TclPreferenceConstants.DOC_MAN_PAGES_LOCATIONS, res); // initialize(); // } protected void updatePageStatus(IStatus status) { if (fPage == null) return; fPage.statusChanged(status); } public void initialize() { this.documentations = ManPageLoader.load(); fLocationsViewer.setInput(documentations); fLocationsViewer.expandToLevel(2); update(); } /** * Saves settings * * @throws IOException */ public void save() throws IOException { documentations.save(null); } private Shell getShell() { if (fPage instanceof IShellProvider) { return ((IShellProvider) fPage).getShell(); } else { return PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getShell(); } } /** * Open the file selection dialog, and add the return locations. */ protected void add() { final ManPagesLocationsDialog dialog = new ManPagesLocationsDialog( getShell(), documentations, null); if (dialog.open() == Window.OK) { final Documentation documentation = dialog.getResult(); documentations.checkDefault(); fLocationsViewer.refresh(); fLocationsViewer .setSelection(new StructuredSelection(documentation)); } } protected void edit(Documentation documentation) { final ManPagesLocationsDialog dialog = new ManPagesLocationsDialog( getShell(), documentations, documentation); if (dialog.open() == Window.OK) { fLocationsViewer.refresh(documentation); } } protected void remove(IStructuredSelection selection) { boolean changes = false; for (Iterator<?> i = selection.iterator(); i.hasNext();) { final Object obj = i.next(); if (obj instanceof EObject) { EcoreUtil.remove(((EObject) obj)); changes = true; } } if (changes) { documentations.checkDefault(); fLocationsViewer.refresh(); } } /* * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent) */ @Override public void selectionChanged(SelectionChangedEvent event) { updateButtons(); } /** * Refresh the enable/disable state for the buttons. */ private void updateButtons() { if (!fEditable) return; final IStructuredSelection selection = getSelection(); final boolean singleDoc = selection.size() == 1 && selection.getFirstElement() instanceof Documentation; fEditButton.setEnabled(singleDoc); fDefaultButton.setEnabled(singleDoc && !((Documentation) selection.getFirstElement()).isDefault()); fRemoveButton.setEnabled(canRemove(selection)); } protected boolean canRemove(IStructuredSelection selection) { if (selection.isEmpty()) { return false; } for (Iterator<?> i = selection.iterator(); i.hasNext();) { final Object obj = i.next(); if (!(obj instanceof Documentation)) { return false; } } return true; } protected IStructuredSelection getSelection() { return (IStructuredSelection) fLocationsViewer.getSelection(); } }