From 8384979b86c14db8cfc1fc3173f68fc88b41c942 Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Thu, 21 Feb 2019 16:26:28 +0300 Subject: [PATCH 01/16] EXA-598, EXA-600: move developers into InternalErrorReportConfigurable --- .../com/intellij/diagnostic/Developer.java | 12 ++++++ .../intellij/diagnostic/IdeErrorsDialog.java | 35 +++++++++++---- .../InternalErrorReportConfigurable.kt | 43 +++++++++++++++++++ .../src/META-INF/PlatformExtensions.xml | 2 + 4 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt diff --git a/platform/platform-impl/src/com/intellij/diagnostic/Developer.java b/platform/platform-impl/src/com/intellij/diagnostic/Developer.java index 8764754a47b5..f3e42fad8082 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/Developer.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/Developer.java @@ -1,14 +1,26 @@ // 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.diagnostic; +import com.intellij.util.xmlb.annotations.Attribute; +import com.intellij.util.xmlb.annotations.Tag; import org.jetbrains.annotations.Nullable; +@Tag("developer") public class Developer { public static final Developer NULL = new Developer(-1, ""); + @Attribute("id") private final int myId; + + @Attribute("name") private final String myName; + @SuppressWarnings("unused") // need for xml serialization + private Developer() { + myId = 0; + myName = ""; + } + public Developer(int id, String name) { myId = id; myName = name; diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 38154ea2957c..fb8341824ca9 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -30,7 +30,6 @@ import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; @@ -72,7 +71,6 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private static final String STACKTRACE_ATTACHMENT = "stacktrace.txt"; private static final String ACCEPTED_NOTICES_KEY = "exception.accepted.notices"; private static final String ACCEPTED_NOTICES_SEPARATOR = ":"; - private static List ourDevelopersList = Collections.emptyList(); private final MessagePool myMessagePool; private final Project myProject; @@ -121,8 +119,9 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } private void loadDevelopersList() { - if (!ourDevelopersList.isEmpty()) { - myAssigneeCombo.setModel(new CollectionComboBoxModel<>(ourDevelopersList)); + InternalErrorReportConfigurable internalConfigurable = InternalErrorReportConfigurable.getInstance(); + if (internalConfigurable.isDevelopersListValid()) { + myAssigneeCombo.setModel(new CollectionComboBoxModel<>(internalConfigurable.getDevelopersList())); } else { new Task.Backgroundable(null, "Loading Developers List", true) { @@ -130,15 +129,21 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene public void run(@NotNull ProgressIndicator indicator) { try { List developers = ITNProxy.fetchDevelopers(indicator); - //noinspection AssignmentToStaticFieldFromInstanceMethod - ourDevelopersList = developers; UIUtil.invokeLaterIfNeeded(() -> { + internalConfigurable.setDevelopersList(developers); if (isShowing()) { myAssigneeCombo.setModel(new CollectionComboBoxModel<>(developers)); } }); } - catch (UnknownHostException e) { LOG.debug(e); } + catch (UnknownHostException e) { + LOG.debug(e); + UIUtil.invokeLaterIfNeeded(() -> { + if (isShowing()) { + myAssigneeCombo.setModel(new CollectionComboBoxModel<>(internalConfigurable.getDevelopersList())); + } + }); + } catch (IOException e) { LOG.warn(e); } } }.queue(); @@ -551,8 +556,20 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene myAssigneeCombo.setSelectedIndex(-1); } else { - Condition lookup = d -> Objects.equals(assignee, d.getId()); - myAssigneeCombo.setSelectedIndex(ContainerUtil.indexOf(ourDevelopersList, lookup)); + int assigneeIndex = -1; + for (int i = 0; i < myAssigneeCombo.getItemCount(); i++) { + if (Objects.equals(assignee, myAssigneeCombo.getItemAt(i).getId())) { + assigneeIndex = i; + break; + } + } + + if (assigneeIndex != -1) { + myAssigneeCombo.setSelectedIndex(assigneeIndex); + } + else { + cluster.first.setAssigneeId(null); + } } } else { diff --git a/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt b/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt new file mode 100644 index 000000000000..11a5987ebfea --- /dev/null +++ b/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt @@ -0,0 +1,43 @@ +// Copyright 2000-2019 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.diagnostic + +import com.intellij.openapi.components.PersistentStateComponent +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.components.State +import com.intellij.openapi.components.Storage + +@State(name = "InternalErrorReportConfigurable", storages = [(Storage(value = "internalReportError.xml"))]) +internal class InternalErrorReportConfigurable : PersistentStateComponent { + private var myState: State = State() + + override fun getState(): State = myState + + override fun loadState(state: State) { + myState = state + } + + fun getDevelopersList(): List { + return myState.developersList.toList() + } + + fun setDevelopersList(developersList: List) { + myState = State(developersList.toList(), System.currentTimeMillis()) + } + + fun isDevelopersListValid(): Boolean { + val developersListObsolete = System.currentTimeMillis() - myState.developersUpdateTimestamp >= DEVELOPERS_OBSOLESCENCE_MILLIS + return !developersListObsolete && myState.developersList.isNotEmpty() + } + + private companion object { + private const val DEVELOPERS_OBSOLESCENCE_MILLIS = 24L * 60 * 60 * 1000 // 24 hours + + @JvmStatic + fun getInstance(): InternalErrorReportConfigurable = ServiceManager.getService(InternalErrorReportConfigurable::class.java) + } + + internal data class State( + var developersList: List = emptyList(), + var developersUpdateTimestamp: Long = 0 + ) +} diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 353c6deca761..14b88e69afce 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -82,6 +82,8 @@ + Date: Thu, 21 Feb 2019 16:47:27 +0300 Subject: [PATCH 02/16] EXA-586: enable internal mode in IdeErrorDialog if EA plugin is installed --- .../src/com/intellij/diagnostic/IdeErrorsDialog.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index fb8341824ca9..5d9715e315f9 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -71,6 +71,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private static final String STACKTRACE_ATTACHMENT = "stacktrace.txt"; private static final String ACCEPTED_NOTICES_KEY = "exception.accepted.notices"; private static final String ACCEPTED_NOTICES_SEPARATOR = ":"; + private static final String EA_PLUGIN_ID = "com.intellij.sisyphus"; private final MessagePool myMessagePool; private final Project myProject; @@ -97,7 +98,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene super(project, true); myMessagePool = messagePool; myProject = project; - myInternalMode = ApplicationManager.getApplication().isInternal(); + myInternalMode = ApplicationManager.getApplication().isInternal() || PluginManager.isPluginInstalled(PluginId.getId(EA_PLUGIN_ID)); setTitle(DiagnosticBundle.message("error.list.title")); setModal(false); From 8f35d1be287ca83424ef6f267b7a6ba96eb63382 Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Fri, 22 Feb 2019 18:09:27 +0300 Subject: [PATCH 03/16] EXA-590: submit timestamp of developers list update --- .../com/intellij/diagnostic/AbstractMessage.java | 9 +++++++++ .../src/com/intellij/diagnostic/ITNProxy.java | 5 ++++- .../com/intellij/diagnostic/IdeErrorsDialog.java | 13 ++++++++++--- .../diagnostic/InternalErrorReportConfigurable.kt | 2 ++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java b/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java index e5787a21bc62..e4a7534d3766 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java @@ -20,6 +20,7 @@ public abstract class AbstractMessage { private SubmittedReportInfo mySubmissionInfo; private String myAdditionalInfo; private Integer myAssigneeId; + private Long myDevelopersUpdateTimestamp; public abstract @NotNull Throwable getThrowable(); public abstract @NotNull String getThrowableText(); @@ -96,6 +97,14 @@ public abstract class AbstractMessage { myAssigneeId = assigneeId; } + public @Nullable Long getDevelopersUpdateTimestamp() { + return myDevelopersUpdateTimestamp; + } + + public void setDevelopersUpdateTimestamp(@Nullable Long developersUpdateTimestamp) { + myDevelopersUpdateTimestamp = developersUpdateTimestamp; + } + /** @deprecated use {@link #getIncludedAttachments()} instead (to be removed in IDEA 2020) */ @Deprecated public List getAttachments() { diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java index 1e75598e5c59..53945aeefdd2 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java @@ -61,7 +61,7 @@ class ITNProxy { private static final NotNullLazyValue> TEMPLATE = AtomicNotNullLazyValue.createValue(() -> { Map template = new LinkedHashMap<>(); - template.put("protocol.version", "1"); + template.put("protocol.version", "1.1"); template.put("os.name", SystemInfo.OS_NAME); template.put("java.version", SystemInfo.JAVA_VERSION); template.put("java.vm.vendor", SystemInfo.JAVA_VENDOR); @@ -254,6 +254,9 @@ class ITNProxy { if (messageObj.getAssigneeId() != null) { append(builder, "assignee.id", Integer.toString(messageObj.getAssigneeId())); } + if (messageObj.getDevelopersUpdateTimestamp() != null) { + append(builder, "assignee.list.timestamp", Long.toString(messageObj.getDevelopersUpdateTimestamp())); + } } return builder.toString().getBytes(StandardCharsets.UTF_8); diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 5d9715e315f9..380d77e36e2b 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -79,6 +79,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private final Set myAcceptedNotices; private final List myMessageClusters = new ArrayList<>(); // exceptions with the same stacktrace private int myIndex, myLastIndex = -1; + private Long myUpdateDevelopersTimestamp; private JLabel myCountLabel; private HyperlinkLabel.Croppable myInfoLabel; @@ -122,7 +123,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private void loadDevelopersList() { InternalErrorReportConfigurable internalConfigurable = InternalErrorReportConfigurable.getInstance(); if (internalConfigurable.isDevelopersListValid()) { - myAssigneeCombo.setModel(new CollectionComboBoxModel<>(internalConfigurable.getDevelopersList())); + setDevelopers(internalConfigurable); } else { new Task.Backgroundable(null, "Loading Developers List", true) { @@ -133,7 +134,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene UIUtil.invokeLaterIfNeeded(() -> { internalConfigurable.setDevelopersList(developers); if (isShowing()) { - myAssigneeCombo.setModel(new CollectionComboBoxModel<>(developers)); + setDevelopers(internalConfigurable); } }); } @@ -141,7 +142,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene LOG.debug(e); UIUtil.invokeLaterIfNeeded(() -> { if (isShowing()) { - myAssigneeCombo.setModel(new CollectionComboBoxModel<>(internalConfigurable.getDevelopersList())); + setDevelopers(internalConfigurable); } }); } @@ -151,6 +152,11 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } } + private void setDevelopers(InternalErrorReportConfigurable internalConfigurable) { + myAssigneeCombo.setModel(new CollectionComboBoxModel<>(internalConfigurable.getDevelopersList())); + myUpdateDevelopersTimestamp = internalConfigurable.getDevelopersUpdateTimestamp(); + } + private int selectMessage(@Nullable LogMessage defaultMessage) { if (defaultMessage != null) { for (int i = 0; i < myMessageClusters.size(); i++) { @@ -599,6 +605,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene if (submitter == null) return false; AbstractMessage message = cluster.first; + message.setDevelopersUpdateTimestamp(myUpdateDevelopersTimestamp); message.setSubmitting(true); String notice = submitter.getPrivacyNoticeText(); diff --git a/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt b/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt index 11a5987ebfea..ad76474cf73a 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt +++ b/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt @@ -29,6 +29,8 @@ internal class InternalErrorReportConfigurable : PersistentStateComponent Date: Mon, 25 Feb 2019 15:27:34 +0300 Subject: [PATCH 04/16] EXA-587: assignee combobox is near submit button and label blinks --- .../intellij/diagnostic/IdeErrorsDialog.java | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 380d77e36e2b..0e3981a9f5dd 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -39,6 +39,7 @@ import com.intellij.ui.*; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBScrollPane; import com.intellij.util.ExceptionUtil; +import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.DateFormatUtil; import com.intellij.util.ui.JBUI; @@ -58,6 +59,7 @@ import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.zip.CRC32; import static com.intellij.openapi.util.Pair.pair; @@ -292,7 +294,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene }; myAssigneePanel = new JPanel(); - myAssigneePanel.add(new JBLabel("Assignee:")); + myAssigneePanel.add(new BlinkingLabel("Suggested assignee:")); myAssigneePanel.add(myAssigneeCombo); } @@ -327,7 +329,6 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene attachmentsPanel.add(scrollPane(myAttachmentArea, 500, 350), BorderLayout.CENTER); JPanel accountRow = new JPanel(new BorderLayout()); - if (myInternalMode) accountRow.add(myAssigneePanel, BorderLayout.WEST); accountRow.add(myCredentialsLabel, BorderLayout.EAST); myNoticePanel = new JPanel(new GridBagLayout()); myNoticePanel.add(new JBLabel(UIUtil.getBalloonWarningIcon()), new GridBagConstraints(0, 0, 1, 1, 0, 0, NORTH, NONE, JBUI.insets(7, 0, 0, 5), 0, 0)); @@ -335,6 +336,11 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene JPanel bottomRow = new JPanel(new BorderLayout()); bottomRow.add(accountRow, BorderLayout.NORTH); bottomRow.add(myNoticePanel, BorderLayout.CENTER); + if (myInternalMode) { + JPanel assigneeRow = new JPanel(new BorderLayout()); + assigneeRow.add(myAssigneePanel, BorderLayout.EAST); + bottomRow.add(assigneeRow, BorderLayout.SOUTH); + } JPanel rootPanel = new JPanel(new BorderLayout()); rootPanel.setPreferredSize(JBUI.size(800, 400)); @@ -797,6 +803,42 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } } + private static class BlinkingLabel extends JBLabel { + + private boolean myFirstPainting = true; + + BlinkingLabel(@NotNull String text) { + super(text); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + + if (myFirstPainting) { + myFirstPainting = false; + + delay(() -> { + reverseBold(this); + delay(() -> reverseBold(this)); + }); + } + } + + private static void reverseBold(JComponent component) { + Font font = component.getFont(); + if ((font.getStyle() & Font.BOLD) == 0) { + component.setFont(font.deriveFont(font.getStyle() | Font.BOLD)); + } else { + component.setFont(font.deriveFont(font.getStyle() & ~Font.BOLD)); + } + } + + private static void delay(Runnable runnable) { + AppExecutorUtil.getAppScheduledExecutorService().schedule(() -> UIUtil.invokeLaterIfNeeded(runnable), 750, TimeUnit.MILLISECONDS); + } + } + /* interfaces */ @Override From ddbe05eddd68f9fb2feb58ab6720d56bc515ef68 Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Mon, 25 Feb 2019 17:05:21 +0300 Subject: [PATCH 05/16] EXA-594: add kotlin version to bug report if kotlin plugin present --- .../src/com/intellij/diagnostic/ITNProxy.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java index 53945aeefdd2..e806276f816a 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java @@ -4,12 +4,15 @@ package com.intellij.diagnostic; import com.intellij.errorreport.error.InternalEAPException; import com.intellij.errorreport.error.NoSuchEAPUserException; import com.intellij.errorreport.error.UpdateAvailableException; +import com.intellij.ide.plugins.IdeaPluginDescriptor; +import com.intellij.ide.plugins.PluginManager; import com.intellij.idea.IdeaLogger; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.diagnostic.Attachment; import com.intellij.openapi.diagnostic.IdeaLoggingEvent; +import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; @@ -88,6 +91,11 @@ class ITNProxy { template.put("app.product.code", build.getProductCode()); template.put("app.build.number", buildNumberWithAllDetails); + IdeaPluginDescriptor kotlinDescriptor = PluginManager.getPlugin(PluginId.getId("org.jetbrains.kotlin")); + if (kotlinDescriptor != null && kotlinDescriptor.getVersion() != null) { + template.put("app.kotlin.version", kotlinDescriptor.getVersion()); + } + return template; }); From 10703bb99b716fc9b02ad9e14edae3e94ce8159f Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Wed, 6 Mar 2019 15:43:04 +0300 Subject: [PATCH 06/16] Revert "EXA-594: add kotlin version to bug report if kotlin plugin present" This reverts commit ddbe05eddd68f9fb2feb58ab6720d56bc515ef68. --- .../src/com/intellij/diagnostic/ITNProxy.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java index e806276f816a..53945aeefdd2 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java @@ -4,15 +4,12 @@ package com.intellij.diagnostic; import com.intellij.errorreport.error.InternalEAPException; import com.intellij.errorreport.error.NoSuchEAPUserException; import com.intellij.errorreport.error.UpdateAvailableException; -import com.intellij.ide.plugins.IdeaPluginDescriptor; -import com.intellij.ide.plugins.PluginManager; import com.intellij.idea.IdeaLogger; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.diagnostic.Attachment; import com.intellij.openapi.diagnostic.IdeaLoggingEvent; -import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; @@ -91,11 +88,6 @@ class ITNProxy { template.put("app.product.code", build.getProductCode()); template.put("app.build.number", buildNumberWithAllDetails); - IdeaPluginDescriptor kotlinDescriptor = PluginManager.getPlugin(PluginId.getId("org.jetbrains.kotlin")); - if (kotlinDescriptor != null && kotlinDescriptor.getVersion() != null) { - template.put("app.kotlin.version", kotlinDescriptor.getVersion()); - } - return template; }); From 45fd84c9b3b72c1d097010fc724c7a0773360575 Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Thu, 7 Mar 2019 13:06:02 +0300 Subject: [PATCH 07/16] cosmetics --- .../com/intellij/diagnostic/BlinkingLabel.kt | 35 +++++++ .../com/intellij/diagnostic/Developer.java | 3 +- .../intellij/diagnostic/IdeErrorsDialog.java | 91 ++++++------------- .../InternalErrorReportConfigurable.kt | 40 ++++---- 4 files changed, 85 insertions(+), 84 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt diff --git a/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt b/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt new file mode 100644 index 000000000000..23eb14b730e0 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt @@ -0,0 +1,35 @@ +// Copyright 2000-2019 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.diagnostic + +import com.intellij.ui.components.JBLabel +import com.intellij.util.concurrency.AppExecutorUtil +import com.intellij.util.ui.UIUtil +import java.awt.Font +import java.awt.Graphics +import java.util.concurrent.TimeUnit + +internal class BlinkingLabel internal constructor(text: String) : JBLabel(text) { + + private var myFirstPainting = true + + override fun paintComponent(g: Graphics) { + super.paintComponent(g) + + if (myFirstPainting) { + myFirstPainting = false + + after(750) { + reverseBold() + after(750) { reverseBold() } + } + } + } + + private fun reverseBold() { + font = font.deriveFont(font.style xor Font.BOLD) + } + + private fun after(delay: Long, f: () -> Unit) { + AppExecutorUtil.getAppScheduledExecutorService().schedule({ UIUtil.invokeLaterIfNeeded(f) }, delay, TimeUnit.MILLISECONDS) + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/diagnostic/Developer.java b/platform/platform-impl/src/com/intellij/diagnostic/Developer.java index f3e42fad8082..123b5c8b6be1 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/Developer.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/Developer.java @@ -17,8 +17,7 @@ public class Developer { @SuppressWarnings("unused") // need for xml serialization private Developer() { - myId = 0; - myName = ""; + this(0, ""); } public Developer(int id, String name) { diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 0e3981a9f5dd..94148a8f37db 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -39,7 +39,6 @@ import com.intellij.ui.*; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBScrollPane; import com.intellij.util.ExceptionUtil; -import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.DateFormatUtil; import com.intellij.util.ui.JBUI; @@ -59,7 +58,6 @@ import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.*; -import java.util.concurrent.TimeUnit; import java.util.zip.CRC32; import static com.intellij.openapi.util.Pair.pair; @@ -77,11 +75,11 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private final MessagePool myMessagePool; private final Project myProject; - private final boolean myInternalMode; + private final boolean myDevelopersListVisible; private final Set myAcceptedNotices; private final List myMessageClusters = new ArrayList<>(); // exceptions with the same stacktrace private int myIndex, myLastIndex = -1; - private Long myUpdateDevelopersTimestamp; + private Long myDevelopersUpdateTimestamp; private JLabel myCountLabel; private HyperlinkLabel.Croppable myInfoLabel; @@ -101,14 +99,14 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene super(project, true); myMessagePool = messagePool; myProject = project; - myInternalMode = ApplicationManager.getApplication().isInternal() || PluginManager.isPluginInstalled(PluginId.getId(EA_PLUGIN_ID)); + myDevelopersListVisible = ApplicationManager.getApplication().isInternal() || PluginManager.isPluginInstalled(PluginId.getId(EA_PLUGIN_ID)); setTitle(DiagnosticBundle.message("error.list.title")); setModal(false); init(); setCancelButtonText(CommonBundle.message("close.action.name")); - if (myInternalMode) { + if (myDevelopersListVisible) { loadDevelopersList(); } @@ -124,8 +122,8 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private void loadDevelopersList() { InternalErrorReportConfigurable internalConfigurable = InternalErrorReportConfigurable.getInstance(); - if (internalConfigurable.isDevelopersListValid()) { - setDevelopers(internalConfigurable); + if (internalConfigurable.isDevelopersListObsolete()) { + loadConfigurable(internalConfigurable); } else { new Task.Backgroundable(null, "Loading Developers List", true) { @@ -134,9 +132,9 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene try { List developers = ITNProxy.fetchDevelopers(indicator); UIUtil.invokeLaterIfNeeded(() -> { - internalConfigurable.setDevelopersList(developers); + internalConfigurable.setDevelopers(developers); if (isShowing()) { - setDevelopers(internalConfigurable); + loadConfigurable(internalConfigurable); } }); } @@ -144,7 +142,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene LOG.debug(e); UIUtil.invokeLaterIfNeeded(() -> { if (isShowing()) { - setDevelopers(internalConfigurable); + loadConfigurable(internalConfigurable); } }); } @@ -154,9 +152,9 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } } - private void setDevelopers(InternalErrorReportConfigurable internalConfigurable) { - myAssigneeCombo.setModel(new CollectionComboBoxModel<>(internalConfigurable.getDevelopersList())); - myUpdateDevelopersTimestamp = internalConfigurable.getDevelopersUpdateTimestamp(); + private void loadConfigurable(InternalErrorReportConfigurable configurable) { + myAssigneeCombo.setModel(new CollectionComboBoxModel<>(configurable.getDevelopers())); + myDevelopersUpdateTimestamp = configurable.getDevelopersUpdateTimestamp(); } private int selectMessage(@Nullable LogMessage defaultMessage) { @@ -271,7 +269,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } }); - if (myInternalMode) { + if (myDevelopersListVisible) { myAssigneeCombo = new ComboBox<>(); myAssigneeCombo.setRenderer(new ListCellRendererWrapper() { @Override @@ -336,7 +334,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene JPanel bottomRow = new JPanel(new BorderLayout()); bottomRow.add(accountRow, BorderLayout.NORTH); bottomRow.add(myNoticePanel, BorderLayout.CENTER); - if (myInternalMode) { + if (myDevelopersListVisible) { JPanel assigneeRow = new JPanel(new BorderLayout()); assigneeRow.add(myAssigneePanel, BorderLayout.EAST); bottomRow.add(assigneeRow, BorderLayout.SOUTH); @@ -362,7 +360,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene @Override protected Action[] createActions() { List actions = new ArrayList<>(); - if (myInternalMode && myProject != null && !myProject.isDefault()) { + if (myDevelopersListVisible && myProject != null && !myProject.isDefault()) { AnAction action = ActionManager.getInstance().getAction("Unscramble"); if (action != null) { actions.add(new AnalyzeAction(action)); @@ -432,7 +430,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene updateLabels(cluster); updateDetails(cluster); - if (myInternalMode) { + if (myDevelopersListVisible) { updateAssigneePanel(cluster); } updateCredentialsPanel(submitter); @@ -569,14 +567,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene myAssigneeCombo.setSelectedIndex(-1); } else { - int assigneeIndex = -1; - for (int i = 0; i < myAssigneeCombo.getItemCount(); i++) { - if (Objects.equals(assignee, myAssigneeCombo.getItemAt(i).getId())) { - assigneeIndex = i; - break; - } - } - + int assigneeIndex = getAssigneeIndex(assignee); if (assigneeIndex != -1) { myAssigneeCombo.setSelectedIndex(assigneeIndex); } @@ -590,6 +581,16 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } } + private int getAssigneeIndex(Integer assigneeId) { + for (int index = 0; index < myAssigneeCombo.getItemCount(); index++) { + if (Objects.equals(assigneeId, myAssigneeCombo.getItemAt(index).getId())) { + return index; + } + } + + return -1; + } + private void updateCredentialsPanel(ErrorReportSubmitter submitter) { if (submitter instanceof ITNReporter) { myCredentialsLabel.setVisible(true); @@ -611,7 +612,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene if (submitter == null) return false; AbstractMessage message = cluster.first; - message.setDevelopersUpdateTimestamp(myUpdateDevelopersTimestamp); + message.setDevelopersUpdateTimestamp(myDevelopersUpdateTimestamp); message.setSubmitting(true); String notice = submitter.getPrivacyNoticeText(); @@ -803,42 +804,6 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } } - private static class BlinkingLabel extends JBLabel { - - private boolean myFirstPainting = true; - - BlinkingLabel(@NotNull String text) { - super(text); - } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - - if (myFirstPainting) { - myFirstPainting = false; - - delay(() -> { - reverseBold(this); - delay(() -> reverseBold(this)); - }); - } - } - - private static void reverseBold(JComponent component) { - Font font = component.getFont(); - if ((font.getStyle() & Font.BOLD) == 0) { - component.setFont(font.deriveFont(font.getStyle() | Font.BOLD)); - } else { - component.setFont(font.deriveFont(font.getStyle() & ~Font.BOLD)); - } - } - - private static void delay(Runnable runnable) { - AppExecutorUtil.getAppScheduledExecutorService().schedule(() -> UIUtil.invokeLaterIfNeeded(runnable), 750, TimeUnit.MILLISECONDS); - } - } - /* interfaces */ @Override diff --git a/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt b/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt index ad76474cf73a..816aee394783 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt +++ b/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt @@ -8,38 +8,40 @@ import com.intellij.openapi.components.Storage @State(name = "InternalErrorReportConfigurable", storages = [(Storage(value = "internalReportError.xml"))]) internal class InternalErrorReportConfigurable : PersistentStateComponent { - private var myState: State = State() + private var myState: State? = null - override fun getState(): State = myState + override fun getState(): State? = myState override fun loadState(state: State) { myState = state } - fun getDevelopersList(): List { - return myState.developersList.toList() + var developers: List + get() = myState?.developers?.toList() ?: emptyList() + set(developersList) { + myState = State(developersList.toList(), System.currentTimeMillis()) + } + + fun isDevelopersListObsolete(): Boolean { + val state = myState ?: return false + val developersListObsolete = System.currentTimeMillis() - state.developersUpdateTimestamp >= UPDATE_INTERVAL + return !developersListObsolete && state.developers.isNotEmpty() } - fun setDevelopersList(developersList: List) { - myState = State(developersList.toList(), System.currentTimeMillis()) - } - - fun isDevelopersListValid(): Boolean { - val developersListObsolete = System.currentTimeMillis() - myState.developersUpdateTimestamp >= DEVELOPERS_OBSOLESCENCE_MILLIS - return !developersListObsolete && myState.developersList.isNotEmpty() - } - - fun getDevelopersUpdateTimestamp(): Long = myState.developersUpdateTimestamp + fun getDevelopersUpdateTimestamp(): Long? = myState?.developersUpdateTimestamp private companion object { - private const val DEVELOPERS_OBSOLESCENCE_MILLIS = 24L * 60 * 60 * 1000 // 24 hours + private const val UPDATE_INTERVAL = 24L * 60 * 60 * 1000 // 24 hours @JvmStatic - fun getInstance(): InternalErrorReportConfigurable = ServiceManager.getService(InternalErrorReportConfigurable::class.java) + val instance: InternalErrorReportConfigurable + get() = ServiceManager.getService(InternalErrorReportConfigurable::class.java) } internal data class State( - var developersList: List = emptyList(), - var developersUpdateTimestamp: Long = 0 - ) + var developers: List, + var developersUpdateTimestamp: Long + ) { + private constructor(): this(emptyList(), 0) // need for xml serialization + } } From d9b5342097e6a8fcb64b3736bb8d639c03176832 Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Mon, 11 Mar 2019 12:30:12 +0300 Subject: [PATCH 08/16] Merge InternalErrorReportConfigurable into ErrorReportConfigurable --- .../diagnostic/ErrorReportConfigurable.kt | 66 +++++++++++++++---- .../intellij/diagnostic/IdeErrorsDialog.java | 22 ++++--- .../InternalErrorReportConfigurable.kt | 47 ------------- .../src/META-INF/PlatformExtensions.xml | 2 - 4 files changed, 65 insertions(+), 72 deletions(-) delete mode 100644 platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt index c84b5ddc83cb..746600ca507c 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt +++ b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt @@ -5,33 +5,71 @@ import com.intellij.credentialStore.CredentialAttributes import com.intellij.credentialStore.Credentials import com.intellij.credentialStore.SERVICE_NAME_PREFIX import com.intellij.ide.passwordSafe.PasswordSafe -import com.intellij.openapi.components.PersistentStateComponent -import com.intellij.openapi.components.RoamingType -import com.intellij.openapi.components.State -import com.intellij.openapi.components.Storage +import com.intellij.openapi.components.* import com.intellij.util.io.decodeBase64 +import com.intellij.util.xmlb.XmlSerializer +import org.jdom.Element -@State(name = "ErrorReportConfigurable", storages = [(Storage(value = "other.xml", deprecated = true, roamingType = RoamingType.DISABLED))]) -internal class ErrorReportConfigurable : PersistentStateComponent { +@State(name = "ErrorReportConfigurable", storages = [Storage(value = "other.xml", deprecated = true, roamingType = RoamingType.DISABLED), Storage(value = "errorReporting.xml")]) +internal class ErrorReportConfigurable : PersistentStateComponent { companion object { + + private const val ITN_LOGIN = "ITN_LOGIN" + private const val ITN_PASSWORD_CRYPT = "ITN_PASSWORD_CRYPT" + @JvmStatic val SERVICE_NAME = "$SERVICE_NAME_PREFIX — JetBrains Account" + @JvmStatic + val instance: ErrorReportConfigurable + get() = ServiceManager.getService(ErrorReportConfigurable::class.java) + @JvmStatic fun getCredentials() = PasswordSafe.instance.get(CredentialAttributes(SERVICE_NAME)) } - override fun getState() = OldState() + private var myState: State? = null - override fun loadState(state: OldState) { - if (!state.ITN_LOGIN.isNullOrEmpty() || !state.ITN_PASSWORD_CRYPT.isNullOrEmpty()) { - PasswordSafe.instance.set(CredentialAttributes(SERVICE_NAME, state.ITN_LOGIN), Credentials(state.ITN_LOGIN, state.ITN_PASSWORD_CRYPT!!.decodeBase64())) + var cachedDeveloper: CachedDevelopers? + get() = myState?.let { CachedDevelopers(it.developers.toList(), it.timestamp) } + set(value) { + myState = value?.let { State(it.developers.toList(), it.timestamp) } } + + override fun getState(): Element? { + return myState?.let { XmlSerializer.serialize(it) } + } + + override fun loadState(state: Element) { + loadOldState(state) + myState = XmlSerializer.deserialize(state, State::class.java) + } + + private fun loadOldState(element: Element) { + val options = element.getChildren("option") + + fun getOptionValue(name: String): String? = + options.find { it.getAttributeValue("name") == name }?.getAttributeValue("value") + + val login = getOptionValue(ITN_LOGIN) + val password = getOptionValue(ITN_PASSWORD_CRYPT) + + if (!login.isNullOrEmpty() || !password.isNullOrEmpty()) { + PasswordSafe.instance.set(CredentialAttributes(SERVICE_NAME, login), Credentials(login, password?.decodeBase64())) + } + } + + internal data class State(var developers: List, var timestamp: Long) { + private constructor(): this(emptyList(), 0) // need for xml serialization } } -@Suppress("PropertyName") -internal class OldState { - var ITN_LOGIN: String? = null - var ITN_PASSWORD_CRYPT: String? = null +internal data class CachedDevelopers(val developers: List, val timestamp: Long) { + companion object { + private const val UPDATE_INTERVAL = 24L * 60 * 60 * 1000 // 24 hours + } + + fun isUpToDateAt(timestamp: Long): Boolean { + return (timestamp - this.timestamp < UPDATE_INTERVAL) && developers.isNotEmpty() + } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 94148a8f37db..c6925a397019 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -121,9 +121,10 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } private void loadDevelopersList() { - InternalErrorReportConfigurable internalConfigurable = InternalErrorReportConfigurable.getInstance(); - if (internalConfigurable.isDevelopersListObsolete()) { - loadConfigurable(internalConfigurable); + ErrorReportConfigurable configurable = ErrorReportConfigurable.getInstance(); + CachedDevelopers cachedDevelopers = configurable.getCachedDeveloper(); + if (cachedDevelopers != null && cachedDevelopers.isUpToDateAt(System.currentTimeMillis())) { + loadCachedDevelopers(cachedDevelopers); } else { new Task.Backgroundable(null, "Loading Developers List", true) { @@ -132,9 +133,10 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene try { List developers = ITNProxy.fetchDevelopers(indicator); UIUtil.invokeLaterIfNeeded(() -> { - internalConfigurable.setDevelopers(developers); + CachedDevelopers cachedDevelopers = new CachedDevelopers(developers, System.currentTimeMillis()); + configurable.setCachedDeveloper(cachedDevelopers); if (isShowing()) { - loadConfigurable(internalConfigurable); + loadCachedDevelopers(cachedDevelopers); } }); } @@ -142,7 +144,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene LOG.debug(e); UIUtil.invokeLaterIfNeeded(() -> { if (isShowing()) { - loadConfigurable(internalConfigurable); + loadCachedDevelopers(cachedDevelopers); } }); } @@ -152,9 +154,11 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } } - private void loadConfigurable(InternalErrorReportConfigurable configurable) { - myAssigneeCombo.setModel(new CollectionComboBoxModel<>(configurable.getDevelopers())); - myDevelopersUpdateTimestamp = configurable.getDevelopersUpdateTimestamp(); + private void loadCachedDevelopers(@Nullable CachedDevelopers cachedDevelopers) { + if (cachedDevelopers != null) { + myAssigneeCombo.setModel(new CollectionComboBoxModel<>(cachedDevelopers.getDevelopers())); + myDevelopersUpdateTimestamp = cachedDevelopers.getTimestamp(); + } } private int selectMessage(@Nullable LogMessage defaultMessage) { diff --git a/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt b/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt deleted file mode 100644 index 816aee394783..000000000000 --- a/platform/platform-impl/src/com/intellij/diagnostic/InternalErrorReportConfigurable.kt +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2000-2019 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.diagnostic - -import com.intellij.openapi.components.PersistentStateComponent -import com.intellij.openapi.components.ServiceManager -import com.intellij.openapi.components.State -import com.intellij.openapi.components.Storage - -@State(name = "InternalErrorReportConfigurable", storages = [(Storage(value = "internalReportError.xml"))]) -internal class InternalErrorReportConfigurable : PersistentStateComponent { - private var myState: State? = null - - override fun getState(): State? = myState - - override fun loadState(state: State) { - myState = state - } - - var developers: List - get() = myState?.developers?.toList() ?: emptyList() - set(developersList) { - myState = State(developersList.toList(), System.currentTimeMillis()) - } - - fun isDevelopersListObsolete(): Boolean { - val state = myState ?: return false - val developersListObsolete = System.currentTimeMillis() - state.developersUpdateTimestamp >= UPDATE_INTERVAL - return !developersListObsolete && state.developers.isNotEmpty() - } - - fun getDevelopersUpdateTimestamp(): Long? = myState?.developersUpdateTimestamp - - private companion object { - private const val UPDATE_INTERVAL = 24L * 60 * 60 * 1000 // 24 hours - - @JvmStatic - val instance: InternalErrorReportConfigurable - get() = ServiceManager.getService(InternalErrorReportConfigurable::class.java) - } - - internal data class State( - var developers: List, - var developersUpdateTimestamp: Long - ) { - private constructor(): this(emptyList(), 0) // need for xml serialization - } -} diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 14b88e69afce..353c6deca761 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -82,8 +82,6 @@ - Date: Mon, 11 Mar 2019 13:07:13 +0300 Subject: [PATCH 09/16] BlinkingLabel: use Timer to delay events, change preferredSize and minimumSize --- .../com/intellij/diagnostic/BlinkingLabel.kt | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt b/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt index 23eb14b730e0..99c92ada6f27 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt +++ b/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt @@ -1,35 +1,50 @@ // Copyright 2000-2019 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.diagnostic +import com.intellij.ui.AncestorListenerAdapter import com.intellij.ui.components.JBLabel -import com.intellij.util.concurrency.AppExecutorUtil -import com.intellij.util.ui.UIUtil import java.awt.Font -import java.awt.Graphics -import java.util.concurrent.TimeUnit +import javax.swing.Timer +import javax.swing.event.AncestorEvent internal class BlinkingLabel internal constructor(text: String) : JBLabel(text) { - private var myFirstPainting = true + private var myPlainFont: Boolean = true + private val myTimer: Timer = Timer(750) { onTimer() } - override fun paintComponent(g: Graphics) { - super.paintComponent(g) + init { + myTimer.isRepeats = false - if (myFirstPainting) { - myFirstPainting = false + addAncestorListener(object: AncestorListenerAdapter() { + override fun ancestorAdded(event: AncestorEvent?) { + this@BlinkingLabel.removeAncestorListener(this) - after(750) { - reverseBold() - after(750) { reverseBold() } + myTimer.start() } + }) + + val sampleLabel = JBLabel(text) + sampleLabel.font = font.deriveFont(font.style or Font.BOLD) + minimumSize = sampleLabel.minimumSize + preferredSize = sampleLabel.preferredSize + } + + private fun onTimer() { + if (myPlainFont) { + setBoldFont() + myTimer.restart() + } else { + setPlainFont() } } - private fun reverseBold() { - font = font.deriveFont(font.style xor Font.BOLD) + private fun setPlainFont() { + myPlainFont = true + font = font.deriveFont(font.style and Font.BOLD.inv()) } - private fun after(delay: Long, f: () -> Unit) { - AppExecutorUtil.getAppScheduledExecutorService().schedule({ UIUtil.invokeLaterIfNeeded(f) }, delay, TimeUnit.MILLISECONDS) + private fun setBoldFont() { + myPlainFont = false + font = font.deriveFont(font.style or Font.BOLD) } } \ No newline at end of file From 8fe19cfef7da00075ced1b7653009f20c6cbd40d Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Mon, 11 Mar 2019 13:08:48 +0300 Subject: [PATCH 10/16] IdeErrorsDialog: return assignee panel to origin place --- .../src/com/intellij/diagnostic/IdeErrorsDialog.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index c6925a397019..358339ca202d 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -331,6 +331,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene attachmentsPanel.add(scrollPane(myAttachmentArea, 500, 350), BorderLayout.CENTER); JPanel accountRow = new JPanel(new BorderLayout()); + if (myDevelopersListVisible) accountRow.add(myAssigneePanel, BorderLayout.WEST); accountRow.add(myCredentialsLabel, BorderLayout.EAST); myNoticePanel = new JPanel(new GridBagLayout()); myNoticePanel.add(new JBLabel(UIUtil.getBalloonWarningIcon()), new GridBagConstraints(0, 0, 1, 1, 0, 0, NORTH, NONE, JBUI.insets(7, 0, 0, 5), 0, 0)); @@ -338,11 +339,6 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene JPanel bottomRow = new JPanel(new BorderLayout()); bottomRow.add(accountRow, BorderLayout.NORTH); bottomRow.add(myNoticePanel, BorderLayout.CENTER); - if (myDevelopersListVisible) { - JPanel assigneeRow = new JPanel(new BorderLayout()); - assigneeRow.add(myAssigneePanel, BorderLayout.EAST); - bottomRow.add(assigneeRow, BorderLayout.SOUTH); - } JPanel rootPanel = new JPanel(new BorderLayout()); rootPanel.setPreferredSize(JBUI.size(800, 400)); From b33021966460f3bba58284bc0a2e2657fa9e0453 Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Mon, 11 Mar 2019 13:10:21 +0300 Subject: [PATCH 11/16] IdeErrorDialog: cosmetics --- .../com/intellij/diagnostic/IdeErrorsDialog.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 358339ca202d..a9c65e3fbe73 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -75,7 +75,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private final MessagePool myMessagePool; private final Project myProject; - private final boolean myDevelopersListVisible; + private final boolean myAssigneeVisible; private final Set myAcceptedNotices; private final List myMessageClusters = new ArrayList<>(); // exceptions with the same stacktrace private int myIndex, myLastIndex = -1; @@ -99,14 +99,14 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene super(project, true); myMessagePool = messagePool; myProject = project; - myDevelopersListVisible = ApplicationManager.getApplication().isInternal() || PluginManager.isPluginInstalled(PluginId.getId(EA_PLUGIN_ID)); + myAssigneeVisible = ApplicationManager.getApplication().isInternal() || PluginManager.isPluginInstalled(PluginId.getId(EA_PLUGIN_ID)); setTitle(DiagnosticBundle.message("error.list.title")); setModal(false); init(); setCancelButtonText(CommonBundle.message("close.action.name")); - if (myDevelopersListVisible) { + if (myAssigneeVisible) { loadDevelopersList(); } @@ -273,7 +273,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } }); - if (myDevelopersListVisible) { + if (myAssigneeVisible) { myAssigneeCombo = new ComboBox<>(); myAssigneeCombo.setRenderer(new ListCellRendererWrapper() { @Override @@ -331,7 +331,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene attachmentsPanel.add(scrollPane(myAttachmentArea, 500, 350), BorderLayout.CENTER); JPanel accountRow = new JPanel(new BorderLayout()); - if (myDevelopersListVisible) accountRow.add(myAssigneePanel, BorderLayout.WEST); + if (myAssigneeVisible) accountRow.add(myAssigneePanel, BorderLayout.WEST); accountRow.add(myCredentialsLabel, BorderLayout.EAST); myNoticePanel = new JPanel(new GridBagLayout()); myNoticePanel.add(new JBLabel(UIUtil.getBalloonWarningIcon()), new GridBagConstraints(0, 0, 1, 1, 0, 0, NORTH, NONE, JBUI.insets(7, 0, 0, 5), 0, 0)); @@ -360,7 +360,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene @Override protected Action[] createActions() { List actions = new ArrayList<>(); - if (myDevelopersListVisible && myProject != null && !myProject.isDefault()) { + if (myAssigneeVisible && myProject != null && !myProject.isDefault()) { AnAction action = ActionManager.getInstance().getAction("Unscramble"); if (action != null) { actions.add(new AnalyzeAction(action)); @@ -430,7 +430,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene updateLabels(cluster); updateDetails(cluster); - if (myDevelopersListVisible) { + if (myAssigneeVisible) { updateAssigneePanel(cluster); } updateCredentialsPanel(submitter); From 469d5e3b4d62384475d2b956148d501cd8ffaf1b Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Mon, 11 Mar 2019 13:50:54 +0300 Subject: [PATCH 12/16] Add assignee visibility flag to error report --- .../src/com/intellij/diagnostic/AbstractMessage.java | 9 +++++++++ .../src/com/intellij/diagnostic/ITNProxy.java | 1 + .../src/com/intellij/diagnostic/IdeErrorsDialog.java | 1 + 3 files changed, 11 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java b/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java index e4a7534d3766..fc14f0ec99fc 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java @@ -20,6 +20,7 @@ public abstract class AbstractMessage { private SubmittedReportInfo mySubmissionInfo; private String myAdditionalInfo; private Integer myAssigneeId; + private boolean myAssigneeVisible; private Long myDevelopersUpdateTimestamp; public abstract @NotNull Throwable getThrowable(); @@ -97,6 +98,14 @@ public abstract class AbstractMessage { myAssigneeId = assigneeId; } + boolean isAssigneeVisible() { + return myAssigneeVisible; + } + + void setAssigneeVisible(boolean assigneeVisible) { + myAssigneeVisible = assigneeVisible; + } + public @Nullable Long getDevelopersUpdateTimestamp() { return myDevelopersUpdateTimestamp; } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java index 53945aeefdd2..d2d16c955df1 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java @@ -254,6 +254,7 @@ class ITNProxy { if (messageObj.getAssigneeId() != null) { append(builder, "assignee.id", Integer.toString(messageObj.getAssigneeId())); } + append(builder, "assignee.list.visible", Boolean.toString(messageObj.isAssigneeVisible())); if (messageObj.getDevelopersUpdateTimestamp() != null) { append(builder, "assignee.list.timestamp", Long.toString(messageObj.getDevelopersUpdateTimestamp())); } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index a9c65e3fbe73..f852c4701a6a 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -612,6 +612,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene if (submitter == null) return false; AbstractMessage message = cluster.first; + message.setAssigneeVisible(myAssigneeVisible); message.setDevelopersUpdateTimestamp(myDevelopersUpdateTimestamp); message.setSubmitting(true); From c6f4ce7a85089a2daf7909adc956b5083db645ae Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Thu, 14 Mar 2019 12:20:05 +0300 Subject: [PATCH 13/16] cosmetics --- .../intellij/diagnostic/AbstractMessage.java | 10 +++---- .../com/intellij/diagnostic/BlinkingLabel.kt | 25 ++++++++++------- .../diagnostic/ErrorReportConfigurable.kt | 6 ++--- .../src/com/intellij/diagnostic/ITNProxy.java | 4 +-- .../intellij/diagnostic/IdeErrorsDialog.java | 27 +++++++++---------- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java b/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java index fc14f0ec99fc..a3d2621ab6eb 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java @@ -21,7 +21,7 @@ public abstract class AbstractMessage { private String myAdditionalInfo; private Integer myAssigneeId; private boolean myAssigneeVisible; - private Long myDevelopersUpdateTimestamp; + private Long myDevelopersTimestamp; public abstract @NotNull Throwable getThrowable(); public abstract @NotNull String getThrowableText(); @@ -106,12 +106,12 @@ public abstract class AbstractMessage { myAssigneeVisible = assigneeVisible; } - public @Nullable Long getDevelopersUpdateTimestamp() { - return myDevelopersUpdateTimestamp; + public @Nullable Long getDevelopersTimestamp() { + return myDevelopersTimestamp; } - public void setDevelopersUpdateTimestamp(@Nullable Long developersUpdateTimestamp) { - myDevelopersUpdateTimestamp = developersUpdateTimestamp; + public void setDevelopersTimestamp(@Nullable Long developersTimestamp) { + myDevelopersTimestamp = developersTimestamp; } /** @deprecated use {@link #getIncludedAttachments()} instead (to be removed in IDEA 2020) */ diff --git a/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt b/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt index 99c92ada6f27..912b6262da42 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt +++ b/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt @@ -9,7 +9,6 @@ import javax.swing.event.AncestorEvent internal class BlinkingLabel internal constructor(text: String) : JBLabel(text) { - private var myPlainFont: Boolean = true private val myTimer: Timer = Timer(750) { onTimer() } init { @@ -17,20 +16,19 @@ internal class BlinkingLabel internal constructor(text: String) : JBLabel(text) addAncestorListener(object: AncestorListenerAdapter() { override fun ancestorAdded(event: AncestorEvent?) { - this@BlinkingLabel.removeAncestorListener(this) - myTimer.start() } + + override fun ancestorRemoved(event: AncestorEvent?) { + myTimer.stop() + } }) - val sampleLabel = JBLabel(text) - sampleLabel.font = font.deriveFont(font.style or Font.BOLD) - minimumSize = sampleLabel.minimumSize - preferredSize = sampleLabel.preferredSize + prepareSizeForBoldChange() } private fun onTimer() { - if (myPlainFont) { + if (isPlainFont()) { setBoldFont() myTimer.restart() } else { @@ -38,13 +36,20 @@ internal class BlinkingLabel internal constructor(text: String) : JBLabel(text) } } + private fun isPlainFont() = font.style and Font.BOLD == 0 + private fun setPlainFont() { - myPlainFont = true font = font.deriveFont(font.style and Font.BOLD.inv()) } private fun setBoldFont() { - myPlainFont = false font = font.deriveFont(font.style or Font.BOLD) } + + private fun prepareSizeForBoldChange() { + val sampleLabel = JBLabel(text) + sampleLabel.font = font.deriveFont(font.style or Font.BOLD) + minimumSize = sampleLabel.minimumSize + preferredSize = sampleLabel.preferredSize + } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt index 746600ca507c..79625bfa18d4 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt +++ b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt @@ -30,8 +30,8 @@ internal class ErrorReportConfigurable : PersistentStateComponent { private var myState: State? = null - var cachedDeveloper: CachedDevelopers? - get() = myState?.let { CachedDevelopers(it.developers.toList(), it.timestamp) } + var developer: Developers? + get() = myState?.let { Developers(it.developers.toList(), it.timestamp) } set(value) { myState = value?.let { State(it.developers.toList(), it.timestamp) } } @@ -64,7 +64,7 @@ internal class ErrorReportConfigurable : PersistentStateComponent { } } -internal data class CachedDevelopers(val developers: List, val timestamp: Long) { +internal data class Developers(val developers: List, val timestamp: Long) { companion object { private const val UPDATE_INTERVAL = 24L * 60 * 60 * 1000 // 24 hours } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java index d2d16c955df1..6bdd35481016 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java @@ -255,8 +255,8 @@ class ITNProxy { append(builder, "assignee.id", Integer.toString(messageObj.getAssigneeId())); } append(builder, "assignee.list.visible", Boolean.toString(messageObj.isAssigneeVisible())); - if (messageObj.getDevelopersUpdateTimestamp() != null) { - append(builder, "assignee.list.timestamp", Long.toString(messageObj.getDevelopersUpdateTimestamp())); + if (messageObj.getDevelopersTimestamp() != null) { + append(builder, "assignee.list.timestamp", Long.toString(messageObj.getDevelopersTimestamp())); } } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index f852c4701a6a..3f4f2c5dec7e 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -79,7 +79,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private final Set myAcceptedNotices; private final List myMessageClusters = new ArrayList<>(); // exceptions with the same stacktrace private int myIndex, myLastIndex = -1; - private Long myDevelopersUpdateTimestamp; + private Long myDevelopersTimestamp; private JLabel myCountLabel; private HyperlinkLabel.Croppable myInfoLabel; @@ -122,21 +122,20 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private void loadDevelopersList() { ErrorReportConfigurable configurable = ErrorReportConfigurable.getInstance(); - CachedDevelopers cachedDevelopers = configurable.getCachedDeveloper(); - if (cachedDevelopers != null && cachedDevelopers.isUpToDateAt(System.currentTimeMillis())) { - loadCachedDevelopers(cachedDevelopers); + Developers developers = configurable.getDeveloper(); + if (developers != null && developers.isUpToDateAt(System.currentTimeMillis())) { + setDevelopers(developers); } else { new Task.Backgroundable(null, "Loading Developers List", true) { @Override public void run(@NotNull ProgressIndicator indicator) { try { - List developers = ITNProxy.fetchDevelopers(indicator); + Developers updatedDevelopers = new Developers(ITNProxy.fetchDevelopers(indicator), System.currentTimeMillis()); UIUtil.invokeLaterIfNeeded(() -> { - CachedDevelopers cachedDevelopers = new CachedDevelopers(developers, System.currentTimeMillis()); - configurable.setCachedDeveloper(cachedDevelopers); + configurable.setDeveloper(updatedDevelopers); if (isShowing()) { - loadCachedDevelopers(cachedDevelopers); + setDevelopers(updatedDevelopers); } }); } @@ -144,7 +143,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene LOG.debug(e); UIUtil.invokeLaterIfNeeded(() -> { if (isShowing()) { - loadCachedDevelopers(cachedDevelopers); + setDevelopers(developers); } }); } @@ -154,10 +153,10 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } } - private void loadCachedDevelopers(@Nullable CachedDevelopers cachedDevelopers) { - if (cachedDevelopers != null) { - myAssigneeCombo.setModel(new CollectionComboBoxModel<>(cachedDevelopers.getDevelopers())); - myDevelopersUpdateTimestamp = cachedDevelopers.getTimestamp(); + private void setDevelopers(@Nullable Developers developers) { + if (developers != null) { + myAssigneeCombo.setModel(new CollectionComboBoxModel<>(developers.getDevelopers())); + myDevelopersTimestamp = developers.getTimestamp(); } } @@ -613,7 +612,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene AbstractMessage message = cluster.first; message.setAssigneeVisible(myAssigneeVisible); - message.setDevelopersUpdateTimestamp(myDevelopersUpdateTimestamp); + message.setDevelopersTimestamp(myDevelopersTimestamp); message.setSubmitting(true); String notice = submitter.getPrivacyNoticeText(); From 0b391bbd736db18d02893b1d88a4c4bc7837211d Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Tue, 26 Mar 2019 15:29:24 +0300 Subject: [PATCH 14/16] Revert "IdeErrorsDialog: return assignee panel to origin place" This reverts commit 8fe19cfef7da00075ced1b7653009f20c6cbd40d. --- .../src/com/intellij/diagnostic/IdeErrorsDialog.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 3f4f2c5dec7e..a787532de9d7 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -330,7 +330,6 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene attachmentsPanel.add(scrollPane(myAttachmentArea, 500, 350), BorderLayout.CENTER); JPanel accountRow = new JPanel(new BorderLayout()); - if (myAssigneeVisible) accountRow.add(myAssigneePanel, BorderLayout.WEST); accountRow.add(myCredentialsLabel, BorderLayout.EAST); myNoticePanel = new JPanel(new GridBagLayout()); myNoticePanel.add(new JBLabel(UIUtil.getBalloonWarningIcon()), new GridBagConstraints(0, 0, 1, 1, 0, 0, NORTH, NONE, JBUI.insets(7, 0, 0, 5), 0, 0)); @@ -338,6 +337,11 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene JPanel bottomRow = new JPanel(new BorderLayout()); bottomRow.add(accountRow, BorderLayout.NORTH); bottomRow.add(myNoticePanel, BorderLayout.CENTER); + if (myAssigneeVisible) { + JPanel assigneeRow = new JPanel(new BorderLayout()); + assigneeRow.add(myAssigneePanel, BorderLayout.EAST); + bottomRow.add(assigneeRow, BorderLayout.SOUTH); + } JPanel rootPanel = new JPanel(new BorderLayout()); rootPanel.setPreferredSize(JBUI.size(800, 400)); From 1bf4c8ab6fea1b8034b5f11dc8cad7de893abd8c Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Wed, 3 Apr 2019 17:17:13 +0300 Subject: [PATCH 15/16] ErrorReportConfigurable: restore old state deserialization --- .../diagnostic/ErrorReportConfigurable.kt | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt index 79625bfa18d4..2b4885c66e7d 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt +++ b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt @@ -14,9 +14,6 @@ import org.jdom.Element internal class ErrorReportConfigurable : PersistentStateComponent { companion object { - private const val ITN_LOGIN = "ITN_LOGIN" - private const val ITN_PASSWORD_CRYPT = "ITN_PASSWORD_CRYPT" - @JvmStatic val SERVICE_NAME = "$SERVICE_NAME_PREFIX — JetBrains Account" @@ -40,28 +37,29 @@ internal class ErrorReportConfigurable : PersistentStateComponent { return myState?.let { XmlSerializer.serialize(it) } } - override fun loadState(state: Element) { - loadOldState(state) - myState = XmlSerializer.deserialize(state, State::class.java) + override fun loadState(element: Element) { + loadOldState(element) + myState = XmlSerializer.deserialize(element, State::class.java) } private fun loadOldState(element: Element) { - val options = element.getChildren("option") + val state = XmlSerializer.deserialize(element, OldState::class.java) - fun getOptionValue(name: String): String? = - options.find { it.getAttributeValue("name") == name }?.getAttributeValue("value") - - val login = getOptionValue(ITN_LOGIN) - val password = getOptionValue(ITN_PASSWORD_CRYPT) - - if (!login.isNullOrEmpty() || !password.isNullOrEmpty()) { - PasswordSafe.instance.set(CredentialAttributes(SERVICE_NAME, login), Credentials(login, password?.decodeBase64())) + if (!state.ITN_LOGIN.isNullOrEmpty() || !state.ITN_PASSWORD_CRYPT.isNullOrEmpty()) { + PasswordSafe.instance.set(CredentialAttributes(SERVICE_NAME, state.ITN_LOGIN), Credentials(state.ITN_LOGIN, state.ITN_PASSWORD_CRYPT!!.decodeBase64())) } } - internal data class State(var developers: List, var timestamp: Long) { + private data class State(var developers: List, var timestamp: Long) { + @Suppress("unused") private constructor(): this(emptyList(), 0) // need for xml serialization } + + @Suppress("PropertyName") + private class OldState { + var ITN_LOGIN: String? = null + var ITN_PASSWORD_CRYPT: String? = null + } } internal data class Developers(val developers: List, val timestamp: Long) { From 3652c7bb6415ec7272dc9f0bbe6a90be3e00e4d9 Mon Sep 17 00:00:00 2001 From: Roman Vasiliev Date: Wed, 3 Apr 2019 17:23:54 +0300 Subject: [PATCH 16/16] IdeErrorsDialog: restore original design --- .../com/intellij/diagnostic/BlinkingLabel.kt | 55 ------------------- .../intellij/diagnostic/IdeErrorsDialog.java | 8 +-- 2 files changed, 2 insertions(+), 61 deletions(-) delete mode 100644 platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt diff --git a/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt b/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt deleted file mode 100644 index 912b6262da42..000000000000 --- a/platform/platform-impl/src/com/intellij/diagnostic/BlinkingLabel.kt +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2000-2019 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.diagnostic - -import com.intellij.ui.AncestorListenerAdapter -import com.intellij.ui.components.JBLabel -import java.awt.Font -import javax.swing.Timer -import javax.swing.event.AncestorEvent - -internal class BlinkingLabel internal constructor(text: String) : JBLabel(text) { - - private val myTimer: Timer = Timer(750) { onTimer() } - - init { - myTimer.isRepeats = false - - addAncestorListener(object: AncestorListenerAdapter() { - override fun ancestorAdded(event: AncestorEvent?) { - myTimer.start() - } - - override fun ancestorRemoved(event: AncestorEvent?) { - myTimer.stop() - } - }) - - prepareSizeForBoldChange() - } - - private fun onTimer() { - if (isPlainFont()) { - setBoldFont() - myTimer.restart() - } else { - setPlainFont() - } - } - - private fun isPlainFont() = font.style and Font.BOLD == 0 - - private fun setPlainFont() { - font = font.deriveFont(font.style and Font.BOLD.inv()) - } - - private fun setBoldFont() { - font = font.deriveFont(font.style or Font.BOLD) - } - - private fun prepareSizeForBoldChange() { - val sampleLabel = JBLabel(text) - sampleLabel.font = font.deriveFont(font.style or Font.BOLD) - minimumSize = sampleLabel.minimumSize - preferredSize = sampleLabel.preferredSize - } -} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index a787532de9d7..326030d00e88 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -295,7 +295,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene }; myAssigneePanel = new JPanel(); - myAssigneePanel.add(new BlinkingLabel("Suggested assignee:")); + myAssigneePanel.add(new JBLabel("Assignee:")); myAssigneePanel.add(myAssigneeCombo); } @@ -330,6 +330,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene attachmentsPanel.add(scrollPane(myAttachmentArea, 500, 350), BorderLayout.CENTER); JPanel accountRow = new JPanel(new BorderLayout()); + if (myAssigneeVisible) accountRow.add(myAssigneePanel, BorderLayout.WEST); accountRow.add(myCredentialsLabel, BorderLayout.EAST); myNoticePanel = new JPanel(new GridBagLayout()); myNoticePanel.add(new JBLabel(UIUtil.getBalloonWarningIcon()), new GridBagConstraints(0, 0, 1, 1, 0, 0, NORTH, NONE, JBUI.insets(7, 0, 0, 5), 0, 0)); @@ -337,11 +338,6 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene JPanel bottomRow = new JPanel(new BorderLayout()); bottomRow.add(accountRow, BorderLayout.NORTH); bottomRow.add(myNoticePanel, BorderLayout.CENTER); - if (myAssigneeVisible) { - JPanel assigneeRow = new JPanel(new BorderLayout()); - assigneeRow.add(myAssigneePanel, BorderLayout.EAST); - bottomRow.add(assigneeRow, BorderLayout.SOUTH); - } JPanel rootPanel = new JPanel(new BorderLayout()); rootPanel.setPreferredSize(JBUI.size(800, 400));