add help page link

Signed-off-by: pengzhile <pengzhile@gmail.com>
pull/8/head
pengzhile 2020-11-26 21:18:06 +08:00
parent a7c926852c
commit 7f72608696
18 changed files with 267 additions and 164 deletions

View File

@ -4,7 +4,7 @@ plugins {
}
group 'io.zhile.research.intellij'
version '2.1.6'
version '2.1.7'
sourceCompatibility = 1.7
targetCompatibility = 1.7
@ -23,12 +23,14 @@ buildPlugin {
// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
version "2020.2.3"
version "2020.2.4"
type "IU"
}
patchPluginXml {
changeNotes """<pre>
Release v2.1.7
1. add help page link
Release v2.1.6
1. fix the pop-up of license window
Release v2.1.5

View File

@ -1,10 +1,8 @@
package io.zhile.research.intellij.ier.action;
import com.intellij.icons.AllIcons;
import com.intellij.notification.Notification;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
@ -12,34 +10,32 @@ import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowEP;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import io.zhile.research.intellij.ier.component.ResetTimer;
import io.zhile.research.intellij.ier.helper.Constants;
import io.zhile.research.intellij.ier.helper.CustomRepository;
import io.zhile.research.intellij.ier.helper.NotificationHelper;
import io.zhile.research.intellij.ier.helper.PluginHelper;
import io.zhile.research.intellij.ier.listener.AppActivationListener;
import io.zhile.research.intellij.ier.listener.AppEventListener;
import io.zhile.research.intellij.ier.tw.MainToolWindowFactory;
import io.zhile.research.intellij.ier.ui.dialog.MainDialog;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.WeakReference;
public class ResetAction extends AnAction implements DumbAware {
private static final DataKey<Notification> NOTIFICATION_KEY = DataKey.create("Notification");
static {
AppEventListener.getInstance().listen();
AppActivationListener.getInstance().listen();
CustomRepository.checkAndAdd(CustomRepository.DEFAULT_HOST);
}
public ResetAction() {
super(Constants.ACTION_NAME, "Reset my IDE eval information", AllIcons.General.Reset);
ResetTimer.start(new WeakReference<>(this));
CustomRepository.checkAndAdd(CustomRepository.DEFAULT_HOST);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
Notification notification = NOTIFICATION_KEY.getData(e.getDataContext());
if (null != notification) {
notification.expire();
}
NotificationHelper.checkAndExpire(e);
if (project == null) {
MainDialog mainDialog = new MainDialog(Constants.ACTION_NAME);

View File

@ -3,8 +3,9 @@ package io.zhile.research.intellij.ier.action;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.DumbAware;
import io.zhile.research.intellij.ier.helper.AppHelper;
import io.zhile.research.intellij.ier.helper.NotificationHelper;
import org.jetbrains.annotations.NotNull;
public class RestartAction extends AnAction implements DumbAware {
@ -14,11 +15,8 @@ public class RestartAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().restart();
}
});
NotificationHelper.checkAndExpire(e);
AppHelper.restart();
}
}

View File

@ -1,18 +1,15 @@
package io.zhile.research.intellij.ier.common;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.PropertiesComponentImpl;
public class PropertyRecord implements EvalRecord {
public static final PropertiesComponentImpl PROPS = (PropertiesComponentImpl) PropertiesComponent.getInstance();
private final String type = "PROPERTY";
private final String key;
private final String value;
public PropertyRecord(String key) {
this.key = key;
this.value = PROPS.getValue(key);
this.value = PropertiesComponent.getInstance().getValue(key);
}
public String getKey() {
@ -25,7 +22,7 @@ public class PropertyRecord implements EvalRecord {
@Override
public void reset() throws Exception {
PROPS.unsetValue(key);
PropertiesComponent.getInstance().unsetValue(key);
}
@Override

View File

@ -3,6 +3,8 @@ package io.zhile.research.intellij.ier.common;
import com.intellij.ide.Prefs;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.PropertiesComponentImpl;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.SystemInfo;
import io.zhile.research.intellij.ier.helper.Constants;
@ -63,7 +65,7 @@ public class Resetter {
}
}
Element state = PropertyRecord.PROPS.getState();
Element state = ((PropertiesComponentImpl) PropertiesComponent.getInstance()).getState();
if (state != null) {
Attribute attrName, attrValue;
for (Element element : state.getChildren()) {

View File

@ -1,96 +0,0 @@
package io.zhile.research.intellij.ier.component;
import com.intellij.ide.AppLifecycleListener;
import com.intellij.ide.Prefs;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.util.messages.MessageBusConnection;
import io.zhile.research.intellij.ier.action.ResetAction;
import io.zhile.research.intellij.ier.action.RestartAction;
import io.zhile.research.intellij.ier.common.Resetter;
import io.zhile.research.intellij.ier.helper.Constants;
import io.zhile.research.intellij.ier.helper.DateTime;
import io.zhile.research.intellij.ier.helper.NotificationHelper;
import io.zhile.research.intellij.ier.helper.PluginHelper;
import io.zhile.research.intellij.ier.listener.AppEventListener;
import java.lang.ref.WeakReference;
public class ResetTimer {
private static final long RESET_PERIOD = 2160000000L; // 25 days
private static final String RESET_KEY = Constants.PLUGIN_PREFS_PREFIX + "." + Constants.IDE_NAME_LOWER + "." + Constants.IDE_HASH;
private static MessageBusConnection connection;
public static long getLastResetTime() {
return Prefs.getLong(RESET_KEY, 0L);
}
public static void resetLastResetTime() {
Prefs.putLong(RESET_KEY, System.currentTimeMillis());
Resetter.syncPrefs();
}
public static String getLastResetTimeStr() {
long lastResetTime = getLastResetTime();
return lastResetTime > 0 ? DateTime.getStringFromTimestamp(lastResetTime) : "Not yet";
}
public synchronized static void start(final WeakReference<ResetAction> weakResetAction) {
if (connection != null) {
return;
}
ApplicationManager.getApplication().getMessageBus().connect().subscribe(AppLifecycleListener.TOPIC, new AppEventListener());
connection = ApplicationManager.getApplication().getMessageBus().connect();
connection.subscribe(ApplicationActivationListener.TOPIC, new ApplicationActivationListener() {
public void applicationActivated(IdeFrame ideFrame) {
if (System.currentTimeMillis() - getLastResetTime() <= RESET_PERIOD) {
return;
}
stop();
AnAction resetAction = weakResetAction.get();
if (resetAction == null) {
return;
}
AnAction action = resetAction;
NotificationType type = NotificationType.INFORMATION;
String message = "It has been a long time since the last reset!\nWould you like to reset it again?";
if (Resetter.isAutoReset()) {
action = new RestartAction();
type = NotificationType.WARNING;
}
Notification notification = NotificationHelper.NOTIFICATION_GROUP.createNotification(PluginHelper.getPluginName(), null, message, type);
notification.addAction(action);
notification.notify(null);
}
public void applicationDeactivated(IdeFrame ideFrame) {
applicationActivated(ideFrame);
}
public void delayedApplicationDeactivated(IdeFrame ideFrame) {
}
});
}
public synchronized static void stop() {
if (connection == null) {
return;
}
connection.disconnect();
connection = null;
}
}

View File

@ -0,0 +1,20 @@
package io.zhile.research.intellij.ier.helper;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Disposer;
import io.zhile.research.intellij.ier.listener.AppActivationListener;
import io.zhile.research.intellij.ier.listener.AppEventListener;
public class AppHelper {
public static void restart() {
Disposer.dispose(AppActivationListener.getInstance());
Disposer.dispose(AppEventListener.getInstance());
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().restart();
}
});
}
}

View File

@ -11,4 +11,6 @@ public class Constants {
public static final String IDE_NAME_LOWER = IDE_NAME.toLowerCase();
public static final String IDE_HASH = Integer.toHexString(FileUtil.pathHashCode(PathManager.getHomePath()));
public static final String PLUGIN_PREFS_PREFIX = "Ide-Eval-Reset";
public static final String RESET_ACTION_ID = "io.zhile.research.intellij.ier.action.ResetAction";
public static final String RESTART_ACTION_ID = "io.zhile.research.intellij.ier.action.RestartAction";
}

View File

@ -1,22 +1,40 @@
package io.zhile.research.intellij.ier.helper;
import com.intellij.icons.AllIcons;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationDisplayType;
import com.intellij.notification.NotificationGroup;
import com.intellij.notification.NotificationType;
import com.intellij.notification.*;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.Nullable;
public class NotificationHelper {
public static final NotificationGroup NOTIFICATION_GROUP = new NotificationGroup(Constants.PLUGIN_ID_STR, NotificationDisplayType.BALLOON, true, null, AllIcons.General.Reset);
public static void checkAndExpire(AnActionEvent e) {
DataKey<Notification> notificationKey = DataKey.create("Notification");
Notification notification = notificationKey.getData(e.getDataContext());
if (null != notification) {
notification.expire();
}
}
public static Notification show(@Nullable Project project, String title, String subtitle, String content, NotificationType type) {
return show(project, title, subtitle, content, type, new AnAction[0]);
}
public static Notification show(@Nullable Project project, String title, String subtitle, String content, NotificationType type, AnAction action) {
return show(project, title, subtitle, content, type, new AnAction[]{action});
}
public static Notification show(@Nullable Project project, String title, String subtitle, String content, NotificationType type, AnAction[] actions) {
if (title == null) {
title = PluginHelper.getPluginName();
}
Notification notification = NOTIFICATION_GROUP.createNotification(title, subtitle, content, type);
NotificationGroup group = new NotificationGroup(Constants.PLUGIN_ID_STR, NotificationDisplayType.BALLOON, true, null, AllIcons.General.Reset);
Notification notification = group.createNotification(title, subtitle, content, type, NotificationListener.URL_OPENING_LISTENER);
for (AnAction action : actions) {
notification.addAction(action);
}
notification.notify(project);
return notification;

View File

@ -5,21 +5,25 @@ import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.extensions.PluginId;
public class PluginHelper {
private static final IdeaPluginDescriptor PLUGIN_DESCRIPTOR = PluginManager.getPlugin(getPluginId());
public static PluginId getPluginId() {
return PluginId.getId(Constants.PLUGIN_ID_STR);
}
public static IdeaPluginDescriptor getPluginDescriptor() {
return PLUGIN_DESCRIPTOR;
return PluginManager.getPlugin(getPluginId());
}
public static String getPluginName() {
return PLUGIN_DESCRIPTOR == null ? "UNKNOWN" : PLUGIN_DESCRIPTOR.getName();
IdeaPluginDescriptor pluginDescriptor = getPluginDescriptor();
return pluginDescriptor == null ? "UNKNOWN" : pluginDescriptor.getName();
}
public static String getPluginVersion() {
return PLUGIN_DESCRIPTOR == null ? "UNKNOWN" : PLUGIN_DESCRIPTOR.getVersion();
IdeaPluginDescriptor pluginDescriptor = getPluginDescriptor();
return pluginDescriptor == null ? "UNKNOWN" : pluginDescriptor.getVersion();
}
public static boolean myself(IdeaPluginDescriptor pluginDescriptor) {
return Constants.PLUGIN_ID_STR.equals(pluginDescriptor.getPluginId().getIdString());
}
}

View File

@ -0,0 +1,28 @@
package io.zhile.research.intellij.ier.helper;
import com.intellij.ide.Prefs;
import io.zhile.research.intellij.ier.common.Resetter;
public class ResetTimeHelper {
public static final long RESET_PERIOD = 2160000000L; // 25 days
private static final String RESET_KEY = Constants.PLUGIN_PREFS_PREFIX + "." + Constants.IDE_NAME_LOWER + "." + Constants.IDE_HASH;
public static long getLastResetTime() {
return Prefs.getLong(RESET_KEY, 0L);
}
public static void resetLastResetTime() {
Prefs.putLong(RESET_KEY, System.currentTimeMillis());
Resetter.syncPrefs();
}
public static boolean overResetPeriod() {
return System.currentTimeMillis() - ResetTimeHelper.getLastResetTime() > RESET_PERIOD;
}
public static String getLastResetTimeStr() {
long lastResetTime = getLastResetTime();
return lastResetTime > 0 ? DateTime.getStringFromTimestamp(lastResetTime) : "Not yet";
}
}

View File

@ -0,0 +1,78 @@
package io.zhile.research.intellij.ier.listener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.util.messages.MessageBusConnection;
import io.zhile.research.intellij.ier.common.Resetter;
import io.zhile.research.intellij.ier.helper.Constants;
import io.zhile.research.intellij.ier.helper.NotificationHelper;
import io.zhile.research.intellij.ier.helper.ResetTimeHelper;
import org.jetbrains.annotations.NotNull;
public class AppActivationListener implements ApplicationActivationListener, Disposable {
private static AppActivationListener instance = new AppActivationListener();
private static MessageBusConnection connection;
protected AppActivationListener() {
}
public static AppActivationListener getInstance() {
return instance;
}
public synchronized void listen() {
if (connection != null) {
return;
}
connection = ApplicationManager.getApplication().getMessageBus().connect();
connection.subscribe(ApplicationActivationListener.TOPIC, this);
}
public synchronized void stop() {
if (connection == null) {
return;
}
connection.disconnect();
connection = null;
}
public void applicationActivated(@NotNull IdeFrame ideFrame) {
if (!ResetTimeHelper.overResetPeriod()) {
return;
}
stop();
AnAction action = ActionManager.getInstance().getAction(Constants.RESET_ACTION_ID);
NotificationType type = NotificationType.INFORMATION;
String message = "It has been a long time since the last reset!\nWould you like to reset it again?";
if (Resetter.isAutoReset()) {
action = ActionManager.getInstance().getAction(Constants.RESTART_ACTION_ID);
type = NotificationType.WARNING;
}
NotificationHelper.show(null, null, null, message, type, action);
}
public void applicationDeactivated(@NotNull IdeFrame ideFrame) {
applicationActivated(ideFrame);
}
public void delayedApplicationDeactivated(@NotNull IdeFrame ideFrame) {
}
@Override
public void dispose() {
stop();
instance = null;
}
}

View File

@ -1,51 +1,78 @@
package io.zhile.research.intellij.ier.listener;
import com.intellij.ide.AppLifecycleListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.util.messages.MessageBusConnection;
import io.zhile.research.intellij.ier.common.Resetter;
import io.zhile.research.intellij.ier.component.ResetTimer;
import io.zhile.research.intellij.ier.helper.ResetTimeHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AppEventListener implements AppLifecycleListener {
private static boolean enabled = true;
public class AppEventListener implements AppLifecycleListener, Disposable {
private static AppEventListener instance = new AppEventListener();
private static MessageBusConnection connection;
public synchronized static void disable() {
enabled = false;
protected AppEventListener() {
}
public static AppEventListener getInstance() {
return instance;
}
public synchronized void listen() {
if (connection != null) {
return;
}
connection = ApplicationManager.getApplication().getMessageBus().connect();
connection.subscribe(AppLifecycleListener.TOPIC, this);
}
public synchronized void stop() {
if (connection == null) {
return;
}
connection.disconnect();
connection = null;
}
public void appFrameCreated(String[] commandLineArgs, @NotNull Ref<Boolean> willOpenProject) {
}
@Override
public void appStarting(@Nullable Project projectFromCommandLine) {
}
@Override
public void projectFrameClosed() {
}
@Override
public void projectOpenFailed() {
}
@Override
public void welcomeScreenDisplayed() {
}
@Override
public void appClosing() {
if (!enabled || !Resetter.isAutoReset()) {
if (!Resetter.isAutoReset()) {
return;
}
Resetter.reset(Resetter.getEvalRecords());
ResetTimer.resetLastResetTime();
ResetTimeHelper.resetLastResetTime();
}
@Override
public void dispose() {
stop();
instance = null;
}
}

View File

@ -3,20 +3,32 @@ package io.zhile.research.intellij.ier.listener;
import com.intellij.ide.plugins.DynamicPluginListener;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.util.Disposer;
import io.zhile.research.intellij.ier.helper.Constants;
import io.zhile.research.intellij.ier.helper.NotificationHelper;
import io.zhile.research.intellij.ier.helper.PluginHelper;
import io.zhile.research.intellij.ier.tw.MainToolWindowFactory;
import org.jetbrains.annotations.NotNull;
public class PluginListener implements DynamicPluginListener {
@Override
public void pluginLoaded(@NotNull IdeaPluginDescriptor pluginDescriptor) {
ActionManager.getInstance().getAction("io.zhile.research.intellij.ier.action.ResetAction");
if (!PluginHelper.myself(pluginDescriptor)) {
return;
}
NotificationHelper.showInfo(null, "Plugin installed successfully! Now enjoy it~");
ActionManager.getInstance().getAction(Constants.RESET_ACTION_ID);
NotificationHelper.showInfo(null, "Plugin installed successfully! Now enjoy it~<br>For more information, visit <a href='https://zhile.io/2020/11/19/jetbrains-eval-reset.html'>here</a>.");
}
@Override
public void beforePluginUnload(@NotNull IdeaPluginDescriptor pluginDescriptor, boolean isUpdate) {
if (!PluginHelper.myself(pluginDescriptor)) {
return;
}
Disposer.dispose(AppActivationListener.getInstance());
Disposer.dispose(AppEventListener.getInstance());
MainToolWindowFactory.unregisterAll();
}
}

View File

@ -17,6 +17,7 @@ public class MainToolWindowFactory implements ToolWindowFactory, DumbAware {
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
MainForm mainForm = new MainForm(null);
Content content = ContentFactory.SERVICE.getInstance().createContent(mainForm.getContent(), "", true);
content.setDisposer(mainForm);
toolWindow.getContentManager().addContent(content);
}

View File

@ -12,7 +12,6 @@ public class MainDialog extends DialogWrapper {
setTitle(title);
}
@Override
protected JComponent createCenterPanel() {
MainForm mainForm = new MainForm(this);

View File

@ -1,21 +1,23 @@
package io.zhile.research.intellij.ier.ui.form;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import io.zhile.research.intellij.ier.common.EvalRecord;
import io.zhile.research.intellij.ier.common.Resetter;
import io.zhile.research.intellij.ier.component.ResetTimer;
import io.zhile.research.intellij.ier.helper.AppHelper;
import io.zhile.research.intellij.ier.helper.PluginHelper;
import io.zhile.research.intellij.ier.listener.AppEventListener;
import io.zhile.research.intellij.ier.helper.ResetTimeHelper;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class MainForm {
public class MainForm implements Disposable {
private JPanel rootPanel;
private JButton btnReset;
private JList lstMain;
@ -31,6 +33,9 @@ public class MainForm {
public MainForm(DialogWrapper dialogWrapper) {
this.dialogWrapper = dialogWrapper;
if (dialogWrapper != null) {
Disposer.register(dialogWrapper.getDisposable(), this);
}
}
public JPanel getContent() {
@ -77,7 +82,7 @@ public class MainForm {
}
private void reloadLastResetTime() {
lblLastResetTime.setText(ResetTimer.getLastResetTimeStr());
lblLastResetTime.setText(ResetTimeHelper.getLastResetTimeStr());
}
private void reloadRecordItems() {
@ -95,24 +100,29 @@ public class MainForm {
}
Resetter.reset(Resetter.getEvalRecords());
ResetTimer.resetLastResetTime();
ResetTimeHelper.resetLastResetTime();
listModel.clear();
if (null != dialogWrapper) {
dialogWrapper.close(0);
}
AppEventListener.disable();
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().restart();
}
});
AppHelper.restart();
}
private static void boldFont(Component component) {
Font font = component.getFont();
component.setFont(font.deriveFont(font.getStyle() | Font.BOLD));
}
@Override
public void dispose() {
for (AbstractButton button : new AbstractButton[]{chkResetAuto, btnReload, btnReset}) {
for (ActionListener listener : button.getActionListeners()) {
button.removeActionListener(listener);
}
}
rootPanel.removeAll();
}
}

View File

@ -5,7 +5,10 @@
<description><![CDATA[
I can reset your IDE eval information.<br>
<em>Click "Help" menu and select "Eval Reset"</em>
<em>Click "Help" menu and select "Eval Reset"</em><br><br>
<p>
<a href="https://zhile.io/2020/11/19/jetbrains-eval-reset.html" target="_blank">Need Help?</a>
</p>
]]></description>
<depends>com.intellij.modules.ultimate</depends>
@ -16,6 +19,8 @@
<add-to-group group-id="HelpMenu" anchor="last"/>
<add-to-group group-id="WelcomeScreen.Documentation" anchor="last"/>
</action>
<action class="io.zhile.research.intellij.ier.action.RestartAction"
id="io.zhile.research.intellij.ier.action.RestartAction"/>
</actions>
<applicationListeners>