mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-60323 Support editing subversion commit messages
also from file history tab
This commit is contained in:
@@ -23,6 +23,7 @@ import com.intellij.openapi.vcs.changes.ChangeRequestChain;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.File;
|
||||
@@ -60,6 +61,6 @@ public interface VcsDataKeys {
|
||||
DataKey<Object> LABEL_AFTER = DataKey.create("LABEL_AFTER");
|
||||
DataKey<String> PRESET_COMMIT_MESSAGE = DataKey.create("PRESET_COMMIT_MESSAGE");
|
||||
DataKey<CommitMessageI> COMMIT_MESSAGE_CONTROL = DataKey.create("COMMIT_MESSAGE_CONTROL");
|
||||
DataKey<Runnable> REMOTE_HISTORY_CHANGED_LISTENER = DataKey.create("REMOTE_HISTORY_CHANGED_LISTENER");
|
||||
DataKey<Consumer<String>> REMOTE_HISTORY_CHANGED_LISTENER = DataKey.create("REMOTE_HISTORY_CHANGED_LISTENER");
|
||||
DataKey<RepositoryLocation> REMOTE_HISTORY_LOCATION = DataKey.create("REMOTE_HISTORY_LOCATION");
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.history;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsKey;
|
||||
import com.intellij.openapi.vcs.annotate.VcsAnnotation;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.SLRUMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -58,6 +59,15 @@ public class VcsHistoryCache {
|
||||
}
|
||||
}
|
||||
|
||||
public void editCached(final FilePath filePath, final VcsKey vcsKey, final Consumer<List<VcsFileRevision>> consumer) {
|
||||
synchronized (myLock) {
|
||||
final CachedHistory cachedHistory = myHistoryCache.get(new HistoryCacheBaseKey(filePath, vcsKey));
|
||||
if (cachedHistory != null) {
|
||||
consumer.consume(cachedHistory.getRevisions());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <C extends Serializable, T extends VcsAbstractHistorySession> T getFull(final FilePath filePath, final VcsKey vcsKey,
|
||||
@NotNull final VcsCacheableHistorySessionFactory<C, T> factory) {
|
||||
|
||||
+3
-3
@@ -69,7 +69,7 @@ public class CommittedChangesPanel extends JPanel implements TypeSafeDataProvide
|
||||
private final List<Runnable> myShouldBeCalledOnDispose;
|
||||
private volatile boolean myDisposed;
|
||||
private volatile boolean myInLoad;
|
||||
private Runnable myIfNotCachedReloader;
|
||||
private Consumer<String> myIfNotCachedReloader;
|
||||
|
||||
public CommittedChangesPanel(Project project, final CommittedChangesProvider provider, final ChangeBrowserSettings settings,
|
||||
@Nullable final RepositoryLocation location, @Nullable ActionGroup extraActions) {
|
||||
@@ -109,9 +109,9 @@ public class CommittedChangesPanel extends JPanel implements TypeSafeDataProvide
|
||||
final AnAction anAction = ActionManager.getInstance().getAction("CommittedChanges.Refresh");
|
||||
anAction.registerCustomShortcutSet(CommonShortcuts.getRerun(), this);
|
||||
myBrowser.addFilter(myFilterComponent);
|
||||
myIfNotCachedReloader = myLocation == null ? null : new Runnable() {
|
||||
myIfNotCachedReloader = myLocation == null ? null : new Consumer<String>() {
|
||||
@Override
|
||||
public void run() {
|
||||
public void consume(String s) {
|
||||
refreshChanges(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1208,8 +1208,14 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
|
||||
}
|
||||
else if (VcsDataKeys.VCS_FILE_REVISIONS.is(dataId)) {
|
||||
return getSelectedRevisions();
|
||||
}
|
||||
else if (VcsDataKeys.CHANGES.is(dataId)) {
|
||||
} else if (VcsDataKeys.REMOTE_HISTORY_CHANGED_LISTENER.is(dataId)) {
|
||||
return new Consumer<String>() {
|
||||
@Override
|
||||
public void consume(String s) {
|
||||
myDualView.rebuild();
|
||||
}
|
||||
};
|
||||
} else if (VcsDataKeys.CHANGES.is(dataId)) {
|
||||
return getChanges();
|
||||
}
|
||||
else if (VcsDataKeys.VCS_VIRTUAL_FILE.is(dataId)) {
|
||||
|
||||
@@ -39,8 +39,7 @@
|
||||
<action id="PropertiesDiff" class="org.jetbrains.idea.svn.actions.ShowPropertiesDiffAction" popup="true" icon="SvnIcons.PropertiesDiff">
|
||||
<add-to-group group-id="RepositoryChangesBrowserToolbar" anchor="last"/>
|
||||
</action>
|
||||
<action id="EditCommitMessage" class="org.jetbrains.idea.svn.history.SvnEditCommitMessageAction" popup="true" icon="AllIcons.Actions.Edit"
|
||||
text="Edit Revision Comment" description="Edit revision comment. Previous message is rewritten.">
|
||||
<action id="EditCommitMessage" class="org.jetbrains.idea.svn.history.SvnEditCommitMessageAction" popup="true">
|
||||
<add-to-group group-id="CommittedChangesToolbar" anchor="last"/>
|
||||
</action>
|
||||
|
||||
|
||||
+35
-16
@@ -33,6 +33,7 @@ import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.ChangeList;
|
||||
import com.intellij.openapi.vcs.changes.committed.CommittedChangesCache;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
@@ -59,12 +60,17 @@ public class SvnEditCommitMessageAction extends AnAction {
|
||||
final SvnChangeList svnList = (SvnChangeList) lists[0];
|
||||
Project project = PlatformDataKeys.PROJECT.getData(dc);
|
||||
project = project == null ? ProjectManager.getInstance().getDefaultProject() : project;
|
||||
final Consumer<String> listener = VcsDataKeys.REMOTE_HISTORY_CHANGED_LISTENER.getData(dc);
|
||||
|
||||
askAndEditRevision(svnList.getNumber(), svnList.getComment(), svnList.getLocation(), project, listener, false);
|
||||
}
|
||||
|
||||
public static void askAndEditRevision(final long number, final String oldComment, final SvnRepositoryLocation location, Project project, Consumer<String> listener, final boolean fromVersionControl) {
|
||||
final String edited = Messages.showMultilineInputDialog(project, "Attention! Previous message will be lost!\n\nNew revision comment:",
|
||||
"Edit Revision # " + svnList.getNumber() + " Comment", svnList.getComment(), Messages.getInformationIcon(), null);
|
||||
if (edited == null || edited.trim().equals(svnList.getComment().trim())) return;
|
||||
final Runnable listener = VcsDataKeys.REMOTE_HISTORY_CHANGED_LISTENER.getData(dc);
|
||||
ProgressManager.getInstance().run(new EditMessageTask(project, edited, svnList, listener));
|
||||
"Edit Revision # " + number + " Comment", oldComment,
|
||||
Messages.getInformationIcon(), null);
|
||||
if (edited == null || edited.trim().equals(oldComment.trim())) return;
|
||||
ProgressManager.getInstance().run(new EditMessageTask(project, edited, location, number, listener, fromVersionControl));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,25 +105,34 @@ public class SvnEditCommitMessageAction extends AnAction {
|
||||
return cr instanceof MarkerVcsContentRevision && SvnVcs.getKey().equals(((MarkerVcsContentRevision) cr).getVcsKey());
|
||||
}*/
|
||||
|
||||
private static class EditMessageTask extends Task.Backgroundable {
|
||||
static class EditMessageTask extends Task.Backgroundable {
|
||||
private final String myNewMessage;
|
||||
private final SvnChangeList myChangeList;
|
||||
private final Runnable myListener;
|
||||
private final SvnRepositoryLocation myLocation;
|
||||
private final long myNumber;
|
||||
private final Consumer<String> myListener;
|
||||
private final boolean myFromVersionControl;
|
||||
private VcsException myException;
|
||||
private final SvnVcs myVcs;
|
||||
|
||||
private EditMessageTask(@Nullable Project project, final String newMessage, final SvnChangeList changeList, Runnable listener) {
|
||||
EditMessageTask(@Nullable Project project,
|
||||
final String newMessage,
|
||||
final SvnRepositoryLocation location,
|
||||
final long number,
|
||||
Consumer<String> listener,
|
||||
boolean fromVersionControl) {
|
||||
super(project, "Edit Revision Comment");
|
||||
myNewMessage = newMessage;
|
||||
myChangeList = changeList;
|
||||
myLocation = location;
|
||||
myNumber = number;
|
||||
myListener = listener;
|
||||
myFromVersionControl = fromVersionControl;
|
||||
myVcs = SvnVcs.getInstance(myProject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
final SVNWCClient client = myVcs.createWCClient();
|
||||
final String url = myChangeList.getLocation().getURL();
|
||||
final String url = myLocation.getURL();
|
||||
final SVNURL root;
|
||||
try {
|
||||
root = SvnUtil.getRepositoryRoot(myVcs, SVNURL.parseURIEncoded(url));
|
||||
@@ -125,7 +140,7 @@ public class SvnEditCommitMessageAction extends AnAction {
|
||||
myException = new VcsException("Can not determine repository root for URL: " + url);
|
||||
return;
|
||||
}
|
||||
client.doSetRevisionProperty(root, SVNRevision.create(myChangeList.getNumber()), "svn:log",
|
||||
client.doSetRevisionProperty(root, SVNRevision.create(myNumber), "svn:log",
|
||||
SVNPropertyValue.create(myNewMessage), false, null);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
@@ -139,14 +154,18 @@ public class SvnEditCommitMessageAction extends AnAction {
|
||||
AbstractVcsHelper.getInstance(myProject).showError(myException, myTitle);
|
||||
} else {
|
||||
if (myListener != null) {
|
||||
myListener.run();
|
||||
myListener.consume(myNewMessage);
|
||||
}
|
||||
if (! myProject.isDefault()) {
|
||||
CommittedChangesCache.getInstance(myProject).commitMessageChanged(myVcs,
|
||||
myChangeList.getLocation(), myChangeList.getNumber(), myNewMessage);
|
||||
CommittedChangesCache.getInstance(myProject).commitMessageChanged(myVcs, myLocation, myNumber, myNewMessage);
|
||||
}
|
||||
if (myFromVersionControl) {
|
||||
VcsBalloonProblemNotifier.showOverVersionControlView(myProject, "Revision #" + myNumber + " comment " +
|
||||
"changed to:\n'" + myNewMessage + "'", MessageType.INFO);
|
||||
} else {
|
||||
VcsBalloonProblemNotifier.showOverChangesView(myProject, "Revision #" + myNumber + " comment " +
|
||||
"changed to:\n'" + myNewMessage + "'", MessageType.INFO);
|
||||
}
|
||||
VcsBalloonProblemNotifier.showOverChangesView(myProject, "Revision #" + myChangeList.getNumber() + " comment " +
|
||||
"changed to:\n'" + myNewMessage + "'", MessageType.INFO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.FilePathImpl;
|
||||
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
|
||||
import com.intellij.openapi.vcs.VcsDataKeys;
|
||||
import com.intellij.openapi.vcs.VcsKey;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 10/25/12
|
||||
* Time: 10:22 AM
|
||||
*/
|
||||
public class SvnEditCommitMessageFromFileHistoryAction extends AnAction {
|
||||
public SvnEditCommitMessageFromFileHistoryAction() {
|
||||
super("Edit Revision Comment", "Edit revision comment. Previous message is rewritten.", AllIcons.Actions.Edit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final Project project = e.getData(PlatformDataKeys.PROJECT);
|
||||
if (project == null) return;
|
||||
final VcsKey vcsKey = e.getData(VcsDataKeys.VCS);
|
||||
if (vcsKey == null || ! SvnVcs.getKey().equals(vcsKey)) return;
|
||||
final VcsFileRevision revision = e.getData(VcsDataKeys.VCS_FILE_REVISION);
|
||||
final VirtualFile revisionVirtualFile = e.getData(VcsDataKeys.VCS_VIRTUAL_FILE);
|
||||
if (revision == null || revisionVirtualFile == null) return;
|
||||
final SvnFileRevision svnFileRevision = (SvnFileRevision) revision;
|
||||
final Consumer<String> listener = VcsDataKeys.REMOTE_HISTORY_CHANGED_LISTENER.getData(e.getDataContext());
|
||||
SvnEditCommitMessageAction.askAndEditRevision(svnFileRevision.getRevision().getNumber(), svnFileRevision.getCommitMessage(),
|
||||
(SvnRepositoryLocation) svnFileRevision.getChangedRepositoryPath(), project, new Consumer<String>() {
|
||||
@Override
|
||||
public void consume(final String newMessage) {
|
||||
svnFileRevision.setCommitMessage(newMessage);
|
||||
if (listener != null) {
|
||||
listener.consume(newMessage);
|
||||
}
|
||||
ProjectLevelVcsManager.getInstance(project).getVcsHistoryCache().editCached(new FilePathImpl(revisionVirtualFile), vcsKey,
|
||||
new Consumer<List<VcsFileRevision>>() {
|
||||
@Override
|
||||
public void consume(List<VcsFileRevision> revisions) {
|
||||
for (VcsFileRevision fileRevision : revisions) {
|
||||
if (! (fileRevision instanceof SvnFileRevision)) continue;
|
||||
if (((SvnFileRevision) fileRevision).getRevision().getNumber() == svnFileRevision.getRevision().getNumber()) {
|
||||
((SvnFileRevision) fileRevision).setCommitMessage(newMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
final VcsKey vcsKey = e.getData(VcsDataKeys.VCS);
|
||||
final boolean isSvn = SvnVcs.getKey().equals(vcsKey);
|
||||
e.getPresentation().setVisible(isSvn);
|
||||
final VcsFileRevision revision = e.getData(VcsDataKeys.VCS_FILE_REVISION);
|
||||
e.getPresentation().setEnabled(isSvn && revision != null);
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ public class SvnFileRevision implements VcsFileRevision {
|
||||
private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.SvnFileRevision");
|
||||
|
||||
private final Date myDate;
|
||||
private final String myCommitMessage;
|
||||
private String myCommitMessage;
|
||||
private final String myAuthor;
|
||||
private final VcsRevisionNumber myRevisionNumber;
|
||||
private final SvnVcs myVCS;
|
||||
@@ -178,6 +178,10 @@ public class SvnFileRevision implements VcsFileRevision {
|
||||
return myCopyFromPath;
|
||||
}
|
||||
|
||||
public void setCommitMessage(String message) {
|
||||
myCommitMessage = message;
|
||||
}
|
||||
|
||||
private class ContentLoader implements Runnable {
|
||||
private final SVNRevision myRevision;
|
||||
private final SVNRevision myPegRevision;
|
||||
|
||||
@@ -474,7 +474,7 @@ public class SvnHistoryProvider
|
||||
}
|
||||
|
||||
public AnAction[] getAdditionalActions(final Runnable refresher) {
|
||||
return new AnAction[]{ ShowAllAffectedGenericAction.getInstance(), new MergeSourceDetailsAction()};
|
||||
return new AnAction[]{ ShowAllAffectedGenericAction.getInstance(), new MergeSourceDetailsAction(), new SvnEditCommitMessageFromFileHistoryAction()};
|
||||
}
|
||||
|
||||
public boolean isDateOmittable() {
|
||||
|
||||
Reference in New Issue
Block a user