Enable shortcuts for git/hg "commit and push" commit dialog actions

This commit is contained in:
Konstantin Kolosovsky
2018-01-30 01:13:44 +03:00
parent 15b64ad205
commit 2970bc5813
13 changed files with 166 additions and 105 deletions
@@ -1,18 +1,4 @@
/*
* 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.ui;
import org.jetbrains.annotations.NotNull;
@@ -23,6 +9,8 @@ import javax.swing.*;
* @author Konstantin Bulenkov
*/
public interface OptionAction extends Action {
String AN_ACTION = "AnAction";
@NotNull
Action[] getOptions();
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ui.components;
import com.intellij.openapi.util.Weighted;
@@ -24,6 +10,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import static com.intellij.openapi.util.text.StringUtil.notNullize;
import static com.intellij.util.containers.UtilKt.stream;
import static java.util.stream.Collectors.toSet;
@@ -146,7 +133,7 @@ public class JBOptionButton extends JButton implements Weighted {
@NotNull
private OptionInfo getMenuInfo(@NotNull Action each) {
final String text = (String)each.getValue(Action.NAME);
final String text = notNullize((String)each.getValue(Action.NAME));
int mnemonic = -1;
int mnemonicIndex = -1;
StringBuilder plainText = new StringBuilder();
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ui.components
@@ -11,6 +9,7 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.ui.DialogWrapperButtonLayout.Companion.EXTRA_WIDTH_KEY
import com.intellij.openapi.ui.OptionAction
import com.intellij.openapi.ui.popup.JBPopupAdapter
import com.intellij.openapi.ui.popup.LightweightWindowEvent
import com.intellij.openapi.ui.popup.ListPopup
@@ -276,13 +275,15 @@ open class BasicOptionButtonUI : OptionButtonUI() {
protected open fun createActionGroup(): ActionGroup = DefaultActionGroup().apply {
optionButton.options
?.map(this@BasicOptionButtonUI::ActionDelegate)
?.map(this@BasicOptionButtonUI::createAnAction)
?.forEachIndexed { index, it ->
if (index > 0) addSeparator()
add(it)
}
}
protected open fun createAnAction(action: Action) = action.getValue(OptionAction.AN_ACTION) as? AnAction ?: ActionDelegate(action)
private fun updateExtraWidth() {
optionButton.putClientProperty(EXTRA_WIDTH_KEY, if (!isSimpleButton) arrowButton.preferredSize.width else null)
}
@@ -279,6 +279,8 @@
icon="AllIcons.General.MessageHistory"/>
</group>
<group id="Vcs.CommitExecutor.Actions"/>
<group id="VcsToobarActions">
<reference ref="Vcs.UpdateProject"/>
<reference ref="CheckinProject"/>
@@ -1,23 +1,10 @@
/*
* Copyright 2000-2009 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vcs.changes;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author max
@@ -26,6 +13,15 @@ public interface CommitExecutor {
@Nls
String getActionText();
default boolean useDefaultAction() {
return true;
}
@Nullable
default String getId() {
return null;
}
@NotNull
CommitSession createCommitSession();
}
@@ -0,0 +1,40 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vcs.changes.actions
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.vcs.CheckinProjectPanel
import com.intellij.openapi.vcs.changes.CommitExecutor
import com.intellij.openapi.vcs.changes.CommitExecutorBase
import com.intellij.openapi.vcs.changes.ui.CommitChangeListDialog
import com.intellij.openapi.vcs.ui.Refreshable
abstract class BaseCommitExecutorAction : DumbAwareAction() {
init {
isEnabledInModalContext = true
}
override fun update(e: AnActionEvent) {
val dialog = getCommitDialog(e)
val executor = getCommitExecutor(dialog)
e.presentation.isVisible = dialog != null && executor != null
e.presentation.isEnabled = dialog != null && executor != null && isEnabled(dialog, executor)
}
override fun actionPerformed(e: AnActionEvent) {
val dialog = getCommitDialog(e)!!
val executor = getCommitExecutor(dialog)!!
dialog.execute(executor)
}
protected abstract val executorId: String
protected fun getCommitDialog(e: AnActionEvent) = Refreshable.PANEL_KEY.getData(e.dataContext) as? CommitChangeListDialog
protected fun getCommitExecutor(dialog: CommitChangeListDialog?) = dialog?.executors?.find { it.id == executorId }
protected fun isEnabled(dialog: CheckinProjectPanel, executor: CommitExecutor) =
dialog.hasDiffs() || (executor is CommitExecutorBase && !executor.areChangesRequired())
}
@@ -1,24 +1,14 @@
/*
* Copyright 2000-2017 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vcs.changes.ui;
import com.intellij.diff.util.DiffPlaces;
import com.intellij.diff.util.DiffUserDataKeysEx;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
@@ -46,7 +36,6 @@ import com.intellij.ui.JBColor;
import com.intellij.ui.SplitterWithSecondHideable;
import com.intellij.util.Alarm;
import com.intellij.util.containers.ContainerUtil;
import java.util.HashSet;
import com.intellij.util.ui.AbstractLayoutManager;
import com.intellij.util.ui.GridBag;
import com.intellij.util.ui.JBDimension;
@@ -60,15 +49,14 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.Collection;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.intellij.openapi.vcs.VcsBundle.message;
import static com.intellij.util.ArrayUtil.isEmpty;
import static com.intellij.util.ArrayUtil.toObjectArray;
import static com.intellij.util.ObjectUtils.notNull;
import static com.intellij.util.containers.ContainerUtil.filter;
import static com.intellij.util.containers.ContainerUtil.isEmpty;
import static com.intellij.util.containers.ContainerUtil.map;
import static com.intellij.util.containers.ContainerUtil.map2SetNotNull;
@@ -99,6 +87,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
@Nullable private final CommitResultHandler myResultHandler;
@NotNull private final Set<AbstractVcs> myAffectedVcses;
@NotNull private final List<CommitExecutor> myExecutors;
@NotNull private final List<CheckinHandler> myHandlers = newArrayList();
private final boolean myAllOfDefaultChangeListChangesIncluded;
@@ -286,6 +275,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
myVcsConfiguration = notNull(VcsConfiguration.getInstance(myProject));
myShowVcsCommit = showVcsCommit;
myAffectedVcses = affectedVcses;
myExecutors = executors;
myForceCommitInVcs = forceCommitInVcs;
myIsAlien = isAlien;
myResultHandler = customResultHandler;
@@ -355,7 +345,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
setTitle(myShowVcsCommit ? TITLE : trimEllipsis(executors.get(0).getActionText()));
myCommitAction = myShowVcsCommit ? new CommitAction(getCommitActionName()) : null;
myExecutorActions = map(executors, CommitExecutorAction::new);
myExecutorActions = createExecutorActions(executors);
if (myCommitAction != null) {
myCommitAction.setOptions(myExecutorActions);
}
@@ -454,6 +444,23 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
}
}
@NotNull
private List<CommitExecutorAction> createExecutorActions(@NotNull List<CommitExecutor> executors) {
List<CommitExecutorAction> result = newArrayList();
if (myShowVcsCommit && UISettings.getShadowInstance().getAllowMergeButtons()) {
ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction("Vcs.CommitExecutor.Actions");
result.addAll(map(group.getChildren(null), CommitExecutorAction::new));
result.addAll(map(filter(executors, CommitExecutor::useDefaultAction), CommitExecutorAction::new));
}
else {
result.addAll(map(executors, CommitExecutorAction::new));
}
return result;
}
@Nullable
private static String getHelpId(@NotNull List<CommitExecutor> executors) {
for (CommitExecutor executor : executors) {
@@ -597,7 +604,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
});
}
private void execute(@NotNull CommitExecutor commitExecutor) {
public void execute(@NotNull CommitExecutor commitExecutor) {
CommitSession session = commitExecutor.createCommitSession();
if (session == CommitSession.VCS_COMMIT) {
executeDefaultCommitSession(commitExecutor);
@@ -880,6 +887,11 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
return myShowVcsCommit ? myAffectedVcses : emptySet();
}
@NotNull
public List<CommitExecutor> getExecutors() {
return myExecutors;
}
@NotNull
@Override
public Collection<VirtualFile> getRoots() {
@@ -1026,7 +1038,12 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
}
private class CommitExecutorAction extends AbstractAction {
@NotNull private final CommitExecutor myCommitExecutor;
@Nullable private final CommitExecutor myCommitExecutor;
public CommitExecutorAction(@NotNull AnAction anAction) {
putValue(OptionAction.AN_ACTION, anAction);
myCommitExecutor = null;
}
public CommitExecutorAction(@NotNull CommitExecutor commitExecutor) {
super(commitExecutor.getActionText());
@@ -1035,12 +1052,16 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
@Override
public void actionPerformed(ActionEvent e) {
execute(myCommitExecutor);
if (myCommitExecutor != null) {
execute(myCommitExecutor);
}
}
public void updateEnabled(boolean hasDiffs) {
setEnabled(
hasDiffs || myCommitExecutor instanceof CommitExecutorBase && !((CommitExecutorBase)myCommitExecutor).areChangesRequired());
if (myCommitExecutor != null) {
setEnabled(
hasDiffs || myCommitExecutor instanceof CommitExecutorBase && !((CommitExecutorBase)myCommitExecutor).areChangesRequired());
}
}
}
+3
View File
@@ -116,6 +116,9 @@
description="Change commit message" />
<action id="Git.Interactive.Rebase" class="git4idea.rebase.GitInteractiveRebaseAction" text="Interactively Rebase from Here..."
description="Show the dialog for interactive rebase which allows to squash, fixup, reorder, remove and reword commits" />
<action id="Git.Commit.And.Push.Executor" class="git4idea.actions.GitCommitAndPushExecutorAction" text="Commit and &amp;Push...">
<add-to-group group-id="Vcs.CommitExecutor.Actions"/>
</action>
<group id="Git.Log.ContextMenu">
<separator/>
@@ -0,0 +1,11 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.actions
import com.intellij.openapi.vcs.changes.actions.BaseCommitExecutorAction
import git4idea.checkin.GitCommitAndPushExecutor
class GitCommitAndPushExecutorAction : BaseCommitExecutorAction() {
override val executorId = GitCommitAndPushExecutor.ID
}
@@ -1,29 +1,18 @@
/*
* Copyright 2000-2009 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.checkin;
import com.intellij.openapi.vcs.changes.CommitExecutor;
import com.intellij.openapi.vcs.changes.CommitSession;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
public class GitCommitAndPushExecutor implements CommitExecutor {
public static final String ID = "Git.Commit.And.Push.Executor";
@NotNull private final GitCheckinEnvironment myCheckinEnvironment;
public GitCommitAndPushExecutor(@NotNull GitCheckinEnvironment checkinEnvironment) {
@@ -35,6 +24,17 @@ public class GitCommitAndPushExecutor implements CommitExecutor {
return "Commit and &Push...";
}
@Override
public boolean useDefaultAction() {
return false;
}
@Nullable
@Override
public String getId() {
return ID;
}
@NotNull
public CommitSession createCommitSession() {
myCheckinEnvironment.setNextCommitIsPushed(true);
+3
View File
@@ -155,6 +155,9 @@
<reference id="ChangesView.ApplyPatch"/>
</group>
<action id="Hg.Commit.And.Push.Executor" class="org.zmlx.hg4idea.action.HgCommitAndPushExecutorAction" text="Commit and &amp;Push...">
<add-to-group group-id="Vcs.CommitExecutor.Actions"/>
</action>
</actions>
<resource-bundle>org.zmlx.hg4idea.HgVcsMessages</resource-bundle>
@@ -0,0 +1,9 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.zmlx.hg4idea.action
import com.intellij.openapi.vcs.changes.actions.BaseCommitExecutorAction
import org.zmlx.hg4idea.provider.commit.HgCommitAndPushExecutor
class HgCommitAndPushExecutorAction : BaseCommitExecutorAction() {
override val executorId = HgCommitAndPushExecutor.ID
}
@@ -1,29 +1,18 @@
/*
* Copyright 2000-2011 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.zmlx.hg4idea.provider.commit;
import com.intellij.openapi.vcs.changes.CommitExecutor;
import com.intellij.openapi.vcs.changes.CommitSession;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Kirill Likhodedov
*/
public class HgCommitAndPushExecutor implements CommitExecutor {
public static final String ID = "Hg.Commit.And.Push.Executor";
private final HgCheckinEnvironment myCheckinEnvironment;
public HgCommitAndPushExecutor(HgCheckinEnvironment checkinEnvironment) {
@@ -35,6 +24,17 @@ public class HgCommitAndPushExecutor implements CommitExecutor {
return "Commit and &Push...";
}
@Override
public boolean useDefaultAction() {
return false;
}
@Nullable
@Override
public String getId() {
return ID;
}
@NotNull
public CommitSession createCommitSession() {
myCheckinEnvironment.setNextCommitIsPushed();