blob: 3973046ddd83d399530f5f43403e316160569499 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}