com.aptana.explorer.internal.ui.GitProjectView.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.explorer.internal.ui.GitProjectView.java

Source

/**
 * Aptana Studio
 * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
 * Please see the license.html included with this distribution for details.
 * Any modifications to this file must keep this entire header intact.
 */
package com.aptana.explorer.internal.ui;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.NotEnabledException;
import org.eclipse.core.commands.NotHandledException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.progress.UIJob;

import com.aptana.core.logging.IdeLog;
import com.aptana.core.util.EclipseUtil;
import com.aptana.core.util.ProcessStatus;
import com.aptana.explorer.ExplorerPlugin;
import com.aptana.git.core.GitPlugin;
import com.aptana.git.core.IDebugScopes;
import com.aptana.git.core.IPreferenceConstants;
import com.aptana.git.core.model.BranchAddedEvent;
import com.aptana.git.core.model.BranchChangedEvent;
import com.aptana.git.core.model.BranchRemovedEvent;
import com.aptana.git.core.model.GitRepository;
import com.aptana.git.core.model.IGitRepositoriesListener;
import com.aptana.git.core.model.IGitRepositoryListener;
import com.aptana.git.core.model.IGitRepositoryManager;
import com.aptana.git.core.model.IndexChangedEvent;
import com.aptana.git.core.model.PullEvent;
import com.aptana.git.core.model.PushEvent;
import com.aptana.git.core.model.RepositoryAddedEvent;
import com.aptana.git.core.model.RepositoryRemovedEvent;
import com.aptana.git.ui.dialogs.CreateBranchDialog;

/**
 * Adds Git UI elements to the Single Project View.
 * 
 * @author cwilliams
 */
public class GitProjectView extends SingleProjectView implements IGitRepositoryListener, IGitRepositoriesListener {
    private static final String TEAM_MAIN = "team.main"; //$NON-NLS-1$
    private static final String DIRTY_SUFFIX = "*"; //$NON-NLS-1$
    private static final String GIT_CHANGED_FILES_FILTER = "GitChangedFilesFilterEnabled"; //$NON-NLS-1$
    private static final String PROJECT_DELIMITER = "######"; //$NON-NLS-1$
    private static final String CHANGED_FILE_FILTER_ICON_PATH = "icons/full/elcl16/filter.png"; //$NON-NLS-1$

    private static final String CREATE_NEW_BRANCH_TEXT = Messages.GitProjectView_createNewBranchOption;

    private Label leftLabel;
    private GridData leftLabelGridData;
    private Label rightLabel;
    private GridData rightLabelGridData;
    private ToolBar branchesToolbar;
    private GridData branchesToolbarGridData;

    private ToolItem branchesToolItem;
    private Menu branchesMenu;

    private GitChangedFilesFilter fChangedFilesFilter;
    // keeps the list of projects which has turned on the changed files filter
    private Set<IProject> fChangedFilesFilterProjects;
    private Job pullCalc;
    private HashMap<String, Boolean> branchToPullIndicator = new HashMap<String, Boolean>();
    private UIJob refreshUIJob;

    public GitProjectView() {
        fChangedFilesFilterProjects = new HashSet<IProject>();
    }

    @Override
    public void createPartControl(Composite aParent) {
        super.createPartControl(aParent);

        getGitRepositoryManager().addListener(this);

        if (fChangedFilesFilterProjects.contains(selectedProject)) {
            UIJob job = new UIJob("Turn on git filter initially") //$NON-NLS-1$
            {

                @Override
                public IStatus runInUIThread(IProgressMonitor monitor) {
                    addGitChangedFilesFilter();
                    return Status.OK_STATUS;
                }
            };
            EclipseUtil.setSystemForJob(job);
            job.setPriority(Job.SHORT);
            job.schedule(300);
        }

        // Calculate the pull indicators in a recurring background job!
        pullCalc = new Job("Calculating git pull indicators") //$NON-NLS-1$
        {

            @Override
            protected IStatus run(IProgressMonitor monitor) {
                // Don't do any work if user has turned off calc'ing pull indicators.
                boolean performFetches = Platform.getPreferencesService().getBoolean(GitPlugin.getPluginId(),
                        IPreferenceConstants.GIT_CALCULATE_PULL_INDICATOR, false, null);
                if (!performFetches) {
                    // FIXME Listen for change to this pref and then schedule if it gets turned on!
                    return Status.OK_STATUS;
                }

                if (monitor != null && monitor.isCanceled())
                    return Status.CANCEL_STATUS;

                GitRepository repo = getGitRepositoryManager().getAttached(selectedProject);
                if (repo == null) {
                    // FIXME Don't reschedule, listen for repo attachment and then start running this.
                    schedule(5 * 60 * 1000); // reschedule for 5 minutes after we return!
                    return Status.OK_STATUS;
                }

                if (monitor != null && monitor.isCanceled())
                    return Status.CANCEL_STATUS;

                synchronized (branchToPullIndicator) {
                    branchToPullIndicator.clear();
                }
                Set<String> branchesToPull = repo.getOutOfDateBranches();
                for (String branch : repo.localBranches()) {
                    if (monitor != null && monitor.isCanceled())
                        return Status.CANCEL_STATUS;
                    synchronized (branchToPullIndicator) {
                        branchToPullIndicator.put(branch, branchesToPull.contains(branch));
                    }
                }

                refreshUI(repo);

                if (monitor != null && monitor.isCanceled())
                    return Status.CANCEL_STATUS;

                // TODO Allow user to have control over how often we poll
                schedule(5 * 60 * 1000); // reschedule for 5 minutes after we return!
                return Status.OK_STATUS;
            }
        };
        EclipseUtil.setSystemForJob(pullCalc);
        pullCalc.setPriority(Job.LONG);
        pullCalc.schedule();
    }

    protected void doCreateToolbar(Composite toolbarComposite) {
        Composite branchComp = new Composite(toolbarComposite, SWT.NONE);

        GridLayout toolbarGridLayout = new GridLayout(3, false);
        toolbarGridLayout.marginWidth = 2;
        toolbarGridLayout.marginHeight = 0;
        toolbarGridLayout.horizontalSpacing = 0;

        branchComp.setLayout(toolbarGridLayout);
        createGitBranchCombo(branchComp);
    }

    private void createGitBranchCombo(Composite parent) {
        leftLabel = new Label(parent, SWT.NONE);
        leftLabel.setText("["); //$NON-NLS-1$
        leftLabelGridData = new GridData(SWT.END, SWT.CENTER, false, false);
        leftLabel.setLayoutData(leftLabelGridData);

        branchesToolbar = new ToolBar(parent, SWT.FLAT);
        branchesToolbarGridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
        branchesToolbar.setLayoutData(branchesToolbarGridData);

        branchesToolItem = new ToolItem(branchesToolbar, SWT.DROP_DOWN);

        branchesMenu = new Menu(branchesToolbar);
        branchesToolItem.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent selectionEvent) {
                Point toolbarLocation = branchesToolbar.getLocation();
                toolbarLocation = branchesToolbar.getParent().toDisplay(toolbarLocation.x, toolbarLocation.y);
                Point toolbarSize = branchesToolbar.getSize();
                branchesMenu.setLocation(toolbarLocation.x, toolbarLocation.y + toolbarSize.y + 2);
                branchesMenu.setVisible(true);
            }
        });

        rightLabel = new Label(parent, SWT.NONE);
        rightLabel.setText("]"); //$NON-NLS-1$
        rightLabelGridData = new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
        rightLabel.setLayoutData(rightLabelGridData);
    }

    @Override
    public void dispose() {
        if (selectedProject != null) {
            GitRepository repo = getGitRepositoryManager().getAttached(selectedProject);
            if (repo != null)
                repo.removeListener(this);
        }
        getGitRepositoryManager().removeListener(this);

        if (pullCalc != null) {
            pullCalc.cancel();
            pullCalc = null;
        }
        branchToPullIndicator = null;
        if (refreshUIJob != null) {
            refreshUIJob.cancel();
            refreshUIJob = null;
        }
        super.dispose();
    }

    @Override
    protected void removeFilter() {
        if (fChangedFilesFilter != null) {
            getCommonViewer().removeFilter(fChangedFilesFilter);
            fChangedFilesFilter = null;
            fChangedFilesFilterProjects.remove(selectedProject);
        }
        super.removeFilter();
    }

    private boolean setNewBranch(String branchName) {
        // Strip off the indicators...
        branchName = stripIndicators(branchName);

        final GitRepository repo = getGitRepositoryManager().getAttached(selectedProject);
        if (repo == null)
            return false;
        if (branchName.equals(repo.currentBranch()))
            return false;

        // If user selected "Create New..." then pop a dialog to generate a new branch
        if (branchName.equals(CREATE_NEW_BRANCH_TEXT)) {
            CreateBranchDialog dialog = new CreateBranchDialog(getSite().getShell(), repo);
            if (dialog.open() != Window.OK) {
                revertToCurrentBranch(repo);
                return false;
            }
            branchName = dialog.getValue().trim();
            boolean track = dialog.track();
            String startPoint = dialog.getStartPoint();
            if (!repo.createBranch(branchName, track, startPoint)) {
                revertToCurrentBranch(repo);
                return false;
            }
        }
        IStatus switchStatus = repo.switchBranch(branchName, new NullProgressMonitor());
        if (switchStatus.isOK()) {
            refreshViewer(); // might be new file structure
            return true;
        }
        String msg = switchStatus.getMessage();
        if (switchStatus instanceof ProcessStatus) {
            msg = ((ProcessStatus) switchStatus).getStdErr();
        }
        MessageDialog.openError(getSite().getShell(), Messages.GitProjectView_SwitchBranchFailedTitle, msg);
        // revertToCurrentBranch(repo);
        return false;
    }

    private String stripIndicators(String branchName) {
        if (branchName.endsWith(" " + getRightArrowChar())) //$NON-NLS-1$
            branchName = branchName.substring(0, branchName.length() - 2);
        if (branchName.endsWith(" " + getLeftArrowChar())) //$NON-NLS-1$
            branchName = branchName.substring(0, branchName.length() - 2);
        if (branchName.endsWith(DIRTY_SUFFIX))
            branchName = branchName.substring(0, branchName.length() - 1);
        return branchName;
    }

    private void revertToCurrentBranch(final GitRepository repo) {
        Job job = new UIJob("Reverting back to current branch") //$NON-NLS-1$
        {

            @Override
            public IStatus runInUIThread(IProgressMonitor monitor) {
                String currentBranchName = repo.currentBranch();
                if (repo.isDirty())
                    currentBranchName += DIRTY_SUFFIX;
                branchesToolItem.setText(currentBranchName);
                MenuItem[] menuItems = branchesMenu.getItems();
                for (MenuItem menuItem : menuItems) {
                    menuItem.setSelection(menuItem.getText().equals(currentBranchName));
                }
                branchesToolbar.pack(true);
                return Status.OK_STATUS;
            }
        };
        EclipseUtil.setSystemForJob(job);
        job.setPriority(Job.INTERACTIVE);
        job.schedule();
    }

    @Override
    protected void projectChanged(IProject oldProject, IProject newProject) {
        GitRepository oldRepo = getGitRepositoryManager().getAttached(oldProject);
        if (oldRepo != null) {
            oldRepo.removeListener(this);
        }

        super.projectChanged(oldProject, newProject);

        if (fChangedFilesFilterProjects.contains(newProject)) {
            addGitChangedFilesFilter();
        } else {
            removeFilter();
        }
        GitRepository repo = getGitRepositoryManager().getAttached(newProject);
        refreshUI(repo);
        if (repo != null) {
            repo.addListener(this);
        }
    }

    private void populateBranches(GitRepository repo, IProgressMonitor monitor) throws CoreException {
        if (monitor != null && monitor.isCanceled())
            throw new CoreException(Status.CANCEL_STATUS);

        MenuItem[] menuItems = branchesMenu.getItems();
        for (MenuItem menuItem : menuItems) {
            menuItem.dispose();
        }
        branchesToolItem.setText(""); //$NON-NLS-1$
        if (repo == null)
            return;

        if (monitor != null && monitor.isCanceled())
            throw new CoreException(Status.CANCEL_STATUS);

        String currentBranchName = repo.currentBranch();
        String tooltip = currentBranchName;
        for (String branchName : repo.localBranches()) {
            // Construct the menu item to for this project
            final MenuItem branchNameMenuItem = new MenuItem(branchesMenu, SWT.RADIO);
            String modifiedBranchName = branchName;
            if (branchName.equals(currentBranchName) && repo.isDirty()) {
                modifiedBranchName += DIRTY_SUFFIX;
                tooltip += Messages.GitProjectView_BranchDirtyTooltipMessage;
            }

            synchronized (branchToPullIndicator) {
                if (branchToPullIndicator.containsKey(branchName) && branchToPullIndicator.get(branchName)) {
                    modifiedBranchName += " " + getLeftArrowChar(); //$NON-NLS-1$
                    if (branchName.equals(currentBranchName))
                        tooltip += Messages.GitProjectView_PullChangesTooltipMessage;
                }
            }
            String[] ahead = repo.commitsAhead(branchName);
            if (ahead != null && ahead.length > 0) {
                modifiedBranchName += " " + getRightArrowChar(); //$NON-NLS-1$
                if (branchName.equals(currentBranchName))
                    tooltip += Messages.GitProjectView_PushChangesTooltipMessage;
            }

            branchNameMenuItem.setText(modifiedBranchName);
            branchNameMenuItem.setSelection(branchName.equals(currentBranchName));
            branchNameMenuItem.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent e) {
                    setNewBranch(branchNameMenuItem.getText());
                }
            });
            if (branchName.equals(currentBranchName)) {
                if (modifiedBranchName.length() > 20) {
                    // truncate the current branch name and append the indicators
                    if (!currentBranchName.equals(modifiedBranchName)) {
                        currentBranchName = currentBranchName.substring(0, 15) + "..." //$NON-NLS-1$
                                + modifiedBranchName.substring(currentBranchName.length());
                    } else {
                        currentBranchName = currentBranchName.substring(0, 15) + "..."; //$NON-NLS-1$
                    }
                } else {
                    currentBranchName = modifiedBranchName;
                }
            }
        }

        if (monitor != null && monitor.isCanceled())
            throw new CoreException(Status.CANCEL_STATUS);

        new MenuItem(branchesMenu, SWT.SEPARATOR);

        final MenuItem branchNameMenuItem = new MenuItem(branchesMenu, SWT.PUSH);
        branchNameMenuItem.setText(CREATE_NEW_BRANCH_TEXT);
        branchNameMenuItem.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                setNewBranch(branchNameMenuItem.getText());
            }
        });
        branchesToolItem.setText(currentBranchName);
        if (tooltip != null) {
            branchesToolItem.setToolTipText(tooltip);
        }
        branchesToolbar.pack();
    }

    private String getRightArrowChar() {
        if (Platform.getOS().equals(Platform.OS_MACOSX)) {
            return "\u2192"; //$NON-NLS-1$
        }
        return "->"; //$NON-NLS-1$
    }

    private String getLeftArrowChar() {
        if (Platform.getOS().equals(Platform.OS_MACOSX)) {
            return "\u2190"; //$NON-NLS-1$
        }
        return "<-"; //$NON-NLS-1$
    }

    public void indexChanged(final IndexChangedEvent e) {
        // no op
    }

    public void pulled(final PullEvent e) {
        if (isCurrentProjectsRepository(e.getRepository())) {
            // When user has done a pull we need to force a recalc of the pull indicators right away!
            pullCalc.cancel();
            pullCalc.schedule();
        }
    }

    public void pushed(PushEvent e) {
        // Need to recalc the push indicators on branch pulldown
        handleBranchEvent(e.getRepository());
    }

    private void refreshUI(final GitRepository repository) {
        // If we get multiple requests queuing up, just cancel current and reschedule
        if (refreshUIJob != null)
            refreshUIJob.cancel();
        refreshUIJob = new UIJob("update UI for index changes") //$NON-NLS-1$
        {

            @Override
            public IStatus runInUIThread(IProgressMonitor monitor) {
                if (monitor != null && monitor.isCanceled())
                    return Status.CANCEL_STATUS;
                try {
                    // Update the branch list so we can reset the dirty status on the branch
                    populateBranches(repository, monitor);
                    if (monitor != null && monitor.isCanceled())
                        return Status.CANCEL_STATUS;
                    if (repository == null) {
                        RowData rd = new RowData();
                        rd.exclude = true;
                        branchesToolbar.getParent().setLayoutData(rd);
                        branchesToolbar.getParent().setVisible(false);
                    } else {
                        RowData rd = new RowData();
                        rd.exclude = false;
                        branchesToolbar.getParent().setLayoutData(rd);
                        branchesToolbar.getParent().setVisible(true);
                    }
                    if (monitor != null && monitor.isCanceled())
                        return Status.CANCEL_STATUS;
                    branchesToolbar.getParent().getParent().layout(true, true);
                    refreshViewer();
                    return Status.OK_STATUS;
                } catch (CoreException e) {
                    ExplorerPlugin.logError(e);
                    return e.getStatus();
                } catch (Exception e) {
                    IdeLog.logError(ExplorerPlugin.getDefault(), e, IDebugScopes.DEBUG);
                    return new Status(IStatus.ERROR, ExplorerPlugin.PLUGIN_ID, e.getMessage(), e);
                }
            }
        };
        EclipseUtil.setSystemForJob(refreshUIJob);
        refreshUIJob.setPriority(Job.INTERACTIVE);
        refreshUIJob.schedule(100);
    }

    public void repositoryAdded(RepositoryAddedEvent e) {
        IProject changed = e.getProject();
        if (changed != null && changed.equals(selectedProject)) {
            refreshUI(e.getRepository());
            e.getRepository().addListener(this);
        }
    }

    public void branchChanged(BranchChangedEvent e) {
        handleBranchEvent(e.getRepository());
    }

    public void branchAdded(BranchAddedEvent e) {
        handleBranchEvent(e.getRepository());
    }

    public void branchRemoved(BranchRemovedEvent e) {
        handleBranchEvent(e.getRepository());
    }

    private void handleBranchEvent(GitRepository repo) {
        if (isCurrentProjectsRepository(repo))
            refreshUI(repo);
    }

    private boolean isCurrentProjectsRepository(GitRepository repo) {
        GitRepository selectedRepo = getGitRepositoryManager().getAttached(selectedProject);
        return selectedRepo != null && selectedRepo.equals(repo);
    }

    public void repositoryRemoved(RepositoryRemovedEvent e) {
        IProject changed = e.getProject();
        if (changed != null && changed.equals(selectedProject)) {
            e.getRepository().removeListener(this);
            refreshUI(null);
        }
    }

    private void addGitChangedFilesFilter() {
        removeFilter();
        fChangedFilesFilter = new GitChangedFilesFilter();
        getCommonViewer().addFilter(fChangedFilesFilter);
        getCommonViewer().expandAll();
        showFilterLabel(ExplorerPlugin.getImage(CHANGED_FILE_FILTER_ICON_PATH),
                Messages.GitProjectView_ChangedFilesFilterTooltip);
        fChangedFilesFilterProjects.add(selectedProject);
    }

    @Override
    public void saveState(IMemento aMemento) {
        StringBuilder text = new StringBuilder();
        for (IProject project : fChangedFilesFilterProjects) {
            text.append(project.getName()).append(PROJECT_DELIMITER);
        }
        int length = text.length();
        if (length > 0) {
            text.delete(length - PROJECT_DELIMITER.length(), length);
        }
        aMemento.putString(GIT_CHANGED_FILES_FILTER, text.toString());
        super.saveState(aMemento);
    }

    /**
     * <p>
     * Note: This method is for internal use only. Clients should not call this method.
     * </p>
     * 
     * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
     */
    public void init(IViewSite aSite, IMemento aMemento) throws PartInitException {
        super.init(aSite, aMemento);
        memento = aMemento;
        if (memento != null) {
            String filteredProjects = memento.getString(GIT_CHANGED_FILES_FILTER);
            if (filteredProjects != null && filteredProjects.length() > 0) {
                String[] projectNames = filteredProjects.split(PROJECT_DELIMITER);
                IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
                IProject project;
                for (String name : projectNames) {
                    try {
                        project = workspaceRoot.getProject(name);
                        if (project.exists()) {
                            fChangedFilesFilterProjects.add(project);
                        }
                    } catch (Exception e) {
                        IdeLog.logError(ExplorerPlugin.getDefault(), e, IDebugScopes.DEBUG);
                    }
                }
            }
        }
    }

    @Override
    protected void mangleContextMenu(Menu menu) {
        GitRepository repo = getGitRepositoryManager().getAttached(selectedProject);
        // Remove Team menu if project is attached to our git provider.
        if (repo != null || selectedProject == null || !selectedProject.isAccessible()) {
            Set<String> toRemove = new HashSet<String>();
            toRemove.add(TEAM_MAIN);
            removeMenuItems(menu, toRemove);
        } else {
            RepositoryProvider provider = RepositoryProvider.getProvider(selectedProject);
            if (provider == null) {
                // no other provider, keep Team menu, but modify it's submenu
                MenuItem[] menuItems = menu.getItems();
                for (int i = 0; i < menuItems.length; i++) {
                    MenuItem menuItem = menuItems[i];
                    Object data = menuItem.getData();
                    if (data instanceof IContributionItem) {
                        IContributionItem contrib = (IContributionItem) data;
                        // Just replace team with initialize git repo
                        if (TEAM_MAIN.equals(contrib.getId())) {
                            addAttachItem(menu, i + 1);
                            break;
                        }
                    }
                }
                Set<String> toRemove = new HashSet<String>();
                toRemove.add(TEAM_MAIN);
                removeMenuItems(menu, toRemove);
            }
        }
        // Remove all the other stuff we normally do...
        super.mangleContextMenu(menu);
    }

    private void addAttachItem(Menu menu, int index) {
        // FIXME Move this constant into an interface on Git UI plugin!
        final String commandId = "com.aptana.git.ui.command.attach"; //$NON-NLS-1$
        final MenuItem customizeMenuItem = new MenuItem(menu, SWT.PUSH, index);
        ICommandService commandService = (ICommandService) PlatformUI.getWorkbench()
                .getService(ICommandService.class);
        Command c = commandService.getCommand(commandId);
        try {
            customizeMenuItem.setText(c.getName());
        } catch (NotDefinedException e2) {
            // ignore
        }
        customizeMenuItem.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench()
                        .getService(IHandlerService.class);
                try {
                    handlerService.executeCommand(commandId, null);
                } catch (ExecutionException e1) {
                } catch (NotDefinedException e1) {
                } catch (NotEnabledException e1) {
                } catch (NotHandledException e1) {
                }
            }
        });
    }

    private IGitRepositoryManager getGitRepositoryManager() {
        return GitPlugin.getDefault().getGitRepositoryManager();
    }

    public void toggleChangedFilesFilter() {
        if (fChangedFilesFilter == null) {
            addGitChangedFilesFilter();
        } else {
            removeFilter();
        }
    }
}