diff --git a/annotations/com/intellij/notification/annotations.xml b/annotations/com/intellij/notification/annotations.xml new file mode 100644 index 00000000000..fc3783fb7af --- /dev/null +++ b/annotations/com/intellij/notification/annotations.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/idea/src/org/jetbrains/jet/plugin/configuration/ConfigureKotlinInProjectUtils.java b/idea/src/org/jetbrains/jet/plugin/configuration/ConfigureKotlinInProjectUtils.java index 58939541286..de01b77ecad 100644 --- a/idea/src/org/jetbrains/jet/plugin/configuration/ConfigureKotlinInProjectUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/configuration/ConfigureKotlinInProjectUtils.java @@ -18,27 +18,24 @@ package org.jetbrains.jet.plugin.configuration; import com.google.common.collect.Lists; import com.google.common.collect.Sets; -import com.intellij.notification.*; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.search.FileTypeIndex; -import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.plugin.JetFileType; -import javax.swing.event.HyperlinkEvent; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; public class ConfigureKotlinInProjectUtils { - private static final NotificationGroup CONFIGURE_KOTLIN_STICKY_BALLOON_GROUP = new NotificationGroup("Configure Kotlin: balloon", NotificationDisplayType.STICKY_BALLOON, true); - public static boolean isProjectConfigured(@NotNull Project project) { Collection modules = getModulesWithKotlinFiles(project); for (Module module : modules) { @@ -89,52 +86,8 @@ public class ConfigureKotlinInProjectUtils { showConfigureKotlinNotification(project); } - private static void showConfigureKotlinNotification(@NotNull final Project project) { - CONFIGURE_KOTLIN_STICKY_BALLOON_GROUP. - createNotification( - "Configure Kotlin", - getNotificationString(project), - NotificationType.WARNING, - new NotificationListener() { - @Override - public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { - if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { - KotlinProjectConfigurator configurator = getConfiguratorByName(event.getDescription()); - if (configurator == null) { - throw new AssertionError("Missed action: " + event.getDescription()); - } - configurator.configure(project); - notification.expire(); - } - } - } - ).notify(project); - } - - private static String getNotificationString(Project project) { - StringBuilder builder = new StringBuilder("Configure "); - - Collection modules = getModulesWithKotlinFiles(project); - final boolean isOnlyOneModule = modules.size() == 1; - if (isOnlyOneModule) { - builder.append("'").append(modules.iterator().next().getName()).append("' module"); - } - else { - builder.append("modules"); - } - - builder.append(" in '").append(project.getName()).append("' project"); - builder.append("
"); - - String links = StringUtil.join(getApplicableConfigurators(project), new Function() { - @Override - public String fun(KotlinProjectConfigurator configurator) { - return getLink(configurator, isOnlyOneModule); - } - }, "
"); - builder.append(links); - - return builder.toString(); + private static void showConfigureKotlinNotification(@NotNull Project project) { + ConfigureKotlinNotificationManager.instance$.notify(project); } @NotNull @@ -181,12 +134,18 @@ public class ConfigureKotlinInProjectUtils { } return result; } + @NotNull - public static String getLink(@NotNull KotlinProjectConfigurator configurator, boolean isOnlyOneModule) { - return StringUtil.join("as Kotlin (", - configurator.getPresentableText(), - isOnlyOneModule ? ") module" : ") modules", - ""); + public static Collection getNonConfiguredModules(@NotNull Project project) { + Set modules = Sets.newHashSet(); + for (KotlinProjectConfigurator configurator : getApplicableConfigurators(project)) { + for (Module module : getModulesWithKotlinFiles(project)) { + if (!configurator.isConfigured(module)) { + modules.add(module); + } + } + } + return modules; } private ConfigureKotlinInProjectUtils() { diff --git a/idea/src/org/jetbrains/jet/plugin/configuration/ConfigureKotlinNotificationManager.kt b/idea/src/org/jetbrains/jet/plugin/configuration/ConfigureKotlinNotificationManager.kt new file mode 100644 index 00000000000..32193af104b --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/configuration/ConfigureKotlinNotificationManager.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2013 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.jet.plugin.configuration + +import com.intellij.openapi.project.Project +import org.jetbrains.jet.plugin.configuration.ui.ConfigureKotlinNotification +import com.intellij.notification.NotificationsManager + +object ConfigureKotlinNotificationManager { + fun notify(project: Project) { + val notificationsManager = NotificationsManager.getNotificationsManager() + if (notificationsManager == null) { + return + } + + val notificationString = ConfigureKotlinNotification.getNotificationString(project) + + var isNotificationExists = false + + val notifications = notificationsManager.getNotificationsOfType(javaClass(), project) + for (oldNotification in notifications) { + if (oldNotification.getNotificationText() == notificationString) { + isNotificationExists = true + } + else { + oldNotification.expire() + } + } + if (!isNotificationExists) { + ConfigureKotlinNotification(project, notificationString).showNotification() + } + } +} + diff --git a/idea/src/org/jetbrains/jet/plugin/configuration/ui/ConfigureKotlinNotification.java b/idea/src/org/jetbrains/jet/plugin/configuration/ui/ConfigureKotlinNotification.java new file mode 100644 index 00000000000..af09a1809c6 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/configuration/ui/ConfigureKotlinNotification.java @@ -0,0 +1,105 @@ +/* + * Copyright 2010-2013 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.jet.plugin.configuration.ui; + +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationListener; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.configuration.ConfigureKotlinInProjectUtils; +import org.jetbrains.jet.plugin.configuration.KotlinProjectConfigurator; + +import javax.swing.event.HyperlinkEvent; +import java.util.Collection; + +public class ConfigureKotlinNotification extends Notification { + private static final String GROUP_ID = "Configure Kotlin: balloon"; + private static final String TITLE = "Configure Kotlin"; + + @NotNull private final Project project; + @NotNull private final String notificationText; + + public ConfigureKotlinNotification( + @NotNull final Project project, + @NotNull String notificationText + ) { + super(GROUP_ID, TITLE, notificationText, NotificationType.WARNING, new NotificationListener() { + @Override + public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { + if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + KotlinProjectConfigurator configurator = ConfigureKotlinInProjectUtils.getConfiguratorByName(event.getDescription()); + if (configurator == null) { + throw new AssertionError("Missed action: " + event.getDescription()); + } + configurator.configure(project); + notification.expire(); + } + } + }); + + this.project = project; + this.notificationText = notificationText; + } + + public void showNotification() { + super.notify(project); + } + + @NotNull + public String getNotificationText() { + return notificationText; + } + + @NotNull + public static String getNotificationString(Project project) { + StringBuilder builder = new StringBuilder("Configure "); + + Collection modules = ConfigureKotlinInProjectUtils.getNonConfiguredModules(project); + final boolean isOnlyOneModule = modules.size() == 1; + if (isOnlyOneModule) { + builder.append("'").append(modules.iterator().next().getName()).append("' module"); + } + else { + builder.append("modules"); + } + + builder.append(" in '").append(project.getName()).append("' project"); + builder.append("
"); + + String links = StringUtil.join(ConfigureKotlinInProjectUtils.getApplicableConfigurators(project), new Function() { + @Override + public String fun(KotlinProjectConfigurator configurator) { + return getLink(configurator, isOnlyOneModule); + } + }, "
"); + builder.append(links); + + return builder.toString(); + } + + @NotNull + private static String getLink(@NotNull KotlinProjectConfigurator configurator, boolean isOnlyOneModule) { + return StringUtil.join("as Kotlin (", + configurator.getPresentableText(), + isOnlyOneModule ? ") module" : ") modules", + ""); + } +}