blob: 00d3d6a3ad2a1d48c11ecb0be67c925831938aa2 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.history;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MultiLineLabelUI;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.vcs.RepositoryLocation;
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
import com.intellij.openapi.vcs.changes.committed.*;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.Consumer;
import com.intellij.util.NullableFunction;
import com.intellij.util.messages.Topic;
import icons.SvnIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.actions.AbstractIntegrateChangesAction;
import org.jetbrains.idea.svn.actions.ChangeListsMergerFactory;
import org.jetbrains.idea.svn.actions.RecordOnlyMergerFactory;
import org.jetbrains.idea.svn.actions.ShowSvnMapAction;
import org.jetbrains.idea.svn.dialogs.WCInfoWithBranches;
import org.jetbrains.idea.svn.integrate.*;
import org.jetbrains.idea.svn.mergeinfo.ListMergeStatus;
import org.jetbrains.idea.svn.mergeinfo.MergeInfoHolder;
import org.jetbrains.idea.svn.update.UpdateEventHandler;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNRevisionRange;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class RootsAndBranches implements CommittedChangeListDecorator {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.RootsAndBranches");
private final Project myProject;
private final DecoratorManager myManager;
private final RepositoryLocation myLocation;
private JPanel myPanel;
private final Map<String, SvnMergeInfoRootPanelManual> myMergePanels;
private final Map<String, MergeInfoHolder> myHolders;
private boolean myHighlightingOn;
private boolean myFromHereDirection;
private JPanel myPanelWrapper;
private final MergePanelFiltering myStrategy;
private final FilterOutMerged myFilterMerged;
private final FilterOutNotMerged myFilterNotMerged;
private final FilterOutAlien myFilterAlien;
private final IntegrateChangeListsAction myIntegrateAction;
private final UndoIntegrateChangeListsAction myUndoIntegrateChangeListsAction;
private JComponent myToolbarComponent;
private boolean myDisposed;
private final WcInfoLoader myDataLoader;
public static final Topic<Runnable> REFRESH_REQUEST = new Topic<Runnable>("REFRESH_REQUEST", Runnable.class);
private MergeInfoHolder getHolder(final String key) {
final MergeInfoHolder holder = myHolders.get(key);
if (holder != null) {
return holder;
}
return myHolders.get(key.endsWith(File.separator) ? key.substring(0, key.length() - 1) : key + File.separator);
}
private SvnMergeInfoRootPanelManual getPanelData(final String key) {
final SvnMergeInfoRootPanelManual panel = myMergePanels.get(key);
if (panel != null) {
return panel;
}
return myMergePanels.get(key.endsWith(File.separator) ? key.substring(0, key.length() - 1) : key + File.separator);
}
public RootsAndBranches(final Project project, final DecoratorManager manager, final RepositoryLocation location) {
myProject = project;
myManager = manager;
myLocation = location;
myDataLoader = new WcInfoLoader(myProject, myLocation);
myMergePanels = new HashMap<String, SvnMergeInfoRootPanelManual>();
myHolders = new HashMap<String, MergeInfoHolder>();
myFilterMerged = new FilterOutMerged();
myFilterNotMerged = new FilterOutNotMerged();
myFilterAlien = new FilterOutAlien();
myIntegrateAction = new IntegrateChangeListsAction();
myUndoIntegrateChangeListsAction = new UndoIntegrateChangeListsAction();
myPanel = new JPanel(new GridBagLayout());
myFromHereDirection = true;
createToolbar();
final GridBagConstraints gb =
new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(1, 1, 1, 1), 0, 0);
gb.insets = new Insets(20, 1, 1, 1);
myPanel.add(new JLabel("Loading..."), gb);
myPanel.setPreferredSize(new Dimension(200, 60));
myManager.install(this);
setDirectionToPanels();
myStrategy = new MergePanelFiltering(getPanel());
}
public IntegrateChangeListsAction getIntegrateAction() {
return myIntegrateAction;
}
public UndoIntegrateChangeListsAction getUndoIntegrateAction() {
return myUndoIntegrateChangeListsAction;
}
public void reloadPanels() {
final Map<Couple<String>, SvnMergeInfoRootPanelManual.InfoHolder> states = new HashMap<Couple<String>, SvnMergeInfoRootPanelManual.InfoHolder>();
for (Map.Entry<String, SvnMergeInfoRootPanelManual> entry : myMergePanels.entrySet()) {
final String localPath = entry.getKey();
final WCInfoWithBranches wcInfo = entry.getValue().getWcInfo();
states.put(Couple.of(localPath, wcInfo.getUrl().toString()), entry.getValue().getInfo());
}
createPanels(myLocation, new Runnable() {
public void run() {
for (Map.Entry<String, SvnMergeInfoRootPanelManual> entry : myMergePanels.entrySet()) {
final String localPath = entry.getKey();
final WCInfoWithBranches wcInfo = entry.getValue().getWcInfo();
final Couple<String> key = Couple.of(localPath, wcInfo.getUrl().toString());
final SvnMergeInfoRootPanelManual.InfoHolder infoHolder = states.get(key);
if (infoHolder != null) {
entry.getValue().initSelection(infoHolder);
}
}
}
});
}
public void turnFromHereHighlighting() {
myHighlightingOn = true;
myFromHereDirection = true;
setDirectionToPanels();
for (MergeInfoHolder holder : myHolders.values()) {
holder.updateMixedRevisionsForPanel();
}
myManager.repaintTree();
}
public void turnFromThereHighlighting() {
myHighlightingOn = true;
myFromHereDirection = false;
setDirectionToPanels();
myManager.repaintTree();
}
private void setDirectionToPanels() {
for (SvnMergeInfoRootPanelManual panel : myMergePanels.values()) {
panel.setDirection(myFromHereDirection);
}
}
public void turnOff() {
myHighlightingOn = false;
for (SvnMergeInfoRootPanelManual panelManual : myMergePanels.values()) {
panelManual.setMixedRevisions(false);
}
myManager.repaintTree();
}
public Icon decorate(final CommittedChangeList list) {
final ListMergeStatus status = getStatus(list, false);
return (status == null) ? ListMergeStatus.ALIEN.getIcon() : status.getIcon();
}
private void createPanels(final RepositoryLocation location, final Runnable afterRefresh) {
final Task.Backgroundable backgroundable = new Task.Backgroundable(myProject, "Subversion: loading working copies data..", false,
BackgroundFromStartOption.getInstance()) {
public void run(@NotNull final ProgressIndicator indicator) {
indicator.setIndeterminate(true);
final Map<String, SvnMergeInfoRootPanelManual> panels = new HashMap<String, SvnMergeInfoRootPanelManual>();
final Map<String, MergeInfoHolder> holders = new HashMap<String, MergeInfoHolder>();
final List<WCInfoWithBranches> roots = myDataLoader.loadRoots();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (myDisposed) return;
final JPanel mainPanel = prepareData(panels, holders, roots);
myMergePanels.clear();
myHolders.clear();
myMergePanels.putAll(panels);
myHolders.putAll(holders);
if (myPanelWrapper != null) {
myPanelWrapper.removeAll();
if (myMergePanels.isEmpty()) {
final JPanel emptyPanel = new JPanel(new GridBagLayout());
final GridBagConstraints gb =
new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 0, 5), 0, 0);
final JLabel label = new JLabel("No Subversion 1.5 working copies\nof 1.5 repositories in the project");
label.setUI(new MultiLineLabelUI());
emptyPanel.add(label, gb);
gb.fill = GridBagConstraints.HORIZONTAL;
myPanelWrapper.add(emptyPanel, gb);
} else {
for (MergeInfoHolder holder : myHolders.values()) {
holder.updateMixedRevisionsForPanel();
}
myPanelWrapper.add(mainPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
}
myPanelWrapper.repaint();
} else {
myPanel = mainPanel;
}
if (afterRefresh != null) {
afterRefresh.run();
}
}
});
}
};
ProgressManager.getInstance().run(backgroundable);
}
public void refreshByLists(final List<CommittedChangeList> committedChangeLists) {
if (! committedChangeLists.isEmpty()) {
final SvnChangeList svnList = (SvnChangeList) committedChangeLists.get(0);
final String wcPath = svnList.getWcPath();
if (wcPath != null) {
final MergeInfoHolder holder = getHolder(wcPath);
if (holder != null) {
holder.refresh(true);
}
}
}
}
private void createToolbar() {
final DefaultActionGroup svnGroup = createActions();
final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, svnGroup, true);
myToolbarComponent = actionToolbar.getComponent();
}
private JPanel prepareData(final Map<String, SvnMergeInfoRootPanelManual> panels, final Map<String, MergeInfoHolder> holders,
List<WCInfoWithBranches> roots) {
final JPanel mainPanel = new JPanel(new GridBagLayout());
boolean onlyOneRoot = roots.size() == 1;
final GridBagConstraints gb = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL,
new Insets(0,0,0,0), 0, 0);
mainPanel.add(myToolbarComponent, gb);
++ gb.gridy;
for (final WCInfoWithBranches root : roots) {
if (root == null) {
continue;
}
final SvnMergeInfoRootPanelManual panel = new SvnMergeInfoRootPanelManual(myProject,
new NullableFunction<WCInfoWithBranches, WCInfoWithBranches>() {
public WCInfoWithBranches fun(final WCInfoWithBranches wcInfoWithBranches) {
final WCInfoWithBranches newInfo =
myDataLoader.reloadInfo(wcInfoWithBranches);
if (newInfo == null) {
// reload all items
myProject.getMessageBus().syncPublisher(SvnVcs.WC_CONVERTED).run();
// do not reload right now
return wcInfoWithBranches;
}
return newInfo;
}
}, new Runnable() {
public void run() {
final MergeInfoHolder holder = getHolder(root.getPath());
if (holder != null) {
holder.refresh(false);
}
}
}, onlyOneRoot, root);
panels.put(root.getPath(), panel);
holders.put(root.getPath(), createHolder(panel));
final JPanel contentPanel = panel.getContentPanel();
mainPanel.add(contentPanel, gb);
++ gb.gridy;
}
if (panels.size() == 1) {
for (SvnMergeInfoRootPanelManual panel : panels.values()) {
panel.setOnlyOneRoot(true);
}
}
return mainPanel;
}
private DefaultActionGroup createActions() {
final DefaultActionGroup svnGroup = new DefaultActionGroup();
svnGroup.add(new HighlightFrom());
svnGroup.add(myIntegrateAction);
svnGroup.add(myUndoIntegrateChangeListsAction);
svnGroup.add(new MarkAsMerged());
svnGroup.add(new MarkAsNotMerged());
svnGroup.add(myFilterMerged);
svnGroup.add(myFilterNotMerged);
svnGroup.add(myFilterAlien);
svnGroup.add(new ShowSvnMapAction());
svnGroup.add(new MyRefresh());
return svnGroup;
}
private MergeInfoHolder createHolder(final SvnMergeInfoRootPanelManual panel) {
return new MergeInfoHolder(myProject, myManager, new Getter<WCInfoWithBranches>() {
public WCInfoWithBranches get() {
if (myFromHereDirection) {
return panel.getWcInfo();
} else {
// actually not used
return null;
}
}
}, new Getter<WCInfoWithBranches.Branch>() {
public WCInfoWithBranches.Branch get() {
if (myFromHereDirection) {
return panel.getBranch();
} else {
final WCInfoWithBranches wcInfo = panel.getWcInfo();
return new WCInfoWithBranches.Branch(wcInfo.getUrl().toString());
}
}
}, new Getter<String>() {
public String get() {
if (myFromHereDirection) {
return panel.getLocalBranch();
} else {
final WCInfoWithBranches wcInfo = panel.getWcInfo();
return wcInfo.getPath();
}
}
}, new Getter<Boolean>() {
public Boolean get() {
return myHighlightingOn && panel.isEnabled();
}
}, new Consumer<Boolean>() {
public void consume(final Boolean aBoolean) {
panel.setMixedRevisions(aBoolean);
}
});
}
public JComponent getPanel() {
myPanelWrapper = new JPanel(new GridBagLayout()) {
@Override
public Dimension getPreferredSize() {
final Dimension oldSize = super.getPreferredSize();
oldSize.width = 200;
return oldSize;
}
};
//myPanelWrapper.setPreferredSize(new Dimension(200, 800));
final GridBagConstraints gb =
new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0);
myPanelWrapper.add(myPanel, gb);
return ScrollPaneFactory
.createScrollPane(myPanelWrapper, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
// todo refactor to get rid of duplicate code dealing with separators
private String ensureEndsWithSeparator(final String wcPath) {
return wcPath.endsWith(File.separator) ? wcPath : (wcPath + File.separator);
}
public void refresh() {
final Map<String, CommittedChangeListsListener> refreshers = new HashMap<String, CommittedChangeListsListener>();
for (Map.Entry<String, MergeInfoHolder> entry : myHolders.entrySet()) {
final CommittedChangeListsListener refresher = entry.getValue().createRefresher(false);
if (refresher != null) {
refreshers.put(ensureEndsWithSeparator(entry.getKey()), refresher);
}
}
if (! refreshers.isEmpty()) {
myManager.reportLoadedLists(new CommittedChangeListsListener() {
public void onBeforeStartReport() {
}
public boolean report(final CommittedChangeList list) {
if (list instanceof SvnChangeList) {
final SvnChangeList svnList = (SvnChangeList) list;
final String wcPath = svnList.getWcPath();
if (wcPath != null) {
final CommittedChangeListsListener refresher = refreshers.get(ensureEndsWithSeparator(wcPath));
if (refresher != null) {
refresher.report(list);
}
}
}
return true;
}
public void onAfterEndReport() {
for (CommittedChangeListsListener refresher : refreshers.values()) {
refresher.onAfterEndReport();
}
myStrategy.notifyListener();
}
});
myManager.repaintTree();
}
}
private class MyRefresh extends AnAction {
private MyRefresh() {
super(SvnBundle.message("committed.changes.action.merge.highlighting.refresh.text"),
SvnBundle.message("committed.changes.action.merge.highlighting.refresh.description"), AllIcons.Actions.Refresh);
}
@Override
public void update(final AnActionEvent e) {
for (MergeInfoHolder holder : myHolders.values()) {
if (holder.refreshEnabled(false)) {
e.getPresentation().setEnabled(true);
return;
}
}
e.getPresentation().setEnabled(false);
}
public void actionPerformed(final AnActionEvent e) {
final Presentation presentation = e.getPresentation();
presentation.setEnabled(false);
refresh();
}
}
private class HighlightTo extends ToggleAction {
@Override
public void update(final AnActionEvent e) {
super.update(e);
final Presentation presentation = e.getPresentation();
presentation.setIcon(SvnIcons.ShowIntegratedTo);
}
public boolean isSelected(final AnActionEvent e) {
return myHighlightingOn && (! myFromHereDirection);
}
public void setSelected(final AnActionEvent e, final boolean state) {
if (state) {
turnFromThereHighlighting();
} else {
turnOff();
}
}
}
private class HighlightFrom extends ToggleAction {
@Override
public void update(final AnActionEvent e) {
super.update(e);
final Presentation presentation = e.getPresentation();
presentation.setIcon(SvnIcons.ShowIntegratedFrom);
presentation.setText(SvnBundle.message("committed.changes.action.enable.merge.highlighting"));
presentation.setDescription(SvnBundle.message("committed.changes.action.enable.merge.highlighting.description.text"));
}
public boolean isSelected(final AnActionEvent e) {
return myHighlightingOn && myFromHereDirection;
}
public void setSelected(final AnActionEvent e, final boolean state) {
if (state) {
turnFromHereHighlighting();
} else {
turnOff();
}
}
}
private abstract class CommonFilter extends ToggleAction {
private boolean mySelected;
private final Icon myIcon;
protected CommonFilter(final Icon icon, final String text) {
super(text);
myIcon = icon;
}
@Override
public void update(final AnActionEvent e) {
super.update(e);
final Presentation presentation = e.getPresentation();
presentation.setEnabled(myHighlightingOn);
presentation.setIcon(myIcon);
presentation.setText(getTemplatePresentation().getText());
}
public boolean isSelected(final AnActionEvent e) {
return mySelected;
}
public void setSelected(final AnActionEvent e, final boolean state) {
mySelected = state;
myStrategy.notifyListener();
}
}
private class FilterOutMerged extends CommonFilter {
private FilterOutMerged() {
super(SvnIcons.FilterIntegrated, SvnBundle.message("tab.repository.merge.panel.filter.plus"));
}
}
private class FilterOutNotMerged extends CommonFilter {
private FilterOutNotMerged() {
super(SvnIcons.FilterNotIntegrated, SvnBundle.message("tab.repository.merge.panel.filter.minus"));
}
}
private class FilterOutAlien extends CommonFilter {
private FilterOutAlien() {
super(SvnIcons.FilterOthers, SvnBundle.message("tab.repository.merge.panel.filter.others"));
}
}
private boolean mergeEnabled(final List<CommittedChangeList> listsList, final boolean forMerge) {
if ((listsList == null) || (listsList.isEmpty())) {
return false;
}
for (CommittedChangeList list : listsList) {
if (! mergeEnabled(list, forMerge)) {
return false;
}
}
return true;
}
private boolean mergeEnabled(final CommittedChangeList list, final boolean forMerge) {
final ListMergeStatus mergeStatus = getStatus(list, true);
if ((mergeStatus == null) || (ListMergeStatus.ALIEN.equals(mergeStatus))) {
return false;
} else if (ListMergeStatus.REFRESHING.equals(mergeStatus)) {
return true;
}
if (forMerge) {
return ListMergeStatus.NOT_MERGED.equals(mergeStatus);
}
return ListMergeStatus.MERGED.equals(mergeStatus);
}
private class MarkAsMerged extends AbstractIntegrateChangesAction<SelectedChangeListsChecker> {
private final String myText;
private final String myDescription;
private MarkAsMerged() {
super(false);
myText = SvnBundle.message("action.mark.list.as.merged.text");
myDescription = SvnBundle.message("action.mark.list.as.merged.description");
}
@NotNull
protected MergerFactory createMergerFactory(SelectedChangeListsChecker checker) {
return new RecordOnlyMergerFactory(checker.getSelectedLists(), false);
}
@NotNull
protected SelectedChangeListsChecker createChecker() {
return new SelectedChangeListsChecker();
}
@Override
protected void updateWithChecker(AnActionEvent e, SelectedCommittedStuffChecker checker) {
final Presentation presentation = e.getPresentation();
presentation.setIcon(SvnIcons.MarkAsMerged);
presentation.setText(myText);
presentation.setDescription(myDescription);
presentation.setEnabled(presentation.isEnabled() && mergeEnabled(checker.getSelectedLists(), true));
}
@Nullable
protected String getSelectedBranchUrl(SelectedCommittedStuffChecker checker) {
final SvnMergeInfoRootPanelManual data = getPanelData(checker.getSelectedLists());
if (data != null) {
return data.getBranch().getUrl();
}
return null;
}
@Nullable
protected String getSelectedBranchLocalPath(SelectedCommittedStuffChecker checker) {
final SvnMergeInfoRootPanelManual data = getPanelData(checker.getSelectedLists());
if (data != null) {
return data.getLocalBranch();
}
return null;
}
protected String getDialogTitle() {
return myText;
}
}
private class MarkAsNotMerged extends AbstractIntegrateChangesAction<SelectedChangeListsChecker> {
private final String myText;
private final String myDescription;
private MarkAsNotMerged() {
super(false);
myText = SvnBundle.message("action.mark.list.as.not.merged.title");
myDescription = SvnBundle.message("action.mark.list.as.not.merged.descrition");
}
@NotNull
protected MergerFactory createMergerFactory(SelectedChangeListsChecker checker) {
return new RecordOnlyMergerFactory(checker.getSelectedLists(), true);
}
@NotNull
protected SelectedChangeListsChecker createChecker() {
return new SelectedChangeListsChecker();
}
@Override
protected void updateWithChecker(AnActionEvent e, SelectedCommittedStuffChecker checker) {
final Presentation presentation = e.getPresentation();
presentation.setIcon(SvnIcons.MarkAsNotMerged);
presentation.setText(myText);
presentation.setDescription(myDescription);
presentation.setEnabled(presentation.isEnabled() && mergeEnabled(checker.getSelectedLists(), false));
}
@Nullable
protected String getSelectedBranchUrl(SelectedCommittedStuffChecker checker) {
final SvnMergeInfoRootPanelManual data = getPanelData(checker.getSelectedLists());
if (data != null) {
return data.getBranch().getUrl();
}
return null;
}
@Nullable
protected String getSelectedBranchLocalPath(SelectedCommittedStuffChecker checker) {
final SvnMergeInfoRootPanelManual data = getPanelData(checker.getSelectedLists());
if (data != null) {
return data.getLocalBranch();
}
return null;
}
protected String getDialogTitle() {
return myText;
}
}
private class UndoIntegrateChangeListsAction extends IntegrateChangeListsAction {
private UndoIntegrateChangeListsAction() {
super(false);
}
@Override
protected void updateWithChecker(AnActionEvent e, SelectedCommittedStuffChecker checker) {
e.getPresentation().setIcon(SvnIcons.UndoIntegrateToBranch);
e.getPresentation().setText(SvnBundle.message("undo.integrate.to.branch"));
e.getPresentation().setDescription(SvnBundle.message("undo.integrate.to.branch.description"));
}
@Override
protected String getDialogTitle() {
return SvnBundle.message("undo.integrate.to.branch.dialog.title");
}
}
private class IntegrateChangeListsAction extends AbstractIntegrateChangesAction<SelectedChangeListsChecker> {
private final boolean myDirect;
public IntegrateChangeListsAction() {
this(true);
}
protected IntegrateChangeListsAction(final boolean direct) {
super(false);
myDirect = direct;
}
@NotNull
protected MergerFactory createMergerFactory(final SelectedChangeListsChecker checker) {
return new ChangeListsMergerFactory(checker.getSelectedLists()) {
@Override
public IMerger createMerger(final SvnVcs vcs,
final File target,
final UpdateEventHandler handler,
final SVNURL currentBranchUrl,
String branchName) {
return new Merger(vcs, myChangeListsList, target, handler, currentBranchUrl, branchName) {
@Override
protected SVNRevisionRange createRange() {
if (myDirect) {
return super.createRange();
} else {
return new SVNRevisionRange(SVNRevision.create(myLatestProcessed.getNumber()), SVNRevision.create(myLatestProcessed.getNumber() - 1));
}
}
};
}
};
}
@NotNull
protected SelectedChangeListsChecker createChecker() {
return new SelectedChangeListsChecker();
}
@Override
protected void updateWithChecker(AnActionEvent e, SelectedCommittedStuffChecker checker) {
e.getPresentation().setIcon(SvnIcons.IntegrateToBranch);
}
protected String getSelectedBranchUrl(SelectedCommittedStuffChecker checker) {
final SvnMergeInfoRootPanelManual data = getPanelData(checker.getSelectedLists());
if (data != null && data.getBranch() != null) {
return data.getBranch().getUrl();
}
return null;
}
protected String getSelectedBranchLocalPath(SelectedCommittedStuffChecker checker) {
final SvnMergeInfoRootPanelManual data = getPanelData(checker.getSelectedLists());
if (data != null) {
return data.getLocalBranch();
}
return null;
}
protected String getDialogTitle() {
return null;
}
}
private SvnMergeInfoRootPanelManual getPanelData(final List<CommittedChangeList> listsList) {
for (CommittedChangeList list : listsList) {
if (! (list instanceof SvnChangeList)) {
return null;
}
final SvnChangeList svnList = (SvnChangeList) list;
final String wcPath = svnList.getWcPath();
if (wcPath == null) {
continue;
}
return getPanelData(wcPath);
}
return null;
}
@Nullable
public ListMergeStatus getStatus(final CommittedChangeList list, final boolean ignoreEnabled) {
if (! (list instanceof SvnChangeList)) {
return null;
}
final SvnChangeList svnList = (SvnChangeList) list;
final String wcPath = svnList.getWcPath();
MergeInfoHolder holder = null;
if (wcPath == null) {
for (Map.Entry<String, SvnMergeInfoRootPanelManual> entry : myMergePanels.entrySet()) {
final SvnMergeInfoRootPanelManual panelManual = entry.getValue();
if ((panelManual.getBranch() != null) && (panelManual.getBranch().getUrl() != null) &&
svnList.allPathsUnder(panelManual.getBranch().getUrl())) {
holder = getHolder(entry.getKey());
}
}
} else {
holder = getHolder(wcPath);
}
if (holder != null) {
return holder.getDecorator().check(list, ignoreEnabled);
}
return null;
}
public MergePanelFiltering getStrategy() {
return myStrategy;
}
public boolean strategyInitialized() {
return myStrategy.isInitialized();
}
private class MergePanelFiltering implements ChangeListFilteringStrategy {
private final JComponent myPanel;
private ChangeListener myListener;
private boolean myInitialized;
private final static String ourKey = "MERGE_PANEL";
public MergePanelFiltering(final JComponent panel) {
myPanel = panel;
}
public boolean isInitialized() {
return myInitialized;
}
public JComponent getFilterUI() {
if (! myInitialized) {
createPanels(myLocation, null);
}
myInitialized = true;
return myPanel;
}
@Override
public CommittedChangesFilterKey getKey() {
return new CommittedChangesFilterKey(ourKey, CommittedChangesFilterPriority.MERGE);
}
public void setFilterBase(final List<CommittedChangeList> changeLists) {
}
public void addChangeListener(final ChangeListener listener) {
myListener = listener;
}
public void removeChangeListener(final ChangeListener listener) {
myListener = null;
}
public void resetFilterBase() {
}
public void appendFilterBase(List<CommittedChangeList> changeLists) {
}
@NotNull
public List<CommittedChangeList> filterChangeLists(final List<CommittedChangeList> changeLists) {
if ((! myFilterAlien.isSelected(null)) && (! myFilterNotMerged.isSelected(null)) && (! myFilterMerged.isSelected(null))) {
return changeLists;
}
final List<CommittedChangeList> result = new ArrayList<CommittedChangeList>();
for (CommittedChangeList list : changeLists) {
final ListMergeStatus status = getStatus(list, true);
if (ListMergeStatus.REFRESHING.equals(status)) {
result.add(list);
} else if ((status == null) || ListMergeStatus.ALIEN.equals(status)) {
if (! myFilterAlien.isSelected(null)) {
result.add(list);
}
} else if (ListMergeStatus.MERGED.equals(status) || ListMergeStatus.COMMON.equals(status)) {
if (! myFilterMerged.isSelected(null)) {
result.add(list);
}
} else {
// not merged
if (! myFilterNotMerged.isSelected(null)) {
result.add(list);
}
}
}
return result;
}
public void notifyListener() {
if (myListener != null) {
myListener.stateChanged(new ChangeEvent(this));
}
myManager.repaintTree();
}
}
public void fireRepaint() {
myManager.repaintTree();
}
public void dispose() {
myDisposed = true;
}
}