/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package org.python.pydev.ui.pythonpathconf; import java.lang.ref.WeakReference; import org.eclipse.core.runtime.Assert; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.program.Program; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.Widget; /** * Helper to create a list of strings with buttons for new/remove. * * Used for the forced builtins. */ abstract/*default*/class AbstractListWithNewRemoveControl extends SelectionAdapter implements DisposeListener { protected Composite box; private Button addBt; private Button removeBt; protected List itemsList; protected WeakReference<AbstractInterpreterEditor> container; public AbstractListWithNewRemoveControl(AbstractInterpreterEditor container) { this.container = new WeakReference<AbstractInterpreterEditor>(container); } /** * Creates the tab */ void createTab(String tabLabel, String internalLabel) { AbstractInterpreterEditor interpreterEditor = container.get(); Composite parent; GridData gd; TabItem tabItem; Composite composite; Composite control; tabItem = new TabItem(interpreterEditor.tabFolder, SWT.None); tabItem.setText(tabLabel); composite = new Composite(interpreterEditor.tabFolder, SWT.None); parent = composite; composite.setLayout(new GridLayout(2, false)); //label Link l2 = new Link(parent, SWT.None); l2.setText(internalLabel); l2.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { Program.launch("http://pydev.org/manual_101_interpreter.html"); } }); gd = new GridData(); gd.horizontalSpan = 2; l2.setLayoutData(gd); //the list with the items List list = getListControl(parent); gd = new GridData(); gd.horizontalAlignment = SWT.FILL; gd.verticalAlignment = SWT.FILL; gd.grabExcessHorizontalSpace = true; gd.grabExcessVerticalSpace = true; gd.heightHint = 200; list.setLayoutData(gd); //the buttons control = getButtonBoxControlOthers(parent); gd = new GridData(); gd.verticalAlignment = GridData.BEGINNING; control.setLayoutData(gd); tabItem.setControl(composite); } /** * Returns this field editor's button box containing the Add and Remove * * @param parent the parent control * @return the button box */ public Composite getButtonBoxControlOthers(Composite parent) { AbstractInterpreterEditor interpreterEditor = this.container.get(); Assert.isNotNull(interpreterEditor); if (box == null) { box = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(); layout.marginWidth = 0; box.setLayout(layout); createButtons(interpreterEditor); box.addDisposeListener(this); } else { checkParent(box, parent); } return box; } /** * To create a button in a subclass, one must override * * - createButtons * - widgetDisposed * - widgetSelected */ protected void createButtons(AbstractInterpreterEditor interpreterEditor) { addBt = interpreterEditor.createBt(box, "ListEditor.add", this);//$NON-NLS-1$ removeBt = interpreterEditor.createBt(box, "ListEditor.remove", this);//$NON-NLS-1$ } public void widgetDisposed(DisposeEvent event) { if (addBt != null) { addBt.dispose(); addBt = null; } if (removeBt != null) { removeBt.dispose(); removeBt = null; } if (box != null) { box.dispose(); box = null; } } public void widgetSelected(SelectionEvent event) { Widget widget = event.widget; if (widget == addBt) { addItem(); } else if (widget == removeBt) { removeItem(); } } /** * Checks if the given parent is the current parent of the * supplied control; throws an (unchecked) exception if they * are not correctly related. * * @param control the control * @param parent the parent control */ protected void checkParent(Control control, Composite parent) { Assert.isTrue(control.getParent() == parent, "Different parents");//$NON-NLS-1$ } /** * @param parent * @return */ private List getListControl(Composite parent) { if (itemsList == null) { itemsList = new List(parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); itemsList.setFont(parent.getFont()); itemsList.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent event) { itemsList = null; } }); } else { checkParent(itemsList, parent); } return itemsList; } /** * */ protected void addItem() { AbstractInterpreterEditor interpreterEditor = this.container.get(); Assert.isNotNull(interpreterEditor); InterpreterInfo info = interpreterEditor.getSelectedInfo(); if (info != null) { String item = getInput(); if (item != null) { addInputToInfo(info, item); interpreterEditor.updateTree(); } } } /** * */ protected void removeItem() { AbstractInterpreterEditor interpreterEditor = this.container.get(); Assert.isNotNull(interpreterEditor); InterpreterInfo info = interpreterEditor.getSelectedInfo(); if (info != null) { String[] selected = itemsList.getSelection(); removeSelectedFrominfo(info, selected); interpreterEditor.updateTree(); } } /** * Removes all items from the internal list. */ public void removeAllFromList() { this.itemsList.removeAll(); } /** * Updates the internal list given the passed info. */ public void update(InterpreterInfo info) { java.util.List<String> stringsFromInfo = this.getStringsFromInfo(info); for (String s : stringsFromInfo) { itemsList.add(s); } } /** * Subclasses must remove the list of selected strings from the corresponding fields * in the interpreter info. */ protected abstract void removeSelectedFrominfo(InterpreterInfo info, String[] item); /** * Subclasses must return the list of strings that should be added to the gui from the * passed info. */ protected abstract java.util.List<String> getStringsFromInfo(InterpreterInfo info); /** * Subclasses must add the passed item to the info. */ protected abstract void addInputToInfo(InterpreterInfo info, String item); /** * Subclasses must override to get the input to be added to the list. If null is returned, * nothing is added. */ protected abstract String getInput(); }