diff --git a/base/src/com/google/idea/blaze/base/dependencies/ExternalFileProjectManagementHelper.java b/base/src/com/google/idea/blaze/base/dependencies/ExternalFileProjectManagementHelper.java index b1c59d66df4..0272dc992b2 100644 --- a/base/src/com/google/idea/blaze/base/dependencies/ExternalFileProjectManagementHelper.java +++ b/base/src/com/google/idea/blaze/base/dependencies/ExternalFileProjectManagementHelper.java @@ -28,6 +28,7 @@ import com.google.idea.blaze.base.projectview.ProjectViewSet; import com.google.idea.blaze.base.qsync.QuerySyncManager; import com.google.idea.blaze.base.qsync.QuerySyncProject; +import com.google.idea.blaze.base.qsync.action.AddToProjectAction; import com.google.idea.blaze.base.scope.BlazeContext; import com.google.idea.blaze.base.settings.Blaze; import com.google.idea.blaze.base.settings.BlazeImportSettings; @@ -54,7 +55,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.EditorNotificationPanel; import com.intellij.ui.EditorNotifications; -import com.intellij.ui.HyperlinkLabel; import java.io.File; import java.nio.file.Path; import java.util.HashSet; @@ -224,10 +224,10 @@ private EditorNotificationPanel createNotificationPanelForQuerySync(VirtualFile return createPanel( virtualFile, - p -> { - HyperlinkLabel unused = - p.createActionLabel("Add file to project", "Blaze.AddToQuerySyncProjectView"); - }); + p -> + p.createActionLabel( + "Add file to project", + () -> AddToProjectAction.Performer.create(project, virtualFile, p).perform())); } private EditorNotificationPanel createPanel( diff --git a/base/src/com/google/idea/blaze/base/qsync/action/AddToProjectAction.java b/base/src/com/google/idea/blaze/base/qsync/action/AddToProjectAction.java index 46c782de096..839257c89dc 100644 --- a/base/src/com/google/idea/blaze/base/qsync/action/AddToProjectAction.java +++ b/base/src/com/google/idea/blaze/base/qsync/action/AddToProjectAction.java @@ -32,6 +32,7 @@ import com.google.idea.blaze.base.qsync.QuerySyncManager; import com.google.idea.blaze.base.qsync.QuerySyncManager.TaskOrigin; import com.google.idea.blaze.base.qsync.QuerySyncProject; +import com.google.idea.blaze.base.qsync.action.BuildDependenciesHelper.PopupPosititioner; import com.google.idea.blaze.exception.BuildException; import com.intellij.notification.NotificationGroupManager; import com.intellij.notification.NotificationType; @@ -51,9 +52,14 @@ import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.EditorNotificationPanel; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.popup.list.ListPopupImpl; +import java.awt.Point; import java.nio.file.Path; import java.util.Optional; import java.util.function.Consumer; +import javax.annotation.Nullable; import org.jetbrains.annotations.NotNull; /** Query sync specific action to add a new directory to the project view. */ @@ -76,12 +82,12 @@ protected QuerySyncStatus querySyncSupport() { @Override protected void actionPerformedInBlazeProject(Project project, AnActionEvent e) { - new Performer(project, e).perform(); + Performer.create(project, e).perform(); } @Override protected void updateForBlazeProject(Project project, AnActionEvent e) { - Performer performer = new Performer(project, e); + Performer performer = Performer.create(project, e); Presentation presentation = e.getPresentation(); if (!performer.canPerform()) { presentation.setEnabledAndVisible(false); @@ -90,22 +96,69 @@ protected void updateForBlazeProject(Project project, AnActionEvent e) { presentation.setEnabled(true); } - static class Performer { + /** Class that handles identifying the package to add and requesting a project update. */ + public static class Performer { private final Project project; - private final AnActionEvent event; private final QuerySyncManager qsManager; private final Path workspacePathToAdd; + @Nullable private final AnActionEvent event; - Performer(Project project, AnActionEvent event) { + private final PopupPosititioner popupPosititioner; + + public Performer( + Project project, + Path workspacePathToAdd, + @Nullable AnActionEvent event, + PopupPosititioner popupPosititioner) { this.project = project; + this.workspacePathToAdd = workspacePathToAdd; this.event = event; + this.popupPosititioner = popupPosititioner; qsManager = QuerySyncManager.getInstance(project); - workspacePathToAdd = - getWorkspaceFile(WorkspaceRoot.fromProject(project).path(), event).orElse(null); + } + + public static Performer create(Project project, AnActionEvent event) { + return new Performer( + project, + getWorkspaceFile(WorkspaceRoot.fromProject(project).path(), event).orElse(null), + event, + popup -> popup.showInBestPositionFor(event.getDataContext())); + } + + /** + * Places the package selection popup under the editor notification, on the right side of the + * window. + * + *
For the positioning logic, see {@link
+ * com.intellij.openapi.roots.ui.configuration.SdkPopupImpl#showUnderneathToTheRightOf}
+ */
+ public static Performer create(
+ Project project, VirtualFile virtualFile, EditorNotificationPanel panel) {
+ return new Performer(
+ project,
+ getWorkspaceFile(WorkspaceRoot.fromProject(project).path(), virtualFile).orElse(null),
+ null,
+ popup -> {
+ if (popup instanceof ListPopupImpl) {
+ int width = (int) ((ListPopupImpl) popup).getList().getPreferredSize().getWidth();
+ popup.show(
+ new RelativePoint(panel, new Point(panel.getWidth() - width, panel.getHeight())));
+ } else {
+ popup.showUnderneathOf(panel);
+ }
+ });
}
private static Optional