/*******************************************************************************
* Copyright (c) 2010 The Eclipse Foundation 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:
* The Eclipse Foundation - initial API and implementation
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceNodeCatalogItem;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
/**
* A controller that controls the multi-state install/uninstall button
*
* @author David Green
*/
@SuppressWarnings("rawtypes")
class ItemButtonController {
private enum ButtonState {
INSTALL(Messages.ItemButtonController_install, Operation.NONE, false), //
UNINSTALL(Messages.ItemButtonController_uninstall, Operation.NONE, false), //
INSTALL_PENDING(Messages.ItemButtonController_installPending, Operation.INSTALL, false), //
UNINSTALL_PENDING(Messages.ItemButtonController_uninstallPending, Operation.UNINSTALL, false), //
DISABLED(Messages.ItemButtonController_install, Operation.NONE, true), //
UPDATE_DISABLED(Messages.ItemButtonController_update, Operation.NONE, true), //
UPDATE(Messages.ItemButtonController_update, Operation.NONE, false), //
UPDATE_PENDING(Messages.ItemButtonController_updatePending, Operation.CHECK_FOR_UPDATES, false);
final String label;
private final Operation operation;
private final boolean disabled;
private ButtonState(String label, Operation operation, boolean disabled) {
this.label = label;
this.operation = operation;
this.disabled = disabled;
}
public ButtonState nextState() {
switch (this) {
case INSTALL:
return INSTALL_PENDING;
case INSTALL_PENDING:
return INSTALL;
case UNINSTALL:
return UNINSTALL_PENDING;
case UNINSTALL_PENDING:
return UNINSTALL;
case UPDATE:
return UPDATE_PENDING;
case UPDATE_PENDING:
return UPDATE;
}
return this;
}
public ButtonState noActionState() {
switch (this) {
case INSTALL_PENDING:
return INSTALL;
case UNINSTALL_PENDING:
return UNINSTALL;
case UPDATE_PENDING:
return UPDATE;
}
return this;
}
}
private final DiscoveryItem item;
private final Button button;
private ButtonState buttonState;
private final Button secondaryButton;
private ButtonState secondaryButtonState;
@SuppressWarnings("unused")
private final MarketplaceViewer viewer;
public ItemButtonController(MarketplaceViewer marketplaceViewer, DiscoveryItem discoveryItem, Button button,
Button secondaryButton) {
this.item = discoveryItem;
this.button = button;
this.viewer = marketplaceViewer;
this.secondaryButton = secondaryButton;
updateButtonState();
updateAppearance();
button.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
buttonClicked(buttonState, secondaryButtonState);
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
});
if (secondaryButton != null) {
secondaryButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
buttonClicked(secondaryButtonState, buttonState);
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
});
}
}
private void buttonClicked(ButtonState primary, ButtonState secondary) {
if (primary != ButtonState.DISABLED) {
primary = primary.nextState();
secondary = secondary.noActionState();
item.maybeModifySelection(primary.operation);
}
refresh();
}
private void updateButtonState() {
MarketplaceNodeCatalogItem catalogItem = (MarketplaceNodeCatalogItem) item.getData();
if (catalogItem.getInstallableUnits().isEmpty()) {
buttonState = ButtonState.DISABLED;
secondaryButtonState = ButtonState.DISABLED;
} else {
Operation operation = item.getOperation();
boolean installed = isItemInstalled();
if (installed) {
switch (operation) {
case CHECK_FOR_UPDATES:
buttonState = ButtonState.UPDATE_PENDING;
secondaryButtonState = ButtonState.UNINSTALL;
break;
case UNINSTALL:
buttonState = ButtonState.UPDATE;
secondaryButtonState = ButtonState.UNINSTALL_PENDING;
break;
case NONE:
buttonState = ButtonState.UPDATE;
secondaryButtonState = ButtonState.UNINSTALL;
break;
}
if (buttonState == ButtonState.UPDATE) {
if (catalogItem.getUpdateAvailable() != null && !catalogItem.getUpdateAvailable()) {
buttonState = ButtonState.UPDATE_DISABLED;
}
}
} else {
switch (operation) {
case INSTALL:
buttonState = ButtonState.INSTALL_PENDING;
break;
case NONE:
buttonState = ButtonState.INSTALL;
break;
}
secondaryButtonState = ButtonState.DISABLED;
if (!isItemAvailable()) {
buttonState = ButtonState.DISABLED;
}
}
}
}
private boolean isItemInstalled() {
return ((CatalogItem) item.getData()).isInstalled();
}
private boolean isItemAvailable() {
Boolean available = ((CatalogItem) item.getData()).getAvailable();
return available == null || available;
}
private void updateAppearance() {
button.setText(buttonState.label);
button.setEnabled(!buttonState.disabled);
if (secondaryButton != null) {
secondaryButton.setText(secondaryButtonState.label);
secondaryButton.setEnabled(!secondaryButtonState.disabled);
}
// button image? Due to platform limitations we can't set the button color
item.layout(true, true);
}
public void refresh() {
updateButtonState();
updateAppearance();
}
}