| /******************************************************************************* |
| * Copyright (c) 2016 Red Hat. |
| * 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: |
| * Red Hat - Initial Contribution |
| *******************************************************************************/ |
| package org.eclipse.linuxtools.internal.docker.ui.preferences; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.jface.preference.PreferencePage; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.viewers.ColumnWeightData; |
| import org.eclipse.jface.viewers.ILabelProviderListener; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.ITableLabelProvider; |
| import org.eclipse.jface.viewers.TableLayout; |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.linuxtools.docker.core.IRegistryAccount; |
| import org.eclipse.linuxtools.internal.docker.core.RegistryAccountManager; |
| import org.eclipse.linuxtools.internal.docker.ui.wizards.RegistryAccountDialog; |
| import org.eclipse.swt.SWT; |
| 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.Control; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableColumn; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.IWorkbenchPreferencePage; |
| |
| /** |
| * @since 2.0 |
| */ |
| public class DockerRegistryAccountPreferencePage extends PreferencePage |
| implements IWorkbenchPreferencePage, Listener { |
| |
| /** |
| * @since 2.1 |
| */ |
| public static final String ACCOUNT_PREFERENCE_PAGE_ID = "org.eclipse.linuxtools.docker.ui.preferences.DockerRegistryAccountPreferencePage"; //$NON-NLS-1$ |
| |
| /** |
| * Inner class to keep track of password modifications (without committing |
| * them to the keyring) while the user modifies the preferences. |
| */ |
| protected class PasswordModification { |
| protected static final int ADD = 1; |
| protected static final int DELETE = 2; |
| |
| protected int changeFlag; |
| protected IRegistryAccount info; |
| |
| protected PasswordModification(int changeFlag, |
| IRegistryAccount info) { |
| this.changeFlag = changeFlag; |
| this.info = info; |
| } |
| } |
| |
| private final class PasswordContentProvider |
| implements IStructuredContentProvider, ITableLabelProvider { |
| |
| /** |
| * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object) |
| */ |
| @Override |
| public Object[] getElements(Object inputElement) { |
| return passwords.toArray(); |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.IContentProvider#dispose() |
| */ |
| @Override |
| public void dispose() { |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, |
| * Object, Object) |
| */ |
| @Override |
| public void inputChanged(Viewer viewer, Object oldInput, |
| Object newInput) { |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(Object, |
| * int) |
| */ |
| @Override |
| public Image getColumnImage(Object element, int columnIndex) { |
| return null; |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(Object, |
| * int) |
| */ |
| @Override |
| public String getColumnText(Object element, int columnIndex) { |
| if (element instanceof IRegistryAccount) { |
| IRegistryAccount info = (IRegistryAccount) element; |
| switch (columnIndex) { |
| case 0: |
| return info.getServerAddress(); |
| case 1: |
| return info.getUsername(); |
| case 2: |
| return info.getEmail(); |
| } |
| } |
| |
| // Should never get here |
| return null; |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(ILabelProviderListener) |
| */ |
| @Override |
| public void addListener(ILabelProviderListener listener) { |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(Object, |
| * String) |
| */ |
| @Override |
| public boolean isLabelProperty(Object element, String property) { |
| return false; |
| } |
| |
| /** |
| * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(ILabelProviderListener) |
| */ |
| @Override |
| public void removeListener(ILabelProviderListener listener) { |
| } |
| |
| } |
| |
| public DockerRegistryAccountPreferencePage() { |
| noDefaultAndApplyButton(); |
| provider = new PasswordContentProvider(); |
| modifications = new ArrayList<>(); |
| } |
| |
| public DockerRegistryAccountPreferencePage(String title) { |
| super(title); |
| } |
| |
| public DockerRegistryAccountPreferencePage(String title, |
| ImageDescriptor image) { |
| super(title, image); |
| } |
| |
| // SWT Widgets and content providers |
| private Table pwdTable; |
| private TableViewer pwdTableViewer; |
| private PasswordContentProvider provider; |
| private Button addButton, changeButton, removeButton; |
| |
| // List of information for table |
| private List<IRegistryAccount> passwords; |
| |
| // List to keep track of additions / deletions / changes. We need to |
| // keep track of these until the user decides whether to cancel the |
| // preference |
| // page (and we forget about the changes) or press ok (and we commit the |
| // changes) |
| private List<PasswordModification> modifications; |
| |
| /** |
| * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite) |
| */ |
| @Override |
| protected Control createContents(Composite parent) { |
| |
| Composite page = createComposite(parent, 1, 2, false, null, -1, -1, GridData.FILL); |
| GridData gd = (GridData) page.getLayoutData(); |
| gd.grabExcessHorizontalSpace = true; |
| gd.grabExcessVerticalSpace = true; |
| |
| // SystemWidgetHelpers.createLabel(page, |
| // SystemResources.RESID_PREF_SIGNON_DESCRIPTION, 2); |
| |
| // Password table |
| pwdTable = new Table(page, SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL |
| | SWT.H_SCROLL | SWT.BORDER); |
| pwdTable.setLinesVisible(true); |
| pwdTable.setHeaderVisible(true); |
| pwdTable.addListener(SWT.Selection, this); |
| |
| TableLayout tableLayout = new TableLayout(); |
| tableLayout.addColumnData(new ColumnWeightData(100, true)); |
| tableLayout.addColumnData(new ColumnWeightData(100, true)); |
| tableLayout.addColumnData(new ColumnWeightData(100, true)); |
| pwdTable.setLayout(tableLayout); |
| |
| gd = new GridData(GridData.FILL_BOTH); |
| gd.grabExcessHorizontalSpace = true; |
| gd.grabExcessVerticalSpace = true; |
| |
| pwdTable.setLayoutData(gd); |
| |
| // Server Address column |
| TableColumn hostnameColumn = new TableColumn(pwdTable, SWT.NONE); |
| hostnameColumn |
| .setText("Server Address"); |
| |
| // Username column |
| TableColumn sysTypeColumn = new TableColumn(pwdTable, SWT.NONE); |
| sysTypeColumn.setText("Username"); |
| |
| // Email column |
| TableColumn useridColumn = new TableColumn(pwdTable, SWT.NONE); |
| useridColumn.setText("Email"); |
| |
| pwdTableViewer = new TableViewer(pwdTable); |
| pwdTableViewer.setContentProvider(provider); |
| pwdTableViewer.setLabelProvider(provider); |
| pwdTableViewer.setInput(passwords); |
| |
| // Create the Button bar for add, change and remove |
| Composite buttonBar = createComposite(page, 1, 1, false, null, -1, -1, GridData.FILL); |
| gd = (GridData) buttonBar.getLayoutData(); |
| gd.grabExcessHorizontalSpace = false; |
| gd.grabExcessVerticalSpace = true; |
| |
| addButton = createPushButton(buttonBar, this, |
| "Add", |
| "Add a new Docker registry account."); |
| changeButton = createPushButton(buttonBar, this, |
| "Edit", |
| "Edit an existing Docker registry account."); |
| removeButton = createPushButton(buttonBar, this, |
| "Remove", |
| "Remove an existing Docker registry account."); |
| |
| changeButton.setEnabled(false); |
| removeButton.setEnabled(false); |
| return parent; |
| } |
| |
| /** |
| * @see org.eclipse.ui.IWorkbenchPreferencePage#init(IWorkbench) |
| */ |
| @Override |
| public void init(IWorkbench workbench) { |
| // get a local copy of the accounts |
| passwords = new ArrayList<>( |
| RegistryAccountManager.getInstance().getAccounts()); |
| |
| // refresh password table |
| if (pwdTableViewer != null) { |
| pwdTableViewer.refresh(); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.swt.widgets.Listener#handleEvent(Event) |
| */ |
| @Override |
| public void handleEvent(Event event) { |
| if (event.type == SWT.Selection) { |
| if (event.widget == addButton) { |
| RegistryAccountDialog dialog = new RegistryAccountDialog( |
| getShell(), |
| "New Registry Account"); |
| if (dialog.open() == Window.OK) { |
| IRegistryAccount info = dialog |
| .getSignonInformation(); |
| passwords.add(info); |
| modifications.add(new PasswordModification( |
| PasswordModification.ADD, info)); |
| |
| pwdTableViewer.refresh(); |
| pwdTable.select(passwords.size() - 1); // select the new |
| // entry |
| } |
| |
| } else if (event.widget == changeButton) { |
| RegistryAccountDialog dialog = new RegistryAccountDialog( |
| getShell(), |
| "Edit Registry Account"); |
| int index = pwdTable.getSelectionIndex(); |
| IRegistryAccount info = passwords |
| .get(index); |
| dialog.setInputData(info); |
| if (dialog.open() == Window.OK) { |
| // Remove old and add new |
| info = dialog.getSignonInformation(); |
| IRegistryAccount oldInfo = passwords |
| .remove(index); |
| passwords.add(index, info); |
| |
| modifications.add(new PasswordModification( |
| PasswordModification.DELETE, oldInfo)); |
| modifications.add(new PasswordModification( |
| PasswordModification.ADD, info)); |
| |
| pwdTableViewer.refresh(); |
| pwdTable.select(index); |
| } |
| |
| } else if (event.widget == removeButton) { |
| int[] indicies = pwdTable.getSelectionIndices(); |
| for (int idx = indicies.length - 1; idx >= 0; idx--) { |
| RegistryAccountManager.getInstance() |
| .remove(passwords.get(indicies[idx])); |
| modifications.add(new PasswordModification( |
| PasswordModification.DELETE, |
| passwords |
| .remove(indicies[idx]))); |
| } |
| |
| pwdTableViewer.refresh(); |
| } |
| |
| // Update table buttons based on changes |
| switch (pwdTable.getSelectionCount()) { |
| case 0: |
| changeButton.setEnabled(false); |
| removeButton.setEnabled(false); |
| break; |
| |
| case 1: |
| changeButton.setEnabled(true); |
| removeButton.setEnabled(true); |
| break; |
| |
| default: |
| changeButton.setEnabled(false); |
| removeButton.setEnabled(true); |
| break; |
| } |
| } |
| } |
| |
| /** |
| * @see org.eclipse.jface.preference.IPreferencePage#performOk() |
| */ |
| @Override |
| public boolean performOk() { |
| |
| if (modifications.size() > 0) { |
| PasswordModification mod; |
| RegistryAccountManager manager = RegistryAccountManager |
| .getInstance(); |
| |
| for (int i = 0; i < modifications.size(); i++) { |
| mod = modifications.get(i); |
| |
| if (mod.changeFlag == PasswordModification.ADD) { |
| manager.add(mod.info); |
| } else if (mod.changeFlag == PasswordModification.DELETE) { |
| manager.remove(mod.info); |
| } |
| } |
| |
| modifications.clear(); |
| } |
| |
| return super.performOk(); |
| } |
| |
| /** |
| * @see org.eclipse.jface.preference.IPreferencePage#performCancel() |
| */ |
| @Override |
| public boolean performCancel() { |
| modifications.clear(); |
| return super.performCancel(); |
| } |
| |
| private static Composite createComposite(Composite parent, int parentSpan, int numColumns, boolean border, String label, int marginSize, int spacingSize, int verticalAlignment) { |
| //border = true; |
| boolean borderNeeded = border; |
| if (label != null) |
| borderNeeded = true; // force the case |
| int style = SWT.NULL; |
| if (borderNeeded) |
| style |= SWT.SHADOW_ETCHED_IN; |
| Composite composite = null; |
| if (borderNeeded) { |
| composite = new Group(parent, style); |
| if (label != null) |
| ((Group) composite).setText(label); |
| } else { |
| composite = new Composite(parent, style); |
| } |
| //GridLayout |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = numColumns; |
| if (marginSize != -1) { |
| layout.marginWidth = 0; |
| layout.marginHeight = 0; |
| } |
| if (spacingSize != -1) { |
| layout.horizontalSpacing = 0; |
| layout.verticalSpacing = 0; |
| } |
| composite.setLayout(layout); |
| //GridData |
| GridData data = new GridData(); |
| data.horizontalSpan = parentSpan; |
| data.horizontalAlignment = GridData.FILL; |
| data.grabExcessHorizontalSpace = true; |
| |
| data.verticalAlignment = verticalAlignment; |
| data.grabExcessVerticalSpace = false; |
| |
| composite.setLayoutData(data); |
| return composite; |
| } |
| |
| public static Button createPushButton(Composite group, Listener listener, String label, String tooltip) { |
| Button button = new Button(group, SWT.PUSH); |
| button.setText(label); |
| if (listener != null) |
| button.addListener(SWT.Selection, listener); |
| GridData data = new GridData(); |
| data.horizontalAlignment = GridData.FILL; |
| data.grabExcessHorizontalSpace = true; |
| button.setLayoutData(data); |
| if (tooltip != null) |
| button.setToolTipText(tooltip); |
| return button; |
| } |
| |
| } |