summaryrefslogtreecommitdiff
path: root/platform/vcs-impl/src
diff options
context:
space:
mode:
Diffstat (limited to 'platform/vcs-impl/src')
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java4
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java3
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java15
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java9
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java8
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java4
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java48
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java18
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java52
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java20
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java2
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java19
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java6
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java305
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java22
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java7
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java4
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java32
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java50
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java21
-rw-r--r--platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java7
23 files changed, 370 insertions, 296 deletions
diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java
index dfce14728906..7db646c94b5b 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * 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.
@@ -43,6 +43,7 @@ import com.intellij.ui.components.JBLoadingPanel;
import com.intellij.ui.table.JBTable;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.StatusText;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -826,6 +827,7 @@ public class DirDiffTableModel extends AbstractTableModel implements DirDiffMode
return true;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return "Do not ask me again";
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java
index 5bcb5fbf165d..0b09f753168f 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.vcs.ui.CommitMessage;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
+import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
@@ -36,7 +37,7 @@ import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
public class CommitCompletionContributor extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
if (document != null) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
index 97f5277ab6e5..025795eb08ed 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
@@ -171,7 +171,8 @@ public class ChangesFragmentedDiffPanel implements Disposable {
descriptor = new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, position.column);
} else {
if (((DiffPanelImpl) panel).getEditor1().getDocument().getTextLength() == 0) {
- FileEditorManager.getInstance(myProject).openTextEditor(new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0), true);
+ FileEditorManager.getInstance(myProject).openTextEditor(new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0),
+ true);
return;
}
@@ -281,11 +282,13 @@ public class ChangesFragmentedDiffPanel implements Disposable {
FragmentedEditorHighlighter bh = fragmentedContent.getBeforeHighlighter();
if (bh != null) {
- ((EditorEx) ((DiffPanelImpl) currentPanel).getEditor1()).setHighlighter(bh);
+ ((EditorEx) ((DiffPanelImpl) myHorizontal).getEditor1()).setHighlighter(bh);
+ ((EditorEx) ((DiffPanelImpl) myVertical).getEditor1()).setHighlighter(bh);
}
FragmentedEditorHighlighter ah = fragmentedContent.getAfterHighlighter();
if (ah != null) {
- ((EditorEx) ((DiffPanelImpl) currentPanel).getEditor2()).setHighlighter(ah);
+ ((EditorEx) ((DiffPanelImpl) myHorizontal).getEditor2()).setHighlighter(ah);
+ ((EditorEx) ((DiffPanelImpl) myVertical).getEditor2()).setHighlighter(ah);
}
if (((DiffPanelImpl) currentPanel).getEditor1() != null) {
highlightTodo(true, fragmentedContent.getBeforeTodoRanges());
@@ -335,7 +338,7 @@ public class ChangesFragmentedDiffPanel implements Disposable {
final DiffPanel diffPanel = new DiffPanelImpl(null, myProject, false, horizontal, SHORT_DIFF_DIVIDER_POLYGONS_OFFSET, null) {
@Override
protected DiffPanelState createDiffPanelState(@NotNull Disposable parentDisposable) {
- return new FragmentedDiffPanelState(this, myProject, ! horizontal, parentDisposable);
+ return new FragmentedDiffPanelState(this, myProject, getDiffDividerPolygonsOffset(), ! horizontal, parentDisposable);
}
};
diffPanel.enableToolbar(false);
@@ -403,7 +406,7 @@ public class ChangesFragmentedDiffPanel implements Disposable {
}
private static final Icon ourIcon = PlatformIcons.CHECK_ICON;
-
+
private class PopupAction extends DumbAwareAction {
private final AnAction myUsual;
private final AnAction myNumbered;
@@ -680,7 +683,7 @@ public class ChangesFragmentedDiffPanel implements Disposable {
private class MyNextDiffAction extends DumbAwareAction {
private boolean myEnabled;
-
+
private MyNextDiffAction() {
super("Next Change", "Next Change", AllIcons.Actions.NextOccurence);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java
index 5b3860523a91..00c9c6c1a0c5 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * 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.
@@ -36,7 +36,7 @@ public class VcsConfirmationDialog extends OptionsDialog {
private final String myMessage;
private final String myDoNotShowMessage;
- protected VcsConfirmationDialog(Project project, VcsShowConfirmationOption option, String message, String doNotShowMessage) {
+ protected VcsConfirmationDialog(Project project, VcsShowConfirmationOption option, String message, @NotNull String doNotShowMessage) {
super(project);
myOption = option;
myMessage = message;
@@ -68,6 +68,7 @@ public class VcsConfirmationDialog extends OptionsDialog {
return panel;
}
+ @NotNull
@Override
protected String getDoNotShowMessage() {
return myDoNotShowMessage;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java
index 87bb5a338ca7..521071b0faf4 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * 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.
@@ -41,7 +41,12 @@ public class BrowseChangesAction extends AnAction implements DumbAware {
assert vcs != null;
final CommittedChangesProvider provider = vcs.getCommittedChangesProvider();
assert provider != null;
- ChangeBrowserSettings settings = provider.createDefaultSettings();
+ final VcsConfiguration vcsConfiguration = VcsConfiguration.getInstance(project);
+ ChangeBrowserSettings settings = vcsConfiguration.CHANGE_BROWSER_SETTINGS.get(vcs.getName());
+ if (settings == null) {
+ settings = provider.createDefaultSettings();
+ vcsConfiguration.CHANGE_BROWSER_SETTINGS.put(vcs.getName(), settings);
+ }
CommittedChangesFilterDialog dlg = new CommittedChangesFilterDialog(project, provider.createFilterUI(true), settings);
dlg.show();
if (!dlg.isOK()) return;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java
index 99c8d796c38b..60750b1cdbad 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * 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.
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotifications;
+import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
@@ -34,11 +35,14 @@ public class ChangelistConflictNotificationProvider extends EditorNotifications.
myConflictTracker = changeListManager.getConflictTracker();
}
+ @Override
+ @NotNull
public Key<ChangelistConflictNotificationPanel> getKey() {
return KEY;
}
- public ChangelistConflictNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
+ @Override
+ public ChangelistConflictNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
return myConflictTracker.hasConflict(file) ? ChangelistConflictNotificationPanel.create(myConflictTracker, file) : null;
}
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
index c213feb38c40..e76ba194672e 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
@@ -294,7 +294,9 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
}
private void notifyStateChanged() {
- myBus.syncPublisher(SHELF_TOPIC).stateChanged(new ChangeEvent(this));
+ if (!myProject.isDisposed()) {
+ myBus.syncPublisher(SHELF_TOPIC).stateChanged(new ChangeEvent(this));
+ }
}
private File getPatchPath(@NonNls final String commitMessage) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java
index ffa8b2a97fc5..497db3da7d9f 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java
@@ -85,7 +85,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
private String myLastKnownComment = "";
private final boolean myAllOfDefaultChangeListChangesIncluded;
@NonNls private static final String SPLITTER_PROPORTION_OPTION = "CommitChangeListDialog.SPLITTER_PROPORTION_" + LAYOUT_VERSION;
- private final Action[] myExecutorActions;
+ private final CommitExecutorAction[] myExecutorActions;
private final boolean myShowVcsCommit;
private final Map<AbstractVcs, JPanel> myPerVcsOptionsPanels = new HashMap<AbstractVcs, JPanel>();
@@ -103,7 +103,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
private final PseudoMap<Object, Object> myAdditionalData;
private String myHelpId;
-
+
private SplitterWithSecondHideable myDetailsSplitter;
private static final String DETAILS_SPLITTER_PROPORTION_OPTION = "CommitChangeListDialog.DETAILS_SPLITTER_PROPORTION_" + LAYOUT_VERSION;
private static final String DETAILS_SHOW_OPTION = "CommitChangeListDialog.DETAILS_SHOW_OPTION_";
@@ -142,9 +142,15 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
private final MyUpdateButtonsRunnable myUpdateButtonsRunnable = new MyUpdateButtonsRunnable(this);
- private static boolean commit(final Project project, final List<Change> changes, final LocalChangeList initialSelection,
- final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment,
- @Nullable CommitResultHandler customResultHandler) {
+ public static boolean commitChanges(final Project project, final List<Change> changes, final LocalChangeList initialSelection,
+ final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment,
+ @Nullable CommitResultHandler customResultHandler, boolean cancelIfNoChanges) {
+ if (cancelIfNoChanges && changes.isEmpty() && !ApplicationManager.getApplication().isUnitTestMode()) {
+ Messages.showInfoMessage(project, VcsBundle.message("commit.dialog.no.changes.detected.text"),
+ VcsBundle.message("commit.dialog.no.changes.detected.title"));
+ return false;
+ }
+
for (BaseCheckinHandlerFactory factory : getCheckInFactories(project)) {
BeforeCheckinDialogHandler handler = factory.createSystemReadyHandler(project);
if (handler != null && !handler.beforeCommitDialogShown(project, changes, executors, showVcsCommit)) {
@@ -208,13 +214,8 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
public static boolean commitChanges(final Project project, final Collection<Change> changes, final LocalChangeList initialSelection,
final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment,
@Nullable CommitResultHandler customResultHandler) {
- if (changes.isEmpty() && !ApplicationManager.getApplication().isUnitTestMode()) {
- Messages.showInfoMessage(project, VcsBundle.message("commit.dialog.no.changes.detected.text") ,
- VcsBundle.message("commit.dialog.no.changes.detected.title"));
- return false;
- }
-
- return commit(project, new ArrayList<Change>(changes), initialSelection, executors, showVcsCommit, comment, customResultHandler);
+ return commitChanges(project, new ArrayList<Change>(changes), initialSelection, executors, showVcsCommit, comment,
+ customResultHandler, true);
}
public static void commitAlienChanges(final Project project, final List<Change> changes, final AbstractVcs vcs,
@@ -317,7 +318,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
myZipperUpdater.queue(myRefreshDetails);
}
});
-
+
myBrowserExtender.addToolbarActions(this);
myBrowserExtender.addSelectedListChangeListener(new SelectedListChangeListener() {
@@ -447,7 +448,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
restoreState();
if (myExecutors != null) {
- myExecutorActions = new Action[myExecutors.size()];
+ myExecutorActions = new CommitExecutorAction[myExecutors.size()];
for (int i = 0; i < myExecutors.size(); i++) {
final CommitExecutor commitExecutor = myExecutors.get(i);
@@ -466,10 +467,10 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
init();
updateButtons();
updateVcsOptionsVisibility();
-
+
updateOnListSelection();
myCommitMessageArea.requestFocusInMessage();
-
+
for (EditChangelistSupport support : Extensions.getExtensions(EditChangelistSupport.EP_NAME, project)) {
support.installSearch(myCommitMessageArea.getEditorField(), myCommitMessageArea.getEditorField());
}
@@ -829,7 +830,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
if (configuration != null) {
configuration.CHECK_COMMIT_MESSAGE_SPELLING = checkSpelling;
}
- myCommitMessageArea.setCheckSpelling(checkSpelling);
+ myCommitMessageArea.setCheckSpelling(checkSpelling);
}
private boolean checkComment() {
@@ -853,7 +854,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
myDisposed = false;
myUpdateButtonsRunnable.restart(this);
}
-
+
private CheckinHandler.ReturnResult runBeforeCommitHandlers(final Runnable okAction, final CommitExecutor executor) {
final Computable<CheckinHandler.ReturnResult> proceedRunnable = new Computable<CheckinHandler.ReturnResult>() {
@Override
@@ -1244,8 +1245,8 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
myCommitAction.setEnabled(enabled);
}
if (myExecutorActions != null) {
- for (Action executorAction : myExecutorActions) {
- executorAction.setEnabled(enabled);
+ for (CommitExecutorAction executorAction : myExecutorActions) {
+ executorAction.updateEnabled(enabled);
}
}
myOKButtonUpdateAlarm.cancelAllRequests();
@@ -1268,7 +1269,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
protected String getDimensionServiceKey() {
return "CommitChangelistDialog" + LAYOUT_VERSION;
}
-
+
@Override
public JComponent getPreferredFocusedComponent() {
return myCommitMessageArea.getEditorField();
@@ -1323,6 +1324,11 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
callExecutor.run();
}
}
+
+ public void updateEnabled(boolean hasDiffs) {
+ setEnabled(hasDiffs
+ || (myCommitExecutor instanceof CommitExecutorBase) && !((CommitExecutorBase)myCommitExecutor).areChangesRequired());
+ }
}
private static class DiffCommitMessageEditor extends CommitMessage implements Disposable {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java
index 2e34d7819e77..19b1420ddda9 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java
@@ -41,6 +41,7 @@ import com.intellij.openapi.vcs.checkin.CheckinHandler;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vcs.update.RefreshVFsSynchronously;
import com.intellij.util.Consumer;
+import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.concurrency.Semaphore;
@@ -581,7 +582,7 @@ public class CommitHelper {
}
else {
if (myCustomResultHandler == null) {
- showErrorDialogAndMoveToAnotherList(processor, errorsSize, warningsSize);
+ showErrorDialogAndMoveToAnotherList(processor, errorsSize, warningsSize, errors);
}
else {
myCustomResultHandler.onFailure();
@@ -589,19 +590,26 @@ public class CommitHelper {
}
}
- private void showErrorDialogAndMoveToAnotherList(final GeneralCommitProcessor processor, final int errorsSize, final int warningsSize) {
+ private void showErrorDialogAndMoveToAnotherList(final GeneralCommitProcessor processor, final int errorsSize, final int warningsSize,
+ @NotNull final List<VcsException> errors) {
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
public void run() {
- final String message;
+ String message;
if (errorsSize > 0 && warningsSize > 0) {
message = VcsBundle.message("message.text.commit.failed.with.errors.and.warnings");
}
else if (errorsSize > 0) {
- message = VcsBundle.message("message.text.commit.failed.with.errors");
+ message = StringUtil.pluralize(VcsBundle.message("message.text.commit.failed.with.error"), errorsSize);
}
else {
- message = VcsBundle.message("message.text.commit.finished.with.warnings");
+ message = StringUtil.pluralize(VcsBundle.message("message.text.commit.finished.with.warning"), warningsSize);
}
+ message += ":\n" + StringUtil.join(errors, new Function<VcsException, String>() {
+ @Override
+ public String fun(VcsException e) {
+ return e.getMessage();
+ }
+ }, "\n");
//new VcsBalloonProblemNotifier(myProject, message, MessageType.ERROR).run();
Messages.showErrorDialog(message, VcsBundle.message("message.title.commit"));
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java
new file mode 100644
index 000000000000..fe9c12036596
--- /dev/null
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java
@@ -0,0 +1,52 @@
+/*
+ * 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 com.intellij.openapi.vcs.changes.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vcs.FilePath;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.tree.DefaultTreeModel;
+import java.util.List;
+
+public class FilePathChangesTreeList extends ChangesTreeList<FilePath> {
+ private final Project myProject;
+
+ public FilePathChangesTreeList(@NotNull Project project, @NotNull List<FilePath> originalFiles,
+ boolean showCheckboxes, boolean highlightProblems,
+ @Nullable Runnable inclusionListener, @Nullable ChangeNodeDecorator nodeDecorator) {
+ super(project, originalFiles, showCheckboxes, highlightProblems, inclusionListener, nodeDecorator);
+ myProject = project;
+ }
+
+ protected DefaultTreeModel buildTreeModel(final List<FilePath> changes, ChangeNodeDecorator changeNodeDecorator) {
+ return new TreeModelBuilder(myProject, false).buildModelFromFilePaths(changes);
+ }
+
+ protected List<FilePath> getSelectedObjects(final ChangesBrowserNode<FilePath> node) {
+ return node.getAllFilePathsUnder();
+ }
+
+ @Nullable
+ protected FilePath getLeadSelectedObject(final ChangesBrowserNode node) {
+ final Object userObject = node.getUserObject();
+ if (userObject instanceof FilePath) {
+ return (FilePath) userObject;
+ }
+ return null;
+ }
+}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java
index b27dc2e64d63..61bcd6ea2ae6 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.tree.DefaultTreeModel;
import java.util.Collection;
import java.util.List;
@@ -38,24 +37,7 @@ public class SelectFilePathsDialog extends AbstractSelectFilesDialog<FilePath> {
final VcsShowConfirmationOption confirmationOption,
@Nullable String okActionName, @Nullable String cancelActionName, boolean showDoNotAskOption) {
super(project, false, confirmationOption, prompt, showDoNotAskOption);
- myFileList = new ChangesTreeList<FilePath>(project, originalFiles, true, true, null, null) {
- protected DefaultTreeModel buildTreeModel(final List<FilePath> changes, ChangeNodeDecorator changeNodeDecorator) {
- return new TreeModelBuilder(project, false).buildModelFromFilePaths(changes);
- }
-
- protected List<FilePath> getSelectedObjects(final ChangesBrowserNode node) {
- return node.getAllFilePathsUnder();
- }
-
- @Nullable
- protected FilePath getLeadSelectedObject(final ChangesBrowserNode node) {
- final Object userObject = node.getUserObject();
- if (userObject instanceof FilePath) {
- return (FilePath) userObject;
- }
- return null;
- }
- };
+ myFileList = new FilePathChangesTreeList(project, originalFiles, true, true, null, null);
if (okActionName != null) {
getOKAction().putValue(Action.NAME, okActionName);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java
index 6c139f9d069f..8806e4544a9c 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java
@@ -93,7 +93,7 @@ public class SelectFilesDialog extends AbstractSelectFilesDialog<VirtualFile> {
return defaultGroup;
}
- private static class VirtualFileList extends ChangesTreeList<VirtualFile> {
+ public static class VirtualFileList extends ChangesTreeList<VirtualFile> {
private final Project myProject;
@Nullable private final DeleteProvider myDeleteProvider;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java
index 587628a27c0b..304275d732d7 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java
@@ -78,6 +78,11 @@ public class VcsManagerConfigurable extends SearchableConfigurable.Parent.Abstra
}
@Override
+ public boolean isVisible() {
+ return ProjectLevelVcsManager.getInstance(myProject).getAllVcss().length > 0;
+ }
+
+ @Override
public void disposeUIResources() {
super.disposeUIResources();
if (myMappings != null) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java
index e43a499f9a33..3ddfe8d9b188 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * 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.
@@ -22,6 +22,7 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.newEditor.OptionsEditor;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsConfiguration;
@@ -31,6 +32,7 @@ import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -42,28 +44,25 @@ import java.awt.*;
* @author Kirill Likhodedov
*/
class VcsUpdateInfoScopeFilterConfigurable implements Configurable, NamedScopesHolder.ScopeListener {
-
private final JCheckBox myCheckbox;
private final JComboBox myComboBox;
- private final Project myProject;
private final VcsConfiguration myVcsConfiguration;
private final NamedScopesHolder[] myNamedScopeHolders;
VcsUpdateInfoScopeFilterConfigurable(Project project, VcsConfiguration vcsConfiguration) {
- myProject = project;
myVcsConfiguration = vcsConfiguration;
myCheckbox = new JCheckBox(VcsBundle.getString("settings.filter.update.project.info.by.scope"));
- myComboBox = new JComboBox();
+ myComboBox = new ComboBox();
myComboBox.setEnabled(myCheckbox.isSelected());
myCheckbox.addChangeListener(new ChangeListener() {
@Override
- public void stateChanged(ChangeEvent e) {
+ public void stateChanged(@NotNull ChangeEvent e) {
myComboBox.setEnabled(myCheckbox.isSelected());
}
});
- myNamedScopeHolders = NamedScopesHolder.getAllNamedScopeHolders(myProject);
+ myNamedScopeHolders = NamedScopesHolder.getAllNamedScopeHolders(project);
for (NamedScopesHolder holder : myNamedScopeHolders) {
holder.addScopeListener(this);
}
@@ -93,12 +92,12 @@ class VcsUpdateInfoScopeFilterConfigurable implements Configurable, NamedScopesH
panel.add(myCheckbox);
panel.add(myComboBox);
panel.add(Box.createHorizontalStrut(UIUtil.DEFAULT_HGAP));
- panel.add(new LinkLabel("Edit scopes", null, new LinkListener() {
+ panel.add(new LinkLabel("Manage Scopes", null, new LinkListener() {
@Override
public void linkSelected(LinkLabel aSource, Object aLinkData) {
- final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(DataManager.getInstance().getDataContext(panel));
+ OptionsEditor optionsEditor = OptionsEditor.KEY.getData(DataManager.getInstance().getDataContext(panel));
if (optionsEditor != null) {
- SearchableConfigurable configurable = optionsEditor.findConfigurableById(new ScopeChooserConfigurable(myProject).getId());
+ SearchableConfigurable configurable = optionsEditor.findConfigurableById(ScopeChooserConfigurable.PROJECT_SCOPES);
if (configurable != null) {
optionsEditor.select(configurable);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java
index bf71a2ffee7c..d6362ffe19c9 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java
@@ -17,6 +17,7 @@ package com.intellij.openapi.vcs.ex;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@@ -27,7 +28,7 @@ import java.util.List;
public class DocumentWrapper {
private final Document myDocument;
- public DocumentWrapper(Document document) {
+ public DocumentWrapper(@NotNull Document document) {
myDocument = document;
}
@@ -35,10 +36,12 @@ public class DocumentWrapper {
return myDocument.getLineNumber(offset);
}
+ @NotNull
public List<String> getLines() {
return getLines(0, myDocument.getLineCount() - 1);
}
+ @NotNull
public List<String> getLines(int from, int to) {
ArrayList<String> result = new ArrayList<String>();
for (int i = from; i <= to; i++) {
@@ -54,6 +57,7 @@ public class DocumentWrapper {
return result;
}
+ @NotNull
private String getLine(final int i) {
TextRange range = new TextRange(myDocument.getLineStartOffset(i), myDocument.getLineEndOffset(i));
if (range.getLength() < 0) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
index 548cc514b300..ac0bc8608368 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
@@ -38,26 +38,26 @@ import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.diff.FilesTooBigForDiffException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* @author irengrig
- * author: lesya
+ * author: lesya
*/
public class LineStatusTracker {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.ex.LineStatusTracker");
- private static final Key<CanNotCalculateDiffPanel> PANEL_KEY = new Key<CanNotCalculateDiffPanel>("LineStatusTracker.CanNotCalculateDiffPanel");
+ private static final Key<CanNotCalculateDiffPanel> PANEL_KEY =
+ new Key<CanNotCalculateDiffPanel>("LineStatusTracker.CanNotCalculateDiffPanel");
private final Object myLock = new Object();
- // true -> have contents
private BaseLoadState myBaseLoaded;
private final Document myDocument;
@@ -71,15 +71,17 @@ public class LineStatusTracker {
private boolean myBulkUpdate;
private final Application myApplication;
- @Nullable
- private RevisionPack myBaseRevisionNumber;
+ @Nullable private RevisionPack myBaseRevisionNumber;
private String myPreviousBaseRevision;
private boolean myAnathemaThrown;
private FileEditorManager myFileEditorManager;
private final VirtualFile myVirtualFile;
private boolean myReleased = false;
- private LineStatusTracker(final Document document, final Document upToDateDocument, final Project project, final VirtualFile virtualFile) {
+ private LineStatusTracker(@NotNull final Document document,
+ @NotNull final Document upToDateDocument,
+ final Project project,
+ @Nullable final VirtualFile virtualFile) {
myVirtualFile = virtualFile;
myApplication = ApplicationManager.getApplication();
myDocument = document;
@@ -156,7 +158,7 @@ public class LineStatusTracker {
}
private void removeAnathema() {
- if (! myAnathemaThrown) return;
+ if (!myAnathemaThrown) return;
myAnathemaThrown = false;
final FileEditor[] editors = myFileEditorManager.getEditors(myVirtualFile);
for (FileEditor editor : editors) {
@@ -171,6 +173,7 @@ public class LineStatusTracker {
@SuppressWarnings({"AutoBoxing"})
private RangeHighlighter createHighlighter(final Range range) {
LOG.assertTrue(!myReleased, "Already released");
+
int first =
range.getOffset1() >= myDocument.getLineCount() ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getOffset1());
@@ -179,6 +182,7 @@ public class LineStatusTracker {
final RangeHighlighter highlighter = DocumentMarkupModel.forDocument(myDocument, myProject, true)
.addRangeHighlighter(first, second, HighlighterLayer.FIRST - 1, null, HighlighterTargetArea.LINES_IN_RANGE);
+
final TextAttributes attr = LineStatusTrackerDrawing.getAttributesFor(range);
highlighter.setErrorStripeMarkColor(attr.getErrorStripeColor());
highlighter.setThinErrorStripeMark(true);
@@ -186,14 +190,21 @@ public class LineStatusTracker {
highlighter.setGreedyToRight(true);
highlighter.setLineMarkerRenderer(LineStatusTrackerDrawing.createRenderer(range, this));
highlighter.setEditorFilter(MarkupEditorFilterFactory.createIsNotDiffFilter());
- final int line1 = myDocument.getLineNumber(first);
- final int line2 = myDocument.getLineNumber(second);
+
final String tooltip;
- if (line1 == line2) {
- tooltip = VcsBundle.message("tooltip.text.line.changed", line1);
+ if (range.getOffset1() == range.getOffset2()) {
+ if (range.getUOffset1() + 1 == range.getUOffset2()) {
+ tooltip = VcsBundle.message("tooltip.text.line.before.deleted", range.getOffset1() + 1);
+ }
+ else {
+ tooltip = VcsBundle.message("tooltip.text.lines.before.deleted", range.getOffset1() + 1, range.getUOffset2() - range.getUOffset1());
+ }
+ }
+ else if (range.getOffset1() + 1 == range.getOffset2()) {
+ tooltip = VcsBundle.message("tooltip.text.line.changed", range.getOffset1() + 1);
}
else {
- tooltip = VcsBundle.message("tooltip.text.lines.changed", line1, line2);
+ tooltip = VcsBundle.message("tooltip.text.lines.changed", range.getOffset1() + 1, range.getOffset2());
}
highlighter.setErrorStripeTooltip(tooltip);
@@ -285,11 +296,15 @@ public class LineStatusTracker {
}
private class MyDocumentListener extends DocumentAdapter {
+ // We have 3 document versions:
+ // * VCS version - upToDate*
+ // * before change - my*
+ // * after change - current*
+
private int myFirstChangedLine;
- private int myUpToDateFirstLine;
- private int myUpToDateLastLine;
private int myLastChangedLine;
- private int myLinesBeforeChange;
+ private int myChangedLines;
+ private int myTotalLines;
private final VcsDirtyScopeManager myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject);
@Override
@@ -302,50 +317,15 @@ public class LineStatusTracker {
try {
myFirstChangedLine = myDocument.getLineNumber(e.getOffset());
myLastChangedLine = myDocument.getLineNumber(e.getOffset() + e.getOldLength());
+ myChangedLines = myLastChangedLine - myFirstChangedLine;
if (StringUtil.endsWithChar(e.getOldFragment(), '\n')) myLastChangedLine++;
-
- myLinesBeforeChange = myDocument.getLineNumber(e.getOffset() + e.getOldLength()) - myDocument.getLineNumber(e.getOffset());
-
- Range firstChangedRange = getLastRangeBeforeLine(myFirstChangedLine);
-
- if (firstChangedRange == null) {
- myUpToDateFirstLine = myFirstChangedLine;
- }
- else if (firstChangedRange.containsLine(myFirstChangedLine)) {
- myFirstChangedLine = firstChangedRange.getOffset1();
- myUpToDateFirstLine = firstChangedRange.getUOffset1();
- }
- else {
- myUpToDateFirstLine = firstChangedRange.getUOffset2() + myFirstChangedLine - firstChangedRange.getOffset2();
- }
-
- Range myLastChangedRange = getLastRangeBeforeLine(myLastChangedLine);
-
- if (myLastChangedRange == null) {
- myUpToDateLastLine = myLastChangedLine;
- }
- else if (myLastChangedRange.containsLine(myLastChangedLine)) {
- myUpToDateLastLine = myLastChangedRange.getUOffset2();
- myLastChangedLine = myLastChangedRange.getOffset2();
- }
- else {
- myUpToDateLastLine = myLastChangedRange.getUOffset2() + myLastChangedLine - myLastChangedRange.getOffset2();
- }
- } catch (ProcessCanceledException ignore) {
+ myTotalLines = e.getDocument().getLineCount();
+ }
+ catch (ProcessCanceledException ignore) {
}
}
}
- @Nullable
- private Range getLastRangeBeforeLine(int line) {
- Range result = null;
- for (Range range : myRanges) {
- if (range.isAfter(line)) return result;
- result = range;
- }
- return result;
- }
-
@Override
public void documentChanged(final DocumentEvent e) {
myApplication.assertWriteAccessAllowed();
@@ -354,41 +334,46 @@ public class LineStatusTracker {
if (myReleased) return;
if (myBulkUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return;
try {
+ int currentChangedLines = myDocument.getLineNumber(e.getOffset() + e.getNewLength()) - myDocument.getLineNumber(e.getOffset());
+ int linesShift = currentChangedLines - myChangedLines;
+ int upToDateTotalLine = myUpToDateDocument.getLineCount();
- int line = myDocument.getLineNumber(e.getOffset() + e.getNewLength());
- int linesAfterChange = line - myDocument.getLineNumber(e.getOffset());
- int linesShift = linesAfterChange - myLinesBeforeChange;
-
- List<Range> rangesAfterChange = getRangesAfter(myRanges, myLastChangedLine);
- List<Range> rangesBeforeChange = getRangesBefore(myRanges, myFirstChangedLine);
+ List<Range> rangesBeforeChange = new ArrayList<Range>();
+ List<Range> rangesAfterChange = new ArrayList<Range>();
+ List<Range> changedRanges = new ArrayList<Range>();
+ sortRanges(myRanges, myFirstChangedLine, myLastChangedLine, rangesBeforeChange, changedRanges, rangesAfterChange);
- List<Range> changedRanges = getChangedRanges(myFirstChangedLine, myLastChangedLine);
+ Range firstChangedRange = ContainerUtil.getFirstItem(changedRanges);
+ Range lastChangedRange = ContainerUtil.getLastItem(changedRanges);
+ Range lastRangeBefore = ContainerUtil.getLastItem(rangesBeforeChange);
+ Range firstRangeAfter = ContainerUtil.getFirstItem(rangesAfterChange);
- int newSize = rangesBeforeChange.size() + changedRanges.size() + rangesAfterChange.size();
- if (myRanges.size() != newSize) {
- LOG.info("Ranges: " + myRanges + "; first changed line: " + myFirstChangedLine + "; last changed line: " + myLastChangedLine);
- LOG.assertTrue(false);
+ if (firstChangedRange != null && firstChangedRange.getOffset1() < myFirstChangedLine) {
+ myFirstChangedLine = firstChangedRange.getOffset1();
+ }
+ if (lastChangedRange != null && lastChangedRange.getOffset2() > myLastChangedLine) {
+ myLastChangedLine = lastChangedRange.getOffset2() - 1;
}
+ int currentFirstLine = myFirstChangedLine;
+ int currentLastLine = myLastChangedLine + linesShift;
- myLastChangedLine += linesShift;
-
+ int upToDateFirstLine = getUpToDateLine1(lastRangeBefore, myFirstChangedLine);
+ int upToDateLastLine = getUpToDateLine2(firstRangeAfter, myLastChangedLine, myTotalLines, upToDateTotalLine);
- List<Range> newChangedRanges = getNewChangedRanges();
+ List<Range> newChangedRanges = getNewChangedRanges(currentFirstLine, currentLastLine, upToDateFirstLine, upToDateLastLine);
shiftRanges(rangesAfterChange, linesShift);
if (!changedRanges.equals(newChangedRanges)) {
replaceRanges(changedRanges, newChangedRanges);
- myRanges = new ArrayList<Range>();
+ myRanges = new ArrayList<Range>(rangesBeforeChange.size() + newChangedRanges.size() + rangesAfterChange.size());
myRanges.addAll(rangesBeforeChange);
myRanges.addAll(newChangedRanges);
myRanges.addAll(rangesAfterChange);
- myRanges = mergeRanges(myRanges);
-
for (Range range : myRanges) {
if (!range.hasHighlighter()) range.setHighlighter(createHighlighter(range));
}
@@ -410,49 +395,36 @@ public class LineStatusTracker {
});
}
}
- } catch (ProcessCanceledException ignore) {
- } catch (FilesTooBigForDiffException e1) {
+ }
+ catch (ProcessCanceledException ignore) {
+ }
+ catch (FilesTooBigForDiffException e1) {
installAnathema();
removeHighlightersFromMarkupModel();
}
}
}
- private List<Range> getNewChangedRanges() throws FilesTooBigForDiffException {
- List<String> lines = new DocumentWrapper(myDocument).getLines(myFirstChangedLine, myLastChangedLine);
- List<String> uLines = new DocumentWrapper(myUpToDateDocument)
- .getLines(myUpToDateFirstLine, myUpToDateLastLine);
- return new RangesBuilder(lines, uLines, myFirstChangedLine, myUpToDateFirstLine).getRanges();
+ private int getUpToDateLine1(@Nullable Range range, int line) {
+ return range == null ? line : line + range.getUOffset2() - range.getOffset2();
}
- private List<Range> mergeRanges(List<Range> ranges) {
- ArrayList<Range> result = new ArrayList<Range>();
- Iterator<Range> iterator = ranges.iterator();
- if (!iterator.hasNext()) return result;
- Range prev = iterator.next();
- while (iterator.hasNext()) {
- Range range = iterator.next();
- if (prev.canBeMergedWith(range)) {
- if (range.getHighlighter() != null) {
- range.getHighlighter().dispose();
- }
- if (prev.getHighlighter() != null) {
- prev.getHighlighter().dispose();
- }
- prev = prev.mergeWith(range);
- }
- else {
- result.add(prev);
- prev = range;
- }
- }
- result.add(prev);
- return result;
+ private int getUpToDateLine2(@Nullable Range range, int line, int totalLinesBefore, int totalLinesAfter) {
+ return range == null ? totalLinesAfter - totalLinesBefore + line : line + range.getUOffset1() - range.getOffset1();
+ }
+
+ private List<Range> getNewChangedRanges(int firstChangedLine, int lastChangedLine, int upToDateFirstLine, int upToDateLastLine)
+ throws FilesTooBigForDiffException {
+ List<String> lines = new DocumentWrapper(myDocument).getLines(firstChangedLine, lastChangedLine);
+ List<String> uLines = new DocumentWrapper(myUpToDateDocument).getLines(upToDateFirstLine, upToDateLastLine);
+ return new RangesBuilder(lines, uLines, firstChangedLine, upToDateFirstLine).getRanges();
}
- private void replaceRanges(List<Range> rangesInChange, List<Range> newRangesInChange) {
+ private void replaceRanges(@NotNull List<Range> rangesInChange, @NotNull List<Range> newRangesInChange) {
for (Range range : rangesInChange) {
- range.getHighlighter().dispose();
+ if (range.getHighlighter() != null) {
+ range.getHighlighter().dispose();
+ }
range.setHighlighter(null);
}
for (Range range : newRangesInChange) {
@@ -460,25 +432,33 @@ public class LineStatusTracker {
}
}
- private void shiftRanges(List<Range> rangesAfterChange, int shift) {
+ private void shiftRanges(@NotNull List<Range> rangesAfterChange, int shift) {
for (final Range aRangesAfterChange : rangesAfterChange) {
aRangesAfterChange.shift(shift);
}
}
-
- }
-
- private List<Range> getChangedRanges(int from, int to) {
- return getChangedRanges(myRanges, from, to);
}
- public static List<Range> getChangedRanges(List<Range> ranges, int from, int to) {
- ArrayList<Range> result = new ArrayList<Range>();
+ public static void sortRanges(@NotNull List<Range> ranges,
+ int firstChangedLine,
+ int lastChangedLine,
+ @NotNull List<Range> rangesBeforeChange,
+ @NotNull List<Range> changedRanges,
+ @NotNull List<Range> rangesAfterChange) {
for (Range range : ranges) {
- if (range.getOffset1() <= to && range.getOffset2() >= from) result.add(range);
-// if (range.getOffset1() > to) break;
+ int offset1 = range.getOffset1() - 1;
+ int offset2 = range.getOffset2();
+
+ if (offset2 < firstChangedLine) {
+ rangesBeforeChange.add(range);
+ }
+ else if (offset1 > lastChangedLine) {
+ rangesAfterChange.add(range);
+ }
+ else {
+ changedRanges.add(range);
+ }
}
- return result;
}
@Nullable
@@ -525,7 +505,7 @@ public class LineStatusTracker {
return getPrevRange(currentRange);
}
- for (ListIterator<Range> iterator = myRanges.listIterator(myRanges.size()); iterator.hasPrevious();) {
+ for (ListIterator<Range> iterator = myRanges.listIterator(myRanges.size()); iterator.hasPrevious(); ) {
final Range range = iterator.previous();
if (range.getOffset1() > line) {
continue;
@@ -536,24 +516,6 @@ public class LineStatusTracker {
}
}
- public static List<Range> getRangesBefore(List<Range> ranges, int line) {
- ArrayList<Range> result = new ArrayList<Range>();
-
- for (Range range : ranges) {
- if (range.getOffset2() < line) result.add(range);
- //if (range.getOffset2() > line) break;
- }
- return result;
- }
-
- public static List<Range> getRangesAfter(List<Range> ranges, int line) {
- ArrayList<Range> result = new ArrayList<Range>();
- for (Range range : ranges) {
- if (range.getOffset1() > line) result.add(range);
- }
- return result;
- }
-
@Nullable
public Range getRangeForLine(final int line) {
synchronized (myLock) {
@@ -573,25 +535,33 @@ public class LineStatusTracker {
myApplication.assertWriteAccessAllowed();
synchronized (myLock) {
- TextRange currentTextRange = getCurrentTextRange(range);
+ TextRange currentTextRange = getCurrentTextRangeWithMagic(range);
+ int offset1 = currentTextRange.getStartOffset();
+ int offset2 = Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength());
if (range.getType() == Range.INSERTED) {
- myDocument
- .replaceString(currentTextRange.getStartOffset(), Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength()), "");
+ myDocument.replaceString(offset1, offset2, "");
}
else if (range.getType() == Range.DELETED) {
- String upToDateContent = getUpToDateContent(range);
- myDocument.insertString(currentTextRange.getStartOffset(), upToDateContent);
+ String upToDateContent = getUpToDateContentWithMagic(range);
+ myDocument.insertString(offset1, upToDateContent);
}
else {
-
- String upToDateContent = getUpToDateContent(range);
- myDocument.replaceString(currentTextRange.getStartOffset(), Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength()),
- upToDateContent);
+ String upToDateContent = getUpToDateContentWithMagic(range);
+ myDocument.replaceString(offset1, offset2, upToDateContent);
}
}
}
+ public String getUpToDateContentWithMagic(Range range) {
+ synchronized (myLock) {
+ TextRange textRange = getUpToDateRangeWithMagic(range);
+ final int startOffset = textRange.getStartOffset();
+ final int endOffset = Math.min(textRange.getEndOffset() + 1, myUpToDateDocument.getTextLength());
+ return myUpToDateDocument.getCharsSequence().subSequence(startOffset, endOffset).toString();
+ }
+ }
+
public String getUpToDateContent(Range range) {
synchronized (myLock) {
TextRange textRange = getUpToDateRange(range);
@@ -605,25 +575,28 @@ public class LineStatusTracker {
return myProject;
}
- TextRange getCurrentTextRange(Range range) {
- return getRange(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument, false);
+ @NotNull
+ TextRange getCurrentTextRangeWithMagic(@NotNull Range range) {
+ return getRangeWithMagic(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument);
}
- TextRange getUpToDateRange(Range range) {
- return getRange(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument, false);
+ @NotNull
+ TextRange getUpToDateRangeWithMagic(@NotNull Range range) {
+ return getRangeWithMagic(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument);
}
- TextRange getCurrentTextRangeWithEndSymbol(Range range) {
- return getRange(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument, true);
+ @NotNull
+ TextRange getCurrentTextRange(@NotNull Range range) {
+ return getRange(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument);
}
- // a hack
- TextRange getUpToDateRangeWithEndSymbol(Range range) {
- return getRange(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument, true);
+ @NotNull
+ TextRange getUpToDateRange(@NotNull Range range) {
+ return getRange(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument);
}
- private static TextRange getRange(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document,
- final boolean keepEnd) {
+ @NotNull
+ private static TextRange getRangeWithMagic(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document) {
if (rangeType == emptyRangeCondition) {
int lineStartOffset;
if (offset1 == 0) {
@@ -634,23 +607,33 @@ public class LineStatusTracker {
}
//if (lineStartOffset > 0) lineStartOffset--;
return new TextRange(lineStartOffset, lineStartOffset);
-
}
else {
int startOffset = document.getLineStartOffset(offset1);
int endOffset = document.getLineEndOffset(offset2 - 1);
if (startOffset > 0) {
- -- startOffset;
- if (! keepEnd) {
- -- endOffset;
- }
+ --startOffset;
+ --endOffset;
}
return new TextRange(startOffset, endOffset);
}
}
- public static LineStatusTracker createOn(@Nullable VirtualFile virtualFile, final Document doc, final Project project) {
- final Document document = new DocumentImpl("",true);
+ @NotNull
+ private static TextRange getRange(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document) {
+ if (rangeType == emptyRangeCondition) {
+ int lineStartOffset = offset1 < document.getLineCount() ? document.getLineStartOffset(offset1) : document.getTextLength();
+ return new TextRange(lineStartOffset, lineStartOffset);
+ }
+ else {
+ int startOffset = document.getLineStartOffset(offset1);
+ int endOffset = document.getLineEndOffset(offset2 - 1);
+ return new TextRange(startOffset, endOffset);
+ }
+ }
+
+ public static LineStatusTracker createOn(@Nullable VirtualFile virtualFile, @NotNull final Document doc, final Project project) {
+ final Document document = new DocumentImpl("", true);
return new LineStatusTracker(doc, document, project, virtualFile);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java
index 6900d46c9f10..5727c62f4d14 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java
@@ -31,6 +31,10 @@ public class Range {
public static final byte INSERTED = 2;
public static final byte DELETED = 3;
+ // offset1/offset2 - line numbers
+ // (2,3) - modified 2nd line
+ // (2,2) - empty range between 1 and 2 lines
+ // index of first line is 0
private int myOffset1;
private int myOffset2;
private final int myUpToDateOffset1;
@@ -154,22 +158,4 @@ public class Range {
public RangeHighlighter getHighlighter() {
return myRangeHighlighter;
}
-
- public boolean contains(int offset1, int offset2) {
- return getOffset1() <= offset1 && getOffset2() >= offset2;
- }
-
- public boolean containsLine(int line) {
- if (myType == DELETED) return (myOffset1 - 1) <= line
- && (myOffset2) >= line;
- return myOffset1 <= line && myOffset2 >= line;
- }
-
- public boolean isAfter(int line) {
- if (myType == DELETED)
- return (getOffset1() - 1) > line;
- else
- return getOffset1() > line;
- }
-
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java
index e17f868ffad4..74f9e43d08ad 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.util.ArrayUtil;
import com.intellij.util.diff.Diff;
import com.intellij.util.diff.FilesTooBigForDiffException;
+import org.jetbrains.annotations.NotNull;
import java.util.LinkedList;
import java.util.List;
@@ -30,22 +31,20 @@ import java.util.List;
public class RangesBuilder {
private List<Range> myRanges;
- public RangesBuilder(Document current, Document upToDate) throws FilesTooBigForDiffException {
+ public RangesBuilder(@NotNull Document current, @NotNull Document upToDate) throws FilesTooBigForDiffException {
this(new DocumentWrapper(current).getLines(), new DocumentWrapper(upToDate).getLines(), 0, 0);
}
- public RangesBuilder(List<String> current, List<String> upToDate, int shift, int uShift) throws FilesTooBigForDiffException {
+ public RangesBuilder(@NotNull List<String> current, @NotNull List<String> upToDate, int shift, int uShift) throws FilesTooBigForDiffException {
myRanges = new LinkedList<Range>();
Diff.Change ch = Diff.buildChanges(ArrayUtil.toStringArray(upToDate), ArrayUtil.toStringArray(current));
-
while (ch != null) {
Range range = Range.createOn(ch, shift, uShift);
myRanges.add(range);
ch = ch.link;
}
-
}
public List<Range> getRanges() {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java
index 50622b27d0ce..c5dba0cab29c 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java
@@ -56,10 +56,10 @@ public class ShowLineStatusRangeDiffAction extends BaseLineStatusRangeAction {
public DiffContent[] getContents() {
return new DiffContent[]{
createDiffContent(myLineStatusTracker.getUpToDateDocument(),
- myLineStatusTracker.getUpToDateRangeWithEndSymbol(myRange),
+ myLineStatusTracker.getUpToDateRange(myRange),
null),
createDiffContent(myLineStatusTracker.getDocument(),
- myLineStatusTracker.getCurrentTextRangeWithEndSymbol(myRange),
+ myLineStatusTracker.getCurrentTextRange(myRange),
myLineStatusTracker.getVirtualFile())};
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java
index f8daa55b0e8f..a1fa2baeb1d2 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java
@@ -794,18 +794,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
}
result.add(new RefreshFileHistoryAction());
if (! myIsStaticAndEmbedded) {
- result.add(new ToggleAction("Show Details", "Display details panel", AllIcons.Actions.Preview) {
- @Override
- public boolean isSelected(AnActionEvent e) {
- return getConfiguration().SHOW_FILE_HISTORY_DETAILS;
- }
-
- @Override
- public void setSelected(AnActionEvent e, boolean state) {
- getConfiguration().SHOW_FILE_HISTORY_DETAILS = state;
- setupDetails();
- }
- });
+ result.add(new MyToggleAction());
}
if (!popup && supportsTree()) {
@@ -1119,7 +1108,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
}
- private class MyAnnotateAction extends AnAction {
+ private class MyAnnotateAction extends AnAction implements DumbAware {
public MyAnnotateAction() {
super(VcsBundle.message("annotate.action.name"), VcsBundle.message("annotate.action.description"),
AllIcons.Actions.Annotate);
@@ -1825,4 +1814,21 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
}
}
+ private class MyToggleAction extends ToggleAction implements DumbAware {
+
+ public MyToggleAction() {
+ super("Show Details", "Display details panel", AllIcons.Actions.Preview);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return getConfiguration().SHOW_FILE_HISTORY_DETAILS;
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ getConfiguration().SHOW_FILE_HISTORY_DETAILS = state;
+ setupDetails();
+ }
+ }
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java
index 7eda8accaa93..8be62f10953d 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java
@@ -25,6 +25,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.VcsActiveEnvironmentsProxy;
import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author yole
@@ -47,29 +49,43 @@ public class VcsEP extends AbstractExtensionPointBean {
public boolean crawlUpToCheckUnderVcs;
private AbstractVcs myVcs;
+ private final Object LOCK = new Object();
- public AbstractVcs getVcs(Project project) {
- if (myVcs == null) {
- try {
- final Class<? extends AbstractVcs> foundClass = findClass(vcsClass);
- final Class<?>[] interfaces = foundClass.getInterfaces();
- for (Class<?> anInterface : interfaces) {
- if (BaseComponent.class.isAssignableFrom(anInterface)) {
- myVcs = PeriodicalTasksCloser.getInstance().safeGetComponent(project, foundClass);
- myVcs = VcsActiveEnvironmentsProxy.proxyVcs(myVcs);
- return myVcs;
- }
- }
- myVcs = VcsActiveEnvironmentsProxy.proxyVcs((AbstractVcs)instantiate(vcsClass, project.getPicoContainer()));
+ @Nullable
+ public AbstractVcs getVcs(@NotNull Project project) {
+ synchronized (LOCK) {
+ if (myVcs != null) {
+ return myVcs;
+ }
+ }
+ AbstractVcs vcs = getInstance(project, vcsClass);
+ synchronized (LOCK) {
+ if (myVcs == null) {
+ myVcs = VcsActiveEnvironmentsProxy.proxyVcs(vcs);
}
- catch(Exception e) {
- LOG.error(e);
- return null;
+ return myVcs;
+ }
+ }
+
+ @Nullable
+ private AbstractVcs getInstance(@NotNull Project project, @NotNull String vcsClass) {
+ try {
+ final Class<? extends AbstractVcs> foundClass = findClass(vcsClass);
+ final Class<?>[] interfaces = foundClass.getInterfaces();
+ for (Class<?> anInterface : interfaces) {
+ if (BaseComponent.class.isAssignableFrom(anInterface)) {
+ return PeriodicalTasksCloser.getInstance().safeGetComponent(project, foundClass);
+ }
}
+ return instantiate(vcsClass, project.getPicoContainer());
+ }
+ catch(Exception e) {
+ LOG.error(e);
+ return null;
}
- return myVcs;
}
+ @NotNull
public VcsDescriptor createDescriptor() {
return new VcsDescriptor(administrativeAreaName, displayName, name, crawlUpToCheckUnderVcs);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java
index f357321d9a00..0a47656491df 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java
@@ -91,14 +91,23 @@ public class AllVcses implements AllVcsesI, Disposable {
if (vcs != null) {
return vcs;
}
- final VcsEP ep = myExtensions.get(name);
- if (ep != null) {
- final AbstractVcs vcs1 = ep.getVcs(myProject);
- LOG.assertTrue(vcs1 != null, name);
+ }
+
+ // unmodifiable map => no sync needed
+ final VcsEP ep = myExtensions.get(name);
+ if (ep == null) {
+ return null;
+ }
+
+ // VcsEP guarantees to always return the same vcs value
+ final AbstractVcs vcs1 = ep.getVcs(myProject);
+ LOG.assertTrue(vcs1 != null, name);
+
+ synchronized (myLock) {
+ if (!myVcses.containsKey(name)) {
addVcs(vcs1);
- return vcs1;
}
- return null;
+ return vcs1;
}
}
diff --git a/platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java b/platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java
index e61b229302f1..d3ed9a84de2c 100644
--- a/platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java
+++ b/platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java
@@ -35,16 +35,17 @@ public class AuthDialog extends DialogWrapper {
public AuthDialog(@NotNull Project project, @NotNull String title, @Nullable String description, @Nullable String login, @Nullable String password, boolean rememberByDefault) {
super(project, false);
setTitle(title);
- boolean rememberPassword = decideOnShowRememberPasswordOption(password, rememberByDefault);
+ Boolean rememberPassword = decideOnShowRememberPasswordOption(password, rememberByDefault);
authPanel = new AuthenticationPanel(description, login, password, rememberPassword);
init();
}
- private static boolean decideOnShowRememberPasswordOption(@Nullable String password, boolean rememberByDefault) {
+ @Nullable
+ private static Boolean decideOnShowRememberPasswordOption(@Nullable String password, boolean rememberByDefault) {
final PasswordSafeImpl passwordSafe = (PasswordSafeImpl)PasswordSafe.getInstance();
// if password saving is disabled, don't show the checkbox.
if (passwordSafe.getSettings().getProviderType().equals(PasswordSafeSettings.ProviderType.DO_NOT_STORE)) {
- return false;
+ return null;
}
// if password is prefilled, it is expected to continue remembering it.
if (!StringUtil.isEmptyOrSpaces(password)) {