com.collabnet.subversion.merge.views.MergeResultsView.java Source code

Java tutorial

Introduction

Here is the source code for com.collabnet.subversion.merge.views.MergeResultsView.java

Source

/*******************************************************************************
 * Copyright (c) 2009 CollabNet.
 * 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:
 *     CollabNet - initial API and implementation
 ******************************************************************************/
package com.collabnet.subversion.merge.views;

import java.io.File;
import java.util.Iterator;

import org.eclipse.compare.CompareUI;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Display;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.actions.OpenWithMenu;
import org.eclipse.ui.part.ViewPart;
import org.tigris.subversion.subclipse.core.ISVNLocalResource;
import org.tigris.subversion.subclipse.core.ISVNRemoteFile;
import org.tigris.subversion.subclipse.core.SVNException;
import org.tigris.subversion.subclipse.core.resources.RemoteFile;
import org.tigris.subversion.subclipse.core.resources.SVNTreeConflict;
import org.tigris.subversion.subclipse.core.resources.SVNWorkspaceRoot;
import org.tigris.subversion.subclipse.ui.SVNUIPlugin;
import org.tigris.subversion.subclipse.ui.actions.EditConflictsAction;
import org.tigris.subversion.subclipse.ui.compare.SVNLocalCompareInput;
import org.tigris.subversion.svnclientadapter.ISVNClientAdapter;
import org.tigris.subversion.svnclientadapter.ISVNStatus;
import org.tigris.subversion.svnclientadapter.SVNClientException;
import org.tigris.subversion.svnclientadapter.SVNConflictDescriptor;
import org.tigris.subversion.svnclientadapter.SVNConflictVersion;
import org.tigris.subversion.svnclientadapter.SVNRevision;
import org.tigris.subversion.svnclientadapter.SVNUrl;

import com.collabnet.subversion.merge.Activator;
import com.collabnet.subversion.merge.AdaptableMergeResult;
import com.collabnet.subversion.merge.AdaptableMergeResultsFolder;
import com.collabnet.subversion.merge.MergeOutput;
import com.collabnet.subversion.merge.MergeResult;
import com.collabnet.subversion.merge.MergeResultsFolder;
import com.collabnet.subversion.merge.Messages;
import com.collabnet.subversion.merge.actions.DeleteMergeOutputAction;
import com.collabnet.subversion.merge.actions.MergeEditConflictsAction;
import com.collabnet.subversion.merge.actions.OpenFileInSystemEditorAction;

public class MergeResultsView extends ViewPart {
    private static MergeResultsView view;
    private TreeViewer treeViewer;
    private MergeResultsViewLabelProvider labelProvider = new MergeResultsViewLabelProvider();
    private static ToggleLayoutAction[] toggleLayoutActions;
    private IAction toggleConflictsOnlyAction;
    private IPreferenceStore store = Activator.getDefault().getPreferenceStore();
    private RemoveAction removeAction = new RemoveAction();
    private RemoveAllAction removeAllAction = new RemoveAllAction();
    private SVNTreeConflict treeConflict;

    private OpenFileInSystemEditorAction openAction;

    public final static String ID = "com.collabnet.subversion.merge.views.MergeResultsView"; //$NON-NLS-1$
    public final static String LAYOUT_PREFERENCE = "MergeResultsView_layout";; //$NON-NLS-1$
    public final static String CONFLICTS_ONLY_PREFERENCE = "MergeResultsView_conflictsOnly";; //$NON-NLS-1$
    public final static int MODE_COMPRESSED_FOLDERS = 0;
    public final static int MODE_FLAT = 1;
    public final static int MODE_TREE = 2;

    public MergeResultsView() {
        super();
        view = this;
    }

    public void createPartControl(Composite parent) {
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;
        layout.verticalSpacing = 2;
        layout.marginWidth = 0;
        layout.marginHeight = 2;
        parent.setLayout(layout);

        treeViewer = new TreeViewer(parent);
        treeViewer.setLabelProvider(labelProvider);
        treeViewer.setContentProvider(new MergeResultsViewContentProvider());
        treeViewer.setUseHashlookup(true);
        GridData layoutData = new GridData();
        layoutData.grabExcessHorizontalSpace = true;
        layoutData.grabExcessVerticalSpace = true;
        layoutData.horizontalAlignment = GridData.FILL;
        layoutData.verticalAlignment = GridData.FILL;
        treeViewer.getControl().setLayoutData(layoutData);
        treeViewer.setInput(this);
        treeViewer.addOpenListener(new IOpenListener() {
            public void open(OpenEvent event) {
                treeConflict = null;
                IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
                Object selectedItem = selection.getFirstElement();
                MergeResult mergeResult = null;
                if (selectedItem instanceof AdaptableMergeResult)
                    mergeResult = (MergeResult) selectedItem;
                if (selectedItem instanceof AdaptableMergeResultsFolder) {
                    MergeResultsFolder mergeResultsFolder = (MergeResultsFolder) selectedItem;
                    mergeResult = mergeResultsFolder.getMergeResult();
                }
                if (mergeResult != null) {
                    if (mergeResult.getResource() instanceof IFile && mergeResult.isConflicted()
                            && !mergeResult.isResolved()) {
                        editConflicts(mergeResult);
                        return;
                    }
                    if (mergeResult.getResource() instanceof IFile && mergeResult.hasTreeConflict()
                            && !mergeResult.isTreeConflictResolved()) {
                        boolean addAddConflict = false;
                        if (mergeResult.getResource() != null && mergeResult.getResource().exists()) {
                            treeConflict = getTreeConflict(mergeResult.getResource());
                            if (treeConflict != null && treeConflict.getDescription() != null
                                    && treeConflict.getDescription().contains("local add") //$NON-NLS-1$
                                    && treeConflict.getDescription().contains("incoming add")) { //$NON-NLS-1$
                                addAddConflict = true;
                            }
                            if (!addAddConflict) {
                                openAction.run();
                            }
                        }
                        if (!addAddConflict) {
                            return;
                        }
                    }
                    if (!mergeResult.getAction().equals(MergeResult.ACTION_DELETE)) {
                        final ISVNLocalResource localResource = SVNWorkspaceRoot
                                .getSVNResourceFor(mergeResult.getResource());
                        if (!localResource.exists()) {
                            return;
                        }
                        BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
                            public void run() {
                                try {
                                    if (treeConflict != null) {
                                        if (!localResource.isFolder()) {
                                            SVNConflictDescriptor descriptor = treeConflict.getConflictDescriptor();
                                            SVNConflictVersion rightVersion = descriptor.getSrcRightVersion();
                                            try {
                                                ISVNRemoteFile remoteFile = new RemoteFile(
                                                        localResource.getRepository(),
                                                        new SVNUrl(rightVersion.getReposURL() + "/"
                                                                + rightVersion.getPathInRepos()),
                                                        new SVNRevision.Number(rightVersion.getPegRevision()));
                                                SVNLocalCompareInput compareInput = new SVNLocalCompareInput(
                                                        localResource, remoteFile);
                                                CompareUI.openCompareEditorOnPage(compareInput,
                                                        getSite().getPage());
                                            } catch (Exception e) {
                                            }
                                        }
                                        return;
                                    }
                                    CompareUI.openCompareEditorOnPage(
                                            new SVNLocalCompareInput(localResource, SVNRevision.BASE),
                                            getSite().getPage());
                                } catch (SVNException e) {
                                    if (!e.operationInterrupted()) {
                                        Activator.handleError(Messages.MergeResultsView_compareError, e);
                                        MessageDialog.openError(Display.getCurrent().getActiveShell(),
                                                Messages.MergeResultsView_compareWithLatest,
                                                e.getLocalizedMessage());
                                    }
                                } catch (SVNClientException e) {
                                    Activator.handleError(Messages.MergeResultsView_compareError, e);
                                    MessageDialog.openError(Display.getCurrent().getActiveShell(),
                                            Messages.MergeResultsView_compareWithLatest, e.getLocalizedMessage());
                                }
                            }
                        });
                    }
                }
            }
        });
        treeViewer.getTree().addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                boolean mergeOutputSelected = false;
                IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
                Iterator iter = selection.iterator();
                while (iter.hasNext()) {
                    if (iter.next() instanceof MergeOutput) {
                        mergeOutputSelected = true;
                        break;
                    }
                }
                removeAction.setEnabled(mergeOutputSelected);
            }
        });
        createMenus();
        createToolbar();
        getSite().setSelectionProvider(treeViewer);

        if (Activator.getDefault().getPreferenceStore().getBoolean(CONFLICTS_ONLY_PREFERENCE))
            setContentDescription(Messages.MergeResultsView_conflictsMode);
    }

    private void editConflicts(MergeResult mergeResult) {
        IFile resource = (IFile) mergeResult.getResource();
        ISVNLocalResource svnResource = SVNWorkspaceRoot.getSVNResourceFor(resource);
        try {
            File conflictNewFile = svnResource.getStatus().getConflictNew();
            File conflictOldFile = svnResource.getStatus().getConflictOld();
            File conflictWorkingFile = svnResource.getStatus().getConflictWorking();
            File mergedFile = new File(resource.getLocation().toString());
            if (conflictWorkingFile == null) {
                EditConflictsAction editConflictsAction = new EditConflictsAction(resource);
                editConflictsAction.run(null);
            } else {
                MergeEditConflictsAction editConflictsAction = new MergeEditConflictsAction(conflictNewFile,
                        conflictOldFile, conflictWorkingFile, mergedFile, resource.getName(), null);
                editConflictsAction.setMergeResult(mergeResult);
                editConflictsAction.run(null);
            }
        } catch (Exception e) {
        }
    }

    private void createMenus() {
        openAction = new OpenFileInSystemEditorAction(getSite().getPage(), treeViewer);

        MenuManager menuMgr = new MenuManager("#MergeResultsViewPopupMenu"); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                MergeResultsView.this.fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(treeViewer.getControl());
        treeViewer.getControl().setMenu(menu);
        getSite().registerContextMenu(menuMgr, treeViewer);

        toggleLayoutActions = new ToggleLayoutAction[] {
                new ToggleLayoutAction(this, Messages.MergeResultsView_flat, Activator.IMAGE_LAYOUT_FLAT,
                        MODE_FLAT),
                new ToggleLayoutAction(this, Messages.MergeResultsView_compressed,
                        Activator.IMAGE_LAYOUT_COMPRESSED, MODE_COMPRESSED_FOLDERS) };
        IActionBars actionBars = getViewSite().getActionBars();
        IMenuManager actionBarsMenu = actionBars.getMenuManager();
        removeAction.setEnabled(false);
        actionBarsMenu.add(removeAction);
        actionBarsMenu.add(removeAllAction);
        actionBarsMenu.add(new Separator());
        actionBarsMenu.add(toggleLayoutActions[0]);
        actionBarsMenu.add(toggleLayoutActions[1]);
        actionBarsMenu.add(new Separator());

        toggleConflictsOnlyAction = new Action("Show conflicts only") { //$NON-NLS-1$
            public void run() {
                store.setValue(MergeResultsView.CONFLICTS_ONLY_PREFERENCE, toggleConflictsOnlyAction.isChecked());
                if (toggleConflictsOnlyAction.isChecked())
                    setContentDescription(Messages.MergeResultsView_conflictsMode);
                else
                    setContentDescription(""); //$NON-NLS-1$
                refresh();
            }
        };
        toggleConflictsOnlyAction.setChecked(store.getBoolean(MergeResultsView.CONFLICTS_ONLY_PREFERENCE));
        toggleConflictsOnlyAction
                .setImageDescriptor(Activator.getDefault().getImageDescriptor(Activator.IMAGE_CONFLICT));
        actionBarsMenu.add(toggleConflictsOnlyAction);
    }

    private void createToolbar() {
        IToolBarManager toolbarManager = getViewSite().getActionBars().getToolBarManager();
        Action refreshAction = new Action(Messages.MergeResultsView_refresh,
                Activator.getDefault().getImageDescriptor(Activator.IMAGE_REFRESH)) {
            public void run() {
                refresh();
            }
        };
        refreshAction.setToolTipText(Messages.MergeResultsView_refreshView);
        toolbarManager.add(refreshAction);
        toolbarManager.add(new Separator());

        PresentationAction presentationAction = new PresentationAction();
        toolbarManager.add(presentationAction);

        toolbarManager.add(new Separator());
        Action collapseAllAction = new Action(Messages.MergeResultsView_collapseAll,
                Activator.getDefault().getImageDescriptor(Activator.IMAGE_COLLAPSE_ALL)) {
            public void run() {
                collapseAll();
            }
        };
        collapseAllAction.setToolTipText(Messages.MergeResultsView_collapseAll);
        toolbarManager.add(collapseAllAction);
        Action expandAllAction = new Action(Messages.MergeResultsView_expandAll,
                Activator.getDefault().getImageDescriptor(Activator.IMAGE_EXPAND_ALL)) {
            public void run() {
                expandAll();
            }
        };
        expandAllAction.setToolTipText(Messages.MergeResultsView_expandAll);
        toolbarManager.add(expandAllAction);
        toolbarManager.add(new Separator());
        toolbarManager.add(toggleConflictsOnlyAction);
    }

    private void fillContextMenu(IMenuManager manager) {
        boolean enableOpen = false;
        IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
        Iterator iter = selection.iterator();
        while (iter.hasNext()) {
            Object element = iter.next();
            if (element instanceof AdaptableMergeResult) {
                MergeResult mergeResult = (MergeResult) element;
                if (mergeResult.getResource() instanceof IFile && !mergeResult.isDelete()) {
                    enableOpen = true;
                }
            }
            if (enableOpen)
                break;
        }
        if (enableOpen) {
            manager.add(openAction);
        }
        if (enableOpen && selection.size() == 1) {
            MenuManager submenu = new MenuManager(Messages.MergeResultsView_openWith);
            MergeResult mergeResult = (MergeResult) selection.getFirstElement();
            submenu.add(new OpenWithMenu(getSite().getPage(), mergeResult.getResource()));
            manager.add(submenu);
        }
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    private void collapseAll() {
        if (treeViewer == null)
            return;
        treeViewer.getControl().setRedraw(false);
        treeViewer.collapseToLevel(treeViewer.getInput(), TreeViewer.ALL_LEVELS);
        treeViewer.getControl().setRedraw(true);
    }

    private void expandAll() {
        if (treeViewer == null)
            return;
        treeViewer.getControl().setRedraw(false);
        treeViewer.expandAll();
        treeViewer.getControl().setRedraw(true);
    }

    public void setFocus() {
        if (treeViewer != null && !treeViewer.getControl().isDisposed()) {
            treeViewer.getControl().setFocus();
        }
    }

    public void dispose() {
        view = null;
        super.dispose();
    }

    public static MergeResultsView getView() {
        return view;
    }

    public void refresh() {
        if (treeViewer == null || treeViewer.getControl().isDisposed())
            return;
        removeAction.setEnabled(false);
        Object[] expandedElements = treeViewer.getVisibleExpandedElements();
        treeViewer.refresh();
        if (expandedElements != null && expandedElements.length > 0)
            treeViewer.setExpandedElements(expandedElements);
    }

    public void refreshAsync(final Object expandedObject) {
        if (treeViewer == null || treeViewer.getControl().isDisposed())
            return;
        treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
            public void run() {
                MergeOutput.setInProgress(true);
                refresh();
                if (expandedObject != null)
                    treeViewer.setExpandedState(expandedObject, true);
                MergeOutput.setInProgress(false);
            }
        });
    }

    public TreeViewer getTreeViewer() {
        return treeViewer;
    }

    private SVNTreeConflict getTreeConflict(final IResource resource) {
        treeConflict = null;
        BusyIndicator.showWhile(Display.getDefault(), new Runnable() {
            public void run() {
                ISVNClientAdapter client = null;
                try {
                    client = SVNWorkspaceRoot.getSVNResourceFor(resource).getRepository().getSVNClient();
                    ISVNStatus[] statuses = client.getStatus(resource.getLocation().toFile(), true, true, true);
                    for (int i = 0; i < statuses.length; i++) {
                        if (statuses[i].hasTreeConflict()) {
                            treeConflict = new SVNTreeConflict(statuses[i]);
                            break;
                        }
                    }
                } catch (Exception e) {
                    SVNUIPlugin.log(IStatus.ERROR, e.getMessage(), e);
                } finally {
                    SVNWorkspaceRoot.getSVNResourceFor(resource).getRepository().returnSVNClient(client);
                }
            }
        });
        return treeConflict;
    }

    public static class RemoveAction extends Action {
        public RemoveAction() {
            super();
            setText(Messages.MergeResultsView_deleteSelected);
            setImageDescriptor(Activator.getDefault().getImageDescriptor(Activator.IMAGE_REMOVE));
        }

        public void run() {
            DeleteMergeOutputAction deleteAction = new DeleteMergeOutputAction();
            deleteAction.selectionChanged(this, view.getView().getTreeViewer().getSelection());
            deleteAction.run(this);
        }
    }

    public static class RemoveAllAction extends Action {
        public RemoveAllAction() {
            super();
            setText(Messages.MergeResultsView_deleteAll);
            setImageDescriptor(Activator.getDefault().getImageDescriptor(Activator.IMAGE_REMOVE_ALL));
        }

        public void run() {
            if (!MessageDialog.openQuestion(Display.getCurrent().getActiveShell(),
                    Messages.MergeResultsView_deleteAll2, Messages.MergeResultsView_confirmDelete))
                return;
            Item[] items = MergeResultsView.getView().getTreeViewer().getTree().getItems();
            for (int i = 0; i < items.length; i++) {
                if (items[i].getData() instanceof MergeOutput) {
                    MergeOutput mergeOutput = (MergeOutput) items[i].getData();
                    mergeOutput.delete();
                }
            }
            MergeResultsView.getView().refresh();
        }
    }

    public static class PresentationAction extends Action implements IMenuCreator {
        private Menu menu;

        public PresentationAction() {
            setText(Messages.MergeResultsView_presentation);
            setImageDescriptor(Activator.getDefault().getImageDescriptor(Activator.IMAGE_PRESENTATION));
            setMenuCreator(this);
        }

        public void dispose() {
            if (menu != null) {
                menu.dispose();
                menu = null;
            }

        }

        public Menu getMenu(Control parent) {
            if (menu != null)
                menu.dispose();
            menu = new Menu(parent);
            addActionToMenu(menu, toggleLayoutActions[0]);
            addActionToMenu(menu, toggleLayoutActions[1]);
            return menu;
        }

        public Menu getMenu(Menu parent) {
            return null;
        }

        private void addActionToMenu(Menu parent, Action action) {
            ActionContributionItem item = new ActionContributionItem(action);
            item.fill(parent, -1);
        }
    }

    public static class ToggleLayoutAction extends Action {
        private final int value;
        private MergeResultsView view;

        public ToggleLayoutAction(MergeResultsView view, String label, String icon, int value) {
            super(label, AS_RADIO_BUTTON);
            this.view = view;
            this.value = value;
            setImageDescriptor(Activator.getDefault().getImageDescriptor(icon));
            IPreferenceStore store = Activator.getDefault().getPreferenceStore();
            setChecked(value == store.getInt(LAYOUT_PREFERENCE));
        }

        public int getValue() {
            return this.value;
        }

        public void run() {
            if (isChecked()) {
                Activator.getDefault().getPreferenceStore().setValue(LAYOUT_PREFERENCE, value);
                view.refresh();
            }
        }
    }

}