blob: 048b0f16268e214bc4ae91965e5ae873812ad69f [file] [log] [blame]
/*
* Copyright 2016 The Bazel Authors. All rights reserved.
*
* 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.google.idea.common.actionhelper;
import com.google.common.collect.Iterables;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.vfs.VirtualFile;
import java.util.Collection;
import javax.annotation.Nullable;
/** Helps setting the presentation enabled/visible/text states. */
public class ActionPresentationHelper {
private final AnActionEvent event;
private boolean enabled = true;
private boolean visible = true;
private boolean disableWithoutSubject;
private boolean hideInContextMenuIfDisabled;
private boolean hasSubject;
private String text;
private String subjectText;
private boolean useTextMnemonic;
private String description;
/** Converts a subject to a string */
@FunctionalInterface
public interface SubjectToString<T> {
String subjectToString(T subject);
}
private ActionPresentationHelper(AnActionEvent event) {
this.event = event;
}
public static ActionPresentationHelper of(AnActionEvent event) {
return new ActionPresentationHelper(event);
}
/** Disables the action if the condition is true. */
public ActionPresentationHelper disableIf(boolean disableCondition) {
this.enabled = this.enabled && !disableCondition;
return this;
}
/** Hides the action if the condition is true. If the action is hidden, it is also disabled. */
public ActionPresentationHelper hideIf(boolean hideCondition) {
this.visible = this.visible && !hideCondition;
return this;
}
public ActionPresentationHelper hideInContextMenuIfDisabled() {
this.hideInContextMenuIfDisabled = true;
return this;
}
/** Disables the action if no subject has been provided. */
public ActionPresentationHelper disableWithoutSubject() {
this.disableWithoutSubject = true;
return this;
}
/** Sets the text of the presentation. */
public ActionPresentationHelper setText(String text) {
this.text = text;
return this;
}
/** Use & or _ in the presentation text as a mnemonic shortcut. */
public ActionPresentationHelper useTextMnemonic() {
this.useTextMnemonic = true;
return this;
}
/** Sets the description of the presentation. */
public ActionPresentationHelper setDescription(String description) {
this.description = description;
return this;
}
/**
* Sets the text depending on the subject.
*
* @param noSubjectText Text to set if there is no subject, or if the action is disabled.
* @param subjectText Text to set if there is a subject. If %s exists in the subject text,
* String.format is used with the quoted file name.
* @param file The subject. May be null.
*/
public ActionPresentationHelper setTextWithSubject(
String noSubjectText, String subjectText, @Nullable VirtualFile file) {
return setTextWithSubject(
noSubjectText, subjectText, file, ActionPresentationHelper::quoteFileName);
}
/**
* Sets the text depending on the subject.
*
* @param noSubjectText Text to set if there is no subject, or if the action is disabled.
* @param subjectText Text to set if there is a subject. If %s exists in the subject text,
* String.format is used with the subject passed through subjectToString
* @param subject The subject. May be null.
* @param subjectToString Method used to convert the subject to a string.
*/
public <T> ActionPresentationHelper setTextWithSubject(
String noSubjectText,
String subjectText,
@Nullable T subject,
SubjectToString<T> subjectToString) {
this.text = noSubjectText;
if (subject != null) {
this.subjectText =
subjectText.contains("%s")
? String.format(subjectText, subjectToString.subjectToString(subject))
: subjectText;
this.hasSubject = true;
}
return this;
}
/**
* Sets the text depending on the subjects.
*
* @param noSubjectText Text to set if there is no subject, or if the action is disabled.
* @param singleSubjectText Text to set if there is a single subject. If %s exists in the subject
* text, String.format is used with the quoted single file name.
* @param multipleSubjectText Text to use if there are multiple subjects.
*/
public ActionPresentationHelper setTextWithSubjects(
String noSubjectText,
String singleSubjectText,
String multipleSubjectText,
Collection<VirtualFile> files) {
return setTextWithSubjects(
noSubjectText,
singleSubjectText,
multipleSubjectText,
files,
ActionPresentationHelper::quoteFileName);
}
/**
* Sets the text depending on the subjects.
*
* @param noSubjectText Text to set if there is no subject, or if the action is disabled.
* @param singleSubjectText Text to set if there is a single subject. If %s exists in the subject
* text, String.format is used with the subject passed through subjectToString.
* @param multipleSubjectText Text to use if there are multiple subjects.
*/
public <T> ActionPresentationHelper setTextWithSubjects(
String noSubjectText,
String singleSubjectText,
String multipleSubjectText,
Collection<T> subjects,
SubjectToString<T> subjectToString) {
if (subjects.size() > 1) {
this.text = noSubjectText;
this.subjectText = multipleSubjectText;
this.hasSubject = true;
return this;
} else {
T subject = !subjects.isEmpty() ? Iterables.getOnlyElement(subjects) : null;
return setTextWithSubject(noSubjectText, singleSubjectText, subject, subjectToString);
}
}
private static String quoteFileName(VirtualFile file) {
return "\"" + file.getName() + "\"";
}
public void commit() {
boolean enabled = this.enabled && this.visible;
if (disableWithoutSubject) {
enabled = enabled && hasSubject;
}
boolean visible = this.visible;
if (hideInContextMenuIfDisabled && !enabled && ActionPlaces.isPopupPlace(event.getPlace())) {
visible = false;
}
Presentation presentation = event.getPresentation();
presentation.setEnabled(enabled);
presentation.setVisible(visible);
String text = enabled && hasSubject ? subjectText : this.text;
if (text != null) {
presentation.setText(text, useTextMnemonic);
}
if (description != null) {
presentation.setDescription(description);
}
}
}