/* * Copyright (c) 2015, 2016 Eike Stepper (Berlin, Germany) 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: * Eike Stepper - initial API and implementation */ package org.eclipse.emf.cdo.explorer.ui.handlers; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.commit.CDOChangeSetData; import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion; import org.eclipse.emf.cdo.common.revision.CDORevisionKey; import org.eclipse.emf.cdo.explorer.ui.ObjectListController; import org.eclipse.emf.cdo.explorer.ui.bundle.OM; import org.eclipse.emf.cdo.internal.explorer.checkouts.OfflineCDOCheckout; import org.eclipse.emf.cdo.spi.workspace.InternalCDOWorkspace; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.net4j.util.ui.handlers.AbstractBaseHandler; import org.eclipse.emf.spi.cdo.InternalCDOView; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.handlers.HandlerUtil; import java.util.ArrayList; import java.util.List; /** * @author Eike Stepper */ public class WorkspaceRevertHandler extends AbstractBaseHandler<OfflineCDOCheckout> { private List<CDOTransaction> dirtyTransactions; public WorkspaceRevertHandler() { super(OfflineCDOCheckout.class, null); } @Override protected boolean updateSelection(ISelection selection) { boolean result = super.updateSelection(selection); if (result) { OfflineCDOCheckout checkout = elements.get(0); if (!checkout.isDirty()) { return false; } } return result; } @Override protected void preRun(ExecutionEvent event) throws Exception { dirtyTransactions = new ArrayList<CDOTransaction>(); InternalCDOWorkspace workspace = getWorkspace(); if (workspace != null) { for (InternalCDOView view : workspace.getViews()) { if (view.isDirty()) { dirtyTransactions.add((CDOTransaction)view); } } Shell shell = HandlerUtil.getActiveShell(event); int size = dirtyTransactions.size(); if (size != 0) { String plural = size == 1 ? "" : "s"; String message = size == 1 ? "is 1" : "are " + size; if (!MessageDialog.openQuestion(shell, "Uncommitted Transaction" + plural, "There " + message + " uncommitted transaction" + plural + ".\n\n" + "Are you sure you want to rollback the transaction" + plural + ", too?")) { cancel(); return; } } OfflineCDOCheckout checkout = elements.get(0); CDOChangeSetData revertData = workspace.getLocalChanges(false); RevertConfirmationDialog dialog = new RevertConfirmationDialog(shell, checkout, revertData); if (dialog.open() == RevertConfirmationDialog.OK) { return; } } cancel(); } @Override protected void doExecute(ExecutionEvent event, IProgressMonitor monitor) throws Exception { try { for (CDOTransaction transaction : dirtyTransactions) { transaction.rollback(); } } finally { dirtyTransactions = null; } InternalCDOWorkspace workspace = getWorkspace(); if (workspace != null) { // TODO Use progress monitor. workspace.revert(); } } private InternalCDOWorkspace getWorkspace() { OfflineCDOCheckout checkout = elements.get(0); return checkout.getWorkspace(); } /** * @author Eike Stepper */ private static class RevertConfirmationDialog extends TitleAreaDialog { private static final String TITLE = "Revert Local Changes"; private final OfflineCDOCheckout checkout; private final CDOChangeSetData revertData; public RevertConfirmationDialog(Shell parentShell, OfflineCDOCheckout checkout, CDOChangeSetData revertData) { super(parentShell); this.checkout = checkout; this.revertData = revertData; setShellStyle(SWT.CLOSE | SWT.RESIZE | SWT.TITLE | SWT.APPLICATION_MODAL); } @Override protected Control createDialogArea(Composite parent) { Composite area = (Composite)super.createDialogArea(parent); getShell().setText(TITLE); setTitle(TITLE); setTitleImage(OM.getImage("icons/wiz/revert.gif")); setMessage("Are you sure you want to revert your local changes?"); Composite container = new Composite(area, SWT.NONE); container.setLayoutData(new GridData(GridData.FILL_BOTH)); GridLayout containerGridLayout = new GridLayout(); containerGridLayout.marginWidth = 10; containerGridLayout.marginHeight = 10; container.setLayout(containerGridLayout); ObjectListController objectListController = new ObjectListController(checkout); CDOView view = checkout.getView(); for (CDORevisionKey key : revertData.getChangedObjects()) { CDOObject object = view.getObject(key.getID()); objectListController.addObject(object, false); } for (CDOIDAndVersion key : revertData.getDetachedObjects()) { CDOObject object = view.getObject(key.getID()); objectListController.addObject(object, true); } TreeViewer treeViewer = new TreeViewer(container); treeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); objectListController.configure(treeViewer); return area; } @Override protected Point getInitialSize() { return new Point(500, 400); } } }